aboutsummaryrefslogtreecommitdiffstats
path: root/mod
diff options
context:
space:
mode:
Diffstat (limited to 'mod')
-rw-r--r--mod/contacts.php116
-rw-r--r--mod/dfrn_confirm.php374
-rw-r--r--mod/dfrn_poll.php58
-rw-r--r--mod/dfrn_request.php290
-rw-r--r--mod/home.php24
-rw-r--r--mod/item.php68
-rw-r--r--mod/login.php8
-rw-r--r--mod/notifications.php98
-rw-r--r--mod/photo.php25
-rw-r--r--mod/profile.php136
-rw-r--r--mod/profile_photo.php227
-rw-r--r--mod/profiles.php190
-rw-r--r--mod/redir.php21
-rw-r--r--mod/register.php175
-rw-r--r--mod/settings.php170
-rw-r--r--mod/test.php4
16 files changed, 1984 insertions, 0 deletions
diff --git a/mod/contacts.php b/mod/contacts.php
new file mode 100644
index 000000000..e6c2005e0
--- /dev/null
+++ b/mod/contacts.php
@@ -0,0 +1,116 @@
+<?php
+function edit_contact(&$a,$contact_id) {
+
+}
+
+function contacts_post(&$a) {
+
+
+ if(($a->argc != 3) || (! local_user()))
+ return;
+
+ $contact_id = intval($a->argv[1]);
+ if(! $contact_id)
+ return;
+
+ $cmd = $a->argv[2];
+
+ $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ intval($contact_id),
+ intval($_SESSION['uid'])
+ );
+
+ if(! count($r))
+ return;
+ $photo = str_replace('-4.jpg', '' , $r[0]['photo']);
+ $photos = q("SELECT `id` FROM `photo` WHERE `resource-id` = '%s' AND `uid` = %d",
+ dbesc($photo),
+ intval($_SESSION['uid'])
+ );
+
+
+ switch($cmd) {
+ case 'edit':
+ edit_contact($a,$contact_id);
+ break;
+ case 'block':
+ $r = q("UPDATE `contact` SET `blocked` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ intval($contact_id),
+ intval($_SESSION['uid'])
+ );
+ if($r)
+ $_SESSION['sysmsg'] .= "Contact has been blocked." . EOL;
+ break;
+ case 'drop':
+ $r = q("DELETE FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ intval($contact_id),
+ intval($_SESSION['uid']));
+ if(count($photos)) {
+ foreach($photos as $p) {
+ q("DELETE FROM `photos` WHERE `id` = %d LIMIT 1",
+ $p['id']);
+ }
+ }
+ if($intval($contact_id))
+ q("DELETE * FROM `item` WHERE `contact-id` = %d ",
+ intval($contact_id)
+ );
+
+ break;
+ default:
+ return;
+ break;
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+
+function contacts_content(&$a) {
+ if(! local_user()) {
+ $_SESSION['sysmsg'] .= "Permission denied." . EOL;
+ return;
+ }
+
+ if(($a->argc2 == 2) && ($a->argv[1] == 'all'))
+ $sql_extra = '';
+ else
+ $sql_extra = " AND `blocked` = 0 ";
+
+ $tpl = file_get_contents("view/contacts-top.tpl");
+ $o .= replace_macros($tpl,array(
+ '$hide_url' => ((strlen($sql_extra)) ? 'contacts/all' : 'contacts' ),
+ '$hide_text' => ((strlen($sql_extra)) ? 'Show Blocked Connections' : 'Hide Blocked Connections')
+ ));
+
+
+ $r = q("SELECT * FROM `contact` WHERE `uid` = %d",
+ intval($_SESSION['uid']));
+
+ if(count($r)) {
+
+ $tpl = file_get_contents("view/contact_template.tpl");
+
+ foreach($r as $rr) {
+ if($rr['self'])
+ continue;
+ $o .= replace_macros($tpl, array(
+ '$id' => $rr['id'],
+ '$thumb' => $rr['thumb'],
+ '$name' => $rr['name'],
+ '$url' => $rr['url']
+ ));
+ }
+ }
+ return $o;
+
+
+} \ No newline at end of file
diff --git a/mod/dfrn_confirm.php b/mod/dfrn_confirm.php
new file mode 100644
index 000000000..c830f1cf2
--- /dev/null
+++ b/mod/dfrn_confirm.php
@@ -0,0 +1,374 @@
+<?php
+
+
+
+function dfrn_confirm_post(&$a) {
+
+ if($a->argc > 1)
+ $node = $a->argv[1];
+
+ if(x($_POST,'source_url')) {
+
+ // We are processing an external confirmation to an introduction created by our user.
+
+ $public_key = $_POST['public_key'];
+ $dfrn_id = $_POST['dfrn_id'];
+ $source_url = $_POST['source_url'];
+ $aes_key = $_POST['aes_key'];
+
+ if(intval($node))
+ $r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
+ intval($node));
+ else
+ $r = q("SELECT * FROM `user` WHERE `nickname` = '%s' LIMIT 1",
+ dbesc($node));
+
+ if(! count($r)) {
+ xml_status(3); // failure
+ }
+
+ $my_prvkey = $r[0]['prvkey'];
+ $local_uid = $r[0]['uid'];
+
+ $decrypted_source_url = "";
+
+ openssl_private_decrypt($source_url,$decrypted_source_url,$my_prvkey);
+
+
+ $ret = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1",
+ dbesc($decrypted_source_url),
+ intval($local_uid));
+
+ if(! count($ret)) {
+ // this is either a bogus confirmation or we deleted the original introduction.
+ xml_status(3);
+ }
+
+ // Decrypt all this stuff we just received
+
+ $foreign_pubkey = $ret[0]['site-pubkey'];
+ $dfrn_record = $ret[0]['id'];
+ $decrypted_dfrn_id = "";
+ openssl_public_decrypt($dfrn_id,$decrypted_dfrn_id,$foreign_pubkey);
+
+ if(strlen($aes_key)) {
+ $decrypted_aes_key = "";
+ openssl_private_decrypt($aes_key,$decrypted_aes_key,$my_prvkey);
+ $dfrn_pubkey = openssl_decrypt($public_key,'AES-256-CBC',$decrypted_aes_key);
+ }
+ else {
+ $dfrn_pubkey = $public_key;
+ }
+
+ $r = q("SELECT * FROM `contact` WHERE `dfrn-id` = '%s' LIMIT 1",
+ dbesc($decrypted_dfrn_id),
+ intval($local_uid));
+ if(count($r))
+ xml_status(1); // Birthday paradox - duplicate dfrn-id
+
+ $r = q("UPDATE `contact` SET `dfrn-id` = '%s', `pubkey` = '%s' WHERE `id` = %d LIMIT 1",
+ dbesc($decrypted_dfrn_id),
+ dbesc($dfrn_pubkey),
+ intval($dfrn_record));
+ if($r) {
+
+ // We're good but now we have to scrape the profile photo and send notifications.
+
+ require_once("Photo.php");
+
+ $photo_failure = false;
+
+ $r = q("SELECT `photo` FROM `contact` WHERE `id` = %d LIMIT 1",
+ intval($dfrn_record));
+ if(count($r)) {
+
+ $filename = basename($r[0]['photo']);
+ $img_str = fetch_url($r[0]['photo'],true);
+ $img = new Photo($img_str);
+ if($img) {
+
+ $img->scaleImageSquare(175);
+
+ $hash = hash('md5',uniqid(mt_rand(),true));
+
+ $r = q("INSERT INTO `photo` ( `uid`, `resource-id`, `created`, `edited`, `filename`,
+ `height`, `width`, `data`, `scale` )
+ VALUES ( %d, '%s', '%s', '%s', '%s', %d, %d, '%s', 4 )",
+ intval($local_uid),
+ dbesc($hash),
+ datetime_convert(),
+ datetime_convert(),
+ dbesc(basename($r[0]['photo'])),
+ intval($img->getHeight()),
+ intval($img->getWidth()),
+ dbesc($img->imageString())
+ );
+ if($r === false)
+ $photo_failure = true;
+ $img->scaleImage(80);
+ $r = q("INSERT INTO `photo` ( `uid`, `resource-id`, `created`, `edited`, `filename`,
+ `height`, `width`, `data`, `scale` )
+ VALUES ( %d, '%s', '%s', '%s', '%s', %d, %d, '%s', 5 )",
+ intval($local_uid),
+ dbesc($hash),
+ datetime_convert(),
+ datetime_convert(),
+ dbesc(basename($r[0]['photo'])),
+ intval($img->getHeight()),
+ intval($img->getWidth()),
+ dbesc($img->imageString())
+ );
+ if($r === false)
+ $photo_failure = true;
+
+ $photo = $a->get_baseurl() . '/photo/' . $hash . '-4.jpg';
+ $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.jpg';
+
+ }
+ else
+ $photo_failure = true;
+ }
+ else
+ $photo_failure = true;
+
+ if($photo_failure) {
+ $photo = $a->get_baseurl() . '/images/default-profile.jpg';
+ $thumb = $a->get_baseurl() . '/images/default-profile-sm.jpg';
+ }
+
+ $r = q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `blocked` = 0 WHERE `id` = %d LIMIT 1",
+ dbesc($photo),
+ dbesc($thumb),
+ intval($dfrn_record)
+ );
+ if($r === false)
+ $_SESSION['sysmsg'] .= "Unable to set contact photo info." . EOL;
+
+ // Otherwise everything seems to have worked and we are almost done. Yay!
+ // Send an email notification
+
+ $r = q("SELECT * FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
+ WHERE `contact`.`id` = %d LIMIT 1",
+ intval($dfrn_record));
+
+ $tpl = file_get_contents('view/intro_complete_eml.tpl');
+
+ $email_tpl = replace_macros($tpl, array(
+ '$sitename' => $a->config['sitename'],
+ '$siteurl' => $a->get_baseurl(),
+ '$username' => $r[0]['username'],
+ '$email' => $r[0]['email'],
+ '$fn' => $r[0]['name'],
+ '$dfrn_url' => $r[0]['url'],
+ '$uid' => $newuid ));
+
+
+ $res = mail($r[0]['email'],"Introduction accepted at {$a->config['sitename']}",
+ $email_tpl,"From: Administrator@{$_SERVER[SERVER_NAME]}");
+ if(!$res) {
+ $_SESSION['sysmsg'] .= "Email notification failed." . EOL;
+ }
+ xml_status(0); // Success
+
+ return; // NOTREACHED
+
+ }
+ else
+ xml_status(2); // Hopefully temporary problem that can be retried.
+
+ return; // NOTREACHED
+
+ ////////////////////// End of this scenario ///////////////////////////////////////////////
+ }
+ else {
+
+ // We are processing a local confirmation initiated on this system by our user to an external introduction.
+
+ $uid = $_SESSION['uid'];
+
+ if(! $uid) {
+ $_SESSION['sysmsg'] = 'Unauthorised.';
+ return;
+ }
+
+ $dfrn_id = ((x($_POST,'dfrn_id')) ? notags(trim($_POST['dfrn_id'])) : "");
+ $intro_id = intval($_POST['intro_id']);
+
+ $r = q("SELECT * FROM `contact` WHERE `issued-id` = '%s' AND `uid` = %d LIMIT 1",
+ dbesc($dfrn_id),
+ intval($uid)
+ );
+
+ if((! $r) || (! count($r))) {
+ $_SESSION['sysmsg'] = 'Node does not exist.' . EOL ;
+ return;
+ }
+
+ $contact_id = $r[0]['id'];
+ $site_pubkey = $r[0]['site-pubkey'];
+ $dfrn_confirm = $r[0]['confirm'];
+ $aes_allow = $r[0]['aes_allow'];
+
+ $res=openssl_pkey_new(array(
+ 'digest_alg' => 'whirlpool',
+ 'private_key_bits' => 4096,
+ 'encrypt_key' => false ));
+
+
+ $private_key = '';
+
+ openssl_pkey_export($res, $private_key);
+
+
+ $pubkey = openssl_pkey_get_details($res);
+ $public_key = $pubkey["key"];
+
+ $r = q("UPDATE `contact` SET `pubkey` = '%s', `prvkey` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ dbesc($public_key),
+ dbesc($private_key),
+ intval($contact_id),
+ intval($uid)
+ );
+
+
+ $params = array();
+
+ $src_aes_key = random_string();
+ $result = "";
+
+ openssl_private_encrypt($dfrn_id,$result,$a->user['prvkey']);
+
+ $params['dfrn_id'] = $result;
+ $params['public_key'] = $public_key;
+
+
+ openssl_public_encrypt($_SESSION['my_url'], $params['source_url'], $site_pubkey);
+
+ if($aes_allow && function_exists('openssl_encrypt')) {
+ openssl_public_encrypt($src_aes_key, $params['aes_key'], $site_pubkey);
+ $params['public_key'] = openssl_encrypt($public_key,'AES-256-CBC',$src_aes_key);
+ }
+
+ $res = post_url($dfrn_confirm,$params);
+
+// uncomment the following two lines and comment the following xml/status lines
+// to debug the remote confirmation section (when both confirmations
+// and responses originate on this system)
+
+// echo $res;
+// $status = 0;
+
+ $xml = simplexml_load_string($res);
+ $status = (int) $xml->status;
+ switch($status) {
+ case 0:
+ $_SESSION['sysmsg'] .= "Confirmation completed successfully" . EOL;
+ break;
+ case 1:
+
+ // birthday paradox - generate new dfrn-id and fall through.
+
+ $new_dfrn_id = random_string();
+ $r = q("UPDATE contact SET `issued-id` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ dbesc($new_dfrn_id),
+ intval($contact_id),
+ intval($uid)
+ );
+
+ case 2:
+ $_SESSION['sysmsg'] .= "Temporary failure. Please wait and try again." . EOL;
+ break;
+
+
+ case 3:
+ $_SESSION['sysmsg'] .= "Introduction failed or was revoked. Cannot complete." . EOL;
+ break;
+ }
+
+ if(($status == 0 || $status == 3) && ($intro_id)) {
+
+ //delete the notification
+
+ $r = q("DELETE FROM `intro` WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ intval($intro_id),
+ intval($uid)
+ );
+
+ }
+ if($status != 0)
+ return;
+
+
+ require_once("Photo.php");
+
+ $photo_failure = false;
+
+ $r = q("SELECT `photo` FROM `contact` WHERE `id` = %d LIMIT 1",
+ intval($contact_id));
+ if(count($r)) {
+
+ $filename = basename($r[0]['photo']);
+ $img_str = fetch_url($r[0]['photo'],true);
+ $img = new Photo($img_str);
+ if($img) {
+
+ $img->scaleImageSquare(175);
+
+ $hash = hash('md5',uniqid(mt_rand(),true));
+
+ $r = q("INSERT INTO `photo` ( `uid`, `resource-id`, `created`, `edited`, `filename`,
+ `height`, `width`, `data`, `scale` )
+ VALUES ( %d, '%s', '%s', '%s', '%s', %d, %d, '%s', 4 )",
+ intval($local_uid),
+ dbesc($hash),
+ datetime_convert(),
+ datetime_convert(),
+ dbesc(basename($r[0]['photo'])),
+ intval($img->getHeight()),
+ intval($img->getWidth()),
+ dbesc($img->imageString())
+ );
+ if($r === false)
+ $photo_failure = true;
+ $img->scaleImage(80);
+ $r = q("INSERT INTO `photo` ( `uid`, `resource-id`, `created`, `edited`, `filename`,
+ `height`, `width`, `data`, `scale` )
+ VALUES ( %d, '%s', '%s', '%s', '%s', %d, %d, '%s', 5 )",
+ intval($local_uid),
+ dbesc($hash),
+ datetime_convert(),
+ datetime_convert(),
+ dbesc(basename($r[0]['photo'])),
+ intval($img->getHeight()),
+ intval($img->getWidth()),
+ dbesc($img->imageString())
+ );
+ if($r === false)
+ $photo_failure = true;
+
+ $photo = $a->get_baseurl() . '/photo/' . $hash . '-4.jpg';
+ $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.jpg';
+
+ }
+ else
+ $photo_failure = true;
+ }
+ else
+ $photo_failure = true;
+
+ if($photo_failure) {
+ $photo = $a->get_baseurl() . '/images/default-profile.jpg';
+ $thumb = $a->get_baseurl() . '/images/default-profile-sm.jpg';
+ }
+
+ $r = q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `blocked` = 0 WHERE `id` = %d LIMIT 1",
+ dbesc($photo),
+ dbesc($thumb),
+ intval($contact_id)
+ );
+ if($r === false)
+ $_SESSION['sysmsg'] .= "Unable to set contact photo info." . EOL;
+ }
+
+ return;
+}
diff --git a/mod/dfrn_poll.php b/mod/dfrn_poll.php
new file mode 100644
index 000000000..e7f4b0786
--- /dev/null
+++ b/mod/dfrn_poll.php
@@ -0,0 +1,58 @@
+<?php
+
+
+function dfrn_poll_init(&$a) {
+
+ if(x($_GET,'dfrn_id'))
+ $dfrn_id = $a->config['dfrn_poll_dfrn_id'] = $_GET['dfrn_id'];
+ if(x($_GET,'type'))
+ $type = $a->config['dfrn_poll_type'] = $_GET['type'];
+ if(x($_GET,'last_update'))
+ $last_update = $a->config['dfrn_poll_last_update'] = $_GET['last_update'];
+
+
+
+ if(! x($dfrn_id))
+ return;
+
+
+ if((x($type)) && ($type == 'profile')) {
+
+ $r = q("SELECT `contact`.*, `user`.`nickname`
+ FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
+ WHERE `issued-id` = '%s' LIMIT 1",
+ dbesc($dfrn_id));
+ if(count($r)) {
+ $s = fetch_url($r[0]['poll'] . '?dfrn_id=' . $dfrn_id . '&type=profile-check');
+ if(strlen($s)) {
+ $xml = simplexml_load_string($s);
+ if((int) $xml->status == 1) {
+ $_SESSION['authenticated'] = 1;
+ $_SESSION['visitor_id'] = $r[0]['id'];
+ $_SESSION['sysmsg'] .= "Hi {$r[0]['name']}" . EOL;
+ // Visitors get 1 day session.
+ $session_id = session_id();
+ $expire = time() + 86400;
+ q("UPDATE `session` SET `expire` = '%s' WHERE `sid` = '%s' LIMIT 1",
+ dbesc($expire),
+ dbesc($session_id));
+ }
+ }
+ $profile = ((strlen($r[0]['nickname'])) ? $r[0]['nickname'] : $r[0]['uid']);
+ goaway($a->get_baseurl() . "/profile/$profile");
+ }
+ goaway($a->get_baseurl());
+ }
+
+ if((x($type)) && ($type == 'profile-check')) {
+
+ q("DELETE FROM `expire` WHERE `expire` < " . time());
+ $r = q("SELECT * FROM `profile_check` WHERE `dfrn_id` = '%s' ORDER BY `expire` DESC",
+ dbesc($dfrn_id));
+ if(count($r))
+ xml_status(1);
+ xml_status(0);
+ return; // NOTREACHED
+ }
+
+}
diff --git a/mod/dfrn_request.php b/mod/dfrn_request.php
new file mode 100644
index 000000000..ef3c7274b
--- /dev/null
+++ b/mod/dfrn_request.php
@@ -0,0 +1,290 @@
+<?php
+
+if(! function_exists('dfrn_request_init')) {
+function dfrn_request_init(&$a) {
+
+ if($_SESSION['authenticated']) {
+ // choose which page to show (could be remote auth)
+
+ }
+
+ if($a->argc > 1)
+ $which = $a->argv[1];
+
+ require_once('mod/profile.php');
+ profile_init($a,$which);
+
+ return;
+}}
+
+
+if(! function_exists('dfrn_request_post')) {
+function dfrn_request_post(&$a) {
+
+ if(($a->argc != 2) || (! count($a->profile)))
+ return;
+
+
+ if($_POST['cancel']) {
+ goaway($a->get_baseurl());
+ }
+
+ // callback to local site after remote request and local confirm
+
+ if((x($_POST,'localconfirm')) && ($_POST['localconfirm'] == 1)
+ && (x($_SESSION,'authenticated')) && (x($_SESSION,'uid'))
+ && ($_SESSION['uid'] == $a->argv[1]) && (x($_POST,'dfrn_url'))) {
+
+ $dfrn_url = notags(trim($_POST['dfrn_url']));
+ $aes_allow = (((x($_POST,'aes_allow')) && ($_POST['aes_allow'] == 1)) ? 1 : 0);
+ $confirm_key = ((x($_POST,'confirm_key')) ? $_POST['confirm_key'] : "");
+ $failed = false;
+
+ require_once('Scrape.php');
+
+ if(x($dfrn_url)) {
+
+ $parms = scrape_dfrn($dfrn_url);
+
+ if(! count($parms)) {
+ $_SESSION['sysmsg'] .= 'URL is not valid or does not contain profile information.' . EOL ;
+ $failed = true;
+ }
+ else {
+ if(! x($parms,'fn'))
+ $_SESSION['sysmsg'] .= 'Warning: DFRN profile has no identifiable owner name.' . EOL ;
+ if(! x($parms,'photo'))
+ $_SESSION['sysmsg'] .= 'Warning: DFRN profile has no profile photo.' . EOL ;
+ $invalid = validate_dfrn($parms);
+ if($invalid) {
+ echo $invalid . ' required DFRN parameter'
+ . (($invalid == 1) ? " was " : "s were " )
+ . "not found at the given URL" . '<br />';
+
+ $failed = true;
+ }
+ }
+ }
+ if(! $failed) {
+
+ $dfrn_request = $parms['dfrn-request'];
+ /////////////////////////
+ dbesc_array($parms);
+ ////////////////////////
+
+ $r = q("INSERT INTO `contact` ( `uid`, `created`,`url`, `name`, `photo`, `site-pubkey`,
+ `request`, `confirm`, `notify`, `poll`, `aes_allow`)
+ VALUES ( %d, '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', %d)",
+ intval($_SESSION['uid']),
+ datetime_convert(),
+ dbesc($dfrn_url),
+ $parms['fn'],
+ $parms['photo'],
+ $parms['key'],
+ $parms['dfrn-request'],
+ $parms['dfrn-confirm'],
+ $parms['dfrn-notify'],
+ $parms['dfrn-poll'],
+ intval($aes_allow)
+ );
+ if($r === false)
+ $_SESSION['sysmsg'] .= "Failed to create contact." . EOL;
+ else
+ $_SESSION['sysmsg'] .= "Introduction complete.";
+
+ // Allow the blocked remote notification to complete
+
+ if(strlen($dfrn_request) && strlen($confirm_key))
+ $s = fetch_url($dfrn_request . '?confirm_key=' . $confirm_key);
+
+ goaway($dfrn_url);
+ }
+ }
+
+
+ // we are operating as a remote site and an introduction was requested of us.
+ // Scrape the originating DFRN-URL for everything we need. Create a contact record
+ // and an introduction to show our user next time he/she logs in.
+ // Finally redirect back to the originator so that their site can record the request.
+ // If our user confirms the request, a record of it will need to exist on the
+ // originator's site in order for the confirmation process to complete..
+
+ if($a->profile['nickname'])
+ $tailname = $a->profile['nickname'];
+ else
+ $tailname = $a->profile['uid'];
+
+ $uid = $a->profile['uid'];
+
+ $failed = false;
+
+ require_once('Scrape.php');
+
+ if( x($_POST,'dfrn_url')) {
+
+ $url = trim($_POST['dfrn_url']);
+ if(x($url)) {
+ $parms = scrape_dfrn($url);
+
+ if(! count($parms)) {
+ $_SESSION['sysmsg'] .= 'URL is not valid or does not contain profile information.' . EOL ;
+ $failed = true;
+ }
+ else {
+ if(! x($parms,'fn'))
+ $_SESSION['sysmsg'] .= 'Warning: DFRN profile has no identifiable owner name.' . EOL ;
+ if(! x($parms,'photo'))
+ $_SESSION['sysmsg'] .= 'Warning: DFRN profile has no profile photo.' . EOL ;
+ $invalid = validate_dfrn($parms);
+ if($invalid) {
+ echo $invalid . ' required DFRN parameter'
+ . (($invalid == 1) ? " was " : "s were " )
+ . "not found at the given URL" . '<br />';
+
+ $failed = true;
+ }
+ }
+ }
+
+ $ret = q("SELECT `url` FROM `contact` WHERE `url` = '%s'", dbesc($url));
+ if($ret !== false && count($ret)) {
+ $_SESSION['sysmsg'] .= 'You have already introduced yourself here.' . EOL;
+ $failed = true;
+ }
+
+
+ if(! $failed) {
+
+ $parms['url'] = $url;
+ $parms['issued-id'] = random_string();
+
+ /////////////////////////
+ dbesc_array($parms);
+ ////////////////////////
+
+ $ret = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `name`, `issued-id`, `photo`, `site-pubkey`,
+ `request`, `confirm`, `notify`, `poll`, `visible` )
+ VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d )",
+ intval($uid),
+ datetime_convert(),
+ $parms['url'],
+ $parms['fn'],
+ $parms['issued-id'],
+ $parms['photo'],
+ $parms['key'],
+ $parms['dfrn-request'],
+ $parms['dfrn-confirm'],
+ $parms['dfrn-notify'],
+ $parms['dfrn-poll'],
+ ((x($_POST,'visible')) ? 1 : 0 )
+ );
+
+ }
+ if($ret === false) {
+ $_SESSION['sysmsg'] .= 'Failed to create contact record.' . EOL;
+ return;
+ }
+
+ $ret = q("SELECT `id` FROM `contact`
+ WHERE `uid` = '%s' AND `url` = '%s' AND `issued-id` = '%s'
+ LIMIT 1",
+ intval($uid),
+ $parms['url'],
+ $parms['issued-id']
+ );
+
+ if(($ret !== NULL) && (count($ret)))
+ $contact_id = $ret[0]['id'];
+
+ $hash = random_string() . (string) time(); // Generate a confirm_key
+
+ if($contact_id) {
+ $ret = q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime`)
+ VALUES ( %d, %d, 1, %d, '%s', '%s', '%s' )",
+ intval($uid),
+ intval($contact_id),
+ ((x($_POST,'knowyou') && ($_POST['knowyou'] == 1)) ? 1 : 0),
+ dbesc(trim($_POST['dfrn-request-message'])),
+ dbesc($hash),
+ dbesc(datetime_convert())
+ );
+ }
+
+
+ // TODO: send an email notification if our user wants one
+
+ if(! $failed)
+ $_SESSION['sysmsg'] .= "Your introduction has been sent." . EOL;
+
+ // "Homecoming" - send the requestor back to their site to record the introduction.
+
+ $dfrn_url = bin2hex($a->get_baseurl() . "/profile/$tailname");
+ $aes_allow = ((function_exists('openssl_encrypt')) ? 1 : 0);
+
+ goaway($parms['dfrn-request'] . "?dfrn_url=$dfrn_url" . '&confirm_key=' . $hash . (($aes_allow) ? "&aes_allow=1" : ""));
+
+ }
+
+}}
+
+if(! function_exists('dfrn_request_content')) {
+function dfrn_request_content(&$a) {
+
+
+
+ if(($a->argc != 2) || (! count($a->profile)))
+ return "";
+
+ $a->page['template'] = 'profile';
+
+ // "Homecoming". Make sure we're logged in to this site as the correct user. Then offer a confirm button
+ // to send us to the post section to record the introduction.
+
+ if(x($_GET,'dfrn_url')) {
+
+ if(! x($_SESSION,'authenticated')) {
+ $_SESSION['sysmsg'] .= "Please login to confirm introduction." . EOL;
+ return login();
+ }
+
+ // Edge case, but can easily happen in the wild. This person is authenticated,
+ // but not as the person who needs to deal with this request.
+
+ if (($_SESSION['uid'] != $a->argv[1]) && ($a->user['nickname'] != $a->argv[1])) {
+ $_SESSION['sysmsg'] .= "Incorrect identity currently logged in. Please login to <strong>this</strong> profile." . EOL;
+ return login();
+ }
+
+ $dfrn_url = notags(trim(pack("H*" , $_GET['dfrn_url'])));
+ $aes_allow = (((x($_GET,'aes_allow')) && ($_GET['aes_allow'] == 1)) ? 1 : 0);
+ $confirm_key = (x($_GET,'confirm_key') ? $_GET['confirm_key'] : "");
+ $o .= file_get_contents("view/dfrn_req_confirm.tpl");
+ $o = replace_macros($o,array(
+ '$dfrn_url' => $dfrn_url,
+ '$aes_allow' => (($aes_allow) ? '<input type="hidden" name="aes_allow" value="1" />' : "" ),
+ '$confirm_key' => $confirm_key,
+ '$username' => $a->user['username'],
+ '$uid' => $_SESSION['uid'],
+ 'dfrn_rawurl' => $_GET['dfrn_url']
+ ));
+ return $o;
+
+ }
+ else {
+ // safe to send our user their introduction
+ if((x($_GET,'confirm_key')) && strlen($_GET['confirm_key'])) {
+ $r = q("UPDATE `intro` SET `blocked` = 0 WHERE `hash` = '%s' LIMIT 1",
+ dbesc($_GET['confirm_key'])
+ );
+ return;
+ }
+
+
+ // Outside request. Display our user's introduction form.
+
+
+ $o = file_get_contents("view/dfrn_request.tpl");
+ $o = replace_macros($o,array('$uid' => $a->profile['uid']));
+ return $o;
+ }
+}} \ No newline at end of file
diff --git a/mod/home.php b/mod/home.php
new file mode 100644
index 000000000..44f2a9888
--- /dev/null
+++ b/mod/home.php
@@ -0,0 +1,24 @@
+<?php
+
+if(! function_exists('home_init')) {
+function home_init(&$a) {
+
+ if(x($_SESSION,'authenticated') && (x($_SESSION,'uid'))) {
+ if($a->user['nickname'])
+ goaway( $a->get_baseurl() . "/profile/" . $a->user['nickname'] );
+ else
+ goaway( $a->get_baseurl() . "/profile/" . $_SESSION['uid'] );
+ }
+}}
+
+
+if(! function_exists('home_content')) {
+function home_content(&$a) {
+
+ $a->page['footer'] .= "<div class=\"powered\" >Powered by <a href=\"http://dfrn.org\" name=\"DFRN.org\" >DFRN</a></div>";
+ $o .= '<h1>Welcome' . ((x($a->config,'sitename')) ? " to {$a->config['sitename']}" : "" ) . '</h1>';
+ $o .= login(1);
+ return $o;
+
+
+}} \ No newline at end of file
diff --git a/mod/item.php b/mod/item.php
new file mode 100644
index 000000000..588dd9a9d
--- /dev/null
+++ b/mod/item.php
@@ -0,0 +1,68 @@
+<?php
+
+
+function item_post(&$a) {
+
+ if((! local_user()) && (! remote_user()))
+ return;
+
+ require_once('include/security.php');
+
+ $uid = $_SESSION['uid'];
+ $parent = ((x($_POST,'parent')) ? intval($_POST['parent']) : 0);
+ $profile_uid = ((x($_POST,'profile_uid')) ? intval($_POST['profile_uid']) : 0);
+ if(! can_write_wall($a,$profile_uid)) {
+ $_SESSION['sysmsg'] .= "Permission denied." . EOL;
+ return;
+ }
+
+ if((x($_SESSION,'visitor_id')) && (intval($_SESSION['visitor_id'])))
+ $contact_id = $_SESSION['visitor_id'];
+ else {
+ $r = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1",
+ intval($_SESSION['uid']));
+ if(count($r))
+ $contact_id = $r[0]['id'];
+
+ if($_POST['type'] == 'jot') {
+
+ do {
+ $dups = false;
+ $hash = random_string();
+ $r = q("SELECT `id` FROM `item` WHERE `hash` = '%s' LIMIT 1",
+ dbesc($hash));
+ if(count($r))
+ $dups = true;
+ } while($dups == true);
+
+ $r = q("INSERT INTO `item` (`uid`,`type`,`contact-id`,`created`,`edited`,`hash`,`body`)
+ VALUES( %d, '%s', %d, '%s', '%s', '%s', '%s' )",
+ intval($profile_uid),
+ "jot",
+ intval($contact_id),
+ datetime_convert(),
+ datetime_convert(),
+ dbesc($hash),
+ dbesc(escape_tags(trim($_POST['body'])))
+ );
+ $r = q("SELECT `id` FROM `item` WHERE `hash` = '%s' LIMIT 1",
+ dbesc($hash));
+ if(count($r)) {
+ $post_id = $r[0]['id'];
+ if(! $parent)
+ $parent = $post_id;
+ $r = q("UPDATE `item` SET `parent` = %d, `visible` = 1
+ WHERE `id` = %d LIMIT 1",
+ intval($parent),
+ intval($post_id));
+ }
+ }
+ goaway($a->get_baseurl() . "/profile/$uid");
+
+
+
+
+
+
+
+} \ No newline at end of file
diff --git a/mod/login.php b/mod/login.php
new file mode 100644
index 000000000..296890a5b
--- /dev/null
+++ b/mod/login.php
@@ -0,0 +1,8 @@
+<?php
+
+
+
+function login_content(&$a) {
+// return login($a->config['register_enabled']);
+ return login(1);
+} \ No newline at end of file
diff --git a/mod/notifications.php b/mod/notifications.php
new file mode 100644
index 000000000..1064729ff
--- /dev/null
+++ b/mod/notifications.php
@@ -0,0 +1,98 @@
+<?php
+
+function notifications_post(&$a) {
+
+ if((! x($_SESSION,'authenticated')) || (! (x($_SESSION,'uid')))) {
+ goaway($a->get_baseurl());
+ }
+
+ $request_id = (($a->argc > 1) ? $a->argv[0] : 0);
+
+ if($request_id == "all")
+ return;
+
+ if($request_id) {
+
+ $r = q("SELECT `id` FROM `intro`
+ WHERE `request-id` = %d
+ AND `uid` = %d LIMIT 1",
+ intval($request_id),
+ intval($_SESSION['uid'])
+ );
+
+ if(count($r)) {
+ $intro_id = $r[0]['id'];
+ }
+ else {
+ $_SESSION['sysmsg'] .= "Invalid request identifier." . EOL;
+ return;
+ }
+ if($_POST['submit'] == 'Discard') {
+ $r = q("DELETE `intro` WHERE `id` = %d LIMIT 1", intval($intro_id));
+ $r = q("DELETE `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ intval($request_id),
+ intval($_SESSION['uid']));
+ return;
+ }
+ if($_POST['submit'] == 'Ignore') {
+ $r = q("UPDATE `intro` SET `ignore` = 1 WHERE `id` = %d LIMIT 1",
+ intval($intro_id));
+ return;
+ }
+ }
+}
+
+
+
+
+
+function notifications_content(&$a) {
+
+ $o = '';
+
+ if((! x($_SESSION,'authenticated')) || (! (x($_SESSION,'uid')))) {
+ goaway($a->get_baseurl());
+ }
+
+ if(($a->argc > 1) && ($a->argv[1] == 'all'))
+ $sql_extra = '';
+ else
+ $sql_extra = " AND `ignore` = 0 ";
+
+
+ $tpl = file_get_contents('view/intros-top.tpl');
+ $o .= replace_macros($tpl,array(
+ '$hide_url' => ((strlen($sql_extra)) ? 'notifications/all' : 'notifications' ),
+ '$hide_text' => ((strlen($sql_extra)) ? 'Show Ignored Requests' : 'Hide Ignored Requests')
+ ));
+dbg(2);
+ $r = q("SELECT `intro`.`id` AS `intro-id`, `intro`.*, `contact`.*
+ FROM `intro` LEFT JOIN `contact` ON `intro`.`contact-id` = `contact`.`id`
+ WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0 ",
+ intval($_SESSION['uid']));
+dbg(0);
+ if(($r !== false) && (count($r))) {
+
+
+ $tpl = file_get_contents("view/intros.tpl");
+
+ foreach($r as $rr) {
+
+ $o .= replace_macros($tpl,array(
+ '$intro_id' => $rr['intro-id'],
+ '$dfrn-id' => $rr['issued-id'],
+ '$uid' => $_SESSION['uid'],
+ '$contact-id' => $rr['contact-id'],
+ '$photo' => ((x($rr,'photo')) ? $rr['photo'] : "images/default-profile.jpg"),
+ '$fullname' => $rr['name'],
+ '$knowyou' => (($rr['knowyou']) ? 'yes' : 'no'),
+ '$url' => $rr['url'],
+ '$note' => $rr['note']
+ ));
+ }
+ }
+ else
+ $_SESSION['sysmsg'] .= "No notifications." . EOL;
+
+ return $o;
+} \ No newline at end of file
diff --git a/mod/photo.php b/mod/photo.php
new file mode 100644
index 000000000..bd0e415bf
--- /dev/null
+++ b/mod/photo.php
@@ -0,0 +1,25 @@
+<?php
+
+function photo_init(&$a) {
+
+ if($a->argc != 2) {
+ killme();
+ }
+ $resolution = 0;
+ $photo = $a->argv[1];
+ $photo = str_replace('.jpg','',$photo);
+ if(substr($photo,-2,1) == '-') {
+ $resolution = intval(substr($photo,-1,1));
+ $photo = substr($photo,0,-2);
+ }
+ $r = q("SELECT * FROM `photo` WHERE `resource-id` = '%s'
+ AND `scale` = %d LIMIT 1",
+ dbesc($photo),
+ intval($resolution));
+ if($r === NULL || (! count($r))) {
+ killme();
+ }
+ header("Content-type: image/jpeg");
+ echo $r[0]['data'];
+
+} \ No newline at end of file
diff --git a/mod/profile.php b/mod/profile.php
new file mode 100644
index 000000000..b37d6487c
--- /dev/null
+++ b/mod/profile.php
@@ -0,0 +1,136 @@
+<?php
+
+if(! function_exists('profile_load')) {
+function profile_load(&$a,$uid,$profile = 0) {
+
+ $sql_extra = (($uid) && (intval($uid))
+ ? " WHERE `user`.`uid` = " . intval($uid)
+ : " WHERE `user`.`nickname` = '" . dbesc($uid) . "' " );
+
+ if(remote_user()) {
+ $r = q("SELECT `profile-id` FROM `contact` WHERE `id` = %d LIMIT 1",
+ intval($_SESSION['visitor_id']));
+ if(count($r))
+ $profile = $r[0]['profile-id'];
+ }
+
+ if($profile) {
+ $profile_int = intval($profile);
+ $sql_which = " AND `profile`.`id` = $profile_int ";
+ }
+ else
+ $sql_which = " AND `profile`.`is-default` = 1 ";
+
+ $r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `user`.* FROM `profile`
+ LEFT JOIN `user` ON `profile`.`uid` = `user`.`uid`
+ $sql_extra $sql_which LIMIT 1"
+ );
+
+ if(($r === false) || (! count($r))) {
+ $_SESSION['sysmsg'] .= "No profile" . EOL ;
+ $a->error = 404;
+ return;
+ }
+
+ $a->profile = $r[0];
+
+ $a->page['template'] = 'profile';
+
+ $a->page['title'] = $a->profile['name'];
+
+ return;
+}}
+
+function profile_init(&$a) {
+
+ if($_SESSION['authenticated']) {
+
+ // choose which page to show (could be remote auth)
+
+ }
+
+ if($a->argc > 1)
+ $which = $a->argv[1];
+ else {
+ $_SESSION['sysmsg'] .= "No profile" . EOL ;
+ $a->error = 404;
+ return;
+ }
+
+ profile_load($a,$which);
+
+ $dfrn_pages = array('request', 'confirm', 'notify', 'poll');
+ foreach($dfrn_pages as $dfrn)
+ $a->page['htmlhead'] .= "<link rel=\"dfrn-{$dfrn}\" href=\"".$a->get_baseurl()."/dfrn_{$dfrn}/{$which}\" />\r\n";
+}
+
+function item_display($item,$template) {
+
+ $o .= replace_macros($template,array(
+ '$id' => $item['item_id'],
+ '$profile_url' => $item['url'],
+ '$name' => $item['name'],
+ '$thumb' => $item['thumb'],
+ '$body' => bbcode($item['body']),
+ '$ago' => relative_date($item['created'])
+ ));
+
+
+ return $o;
+}
+
+
+
+function profile_content(&$a) {
+
+ require_once("include/bbcode.php");
+ require_once('include/security.php');
+
+// $tpl = file_get_contents('view/profile_tabs.tpl');
+
+
+ if(can_write_wall($a,$a->profile['profile_uid'])) {
+ $tpl = file_get_contents('view/jot-header.tpl');
+
+ $a->page['htmlhead'] .= replace_macros($tpl, array('$baseurl' => $a->get_baseurl()));
+
+ $tpl = file_get_contents("view/jot.tpl");
+ $o .= replace_macros($tpl,array(
+ '$baseurl' => $a->get_baseurl(),
+ '$profile_uid' => $a->profile['profile_uid']
+ ));
+ }
+
+
+ if($a->profile['is-default']) {
+
+ // TODO left join with contact which will carry names and photos. (done)Store local users in contact as well as user.(done)
+ // Alter registration and settings
+ // and profile to update contact table when names and photos change.
+ // work on item_display and can_write_wall
+
+ // Add comments.
+
+ $r = q("SELECT `item`.*, `contact`.`name`, `contact`.`photo`, `contact`.`thumb`, `contact`.`id` AS `cid`
+ FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
+ WHERE `item`.`uid` = %d AND `item`.`visible` = 1
+ AND `contact`.`blocked` = 0
+ AND `allow_uid` = '' AND `allow_gid` = '' AND `deny_uid` = '' AND `deny_gid` = ''
+ GROUP BY `item`.`parent`, `item`.`id`
+ ORDER BY `created` DESC LIMIT 0,30 ",
+ intval($a->profile['uid'])
+ );
+
+ $tpl = file_get_contents('view/wall_item.tpl');
+
+ if(count($r)) {
+ foreach($r as $rr) {
+ $o .= item_display($rr,$tpl);
+ }
+ }
+ }
+
+ return $o;
+
+
+} \ No newline at end of file
diff --git a/mod/profile_photo.php b/mod/profile_photo.php
new file mode 100644
index 000000000..f7e6825ae
--- /dev/null
+++ b/mod/profile_photo.php
@@ -0,0 +1,227 @@
+<?php
+
+require_once("Photo.php");
+
+function profile_photo_init(&$a) {
+
+ if((! x($_SESSION,'authenticated')) && (x($_SESSION,'uid'))) {
+ $_SESSION['sysmsg'] .= "Permission denied." . EOL;
+ $a->error = 404;
+ return;
+ }
+ require_once("mod/profile.php");
+ profile_load($a,$_SESSION['uid']);
+}
+
+
+function profile_photo_post(&$a) {
+
+
+
+ if((! x($_SESSION,'authenticated')) && (! (x($_SESSION,'uid')))) {
+ $_SESSION['sysmsg'] .= "Permission denied." . EOL;
+ return;
+ }
+
+ if($a->argc > 1)
+ $profile_id = intval($a->argv[1]);
+
+ if(x($_POST,'xstart') !== false) {
+ // phase 2 - we have finished cropping
+ if($a->argc != 3) {
+ $_SESSION['sysmsg'] .= "Image uploaded but image cropping failed." . EOL;
+ return;
+ }
+ $image_id = $a->argv[2];
+ if(substr($image_id,-2,1) == '-') {
+ $scale = substr($image_id,-1,1);
+ $image_id = substr($image_id,0,-2);
+ }
+
+
+ $srcX = $_POST['xstart'];
+ $srcY = $_POST['ystart'];
+ $srcW = $_POST['xfinal'] - $srcX;
+ $srcH = $_POST['yfinal'] - $srcY;
+
+ $r = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' AND `scale` = %d LIMIT 1",
+ dbesc($image_id),
+ intval($scale));
+ if($r !== NULL && (count($r))) {
+ $im = new Photo($r[0]['data']);
+ $im->cropImage(175,$srcX,$srcY,$srcW,$srcH);
+ $s = $im->imageString();
+ $x = $im->getWidth();
+ $y = $im->getHeight();
+
+ $ret = q("INSERT INTO `photo` ( `uid`, `resource-id`, `created`, `edited`, `filename`,
+ `height`, `width`, `data`, `scale` )
+ VALUES ( %d, '%s', '%s', '%s', '%s', %d, %d, '%s', 4 )",
+ intval($_SESSION['uid']),
+ dbesc($r[0]['resource-id']),
+ datetime_convert(),
+ datetime_convert(),
+ dbesc($r[0]['filename']),
+ intval($y),
+ intval($x),
+ dbesc($s));
+ if($r === NULL)
+ $_SESSION['sysmsg'] .= "Image size reduction (175) failed." . EOL;
+
+ $im->scaleImage(80);
+ $s = $im->imageString();
+ $x = $im->getWidth();
+ $y = $im->getHeight();
+ $ret = q("INSERT INTO `photo` ( `uid`, `resource-id`, `created`, `edited`, `filename`,
+ `height`, `width`, `data`, `scale` )
+ VALUES ( %d, '%s', '%s', '%s', '%s', %d, %d, '%s', 5 )",
+ intval($_SESSION['uid']),
+ dbesc($r[0]['resource-id']),
+ datetime_convert(),
+ datetime_convert(),
+ dbesc($r[0]['filename']),
+ intval($y),
+ intval($x),
+ dbesc($s));
+ if($r === NULL)
+ $_SESSION['sysmsg'] .= "Image size reduction (80) failed." . EOL;
+ $r = q("UPDATE `profile` SET `photo` = '%s', `thumb` = '%s' WHERE `id` = %d LIMIT 1",
+ dbesc($a->get_baseurl() . '/photo/' . $image_id . '-4.jpg'),
+ dbesc($a->get_baseurl() . '/photo/' . $image_id . '-5.jpg'),
+ intval($profile_id));
+ if($r === NULL)
+ $_SESSION['sysmsg'] .= "Failed to add image to profile." . EOL;
+
+ }
+ goaway($a->get_baseurl() . '/profiles');
+ }
+
+ $extra_sql = (($profile_id) ? " AND `id` = " . intval($profile_id) : " AND `is-default` = 1 " );
+
+
+ $r = q("SELECT `id` FROM `profile` WHERE `uid` = %d $extra_sql LIMIT 1", intval($_SESSION['uid']));
+ if($r === NULL || (! count($r))) {
+ $_SESSION['sysmsg'] .= "Profile unavailable." . EOL;
+ return;
+ }
+
+ $src = $_FILES['userfile']['tmp_name'];
+ $filename = basename($_FILES['userfile']['name']);
+ $filesize = intval($_FILES['userfile']['size']);
+
+ $imagedata = @file_get_contents($src);
+ $ph = new Photo($imagedata);
+
+ if(! ($image = $ph->getImage())) {
+ $_SESSION['sysmsg'] .= "Unable to process image." . EOL;
+ @unlink($src);
+ return;
+ }
+
+ @unlink($src);
+ $width = $ph->getWidth();
+ $height = $ph->getHeight();
+
+ if($width < 175 || $width < 175) {
+ $ph->scaleImageUp(200);
+ $width = $ph->getWidth();
+ $height = $ph->getHeight();
+ }
+
+ $hash = hash('md5',uniqid(mt_rand(),true));
+
+ $str_image = $ph->imageString();
+ $smallest = 0;
+ $r = q("INSERT INTO `photo` ( `uid`, `resource-id`, `created`, `edited`, `filename`,
+ `height`, `width`, `data`, `scale` )
+ VALUES ( %d, '%s', '%s', '%s', '%s', %d, %d, '%s', 0 )",
+ intval($_SESSION['uid']),
+ dbesc($hash),
+ datetime_convert(),
+ datetime_convert(),
+ dbesc(basename($filename)),
+ intval($height),
+ intval($width),
+ dbesc($str_image));
+ if($r)
+ $_SESSION['sysmsg'] .= "Image uploaded successfully." . EOL;
+ else
+ $_SESSION['sysmsg'] .= "Image upload failed." . EOL;
+
+ if($width > 640 || $height > 640) {
+ $ph->scaleImage(640);
+ $str_image = $ph->imageString();
+ $width = $ph->getWidth();
+ $height = $ph->getHeight();
+
+ $r = q("INSERT INTO `photo` ( `uid`, `resource-id`, `created`, `edited`, `filename`,
+ `height`, `width`, `data`, `scale` )
+ VALUES ( %d, '%s', '%s', '%s', '%s', %d, %d, '%s', 1 )",
+ intval($_SESSION['uid']),
+ dbesc($hash),
+ datetime_convert(),
+ datetime_convert(),
+ dbesc(basename($filename)),
+ intval($height),
+ intval($width),
+ dbesc($str_image));
+ if($r === NULL)
+ $_SESSION['sysmsg'] .= "Image size reduction (640) failed." . EOL;
+ else
+ $smallest = 1;
+ }
+
+ $a->config['imagecrop'] = $hash;
+ $a->config['imagecrop_resolution'] = $smallest;
+ $a->page['htmlhead'] .= file_get_contents("view/crophead.tpl");
+
+}
+
+
+if(! function_exists('profile_photo_content')) {
+function profile_photo_content(&$a) {
+
+
+ if(! x($a->config,'imagecrop')) {
+ if((! x($_SESSION['authenticated'])) && (! (x($_SESSION,'uid')))) {
+ $_SESSION['sysmsg'] .= "Permission denied." . EOL;
+ return;
+ }
+
+ if($a->argc > 1)
+ $profile_id = intval($a->argv[1]);
+
+ $extra_sql = (($profile_id) ? " AND `id` = $profile_id " : " AND `is-default` = 1 " );
+
+
+ $r = q("SELECT `id` FROM `profile` WHERE `uid` = %d $extra_sql LIMIT 1", intval($_SESSION['uid']));
+ if($r === NULL || (! count($r))) {
+ $_SESSION['sysmsg'] .= "Profile unavailable." . EOL;
+ return;
+ }
+
+ $o = file_get_contents('view/profile_photo.tpl');
+
+ $o = replace_macros($o,array(
+ '$profile_id' => $r[0]['id'],
+ '$uid' => $_SESSION['uid'],
+ ));
+
+ return $o;
+ }
+ else {
+ $filename = $a->config['imagecrop'] . '-' . $a->config['imagecrop_resolution'] . '.jpg';
+ $resolution = $a->config['imagecrop_resolution'];
+ $o = file_get_contents("view/cropbody.tpl");
+ $o = replace_macros($o,array(
+ '$filename' => $filename,
+ '$profile_id' => $a->argv[1],
+ '$resource' => $a->config['imagecrop'] . '-' . $a->config['imagecrop_resolution'],
+ '$image_url' => $a->get_baseurl() . '/photo/' . $filename
+ ));
+
+ return $o;
+ }
+
+
+}} \ No newline at end of file
diff --git a/mod/profiles.php b/mod/profiles.php
new file mode 100644
index 000000000..cba358a67
--- /dev/null
+++ b/mod/profiles.php
@@ -0,0 +1,190 @@
+<?php
+
+
+function profiles_post(&$a) {
+
+ if(! local_user()) {
+ $_SESSION['sysmsg'] .= "Unauthorised." . EOL;
+ return;
+ }
+
+ // todo - delete... ensure that all contacts using the to-be-deleted profile are moved to the default.
+
+
+
+ if(($a->argc > 1) && ($a->argv[1] != "new") && intval($a->argv[1])) {
+ $r = q("SELECT * FROM `profile` WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ intval($a->argv[1]),
+ intval($_SESSION['uid'])
+ );
+ if(! count($r)) {
+ $_SESSION['sysmsg'] .= "Profile not found." . EOL;
+ return;
+ }
+
+ $profile_name = notags(trim($_POST['profile_name']));
+ if(! strlen($profile_name)) {
+ $a->$_SESSION['sysmsg'] .= "Profile Name is required." . EOL;
+ return;
+ }
+
+ $name = notags(trim($_POST['name']));
+ $gender = notags(trim($_POST['gender']));
+ $address = notags(trim($_POST['address']));
+ $locality = notags(trim($_POST['locality']));
+ $region = notags(trim($_POST['region']));
+ $postal_code = notags(trim($_POST['postal_code']));
+ $country_name = notags(trim($_POST['country_name']));
+ $marital = notags(trim(implode(', ',$_POST['marital'])));
+ $homepage = notags(trim($_POST['homepage']));
+ $about = str_replace(array('<','>','&'),array('&lt;','&gt;','&amp;'),trim($_POST['about']));
+
+ if(! in_array($gender,array('','Male','Female','Other')))
+ $gender = '';
+
+ $r = q("UPDATE `profile`
+ SET `profile-name` = '%s',
+ `name` = '%s',
+ `gender` = '%s',
+ `address` = '%s',
+ `locality` = '%s',
+ `region` = '%s',
+ `postal-code` = '%s',
+ `country-name` = '%s',
+ `marital` = '%s',
+ `homepage` = '%s',
+ `about` = '%s'
+ WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ dbesc($profile_name),
+ dbesc($name),
+ dbesc($gender),
+ dbesc($address),
+ dbesc($locality),
+ dbesc($region),
+ dbesc($postal_code),
+ dbesc($country_name),
+ dbesc($marital),
+ dbesc($homepage),
+ dbesc($about),
+ intval($a->argv[1]),
+ intval($_SESSION['uid'])
+ );
+
+ if($r)
+ $_SESSION['sysmsg'] .= "Profile updated." . EOL;
+ }
+
+
+
+}
+
+
+
+
+function profiles_content(&$a) {
+ if(! local_user()) {
+ $_SESSION['sysmsg'] .= "Unauthorised." . EOL;
+ return;
+ }
+
+ if(($a->argc > 1) && ($a->argv[1] == 'new')) {
+
+ $r0 = q("SELECT `id` FROM `profile` WHERE `uid` = %d",
+ intval($_SESSION['uid']));
+ $num_profiles = count($r0);
+
+ $name = "Profile-" . ($num_profiles + 1);
+
+ $r1 = q("SELECT `name`, `photo`, `thumb` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1",
+ intval($_SESSION['uid']));
+
+ $r2 = q("INSERT INTO `profile` (`uid` , `profile-name` , `name`, `photo`, `thumb`)
+ VALUES ( %d, '%s', '%s', '%s', '%s' )",
+ intval($_SESSION['uid']),
+ dbesc($name),
+ dbesc($r1[0]['name']),
+ dbesc($r1[0]['photo']),
+ dbesc($ra[0]['thumb'])
+ );
+
+ $r3 = q("SELECT `id` FROM `profile` WHERE `uid` = %d AND `profile-name` = '%s' LIMIT 1",
+ intval($_SESSION['uid']),
+ dbesc($name)
+ );
+ $_SESSION['sysmsg'] .= "New profile created." . EOL;
+ if(count($r3) == 1)
+ goaway($a->get_baseurl() . '/profiles/' . $r3[0]['id']);
+ goaway($a->get_baseurl() . '/profiles');
+ }
+
+
+ if(intval($a->argv[1])) {
+ $r = q("SELECT * FROM `profile` WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ intval($a->argv[1]),
+ intval($_SESSION['uid'])
+ );
+ if(! count($r)) {
+ $_SESSION['sysmsg'] .= "Profile not found." . EOL;
+ return;
+ }
+
+ require_once('mod/profile.php');
+ profile_load($a,$_SESSION['uid'],$r[0]['id']);
+
+ require_once('view/profile_selectors.php');
+
+ $tpl = file_get_contents('view/jot-header.tpl');
+ $profile_in_dir = file_get_contents("view/profile-in-directory.tpl");
+
+ $a->page['htmlhead'] .= replace_macros($tpl, array('$baseurl' => $a->get_baseurl()));
+
+ $a->page['aside'] = file_get_contents('view/sidenote.tpl');
+ $is_default = (($r[0]['is-default']) ? 1 : 0);
+ $tpl = file_get_contents("view/profile_edit.tpl");
+ $o .= replace_macros($tpl,array(
+ '$baseurl' => $a->get_baseurl(),
+ '$profile_id' => $r[0]['id'],
+ '$profile_name' => $r[0]['profile-name'],
+ '$default' => (($is_default) ? "<p id=\"profile-edit-default-desc\">This is your <strong>public</strong> profile.</p>" : ""),
+ '$name' => $r[0]['name'],
+ '$dob' => $r[0]['dob'],
+ '$address' => $r[0]['address'],
+ '$locality' => $r[0]['locality'],
+ '$region' => $r[0]['region'],
+ '$postal_code' => $r[0]['postal-code'],
+ '$country_name' => $r[0]['country-name'],
+ '$age' => $r[0]['age'],
+ '$gender' => gender_selector($r[0]['gender']),
+ '$marital' => marital_selector($r[0]['marital']),
+ '$about' => $r[0]['about'],
+ '$homepage' => $r[0]['homepage'],
+ '$profile_in_dir' => (($is_default) ? $profile_in_dir : '')
+ ));
+
+ return $o;
+
+
+ }
+ else {
+
+ $r = q("SELECT * FROM `profile` WHERE `uid` = %d",
+ $_SESSION['uid']);
+ if(count($r)) {
+
+ $o .= file_get_contents('view/profile_listing_header.tpl');
+ $tpl_default = file_get_contents('view/profile_entry_default.tpl');
+ $tpl = file_get_contents('view/profile_entry.tpl');
+
+ foreach($r as $rr) {
+ $template = (($rr['is-default']) ? $tpl_default : $tpl);
+ $o .= replace_macros($template, array(
+ '$photo' => $rr['thumb'],
+ '$id' => $rr['id'],
+ '$profile_name' => $rr['profile-name']
+ ));
+ }
+ }
+ return $o;
+ }
+
+} \ No newline at end of file
diff --git a/mod/redir.php b/mod/redir.php
new file mode 100644
index 000000000..ee15a18d4
--- /dev/null
+++ b/mod/redir.php
@@ -0,0 +1,21 @@
+<?php
+
+function redir_init(&$a) {
+
+ if((! local_user()) || (! ($a->argc == 2)) || (! intval($a->argv[1])))
+ goaway($a->get_baseurl());
+ $r = q("SELECT `dfrn-id`, `poll` FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ intval($a->argv[1]),
+ intval($_SESSION['uid']));
+ if(! count($r))
+ goaway($a->get_baseurl());
+ q("INSERT INTO `profile_check` ( `uid`, `dfrn_id`, `expire`)
+ VALUES( %d, '%s', %d )",
+ intval($_SESSION['uid']),
+ dbesc($r[0]['dfrn-id']),
+ intval(time() + 30));
+ goaway ($r[0]['poll'] . '?dfrn_id=' . $r[0]['dfrn-id'] . '&type=profile');
+
+
+
+} \ No newline at end of file
diff --git a/mod/register.php b/mod/register.php
new file mode 100644
index 000000000..4e2c0bfb9
--- /dev/null
+++ b/mod/register.php
@@ -0,0 +1,175 @@
+<?php
+
+if(! function_exists('register_post')) {
+function register_post(&$a) {
+
+ $verified = 0;
+ $blocked = 1;
+
+ switch($a->config['register_policy']) {
+
+
+ case REGISTER_OPEN:
+ $blocked = 0;
+ $verified = 1;
+ break;
+
+ case REGISTER_VERIFY:
+ $blocked = 1;
+ $verify = 0;
+ break;
+
+ default:
+ case REGISTER_CLOSED:
+ if((! x($_SESSION,'authenticated') && (! x($_SESSION,'administrator')))) {
+ $_SESSION['sysmsg'] .= "Permission denied." . EOL;
+ return;
+ }
+ $blocked = 0;
+ $verified = 0;
+ break;
+ }
+
+ if(x($_POST,'username'))
+ $username = notags(trim($_POST['username']));
+ if(x($_POST,'email'))
+ $email =notags(trim($_POST['email']));
+
+ if((! x($username)) || (! x($email))) {
+ $_SESSION['sysmsg'] .= "Please enter the required information.". EOL;
+ return;
+ }
+
+ $err = '';
+
+ if(!eregi('[A-Za-z0-9._%-]+@[A-Za-z0-9._%-]+\.[A-Za-z]{2,6}',$email))
+ $err .= " Not valid email.";
+ if(strlen($username) > 40)
+ $err .= " Please use a shorter name.";
+ if(strlen($username) < 3)
+ $err .= " Name too short.";
+ $r = q("SELECT `uid` FROM `user`
+ WHERE `email` = '%s' LIMIT 1",
+ dbesc($email)
+ );
+ if($r !== false && count($r))
+ $err .= " This email address is already registered." . EOL;
+ if(strlen($err)) {
+ $_SESSION['sysmsg'] .= $err;
+ return;
+ }
+
+
+ $new_password = autoname(6) . mt_rand(100,9999);
+ $new_password_encoded = hash('whirlpool',$new_password);
+
+ $res=openssl_pkey_new(array(
+ 'digest_alg' => 'whirlpool',
+ 'private_key_bits' => 4096,
+ 'encrypt_key' => false ));
+
+ // Get private key
+
+ $prvkey = '';
+
+ openssl_pkey_export($res, $prvkey);
+
+ // Get public key
+
+ $pkey = openssl_pkey_get_details($res);
+ $pubkey = $pkey["key"];
+
+ $r = q("INSERT INTO `user` ( `username`, `password`, `email`,
+ `pubkey`, `prvkey`, `verified`, `blocked` )
+ VALUES ( '%s', '%s', '%s', '%s', '%s', %d, %d )",
+ dbesc($username),
+ dbesc($new_password_encoded),
+ dbesc($email),
+ dbesc($pubkey),
+ dbesc($prvkey),
+ intval($verified),
+ intval($blocked)
+ );
+
+ if($r) {
+ $r = q("SELECT `uid` FROM `user`
+ WHERE `username` = '%s' AND `password` = '%s' LIMIT 1",
+ dbesc($username),
+ dbesc($new_password_encoded)
+ );
+ if($r !== false && count($r))
+ $newuid = intval($r[0]['uid']);
+ }
+ else {
+ $_SESSION['sysmsg'] .= "An error occurred during registration. Please try again." . EOL;
+ return;
+ }
+
+ if(x($newuid) !== NULL) {
+ $r = q("INSERT INTO `profile` ( `uid`, `profile-name`, `is-default`, `name`, `photo`, `thumb` )
+ VALUES ( %d, '%s', %d, '%s', '%s', '%s' ) ",
+ intval($newuid),
+ 'default',
+ 1,
+ dbesc($username),
+ dbesc($a->get_baseurl() . '/images/default-profile.jpg'),
+ dbesc($a->get_baseurl() . '/images/default-profile-sm.jpg')
+ );
+ if($r === false) {
+ $_SESSION['sysmsg'] .= "An error occurred creating your default profile. Please try again." . EOL ;
+ // Start fresh next time.
+ $r = q("DELETE FROM `user` WHERE `uid` = %d",
+ intval($newuid));
+ return;
+ }
+ $r = q("INSERT INTO `contact` ( `uid`, `created`, `self`, `name`, `photo`, `thumb`, `blocked` )
+ VALUES ( %d, '%s', 1, '%s', '%s', '%s', 0 ) ",
+ intval($newuid),
+ datetime_convert(),
+ dbesc($username),
+ dbesc($a->get_baseurl() . '/images/default-profile.jpg'),
+ dbesc($a->get_baseurl() . '/images/default-profile-sm.jpg')
+ );
+
+
+ }
+
+ if( $a->config['register_policy'] == REGISTER_OPEN ) {
+ $email_tpl = file_get_contents("view/register_open_eml.tpl");
+ $email_tpl = replace_macros($email_tpl, array(
+ '$sitename' => $a->config['sitename'],
+ '$siteurl' => $a->get_baseurl(),
+ '$username' => $username,
+ '$email' => $email,
+ '$password' => $new_password,
+ '$uid' => $newuid ));
+
+ $res = mail($email,"Registration details for {$a->config['sitename']}",$email_tpl,"From: Administrator@{$_SERVER[SERVER_NAME]}");
+
+ }
+
+ if($res) {
+ $_SESSION['sysmsg'] .= "Registration successful. Please check your email for further instructions." . EOL ;
+ goaway($a->get_baseurl());
+ }
+ else {
+ $_SESSION['sysmsg'] .= "Failed to send email message. Here is the message that failed. $email_tpl " . EOL;
+ }
+
+ return;
+}}
+
+
+
+
+
+
+if(! function_exists('register_content')) {
+function register_content(&$a) {
+
+ $o = file_get_contents("view/register.tpl");
+ $o = replace_macros($o, array('$registertext' =>((x($a->config,'register_text'))? $a->config['register_text'] : "" )));
+ return $o;
+
+}}
+
diff --git a/mod/settings.php b/mod/settings.php
new file mode 100644
index 000000000..de1133faf
--- /dev/null
+++ b/mod/settings.php
@@ -0,0 +1,170 @@
+<?php
+
+
+function settings_init(&$a) {
+
+ if((! x($_SESSION,'authenticated')) && (x($_SESSION,'uid'))) {
+ $_SESSION['sysmsg'] .= "Permission denied." . EOL;
+ $a->error = 404;
+ return;
+ }
+ require_once("mod/profile.php");
+ profile_load($a,$_SESSION['uid']);
+}
+
+
+function settings_post(&$a) {
+
+ if((! x($_SESSION['authenticated'])) && (! (x($_SESSION,'uid')))) {
+ $_SESSION['sysmsg'] .= "Permission denied." . EOL;
+ return;
+ }
+ if(count($a->user) && x($a->user,'uid') && $a->user['uid'] != $_SESSION['uid']) {
+ $_SESSION['sysmsg'] .= "Permission denied." . EOL;
+ return;
+ }
+ if((x($_POST,'password')) || (x($_POST,'confirm'))) {
+
+ $newpass = trim($_POST['password']);
+ $confirm = trim($_POST['confirm']);
+
+ $err = false;
+ if($newpass != $confirm ) {
+ $_SESSION['sysmsg'] .= "Passwords do not match. Password unchanged." . EOL;
+ $err = true;
+ }
+
+ if((! x($newpass)) || (! x($confirm))) {
+ $_SESSION['sysmsg'] .= "Empty passwords are not allowed. Password unchanged." . EOL;
+ $err = true;
+ }
+
+ if(! $err) {
+ $password = hash('whirlpool',$newpass);
+ $r = q("UPDATE `user` SET `password` = '%s' WHERE `uid` = %d LIMIT 1",
+ dbesc($password),
+ intval($_SESSION['uid']));
+ if($r)
+ $_SESSION['sysmsg'] .= "Password changed." . EOL;
+ else
+ $_SESSION['sysmsg'] .= "Password update failed. Please try again." . EOL;
+ }
+ }
+
+ $username = notags(trim($_POST['username']));
+ $email = notags(trim($_POST['email']));
+ if(x($_POST,'nick'))
+ $nick = notags(trim($_POST['nick']));
+ $timezone = notags(trim($_POST['timezone']));
+
+ $username_changed = false;
+ $email_changed = false;
+ $nick_changed = false;
+ $zone_changed = false;
+ $err = '';
+
+ if($username != $a->user['username']) {
+ $username_changed = true;
+ if(strlen($username) > 40)
+ $err .= " Please use a shorter name.";
+ if(strlen($username) < 3)
+ $err .= " Name too short.";
+ }
+ if($email != $a->user['email']) {
+ $email_changed = true;
+ if(!eregi('[A-Za-z0-9._%-]+@[A-Za-z0-9._%-]+\.[A-Za-z]{2,6}',$email))
+ $err .= " Not valid email.";
+ $r = q("SELECT `uid` FROM `user`
+ WHERE `email` = '%s' LIMIT 1",
+ dbesc($email)
+ );
+ if($r !== NULL && count($r))
+ $err .= " This email address is already registered." . EOL;
+ }
+ if((x($nick)) && ($nick != $a->user['nickname'])) {
+ $nick_changed = true;
+ if(! preg_match("/^[a-zA-Z][a-zA-Z0-9\-\_]*$/",$nick))
+ $err .= " Nickname must start with a letter and contain only contain letters, numbers, dashes, and underscore.";
+ $r = q("SELECT `uid` FROM `user`
+ WHERE `nickname` = '%s' LIMIT 1",
+ dbesc($nick)
+ );
+ if($r !== NULL && count($r))
+ $err .= " Nickname is already registered. Try another." . EOL;
+ }
+ else
+ $nick = $a->user['nickname'];
+
+ if(strlen($err)) {
+ $_SESSION['sysmsg'] .= $err . EOL;
+ return;
+ }
+ if($timezone != $a->user['timezone']) {
+ $zone_changed = true;
+ if(strlen($timezone))
+ date_default_timezone_set($timezone);
+ }
+ if($email_changed || $username_changed || $nick_changed || $zone_changed ) {
+ $r = q("UPDATE `user` SET `username` = '%s', `email` = '%s', `nickname` = '%s', `timezone` = '%s' WHERE `uid` = %d LIMIT 1",
+ dbesc($username),
+ dbesc($email),
+ dbesc($nick),
+ dbesc($timezone),
+ intval($_SESSION['uid']));
+ if($r)
+ $_SESSION['sysmsg'] .= "Settings updated." . EOL;
+ }
+ if($email_changed && $a->config['register_policy'] == REGISTER_VERIFY) {
+
+ // FIXME - set to un-verified, blocked and redirect to logout
+
+ }
+
+ // Refresh the content display with new data
+
+ $r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
+ intval($_SESSION['uid']));
+ if(count($r))
+ $a->user = $r[0];
+}
+
+
+if(! function_exists('settings_content')) {
+function settings_content(&$a) {
+
+ if((! x($_SESSION['authenticated'])) && (! (x($_SESSION,'uid')))) {
+ $_SESSION['sysmsg'] .= "Permission denied." . EOL;
+ return;
+ }
+
+
+ $username = $a->user['username'];
+ $email = $a->user['email'];
+ $nickname = $a->user['nickname'];
+ $timezone = $a->user['timezone'];
+
+
+ if(x($nickname))
+ $nickname_block = file_get_contents("view/settings_nick_set.tpl");
+ else
+ $nickname_block = file_get_contents("view/settings_nick_unset.tpl");
+
+ $nickname_block = replace_macros($nickname_block,array(
+ '$nickname' => $nickname,
+ '$baseurl' => $a->get_baseurl()));
+
+ $o = file_get_contents('view/settings.tpl');
+
+ $o = replace_macros($o,array(
+ '$baseurl' => $a->get_baseurl(),
+ '$uid' => $_SESSION['uid'],
+ '$username' => $username,
+ '$email' => $email,
+ '$nickname_block' => $nickname_block,
+ '$timezone' => $timezone,
+ '$zoneselect' => select_timezone($timezone)
+ ));
+
+ return $o;
+
+}} \ No newline at end of file
diff --git a/mod/test.php b/mod/test.php
new file mode 100644
index 000000000..4fa625f6f
--- /dev/null
+++ b/mod/test.php
@@ -0,0 +1,4 @@
+<?php
+function test_content(&$a) {
+print_r($a->user);
+} \ No newline at end of file