diff options
author | MicMee <michael@meer.name> | 2013-01-23 04:55:09 -0800 |
---|---|---|
committer | MicMee <michael@meer.name> | 2013-01-23 04:55:09 -0800 |
commit | 9996d5ee9b7196774cb1d95334507c20f1883428 (patch) | |
tree | 4c10561076f16d9f18b7b5943bc1930814c6d52c | |
parent | fca354aa463e84b67fe62e4067905e8f363c0e80 (diff) | |
parent | 0b18dd15c5377da121f0fb781c0530ca0d328eb9 (diff) | |
download | volse-hubzilla-9996d5ee9b7196774cb1d95334507c20f1883428.tar.gz volse-hubzilla-9996d5ee9b7196774cb1d95334507c20f1883428.tar.bz2 volse-hubzilla-9996d5ee9b7196774cb1d95334507c20f1883428.zip |
Merge pull request #1 from friendica/master
get changes
49 files changed, 1334 insertions, 1126 deletions
@@ -16,7 +16,7 @@ require_once('include/features.php'); define ( 'FRIENDICA_PLATFORM', 'Friendica Red'); define ( 'FRIENDICA_VERSION', trim(file_get_contents('version.inc')) . 'R'); define ( 'ZOT_REVISION', 1 ); -define ( 'DB_UPDATE_VERSION', 1020 ); +define ( 'DB_UPDATE_VERSION', 1021 ); define ( 'EOL', '<br />' . "\r\n" ); define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' ); @@ -266,6 +266,8 @@ define ( 'HUBLOC_FLAGS_PRIMARY', 0x0001); define ( 'HUBLOC_FLAGS_UNVERIFIED', 0x0002); +define ( 'XCHAN_FLAGS_HIDDEN', 0x0001); + /** * Tag/term types @@ -454,7 +456,7 @@ if(! class_exists('App')) { private $widgets = array(); // widgets for this page - + public $groups; public $language; public $module_loaded = false; public $query_string; @@ -749,6 +751,13 @@ if(! class_exists('App')) { $this->apps = $arr; } + function set_groups($g) { + $this->groups = $g; + } + + function get_groups() { + return $this->groups; + } function set_widget($title,$html, $location = 'aside') { $this->widgets[] = array('title' => $title, 'html' => $html, 'location' => $location); @@ -1179,7 +1188,7 @@ if(! function_exists('local_user')) { if(! function_exists('remote_user')) { function remote_user() { if((x($_SESSION,'authenticated')) && (x($_SESSION,'visitor_id'))) - return intval($_SESSION['visitor_id']); + return $_SESSION['visitor_id']; return false; } } @@ -1258,7 +1267,7 @@ function profile_load(&$a, $nickname, $profile = 0) { require_once('include/permissions.php'); if(! perm_is_allowed($user[0]['channel_id'],$observer['xchan_hash'],'view_profile')) { // permission denied - notice( t(' Sorry, you don't have the permission to view this profile. ') . EOL); + notice( t(' Sorry, you don\'t have the permission to view this profile. ') . EOL); return; } @@ -15,7 +15,7 @@ include/ + account.php acl_selectors.php + activities.php - api.php +? api.php ? attach.php + auth.php - bb2diaspora.php (check for function dependencies before removing) @@ -34,7 +34,7 @@ include/ + directory.php - email.php + enotify.php - event.php ++ event.php + expire.php fcontact.php ? follow.php @@ -47,23 +47,23 @@ include/ ? items.php + js_strings.php + language.php - message.php +? message.php - msgclean.php ? nav.php network.php - notifier.php ++ notifier.php oauth.php oembed.php -? onepoll.php +? onepoll.php ? Photo.php ? plugin.php -? poller.php +? poller.php ? profile_advanced.php profile_selectors.php ? queue_fn.php ? queue.php - salmon.php - Scrape.php += Scrape.php + security.php ? session.php socgraph.php @@ -87,14 +87,14 @@ mod/ - cb.php common.php community.php - contactgroup.php ++ contactgroup.php crepair.php delegate.php - directory.php +? directory.php dirfind.php display.php editpost.php - events.php +? events.php fbrowser.php feed.php filerm.php @@ -104,17 +104,17 @@ mod/ fsuggest.php + group.php - hcard.php -> not needed - help.php += help.php + home.php hostxrd.php -> probably not needed ? install.php invite.php + item.php + like.php - lockview.php ++ lockview.php + login.php lostpass.php - magic.php +? magic.php + manage.php match.php ? message.php @@ -157,15 +157,15 @@ mod/ suggest.php tagger.php tagrm.php - uexport.php - update_community.php - needs converting to json - update_network.php - needs converting to json - update_profile.php - needs converting to json +? uexport.php +? update_community.php - needs converting to json +? update_network.php - needs converting to json +? update_profile.php - needs converting to json viewcontacts.php view.php + viewsrc.php -? wall_attach.php (needs remote permissions refactor) -? wall_upload.php (needs remote permissions refactor) ++ wall_attach.php (needs remote permissions refactor) ++ wall_upload.php (needs remote permissions refactor) webfinger.php + _well_known.php xrd.php diff --git a/include/ItemObject.php b/include/ItemObject.php index 6f9eaa18e..b6f1e53a4 100644 --- a/include/ItemObject.php +++ b/include/ItemObject.php @@ -49,6 +49,7 @@ class Item extends BaseObject { // fixme $this->writable = ($this->get_data_value('writable') || $this->get_data_value('self')); // FIXME - base this on observer permissions + $this->writable = ((local_user() && $channel['channel_hash'] === $item['owner_xchan']) ? true : false); @@ -227,8 +228,8 @@ class Item extends BaseObject { 'body' => $body_e, 'text' => strip_tags($body_e), 'id' => $this->get_id(), - 'linktitle' => sprintf( t('View %s\'s profile @ %s'), $profile_name, ((strlen($item['author-link'])) ? $item['author-link'] : $item['url'])), - 'olinktitle' => sprintf( t('View %s\'s profile @ %s'), $this->get_owner_name(), ((strlen($item['owner-link'])) ? $item['owner-link'] : $item['url'])), + 'linktitle' => sprintf( t('View %s\'s profile - %s'), $profile_name, $item['author']['xchan_addr']), + 'olinktitle' => sprintf( t('View %s\'s profile - %s'), $this->get_owner_name(), $item['owner']['xchan_addr']), 'to' => t('to'), 'wall' => t('Wall-to-Wall'), 'vwall' => t('via Wall-To-Wall:'), diff --git a/include/Photo.php b/include/Photo.php index c3165cc9f..a60cfc868 100644 --- a/include/Photo.php +++ b/include/Photo.php @@ -523,7 +523,7 @@ class Photo { - public function store($uid, $xchan, $rid, $filename, $album, $scale, $profile = 0, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') { + public function store($aid, $uid, $xchan, $rid, $filename, $album, $scale, $profile = 0, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') { $x = q("select id from photo where `resource_id` = '%s' and uid = %d and `xchan` = '%s' and `scale` = %d limit 1", dbesc($rid), @@ -533,6 +533,7 @@ class Photo { ); if(count($x)) { $r = q("UPDATE `photo` + set `aid` = %d, set `uid` = %d, `xchan` = '%s', `resource_id` = '%s', @@ -544,6 +545,7 @@ class Photo { `height` = %d, `width` = %d, `data` = '%s', + `size` = %d, `scale` = %d, `profile` = %d, `allow_cid` = '%s', @@ -552,6 +554,7 @@ class Photo { `deny_gid` = '%s' where id = %d limit 1", + intval($aid), intval($uid), dbesc($xchan), dbesc($rid), @@ -563,6 +566,7 @@ class Photo { intval($this->getHeight()), intval($this->getWidth()), dbesc($this->imageString()), + intval(strlen($this->imageString())), intval($scale), intval($profile), dbesc($allow_cid), @@ -574,8 +578,9 @@ class Photo { } else { $r = q("INSERT INTO `photo` - ( `uid`, `xchan`, `resource_id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` ) - VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, '%s', '%s', '%s', '%s' )", + ( `aid`, `uid`, `xchan`, `resource_id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `data`, `size`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` ) + VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s' )", + intval($aid), intval($uid), dbesc($xchan), dbesc($rid), @@ -587,6 +592,7 @@ class Photo { intval($this->getHeight()), intval($this->getWidth()), dbesc($this->imageString()), + intval(strlen($this->imageString())), intval($scale), intval($profile), dbesc($allow_cid), @@ -669,21 +675,21 @@ function import_profile_photo($photo,$xchan) { $img->scaleImageSquare(175); - $r = $img->store(0, $xchan, $hash, $filename, 'Contact Photos', 4 ); + $r = $img->store(0, 0, $xchan, $hash, $filename, 'Contact Photos', 4 ); if($r === false) $photo_failure = true; $img->scaleImage(80); - $r = $img->store(0, $xchan, $hash, $filename, 'Contact Photos', 5 ); + $r = $img->store(0, 0, $xchan, $hash, $filename, 'Contact Photos', 5 ); if($r === false) $photo_failure = true; $img->scaleImage(48); - $r = $img->store(0, $xchan, $hash, $filename, 'Contact Photos', 6 ); + $r = $img->store(0, 0, $xchan, $hash, $filename, 'Contact Photos', 6 ); if($r === false) $photo_failure = true; diff --git a/include/api.php b/include/api.php index 1864d511e..cf4d45c1a 100644 --- a/include/api.php +++ b/include/api.php @@ -1,10 +1,11 @@ <?php - require_once("bbcode.php"); - require_once("datetime.php"); - require_once("conversation.php"); - require_once("oauth.php"); - require_once("html2plain.php"); - require_once('include/security.php'); + +require_once("bbcode.php"); +require_once("datetime.php"); +require_once("conversation.php"); +require_once("oauth.php"); +require_once("html2plain.php"); +require_once('include/security.php'); /* * @@ -12,7 +13,13 @@ * */ - $API = Array(); + + /** + ** TWITTER API + */ + + $API = array(); + $called_api = Null; // All commands which require authentication accept a "channel" parameter @@ -114,6 +121,7 @@ /************************** * MAIN API ENTRY POINT * **************************/ + function api_call(&$a){ GLOBAL $API, $called_api; @@ -373,30 +381,20 @@ } + function api_item_get_user(&$a, $item) { global $usercache; // The author is our direct contact, in a conversation with us. - if(link_compare($item['url'],$item['author-link'])) { - return api_get_user($a,$item['cid']); - } - else { - // The author may be a contact of ours, but is replying to somebody else. - // Figure out if we know him/her. - $normalised = normalise_link((strlen($item['author-link'])) ? $item['author-link'] : $item['url']); - if(($normalised != 'mailbox') && (x($a->contacts[$normalised]))) - return api_get_user($a,$a->contacts[$normalised]['id']); - } + + if($item['author']['abook_id']) { + return api_get_user($a,$item['author']['abook_id']); + } + // We don't know this person directly. - list($nick, $name) = array_map("trim",explode("(",$item['author-name'])); - $name=str_replace(")","",$name); - - if ($name == '') - $name = $nick; - - if ($nick == '') - $nick = $name; + $nick = substr($item['author']['xchan_addr'],0,strpos($item['author']['xchan_addr'],'@')); + $name = $item['author']['xchan_name']; // Generating a random ID if (is_null($usercache[$nick]) or !array_key_exists($nick, $usercache)) @@ -408,8 +406,8 @@ 'screen_name' => $nick, 'location' => '', //$uinfo[0]['default-location'], 'description' => '', - 'profile_image_url' => $item['author-avatar'], - 'url' => $item['author-link'], + 'profile_image_url' => $item['author']['xchan_photo_m'], + 'url' => $item['author']['xchan_url'], 'protected' => false, # 'followers_count' => 0, 'friends_count' => 0, @@ -466,9 +464,6 @@ return $ret; } - /** - ** TWITTER API - */ /** * Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful; @@ -524,27 +519,27 @@ function api_statuses_mediap(&$a, $type) { - if (api_user()===false) { - logger('api_statuses_update: no user'); - return false; - } - $user_info = api_get_user($a); - - $_REQUEST['type'] = 'wall'; - $_REQUEST['profile_uid'] = api_user(); - $_REQUEST['api_source'] = true; - $txt = requestdata('status'); - //$txt = urldecode(requestdata('status')); - - require_once('library/HTMLPurifier.auto.php'); - require_once('include/html2bbcode.php'); - - if((strpos($txt,'<') !== false) || (strpos($txt,'>') !== false)) { + if (api_user() === false) { + logger('api_statuses_update: no user'); + return false; + } + $user_info = api_get_user($a); + + $_REQUEST['type'] = 'wall'; + $_REQUEST['profile_uid'] = api_user(); + $_REQUEST['api_source'] = true; + + $txt = requestdata('status'); + + require_once('library/HTMLPurifier.auto.php'); + require_once('include/html2bbcode.php'); + + if((strpos($txt,'<') !== false) || (strpos($txt,'>') !== false)) { $txt = html2bb_video($txt); $config = HTMLPurifier_Config::createDefault(); - $config->set('Cache.DefinitionImpl', null); + $config->set('Cache.DefinitionImpl', null); $purifier = new HTMLPurifier($config); - $txt = $purifier->purify($txt); + $txt = $purifier->purify($txt); } $txt = html2bbcode($txt); @@ -552,10 +547,10 @@ $_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo require_once('mod/wall_upload.php'); - $bebop = wall_upload_post($a); + $posted = wall_upload_post($a); //now that we have the img url in bbcode we can add it to the status and insert the wall item. - $_REQUEST['body']=$txt."\n\n".$bebop; + $_REQUEST['body']=$txt."\n\n".$posted; require_once('mod/item.php'); item_post($a); @@ -564,8 +559,6 @@ } api_register_func('api/statuses/mediap','api_statuses_mediap', true); - - function api_statuses_update(&$a, $type) { if (api_user() === false) { logger('api_statuses_update: no user'); @@ -647,13 +640,15 @@ // get last public message + require_once('include/security.php'); + $lastwall = q("SELECT * from item where 1 - and not ( item_flags & %d ) and item_restrict = 0 + and item_private != 0 and item_restrict = 0 and author_xchan = '%s' and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = '' and verb = '%s' + and uid in ( " . stream_perms_api_uids() . " ) order by created desc limit 1", - intval(ITEM_PRIVATE), dbesc($user_info['guid']), dbesc(ACTIVITY_POST) ); @@ -717,13 +712,15 @@ function api_users_show(&$a, $type){ $user_info = api_get_user($a); + require_once('include/security.php'); + $lastwall = q("SELECT * from item where 1 - and not ( item_flags & %d ) and item_restrict = 0 + and item_private != 0 and item_restrict = 0 and author_xchan = '%s' and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = '' and verb = '%s' + and uid in ( " . stream_perms_api_uids() . " ) order by created desc limit 1", - intval(ITEM_PRIVATE), dbesc($user_info['guid']), dbesc(ACTIVITY_POST) ); @@ -784,18 +781,20 @@ */ function api_statuses_home_timeline(&$a, $type){ - if (api_user()===false) return false; + if (api_user() === false) + return false; $user_info = api_get_user($a); - // get last newtork messages + // get last network messages // params - $count = (x($_REQUEST,'count')?$_REQUEST['count']:20); - $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0); - if ($page<0) $page=0; - $since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0); - $max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0); + $count = (x($_REQUEST,'count')?$_REQUEST['count']:20); + $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0); + if($page < 0) + $page = 0; + $since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0); + $max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0); $exclude_replies = (x($_REQUEST,'exclude_replies')?1:0); //$since_id = 0;//$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0); @@ -809,33 +808,40 @@ if ($exclude_replies > 0) $sql_extra .= ' AND `item`.`parent` = `item`.`id`'; - $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, - `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, - `contact`.`network`, `contact`.`thumb`, `contact`.`dfrn_id`, `contact`.`self`, - `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid` - FROM `item`, `contact` - WHERE `item`.`uid` = %d - AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0 - AND `contact`.`id` = `item`.`contact-id` - AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 + if (api_user() != $user_info['uid']) { + $observer = get_app()->get_observer(); + require_once('include/permissions.php'); + if(! perm_is_allowed($user_info['uid'],(($observer) ? $observer['xchan_hash'] : ''),'view_stream')) + return ''; + $sql_extra .= " and item_private = 0 "; + } + + $r = q("SELECT * from item WHERE uid = %d and item_restrict = 0 $sql_extra - AND `item`.`id`>%d - ORDER BY `item`.`received` DESC LIMIT %d ,%d ", + AND id > %d + ORDER BY received DESC LIMIT %d ,%d ", intval($user_info['uid']), intval($since_id), - intval($start), intval($count) + intval($start), + intval($count) ); + xchan_query($r,true); + $ret = api_format_items($r,$user_info); // We aren't going to try to figure out at the item, group, and page // level which items you've seen and which you haven't. If you're looking // at the network timeline just mark everything seen. - $r = q("UPDATE `item` SET `unseen` = 0 - WHERE `unseen` = 1 AND `uid` = %d", - intval($user_info['uid']) - ); + if (api_user() == $user_info['uid']) { + $r = q("UPDATE `item` SET item_flags = ( item_flags ^ %d ) + WHERE item_flags & %d and uid = %d", + intval(ITEM_UNSEEN), + intval(ITEM_UNSEEN), + intval($user_info['uid']) + ); + } $data = array('$statuses' => $ret); @@ -878,42 +884,22 @@ if ($max_id > 0) $sql_extra = 'AND `item`.`id` <= '.intval($max_id); + require_once('include/security.php'); - /*$r = q("SELECT `item`.*, `item`.`id` AS `item_id`, - `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, - `contact`.`network`, `contact`.`thumb`, `contact`.`dfrn_id`, `contact`.`self`, - `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid` - FROM `item`, `contact` - WHERE `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0 - AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' - AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' - AND `item`.`private` = 0 AND `item`.`wall` = 1 AND `user`.`hidewall` = 0 - AND `contact`.`id` = `item`.`contact-id` - AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 + $r = q("select * from item where item_restrict = 0 + and allow_cid = '' and allow_gid = '' + and deny_cid = '' and deny_gid = '' + and item_private = 0 + and uid in ( " . stream_perms_api_uids() . " ) $sql_extra - AND `item`.`id`>%d - ORDER BY `item`.`received` DESC LIMIT %d ,%d ", + AND id > %d group by uri + order by received desc LIMIT %d, %d ", intval($since_id), - intval($start), intval($count) - );*/ - $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, - `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, - `contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`, - `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`, - `user`.`nickname`, `user`.`hidewall` - FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` - LEFT JOIN `user` ON `user`.`uid` = `item`.`uid` - WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0 - AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' - AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' - AND `item`.`private` = 0 AND `item`.`wall` = 1 AND `user`.`hidewall` = 0 - AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 - $sql_extra - AND `item`.`id`>%d - ORDER BY `received` DESC LIMIT %d, %d ", - intval($since_id), - intval($start), - intval($count)); + intval($start), + intval($count) + ); + + xchan_query($r,true); $ret = api_format_items($r,$user_info); @@ -926,7 +912,7 @@ break; case "as": $as = api_format_as($a, $ret, $user_info); - $as['title'] = $a->config['sitename']." Public Timeline"; + $as['title'] = $a->config['sitename']. " " . t('Public Timeline'); $as['link']['url'] = $a->get_baseurl()."/"; return($as); break; @@ -938,6 +924,7 @@ /** * + */ function api_statuses_show(&$a, $type){ if (api_user()===false) return false; @@ -945,7 +932,7 @@ $user_info = api_get_user($a); // params - $id = intval($a->argv[3]); + $id = intval(argv(3)); logger('API: api_statuses_show: '.$id); @@ -958,17 +945,10 @@ else $sql_extra .= " AND `item`.`id` = %d"; - $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, - `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, - `contact`.`network`, `contact`.`thumb`, `contact`.`dfrn_id`, `contact`.`self`, - `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid` - FROM `item`, `contact` - WHERE `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0 - AND `contact`.`id` = `item`.`contact-id` - AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 - $sql_extra", + $r = q("select * from item where item_restrict = 0 $sql_extra", intval($id) ); + xchan_query($r,true); $ret = api_format_items($r,$user_info); @@ -997,34 +977,31 @@ $user_info = api_get_user($a); // params - $id = intval($a->argv[3]); + $id = intval(argv(3)); logger('API: api_statuses_repeat: '.$id); //$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false); - $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, `contact`.`nick` as `reply_author`, - `contact`.`name`, `contact`.`photo`, `contact`.`url` as `reply_url`, `contact`.`rel`, - `contact`.`network`, `contact`.`thumb`, `contact`.`dfrn_id`, `contact`.`self`, - `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid` - FROM `item`, `contact` - WHERE `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0 - AND `contact`.`id` = `item`.`contact-id` - AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 - $sql_extra - AND `item`.`id`=%d", + $observer = get_app()->get_observer(); + + $r = q("SELECT * from item where item_restrict = 0 and id = %d limit 1", intval($id) ); - if ($r[0]['body'] != "") { - $_REQUEST['body'] = html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8')."[url=".$r[0]['reply_url']."]".$r[0]['reply_author']."[/url] \n".$r[0]['body']; - $_REQUEST['profile_uid'] = api_user(); - $_REQUEST['type'] = 'wall'; - $_REQUEST['api_source'] = true; + if(perm_is_allowed($r[0]['uid'],$observer['xchan_hash'],'view_stream')) { + if ($r[0]['body'] != "") { + $_REQUEST['body'] = html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8')."[url=".$r[0]['reply_url']."]".$r[0]['reply_author']."[/url] \n".$r[0]['body']; + $_REQUEST['profile_uid'] = api_user(); + $_REQUEST['type'] = 'wall'; + $_REQUEST['api_source'] = true; - require_once('mod/item.php'); - item_post($a); + require_once('mod/item.php'); + item_post($a); + } } + else + return false; if ($type == 'xml') $ok = "true"; @@ -1038,13 +1015,14 @@ /** * */ + function api_statuses_destroy(&$a, $type){ if (api_user()===false) return false; $user_info = api_get_user($a); // params - $id = intval($a->argv[3]); + $id = intval(argv(3)); logger('API: api_statuses_destroy: '.$id); @@ -1065,6 +1043,8 @@ * http://developer.twitter.com/doc/get/statuses/mentions * */ + +// FIXME function api_statuses_mentions(&$a, $type){ if (api_user()===false) return false; @@ -1142,6 +1122,7 @@ return api_apply_template("timeline", $type, $data); } api_register_func('api/statuses/mentions','api_statuses_mentions', true); + // FIXME?? I don't think mentions and replies are congruent in this case api_register_func('api/statuses/replies','api_statuses_mentions', true); @@ -1149,7 +1130,7 @@ if (api_user()===false) return false; $user_info = api_get_user($a); - // get last newtork messages + // get last network messages logger("api_statuses_user_timeline: api_user: ". api_user() . @@ -1325,7 +1306,7 @@ function api_format_messages($item, $recipient, $sender) { // standard meta information - $ret=Array( + $ret = array( 'id' => $item['id'], 'created_at' => api_date($item['created']), 'sender_id' => $sender['id'] , @@ -1364,25 +1345,27 @@ //logger('api_format_items: ' . print_r($user_info,true)); $a = get_app(); - $ret = Array(); + $ret = array(); foreach($r as $item) { localize_item($item); - $status_user = (($item['cid']==$user_info['id'])?$user_info: api_item_get_user($a,$item)); - if ($item['parent']!=$item['id']) { - $r = q("select id from item where parent=%s and id<%s order by id desc limit 1", - intval($item['parent']), intval($item['id'])); + $status_user = (($item['author_xchan']==$user_info['guid'])?$user_info: api_item_get_user($a,$item)); + + if($item['parent'] != $item['id']) { + $r = q("select id from item where parent= %d and id < %d order by id desc limit 1", + intval($item['parent']), + intval($item['id']) + ); if ($r) $in_reply_to_status_id = $r[0]['id']; else $in_reply_to_status_id = $item['parent']; - $r = q("select `item`.`contact-id`, `contact`.nick, `item`.`author-name` from item, contact - where `contact`.`id` = `item`.`contact-id` and `item`.id=%d", intval($in_reply_to_status_id)); + xchan_query($r,true); - $in_reply_to_screen_name = $r[0]['author-name']; - $in_reply_to_user_id = $r[0]['contact-id']; + $in_reply_to_screen_name = $r[0]['author']['xchan_name']; + $in_reply_to_user_id = $r[0]['author']['abook_id']; } else { $in_reply_to_screen_name = ''; @@ -1399,41 +1382,39 @@ else $statustext = trim($statustitle."\n\n".$statusbody); - if (($item["network"] == NETWORK_FEED) and (strlen($statustext)> 1000)) - $statustext = substr($statustext, 0, 1000)."... \n".$item["plink"]; $status = array( - 'text' => $statustext, - 'truncated' => False, - 'created_at'=> api_date($item['created']), - 'in_reply_to_status_id' => $in_reply_to_status_id, - 'source' => (($item['app']) ? $item['app'] : 'web'), - 'id' => intval($item['id']), - 'in_reply_to_user_id' => $in_reply_to_user_id, - 'in_reply_to_screen_name' => $in_reply_to_screen_name, - 'geo' => '', - 'favorited' => $item['starred'] ? true : false, - 'user' => $status_user , - 'statusnet_html' => trim(bbcode($item['body'])), + 'text' => $statustext, + 'truncated' => False, + 'created_at' => api_date($item['created']), + 'in_reply_to_status_id' => $in_reply_to_status_id, + 'source' => (($item['app']) ? $item['app'] : 'web'), + 'id' => intval($item['id']), + 'in_reply_to_user_id' => $in_reply_to_user_id, + 'in_reply_to_screen_name' => $in_reply_to_screen_name, + 'geo' => '', + 'favorited' => (($item['item_flags'] & ITEM_STARRED) ? true : false), + 'user' => $status_user , + 'statusnet_html' => trim(bbcode($item['body'])), 'statusnet_conversation_id' => $item['parent'], ); // Seesmic doesn't like the following content if ($_SERVER['HTTP_USER_AGENT'] != 'Seesmic') { $status2 = array( - 'updated' => api_date($item['edited']), - 'published' => api_date($item['created']), - 'message_id' => $item['uri'], - 'url' => ($item['plink']!=''?$item['plink']:$item['author-link']), - 'coordinates' => $item['coord'], - 'place' => $item['location'], + 'updated' => api_date($item['edited']), + 'published' => api_date($item['created']), + 'message_id' => $item['uri'], + 'url' => $item['plink'], + 'coordinates' => $item['coord'], + 'place' => $item['location'], 'contributors' => '', 'annotations' => '', - 'entities' => '', - 'objecttype' => (($item['obj_type']) ? $item['obj_type'] : ACTIVITY_OBJ_NOTE), - 'verb' => (($item['verb']) ? $item['verb'] : ACTIVITY_POST), - 'self' => $a->get_baseurl()."/api/statuses/show/".$item['id'].".".$type, - 'edit' => $a->get_baseurl()."/api/statuses/show/".$item['id'].".".$type, + 'entities' => '', + 'objecttype' => (($item['obj_type']) ? $item['obj_type'] : ACTIVITY_OBJ_NOTE), + 'verb' => (($item['verb']) ? $item['verb'] : ACTIVITY_POST), + 'self' => $a->get_baseurl()."/api/statuses/show/".$item['id'].".".$type, + 'edit' => $a->get_baseurl()."/api/statuses/show/".$item['id'].".".$type, ); $status = array_merge($status, $status2); @@ -1499,12 +1480,14 @@ return false; } + // For Red, the closest thing we can do to figure out if you're friends is if both of you are sending each other your streams. + // This won't work if either of you send your stream to everybody on the network if($qtype == 'friends') - $sql_extra = sprintf(" AND ( `rel` = %d OR `rel` = %d ) ", intval(CONTACT_IS_SHARING), intval(CONTACT_IS_FRIEND)); + $sql_extra = sprintf(" AND ( their_perms & %d ) and ( my_perms & %d ) ", intval(PERMS_W_STREAM), intval(PERMS_W_STREAM)); if($qtype == 'followers') - $sql_extra = sprintf(" AND ( `rel` = %d OR `rel` = %d ) ", intval(CONTACT_IS_FOLLOWER), intval(CONTACT_IS_FRIEND)); + $sql_extra = sprintf(" AND ( my_perms & %d ) and not ( their_perms & %d ) ", intval(PERMS_W_STREAM), intval(PERMS_W_STREAM)); - $r = q("SELECT id FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 $sql_extra", + $r = q("SELECT id FROM abook where abook_flags = 0 and abook_channel = %d $sql_extra", intval(api_user()) ); @@ -1611,13 +1594,16 @@ if(! api_user()) return false; + + // For Red, the closest thing we can do to figure out if you're friends is if both of you are sending each other your streams. + // This won't work if either of you send your stream to everybody on the network + if($qtype == 'friends') - $sql_extra = sprintf(" AND ( `rel` = %d OR `rel` = %d ) ", intval(CONTACT_IS_SHARING), intval(CONTACT_IS_FRIEND)); + $sql_extra = sprintf(" AND ( their_perms & %d ) and ( my_perms & %d ) ", intval(PERMS_W_STREAM), intval(PERMS_W_STREAM)); if($qtype == 'followers') - $sql_extra = sprintf(" AND ( `rel` = %d OR `rel` = %d ) ", intval(CONTACT_IS_FOLLOWER), intval(CONTACT_IS_FRIEND)); + $sql_extra = sprintf(" AND ( my_perms & %d ) and not ( their_perms & %d ) ", intval(PERMS_W_STREAM), intval(PERMS_W_STREAM)); - - $r = q("SELECT id FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 $sql_extra", + $r = q("SELECT id FROM abook where abook_flags = 0 and abook_channel = %d $sql_extra", intval(api_user()) ); diff --git a/include/auth.php b/include/auth.php index c12432449..9cdbd80d5 100644 --- a/include/auth.php +++ b/include/auth.php @@ -63,16 +63,21 @@ if((isset($_SESSION)) && (x($_SESSION,'authenticated')) && ((! (x($_POST,'auth-p info( t('Logged out.') . EOL); goaway(z_root()); } - -// if(x($_SESSION,'visitor_id') && (! x($_SESSION,'uid'))) { -// $r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", -// intval($_SESSION['visitor_id']) -// ); -// if(count($r)) { -// $a->contact = $r[0]; -// } -// } - +dbg(1); + if(x($_SESSION,'visitor_id') && (! x($_SESSION,'uid'))) { + $r = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_hash = '%s' limit 1", + dbesc($_SESSION['visitor_id']) + ); + if($r) { + get_app()->set_observer($r[0]); + } + else { + unset($_SESSION['visitor_id']); + unset($_SESSION['authenticated']); + } + $a->set_groups(init_groups_visitor($_SESSION['visitor_id'])); + } +dbg(0); if(x($_SESSION,'uid') || x($_SESSION,'account_id')) { // already logged in user returning diff --git a/include/contact_widgets.php b/include/contact_widgets.php index 47945e66e..cb3dc0740 100644 --- a/include/contact_widgets.php +++ b/include/contact_widgets.php @@ -116,23 +116,23 @@ function common_friends_visitor_widget($profile_uid) { } // FIXME - if(! $cid) { - if(get_my_url()) { - $r = q("select id from contact where nurl = '%s' and uid = %d limit 1", - dbesc(normalise_link(get_my_url())), - intval($profile_uid) - ); - if(count($r)) - $cid = $r[0]['id']; - else { - $r = q("select id from gcontact where nurl = '%s' limit 1", - dbesc(normalise_link(get_my_url())) - ); - if(count($r)) - $zcid = $r[0]['id']; - } - } - } +// if(! $cid) { +// if(get_my_url()) { +// $r = q("select id from contact where nurl = '%s' and uid = %d limit 1", +// dbesc(normalise_link(get_my_url())), +// intval($profile_uid) +// ); +// if(count($r)) +// $cid = $r[0]['id']; +// else { +// $r = q("select id from gcontact where nurl = '%s' limit 1", +// dbesc(normalise_link(get_my_url())) +// ); +// if(count($r)) +// $zcid = $r[0]['id']; +// } +// } +// } if($cid == 0 && $zcid == 0) return; diff --git a/include/event.php b/include/event.php index 685842fc3..8bf65016f 100644 --- a/include/event.php +++ b/include/event.php @@ -205,30 +205,36 @@ function event_store($arr) { $a = get_app(); - $arr['created'] = (($arr['created']) ? $arr['created'] : datetime_convert()); - $arr['edited'] = (($arr['edited']) ? $arr['edited'] : datetime_convert()); - $arr['type'] = (($arr['type']) ? $arr['type'] : 'event' ); + $arr['created'] = (($arr['created']) ? $arr['created'] : datetime_convert()); + $arr['edited'] = (($arr['edited']) ? $arr['edited'] : datetime_convert()); + $arr['type'] = (($arr['type']) ? $arr['type'] : 'event' ); $arr['event_xchan'] = (($arr['event_xchan']) ? $arr['event_xchan'] : ''); // Existing event being modified - if($arr['id']) { + if($arr['id'] || $arr['event_hash']) { // has the event actually changed? - $r = q("SELECT * FROM `event` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($arr['id']), - intval($arr['uid']) - ); - if((! $r) || ($r[0]['edited'] === $arr['edited'])) { - - // Nothing has changed. Grab the item id to return. - - $r = q("SELECT id FROM item WHERE resource_type = 'event' and resource_id = '%s' AND uid = %d LIMIT 1", - intval($arr['event_hash']), + if($arr['event_hash']) { + $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + dbesc($arr['event_hash']), intval($arr['uid']) ); - return(($r) ? $r[0]['id'] : 0); + } + else { + $r = q("SELECT * FROM event WHERE id = %d AND uid = %d LIMIT 1", + intval($arr['id']), + intval($arr['uid']) + ); + } + + if(! $r) + return 0; + + if($r[0]['edited'] === $arr['edited']) { + // Nothing has changed. Return the ID. + return $r[0]['id']; } // The event changed. Update it. @@ -262,12 +268,12 @@ function event_store($arr) { dbesc($arr['allow_gid']), dbesc($arr['deny_cid']), dbesc($arr['deny_gid']), - intval($arr['id']), + intval($r[0]['id']), intval($arr['uid']) ); $r = q("SELECT * FROM item left join xchan on author_xchan = xchan_hash WHERE resource_id = '%s' AND resource_type = 'event' and uid = %d LIMIT 1", - intval($arr['event_hash']), + intval($r[0]['event_hash']), intval($arr['uid']) ); @@ -291,7 +297,8 @@ function event_store($arr) { $private = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0); - q("UPDATE item SET title = '%s', body = '%s', object = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', edited = '%s', item_flags = %d WHERE id = %d AND uid = %d LIMIT 1", + + q("UPDATE item SET title = '%s', body = '%s', object = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', edited = '%s', item_flags = %d, item_private = %d WHERE id = %d AND uid = %d LIMIT 1", dbesc($arr['summary']), dbesc(format_event_bbcode($arr)), dbesc($object), @@ -300,7 +307,8 @@ function event_store($arr) { dbesc($arr['deny_cid']), dbesc($arr['deny_gid']), dbesc($arr['edited']), - intval(($private && ($r[0]['item_flags'] & ITEM_PRIVATE)) ? $r[0]['item_flags'] : $r[0]['item_flags'] ^ ITEM_PRIVATE), + intval($r[0]['item_flags']), + intval($private), intval($r[0]['id']), intval($arr['uid']) ); @@ -320,8 +328,12 @@ function event_store($arr) { $hash = random_string(); - $r = q("INSERT INTO `event` ( `uid`,`aid`,`event_xchan`,`event_hash`,`created`,`edited`,`start`,`finish`,`summary`, `desc`,`location`,`type`, - `adjust`,`nofinish`,`allow_cid`,`allow_gid`,`deny_cid`,`deny_gid`) + if(! $arr['uri']) + $arr['uri'] = item_message_id(); + + + $r = q("INSERT INTO event ( uid,aid,event_xchan,event_hash,created,edited,start,finish,summary, desc,location,type, + adjust,nofinish,allow_cid,allow_gid,deny_cid,deny_gid) VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s' ) ", intval($arr['uid']), intval($arr['account']), @@ -344,7 +356,7 @@ function event_store($arr) { ); - $r = q("SELECT * FROM `event` WHERE `event_hash` = '%s' AND `uid` = %d LIMIT 1", + $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", dbesc($hash), intval($arr['uid']) ); @@ -364,19 +376,14 @@ function event_store($arr) { $item_flags |= ITEM_ORIGIN; } - - $uri = item_message_id(); - $private = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0); - if($private) - $item_flags |= ITEM_PRIVATE; $item_arr = array(); $item_arr['uid'] = $arr['uid']; $item_arr['author_xchan'] = $arr['event_xchan']; - $item_arr['uri'] = $uri; - $item_arr['parent_uri'] = $uri; + $item_arr['uri'] = $arr['uri']; + $item_arr['parent_uri'] = $arr['uri']; $item_arr['item_flags'] = $item_flags; @@ -387,12 +394,13 @@ function event_store($arr) { $item_arr['allow_gid'] = $arr['allow_gid']; $item_arr['deny_cid'] = $arr['deny_cid']; $item_arr['deny_gid'] = $arr['deny_gid']; + $item_arr['item_private'] = $private; $item_arr['verb'] = ACTIVITY_POST; $item_arr['resource_type'] = 'event'; $item_arr['resource_id'] = $hash; - $item_arr['obj_type'] = ACTIVITY_OBJ_EVENT; + $item_arr['obj_type'] = ACTIVITY_OBJ_EVENT; $item_arr['body'] = format_event_bbcode($arr); $x = q("select * from xchan where xchan_hash = '%s' limit 1", diff --git a/include/group.php b/include/group.php index 6568af0c7..3a2fe7a3c 100644 --- a/include/group.php +++ b/include/group.php @@ -169,7 +169,7 @@ function group_add_member($uid,$name,$member,$gid = 0) { function group_get_members($gid) { $ret = array(); if(intval($gid)) { - $r = q("SELECT abook.*,xchan.*,group_member.* FROM `group_member` + $r = q("SELECT * FROM `group_member` LEFT JOIN abook ON abook_xchan = `group_member`.`xchan` left join xchan on xchan_hash = abook_xchan WHERE `gid` = %d AND `group_member`.`uid` = %d and not ( abook_flags & %d ) and not ( abook_flags & %d ) and not ( abook_flags & %d ) ORDER BY xchan_name ASC ", intval($gid), @@ -228,7 +228,6 @@ function group_side($every="contacts",$each="group",$edit = false, $group_id = 0 ); - $r = q("SELECT * FROM `group` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `name` ASC", intval($_SESSION['uid']) ); diff --git a/include/html2plain.php b/include/html2plain.php index e5615f8ba..b8c9c440d 100644 --- a/include/html2plain.php +++ b/include/html2plain.php @@ -205,7 +205,7 @@ function html2plain($html, $wraplength = 75, $compact = false) if (!$compact) { $counter = 1; foreach ($urls as $id=>$url) - if (strpos($message, $url) == false) + if ($url && strpos($message, $url) === false) $message .= "\n".$url." "; //$message .= "\n[".($counter++)."] ".$url; } diff --git a/include/identity.php b/include/identity.php index 94de192c6..a66929b63 100644 --- a/include/identity.php +++ b/include/identity.php @@ -201,6 +201,9 @@ function identity_basic_export($channel_id) { */ $ret = array(); + + $ret['compatibility'] = array('project' => FRIENDICA_PLATFORM, 'version' => FRIENDICA_VERSION, 'database' => DB_UPDATE_VERSION); + $r = q("select * from channel where channel_id = %d limit 1", intval($channel_id) ); @@ -240,4 +243,49 @@ function identity_basic_export($channel_id) { +function identity_basic_import($arr, $seize_primary = false) { + + $ret = array('result' => false ); + + if($arr['channel']) { + // import channel + + // create a new xchan (if necessary) + + // create a new hubloc and seize control if applicable + + + } + if($arr['profile']) { + // FIXME - change profile assignment to a hash instead of an id we have to fix + + + } + + if($arr['xchan']) { + + // import any xchan and hubloc which are not yet available on this site + // Unset primary for all other hubloc on our own record if $seize_primary + + + } + + if($arr['abook']) { + // import the abook entries + + + } + + + if($seize_primary) { + + // send a refresh message to all our friends, telling them we've moved + + } + + + $ret['result'] = true ; + return $ret; + +}
\ No newline at end of file diff --git a/include/items.php b/include/items.php index a462c8073..dcc6c9b50 100755 --- a/include/items.php +++ b/include/items.php @@ -1598,17 +1598,16 @@ function tag_deliver($uid,$item_id) { $private = ($u[0]['allow_cid'] || $u[0]['allow_gid'] || $u[0]['deny_cid'] || $u[0]['deny_gid']) ? 1 : 0; $flag_bits = ITEM_WALL|ITEM_ORIGIN|ITEM_UPLINK; - if($private) - $flag_bits = $flag_bits | ITEM_PRIVATE; $r = q("update item set item_flags = ( $item_flags | %d ), owner_xchan = '%s', allow_cid = '%s', allow_gid = '%s', - deny_cid = '%s', deny_gid = '%s' where id = %d limit 1", + deny_cid = '%s', deny_gid = '%s', item_private = %d where id = %d limit 1", intval($flag_bits), dbesc($u[0]['channel_hash']), dbesc($u[0]['allow_cid']), dbesc($u[0]['allow_gid']), dbesc($u[0]['deny_cid']), dbesc($u[0]['deny_gid']), + intval($private), intval($item_id) ); if($r) @@ -2081,13 +2080,13 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) $img->scaleImageSquare(175); $hash = $resource_id; - $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 4); + $r = $img->store(0, $contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 4); $img->scaleImage(80); - $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 5); + $r = $img->store(0, $contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 5); $img->scaleImage(48); - $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 6); + $r = $img->store(0, $contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 6); $a = get_app(); diff --git a/include/nav.php b/include/nav.php index 644264a92..3a565af55 100644 --- a/include/nav.php +++ b/include/nav.php @@ -90,8 +90,12 @@ EOT; ); } - - $nav['lock'] = array('rmagic','',(($observer) ? 'lock' : 'unlock'), (($observer) ? $observer['xchan_addr'] : t('Click to authenticate to your home hub'))); + if($observer) + $nav['lock'] = array('logout','','lock', + sprintf( t('%s - click to logout'), $observer['xchan_addr'])); + else + $nav['lock'] = array('rmagic','','unlock', + t('Click to authenticate to your home hub')); /** * "Home" should also take you home from an authenticated remote profile connection @@ -118,9 +122,9 @@ EOT; $nav['search'] = array('search', t('Search'), "", t('Search site content')); - $gdirpath = 'directory'; - $nav['directory'] = array($gdirpath, t('Directory'), "", t('People directory')); + $nav['directory'] = array('directory', t('Channel Directory'), "", t('Channel Locator')); + /** * @@ -199,6 +203,7 @@ EOT; '$localuser' => local_user(), '$sel' => $a->nav_sel, '$apps' => $a->get_apps(), + '$pleasewait' => t('Please wait...') )); call_hooks('page_header', $a->page['nav']); diff --git a/include/onepoll.php b/include/onepoll.php index 4b44ff5b9..019fe8ed3 100644 --- a/include/onepoll.php +++ b/include/onepoll.php @@ -113,16 +113,14 @@ function onepoll_run($argv, $argc){ // set last updated timestamp - $r = null; - if($contact['xchan_connurl']) { $r = q("SELECT xlink_id from xlink where xlink_xchan = '%s' and xlink_updated > UTC_TIMESTAMP() - INTERVAL 1 DAY", intval($contact['xchan_hash']) ); - } - if($r) { - poco_load($contact['xchan_hash'],$contact['xchan_connurl']); + if($r) { + poco_load($contact['xchan_hash'],$contact['xchan_connurl']); + } } return; diff --git a/include/security.php b/include/security.php index 0783a3c20..f28174153 100644 --- a/include/security.php +++ b/include/security.php @@ -236,7 +236,7 @@ function item_permissions_sql($owner_id,$remote_verified = false,$groups = null) * default permissions - anonymous user */ - $sql = " AND not (item_flags & " . ITEM_PRIVATE . ") "; + $sql = " AND not item_private "; /** @@ -349,7 +349,7 @@ if(! function_exists('init_groups_visitor')) { function init_groups_visitor($contact_id) { $groups = array(); $r = q("SELECT gid FROM group_member WHERE xchan = '%s' ", - intval($contact_id) + dbesc($contact_id) ); if(count($r)) { foreach($r as $rr) @@ -359,3 +359,36 @@ function init_groups_visitor($contact_id) { }} + + + +// This is used to determine which uid have posts which are visible to the logged in user (from the API) for the +// public_timeline, and we can use this in a community page by making $perms_min = PERMS_NETWORK unless logged in. +// Collect uids of everybody on this site who has opened their posts to everybody on this site (or greater visibility) +// We always include yourself if logged in because you can always see your own posts +// resolving granular permissions for the observer against every person and every post on the site +// will likely be too expensive. +// Returns a string list of comma separated channel_ids suitable for direct inclusion in a SQL query + +function stream_perms_api_uids($perms_min = PERMS_SITE) { + $ret = array(); + if(local_user()) + $ret[] = local_user(); + $r = q("select channel_id from channel where channel_r_stream <= %d", + intval($perms_min) + ); + if($r) + foreach($r as $rr) + if(! in_array($rr['channel_id'],$ret)) + $ret[] = $rr['channel_id']; + + $str = ''; + if($ret) + foreach($ret as $rr) { + if($str) + $str .= ','; + $str .= intval($rr); + } + return $str; +} + diff --git a/include/socgraph.php b/include/socgraph.php index aa5a24e89..081927dcc 100644 --- a/include/socgraph.php +++ b/include/socgraph.php @@ -23,12 +23,11 @@ function poco_load($xchan = null,$url = null) { $a = get_app(); if($xchan && ! $url) { - $r = q("select xchan_connurl from xchan where xchan_hash = %d limit 1", - intval($xchan) + $r = q("select xchan_connurl from xchan where xchan_hash = '%s' limit 1", + dbesc($xchan) ); if($r) { $url = $r[0]['xchan_connurl']; - $uid = $r[0]['abook_channel']; } } @@ -109,24 +108,25 @@ function poco_load($xchan = null,$url = null) { } - $r = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' limit 1", - dbesc($xchan), - dbesc($hash) - ); - if(! $r) { - q("insert into xlink ( xlink_xchan, xlink_link, xlink_updated ) values ( '%s', '%s', '%s' ) ", + if($xchan) { + $r = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' limit 1", dbesc($xchan), - dbesc($hash), - dbesc(datetime_convert()) - ); - } - else { - q("update xlink set xlink_updated = '%s' where xlink_id = %d limit 1", - dbesc(datetime_convert()), - intval($r[0]['xlink_id']) + dbesc($hash) ); + if(! $r) { + q("insert into xlink ( xlink_xchan, xlink_link, xlink_updated ) values ( '%s', '%s', '%s' ) ", + dbesc($xchan), + dbesc($hash), + dbesc(datetime_convert()) + ); + } + else { + q("update xlink set xlink_updated = '%s' where xlink_id = %d limit 1", + dbesc(datetime_convert()), + intval($r[0]['xlink_id']) + ); + } } - } logger("poco_load: loaded $total entries",LOGGER_DEBUG); @@ -295,37 +295,38 @@ function suggestion_query($uid, $start = 0, $limit = 80) { function update_suggestions() { +// FIXME +return; $a = get_app(); $done = array(); - poco_load(0,0,0,$a->get_baseurl() . '/poco'); + // fix this to get a json list from an upstream directory +// poco_load(0,0,0,$a->get_baseurl() . '/poco'); - $done[] = $a->get_baseurl() . '/poco'; +// $done[] = $a->get_baseurl() . '/poco'; - if(strlen(get_config('system','directory_submit_url'))) { - $x = fetch_url('http://dir.friendica.com/pubsites'); - if($x) { - $j = json_decode($x); - if($j->entries) { - foreach($j->entries as $entry) { - $url = $entry->url . '/poco'; - if(! in_array($url,$done)) - poco_load(0,0,0,$entry->url . '/poco'); - } - } - } - } +// if(strlen(get_config('system','directory_submit_url'))) { +// $x = fetch_url('http://dir.friendica.com/pubsites'); +// if($x) { +// $j = json_decode($x); +// if($j->entries) { +// foreach($j->entries as $entry) { +// $url = $entry->url . '/poco'; +// if(! in_array($url,$done)) +// poco_load(0,0,0,$entry->url . '/poco'); +// } +// } +// } +// } - $r = q("select distinct(poco) as poco from contact where network = '%s'", - dbesc(NETWORK_DFRN) - ); + $r = q("select distinct(xchan_connurl) as poco from xchan where xchan_network = 'zot'"); - if(count($r)) { + if($r) { foreach($r as $rr) { $base = substr($rr['poco'],0,strrpos($rr['poco'],'/')); if(! in_array($base,$done)) - poco_load(0,0,0,$base); + poco_load('',$base); } } } diff --git a/include/text.php b/include/text.php index 9db22d9ed..167fbb1df 100644 --- a/include/text.php +++ b/include/text.php @@ -302,26 +302,33 @@ function paginate(&$a) { }} if(! function_exists('alt_pager')) { -function alt_pager(&$a, $i) { - $o = ''; +function alt_pager(&$a, $i, $more = '', $less = '') { + + $o = ''; + + if(! $more) + $more = t('older'); + if(! $less) + $less = t('newer'); + $stripped = preg_replace('/(&page=[0-9]*)/','',$a->query_string); $stripped = str_replace('q=','',$stripped); $stripped = trim($stripped,'/'); $pagenum = $a->pager['page']; - $url = $a->get_baseurl() . '/' . $stripped; + $url = $a->get_baseurl() . '/' . $stripped; - $o .= '<div class="pager">'; + $o .= '<div class="pager">'; - if($a->pager['page']>1) - $o .= "<a href=\"$url"."&page=".($a->pager['page'] - 1).'">' . t('newer') . '</a>'; - if($i>0) { - if($a->pager['page']>1) - $o .= " - "; - $o .= "<a href=\"$url"."&page=".($a->pager['page'] + 1).'">' . t('older') . '</a>'; + if($a->pager['page'] > 1) + $o .= "<a href=\"$url"."&page=".($a->pager['page'] - 1).'">' . $less . '</a>'; + if($i > 0 && $i == $a->pager['itemspage']) { + if($a->pager['page']>1) + $o .= " | "; + $o .= "<a href=\"$url"."&page=".($a->pager['page'] + 1).'">' . $more . '</a>'; } - $o .= '</div>'."\r\n"; + $o .= '</div>'."\r\n"; return $o; }} @@ -1711,7 +1718,11 @@ function ids_to_querystr($arr,$idx = 'id') { return(implode(',', $t)); } -function xchan_query(&$items) { +// Fetches xchan and hubloc data for an array of items with only an +// author_xchan and owner_xchan. If $abook is true also include the abook info. +// This is needed in the API to save extra per item lookups there. + +function xchan_query(&$items,$abook = false) { $arr = array(); if($items && count($items)) { foreach($items as $item) { @@ -1722,8 +1733,14 @@ function xchan_query(&$items) { } } if(count($arr)) { - $chans = q("select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash - where xchan_hash in (" . implode(',', $arr) . ") and ( hubloc_flags & " . intval(HUBLOC_FLAGS_PRIMARY) . " )"); + if($abook) { + $chans = q("select * from xchan left join hubloc on hubloc_hash = xchan_hash left join abook on abook_xchan = xchan_hash + where xchan_hash in (" . implode(',', $arr) . ") and ( hubloc_flags & " . intval(HUBLOC_FLAGS_PRIMARY) . " )"); + } + else { + $chans = q("select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash + where xchan_hash in (" . implode(',', $arr) . ") and ( hubloc_flags & " . intval(HUBLOC_FLAGS_PRIMARY) . " )"); + } } if($items && count($items) && $chans && count($chans)) { for($x = 0; $x < count($items); $x ++) { @@ -1781,9 +1798,11 @@ function magic_link($s) { return $s; } -function stringify_array_elms(&$arr) { +// if $escape is true, dbesc() each element before adding quotes + +function stringify_array_elms(&$arr,$escape = false) { for($x = 0; $x < count($arr); $x ++) - $arr[$x] = "'" . $arr[$x] . "'"; + $arr[$x] = "'" . (($escape) ? dbesc($arr[$x]) : $arr[$x]) . "'"; } /** diff --git a/include/user.php b/include/user.php deleted file mode 100644 index d71f024d1..000000000 --- a/include/user.php +++ /dev/null @@ -1,320 +0,0 @@ -<?php - -require_once('include/config.php'); -require_once('include/network.php'); -require_once('include/plugin.php'); -require_once('include/text.php'); -require_once('include/language.php'); -require_once('include/datetime.php'); - -function create_user($arr) { - - // Required: { username, nickname, email } or { openid_url } - - $a = get_app(); - $result = array('success' => false, 'user' => null, 'password' => '', 'message' => ''); - - $using_invites = get_config('system','invitation_only'); - $num_invites = get_config('system','number_invites'); - - - $invite_id = ((x($arr,'invite_id')) ? notags(trim($arr['invite_id'])) : ''); - $username = ((x($arr,'username')) ? notags(trim($arr['username'])) : ''); - $nickname = ((x($arr,'nickname')) ? notags(trim($arr['nickname'])) : ''); - $email = ((x($arr,'email')) ? notags(trim($arr['email'])) : ''); - $openid_url = ((x($arr,'openid_url')) ? notags(trim($arr['openid_url'])) : ''); - $photo = ((x($arr,'photo')) ? notags(trim($arr['photo'])) : ''); - $password = ((x($arr,'password')) ? trim($arr['password']) : ''); - $blocked = ((x($arr,'blocked')) ? intval($arr['blocked']) : 0); - $verified = ((x($arr,'verified')) ? intval($arr['verified']) : 0); - - $publish = ((x($arr,'profile_publish_reg') && intval($arr['profile_publish_reg'])) ? 1 : 0); - $netpublish = ((strlen(get_config('system','directory_submit_url'))) ? $publish : 0); - - $tmp_str = $openid_url; - - if($using_invites) { - if(! $invite_id) { - $result['message'] .= t('An invitation is required.') . EOL; - return $result; - } - $r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_id)); - if(! results($r)) { - $result['message'] .= t('Invitation could not be verified.') . EOL; - return $result; - } - } - - if((! x($username)) || (! x($email)) || (! x($nickname))) { - if($openid_url) { - if(! validate_url($tmp_str)) { - $result['message'] .= t('Invalid OpenID url') . EOL; - return $result; - } - $_SESSION['register'] = 1; - $_SESSION['openid'] = $openid_url; - require_once('library/openid.php'); - $openid = new LightOpenID; - $openid->identity = $openid_url; - $openid->returnUrl = $a->get_baseurl() . '/openid'; - $openid->required = array('namePerson/friendly', 'contact/email', 'namePerson'); - $openid->optional = array('namePerson/first','media/image/aspect11','media/image/default'); - goaway($openid->authUrl()); - // NOTREACHED - } - - notice( t('Please enter the required information.') . EOL ); - return; - } - - if(! validate_url($tmp_str)) - $openid_url = ''; - - - $err = ''; - - // collapse multiple spaces in name - $username = preg_replace('/ +/',' ',$username); - - if(mb_strlen($username) > 48) - $result['message'] .= t('Please use a shorter name.') . EOL; - if(mb_strlen($username) < 3) - $result['message'] .= t('Name too short.') . EOL; - - // I don't really like having this rule, but it cuts down - // on the number of auto-registrations by Russian spammers - - // Using preg_match was completely unreliable, due to mixed UTF-8 regex support - // $no_utf = get_config('system','no_utf'); - // $pat = (($no_utf) ? '/^[a-zA-Z]* [a-zA-Z]*$/' : '/^\p{L}* \p{L}*$/u' ); - - // So now we are just looking for a space in the full name. - - $loose_reg = get_config('system','no_regfullname'); - if(! $loose_reg) { - $username = mb_convert_case($username,MB_CASE_TITLE,'UTF-8'); - if(! strpos($username,' ')) - $result['message'] .= t("That doesn't appear to be your full \x28First Last\x29 name.") . EOL; - } - - - if(! allowed_email($email)) - $result['message'] .= t('Your email domain is not among those allowed on this site.') . EOL; - - if((! valid_email($email)) || (! validate_email($email))) - $result['message'] .= t('Not a valid email address.') . EOL; - - // Disallow somebody creating an account using openid that uses the admin email address, - // since openid bypasses email verification. We'll allow it if there is not yet an admin account. - - if((x($a->config,'admin_email')) && (strcasecmp($email,$a->config['admin_email']) == 0) && strlen($openid_url)) { - $r = q("SELECT * FROM `user` WHERE `email` = '%s' LIMIT 1", - dbesc($email) - ); - if(count($r)) - $result['message'] .= t('Cannot use that email.') . EOL; - } - - $nickname = $arr['nickname'] = strtolower($nickname); - - if(! preg_match("/^[a-z][a-z0-9\-\_]*$/",$nickname)) - $result['message'] .= t('Your "nickname" can only contain "a-z", "0-9", "-", and "_", and must also begin with a letter.') . EOL; - $r = q("SELECT `uid` FROM `user` - WHERE `nickname` = '%s' LIMIT 1", - dbesc($nickname) - ); - if(count($r)) - $result['message'] .= t('Nickname is already registered. Please choose another.') . EOL; - - // Check deleted accounts that had this nickname. Doesn't matter to us, - // but could be a security issue for federated platforms. - - $r = q("SELECT * FROM `userd` - WHERE `username` = '%s' LIMIT 1", - dbesc($nickname) - ); - if(count($r)) - $result['message'] .= t('Nickname was once registered here and may not be re-used. Please choose another.') . EOL; - - if(strlen($result['message'])) { - return $result; - } - - $new_password = ((strlen($password)) ? $password : autoname(6) . mt_rand(100,9999)); - $new_password_encoded = hash('whirlpool',$new_password); - - $result['password'] = $new_password; - - require_once('include/crypto.php'); - - $keys = new_keypair(4096); - - if($keys === false) { - $result['message'] .= t('SERIOUS ERROR: Generation of security keys failed.') . EOL; - return $result; - } - - $default_service_class = get_config('system','default_service_class'); - if(! $default_service_class) - $default_service_class = ''; - - - $prvkey = $keys['prvkey']; - $pubkey = $keys['pubkey']; - - $r = q("INSERT INTO `user` ( `guid`, `username`, `password`, `email`, `openid`, `nickname`, - `pubkey`, `prvkey`, `register_date`, `verified`, `blocked`, `timezone`, `service_class` ) - VALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, 'UTC', '%s' )", - dbesc(generate_user_guid()), - dbesc($username), - dbesc($new_password_encoded), - dbesc($email), - dbesc($openid_url), - dbesc($nickname), - dbesc($pubkey), - dbesc($prvkey), - dbesc(datetime_convert()), - intval($verified), - intval($blocked), - dbesc($default_service_class) - ); - - if($r) { - $r = q("SELECT * FROM `user` - WHERE `username` = '%s' AND `password` = '%s' LIMIT 1", - dbesc($username), - dbesc($new_password_encoded) - ); - if($r !== false && count($r)) { - $u = $r[0]; - $newuid = intval($r[0]['uid']); - } - } - else { - $result['message'] .= t('An error occurred during registration. Please try again.') . EOL ; - return $result; - } - - /** - * if somebody clicked submit twice very quickly, they could end up with two accounts - * due to race condition. Remove this one. - */ - - $r = q("SELECT `uid` FROM `user` - WHERE `nickname` = '%s' ", - dbesc($nickname) - ); - if((count($r) > 1) && $newuid) { - $result['message'] .= t('Nickname is already registered. Please choose another.') . EOL; - q("DELETE FROM `user` WHERE `uid` = %d LIMIT 1", - intval($newuid) - ); - return $result; - } - - if(x($newuid) !== false) { - $r = q("INSERT INTO `profile` ( `uid`, `profile_name`, `is_default`, `name`, `photo`, `thumb`, `publish`, `net-publish` ) - VALUES ( %d, '%s', %d, '%s', '%s', '%s', %d, %d ) ", - intval($newuid), - t('default'), - 1, - dbesc($username), - dbesc($a->get_baseurl() . "/photo/profile/{$newuid}"), - dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}"), - intval($publish), - intval($netpublish) - - ); - if($r === false) { - $result['message'] .= t('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 $result; - } - $r = q("INSERT INTO `contact` ( `uid`, `created`, `self`, `name`, `nick`, `photo`, `thumb`, `micro`, `blocked`, `pending`, `url`, `nurl`, - `request`, `notify`, `poll`, `confirm`, `poco`, `name_date`, `uri_date`, `avatar_date`, `closeness` ) - VALUES ( %d, '%s', 1, '%s', '%s', '%s', '%s', '%s', 0, 0, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 0 ) ", - intval($newuid), - datetime_convert(), - dbesc($username), - dbesc($nickname), - dbesc($a->get_baseurl() . "/photo/profile/{$newuid}"), - dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}"), - dbesc($a->get_baseurl() . "/photo/micro/{$newuid}"), - dbesc($a->get_baseurl() . "/channel/$nickname"), - dbesc(normalise_link($a->get_baseurl() . "/channel/$nickname")), - dbesc($a->get_baseurl() . "/dfrn_request/$nickname"), - dbesc($a->get_baseurl() . "/dfrn_notify/$nickname"), - dbesc($a->get_baseurl() . "/dfrn_poll/$nickname"), - dbesc($a->get_baseurl() . "/dfrn_confirm/$nickname"), - dbesc($a->get_baseurl() . "/poco/$nickname"), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - dbesc(datetime_convert()) - ); - - // Create a group with no members. This allows somebody to use it - // right away as a default group for new contacts. - - require_once('include/group.php'); - group_add($newuid, t('Friends')); - - } - - // if we have no OpenID photo try to look up an avatar - if(! strlen($photo)) - $photo = avatar_img($email); - - // unless there is no avatar-plugin loaded - if(strlen($photo)) { - require_once('include/Photo.php'); - $photo_failure = false; - - $filename = basename($photo); - $img_str = fetch_url($photo,true); - // guess mimetype from headers or filename - $type = guess_image_type($photo,true); - - - $img = new Photo($img_str, $type); - if($img->is_valid()) { - - $img->scaleImageSquare(175); - - $hash = photo_new_resource(); - - $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 4 ); - - if($r === false) - $photo_failure = true; - - $img->scaleImage(80); - - $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 5 ); - - if($r === false) - $photo_failure = true; - - $img->scaleImage(48); - - $r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 6 ); - - if($r === false) - $photo_failure = true; - - if(! $photo_failure) { - q("UPDATE `photo` SET `profile` = 1 WHERE `resource_id` = '%s' ", - dbesc($hash) - ); - } - } - } - - call_hooks('register_account', $newuid); - - $result['success'] = true; - $result['user'] = $u; - return $result; - -} diff --git a/include/zot.php b/include/zot.php index 28ecdc4dc..f35c6f93e 100644 --- a/include/zot.php +++ b/include/zot.php @@ -101,12 +101,13 @@ function zot_build_packet($channel,$type = 'notify',$recipients = null, $remote_ 'version' => ZOT_REVISION ); - if($recipients) $data['recipients'] = $recipients; - if($secret) + if($secret) { $data['secret'] = $secret; + $data['secret_sig'] = base64url_encode(rsa_sign($secret,$channel['channel_prvkey'])); + } logger('zot_build_packet: ' . print_r($data,true)); @@ -530,14 +531,35 @@ function import_xchan($arr) { dbesc($xchan_hash) ); + if($r) { if($r[0]['xchan_photo_date'] != $arr['photo_updated']) - $update_photos = true; - if(($r[0]['xchan_name_date'] != $arr['name_updated']) || ($r[0]['xchan_connurl'] != $arr['connections_url'])) { - $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s', xchan_connurl = '%s' where xchan_hash = '%s' limit 1", + $import_photos = true; + + // if we import an entry from a site that's not ours and either or both of us is off the grid - hide the entry. + // TODO: check if we're the same directory realm, which would mean we are allowed to see it + + $dirmode = get_config('system','directory_mode'); + + if((($arr['site']['directory_mode'] === 'standalone') || ($dirmode & DIRECTORY_MODE_STANDALONE)) +&& ($arr['site']['url'] != z_root())) + $arr['searchable'] = false; + + + + // Be careful - XCHAN_FLAGS_HIDDEN should evaluate to 1 + if(($r[0]['xchan_flags'] & XCHAN_FLAGS_HIDDEN) != $arr['searchable']) + $new_flags = $r[0]['xchan_flags'] ^ XCHAN_FLAGS_HIDDEN; + else + $new_flags = $r[0]['xchan_flags']; + + + if(($r[0]['xchan_name_date'] != $arr['name_updated']) || ($r[0]['xchan_connurl'] != $arr['connections_url']) || ($r[0]['xchan_flags'] != $new_flags)) { + $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s', xchan_connurl = '%s', xchan_flags = %d where xchan_hash = '%s' limit 1", dbesc($arr['name']), dbesc($arr['name_updated']), dbesc($arr['connections_url']), + intval($new_flags), dbesc($xchan_hash) ); } @@ -901,16 +923,18 @@ function process_delivery($sender,$arr,$deliveries,$relay) { $ev['uid'] = $channel['channel_id']; $ev['account'] = $channel['channel_account_id']; $ev['edited'] = $arr['edited']; + $ev['uri'] = $arr['uri']; + $ev['private'] = $arr['item_private']; // is this an edit? - $r = q("SELECT * FROM event left join item on resource_id = event_hash WHERE resource_type = 'event' and - `uri` = '%s' AND event.uid = %d LIMIT 1", + $r = q("SELECT resource_id FROM item where uri = '%s' and uid = %d and resource_type = 'event' limit 1", dbesc($arr['uri']), intval($channel['channel_id']) ); - if($r) - $ev['event_hash'] = $r[0]['event_hash']; + if($r) { + $ev['event_hash'] = $r[0]['resource_id']; + } dbg(1); $xyz = event_store($ev); dbg(0); diff --git a/install/database.sql b/install/database.sql index 914add2d8..39c3b81c2 100644 --- a/install/database.sql +++ b/install/database.sql @@ -630,8 +630,6 @@ CREATE TABLE IF NOT EXISTS `photo` ( `aid` int(10) unsigned NOT NULL DEFAULT '0', `uid` int(10) unsigned NOT NULL, `xchan` char(255) NOT NULL DEFAULT '', - `contact-id` int(10) unsigned NOT NULL DEFAULT '0', - `guid` char(64) NOT NULL, `resource_id` char(255) NOT NULL, `created` datetime NOT NULL, `edited` datetime NOT NULL, @@ -652,7 +650,7 @@ CREATE TABLE IF NOT EXISTS `photo` ( `deny_gid` mediumtext NOT NULL, PRIMARY KEY (`id`), KEY `uid` (`uid`), - KEY `resource-id` (`resource_id`), + KEY `resource_id` (`resource_id`), KEY `album` (`album`), KEY `scale` (`scale`), KEY `profile` (`profile`), diff --git a/install/update.php b/install/update.php index 0459df817..8decfc133 100644 --- a/install/update.php +++ b/install/update.php @@ -1,6 +1,6 @@ <?php -define( 'UPDATE_VERSION' , 1020 ); +define( 'UPDATE_VERSION' , 1021 ); /** * @@ -285,3 +285,10 @@ function update_r1019() { return UPDATE_SUCCESS; return UPDATE_FAILED; } + +function update_r1020() { + $r = q("alter table photo drop `contact-id`, drop guid, drop index `resource-id`, add index ( `resource_id` )"); + if($r) + return UPDATE_SUCCESS; + return UPDATE_FAILED; +} diff --git a/library/jquery_ac/friendica.complete.js b/library/jquery_ac/friendica.complete.js index 4599c7bc1..c8a28c0a7 100644 --- a/library/jquery_ac/friendica.complete.js +++ b/library/jquery_ac/friendica.complete.js @@ -242,6 +242,7 @@ } else if (!this.isBadQuery(q)) {
me = this;
me.options.params.query = q;
+ $('#nav-search-spinner').show();
$.get(this.serviceUrl, me.options.params, function(txt) { me.processResponse(txt); }, 'text');
}
},
@@ -304,6 +305,7 @@ this.data = response.data;
this.suggest();
}
+ $('#nav-search-spinner').hide();
},
activate: function(index) {
diff --git a/mod/acl.php b/mod/acl.php index 76be01ee6..2f1866f85 100644 --- a/mod/acl.php +++ b/mod/acl.php @@ -5,6 +5,7 @@ require_once("include/acl_selectors.php"); function acl_init(&$a){ +// logger('mod_acl: ' . print_r($_REQUEST,true)); $start = (x($_REQUEST,'start')?$_REQUEST['start']:0); $count = (x($_REQUEST,'count')?$_REQUEST['count']:100); @@ -21,12 +22,11 @@ function acl_init(&$a){ } - if(! (local_user() || $type == 'x')) - return ""; + if(!(local_user())) + if($type != 'x') + killme(); - - - if ($search!=""){ + if ($search != "") { $sql_extra = " AND `name` LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " "; $sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . ") "; @@ -150,18 +150,31 @@ function acl_init(&$a){ ); } elseif($type == 'x') { - $r = q("SELECT xchan_name as id, xchan_name as name, xchan_photo_s as micro, xchan_url as url from xchan - where 1 - $sql_extra3 - ORDER BY `xchan_name` ASC ", - intval(local_user()) - ); + + $r = navbar_complete($a); + $x = array(); + $x['query'] = $search; + $x['photos'] = array(); + $x['links'] = array(); + $x['suggestions'] = array(); + $x['data'] = array(); + if($r) { + foreach($r as $g) { + $x['photos'][] = $g['photo']; + $x['links'][] = $g['url']; + $x['suggestions'][] = '@' . $g['name']; + $x['data'][] = $g['name']; + } + } + echo json_encode($x); + killme(); + } else $r = array(); - if($type == 'm' || $type == 'a' || $type == 'x') { + if($type == 'm' || $type == 'a') { $x = array(); $x['query'] = $search; $x['photos'] = array(); @@ -172,7 +185,7 @@ function acl_init(&$a){ foreach($r as $g) { $x['photos'][] = $g['micro']; $x['links'][] = $g['url']; - $x['suggestions'][] = (($type === 'x') ? '@' : '') . $g['name']; + $x['suggestions'][] = $g['name']; $x['data'][] = $g['id']; } } @@ -188,8 +201,8 @@ function acl_init(&$a){ "name" => $g['name'], "id" => $g['id'], "xid" => $g['hash'], - "link" => $g['url'], - "nick" => $g['nick'], + "link" => $g['nick'], + "nick" => substr($g['nick'],0,strpos($g['nick'],'@')) ); } } @@ -209,3 +222,57 @@ function acl_init(&$a){ } +function navbar_complete(&$a) { + +// logger('navbar_complete'); + + $dirmode = intval(get_config('system','directory_mode')); + $search = ((x($_REQUEST,'query')) ? htmlentities($_REQUEST['query'],ENT_COMPAT,'UTF-8',false) : ''); + if(! $search || mb_strlen($search) < 2) + return array(); + + $star = false; + $address = false; + + if(substr($search,0,1) === '@') + $search = substr($search,1); + + if(substr($search,0,1) === '*') { + $star = true; + $search = substr($search,1); + } + + if(strpos($search,'@') !== false) { + $address = true; + } + + if(($dirmode == DIRECTORY_MODE_PRIMARY) || ($dirmode == DIRECTORY_MODE_STANDALONE)) { + $url = z_root() . '/dirsearch'; + } + + if(! $url) { + $directory = find_upstream_directory($dirmode); + + if($directory) { + $url = $directory['url']; + } + else { + $url = DIRECTORY_FALLBACK_MASTER . '/dirsearch'; + } + } + + if($url) { + $query = $url . '?f=' ; + $query .= '&name=' . urlencode($search) . '&limit=50' . (($address) ? '&address=' . urlencode($search) : ''); + + $x = z_fetch_url($query); + if($x['success']) { + $t = 0; + $j = json_decode($x['body'],true); + if($j && $j['results']) { + return $j['results']; + } + } + } + return array(); +}
\ No newline at end of file diff --git a/mod/chanview.php b/mod/chanview.php index 1de4f4e1b..92ed757f9 100644 --- a/mod/chanview.php +++ b/mod/chanview.php @@ -1,9 +1,11 @@ <?php require_once('include/Contact.php'); +require_once('include/zot.php'); function chanview_content(&$a) { + $observer = $a->get_observer(); $xchan = null; $r = null; @@ -13,6 +15,11 @@ function chanview_content(&$a) { dbesc($_REQUEST['hash']) ); } + if($_REQUEST['address']) { + $r = q("select * from xchan where xchan_addr = '%s' limit 1", + dbesc($_REQUEST['address']) + ); + } elseif(local_user() && intval($_REQUEST['cid'])) { $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash @@ -25,22 +32,61 @@ function chanview_content(&$a) { $r = q("select * from xchan where xchan_url = '%s' limit 1", dbesc($_REQUEST['url']) ); - if(! $r) - $r = array(array('xchan_url' => $_REQUEST['url'])); } if($r) { $xchan = $r[0]; - if($xchan['xchan_hash']) - $a->set_widget('vcard',vcard_from_xchan($xchan)); + } + + + + // Here, let's see if we have an xchan. If we don't, how we proceed is determined by what + // info we do have. If it's a URL, we can offer to visit it directly. If it's a webbie or + // address, we can and should try to import it. If it's just a hash, we can't continue, but we + // probably wouldn't have a hash if we don't already have an xchan for this channel. + if(! $xchan) { + logger('mod_chanview: fallback'); + // This is hackish - construct a zot address from the url + if($_REQUEST['url']) { + if(preg_match('/https?\:\/\/(.*?)(\/channel\/|\/profile\/)(.*?)$/ism',$_REQUEST['url'],$matches)) { + $_REQUEST['address'] = $matches[3] . '@' . $matches[1]; + } + logger('mod_chanview: constructed address ' . print_r($matches,true)); + } + + if($_REQUEST['address']) { + $ret = zot_finger($_REQUEST['address'],null); + if($ret['success']) { + $j = json_decode($ret['body'],true); + if($j) + import_xchan($j); + $r = q("select * from xchan where xchan_addr = '%s' limit 1", + dbesc($_REQUEST['address']) + ); + if($r) + $xchan = $r[0]; + } + + } } - else { - notice( t('No valid channel provided.') . EOL); + + if(! $xchan) { + notice( t('Channel not found.') . EOL); return; } + if($xchan['xchan_hash']) + $a->set_widget('vcard',vcard_from_xchan($xchan)); + + $url = (($observer) + ? z_root() . '/magic?f=&dest=' . $xchan['xchan_url'] . '&addr=' . $xchan['xchan_addr'] + : $xchan['xchan_url'] + ); + + + $o = replace_macros(get_markup_template('chanview.tpl'),array( - '$url' => z_root() . '/magic?f=&dest=' . $xchan['xchan_url'] . '&addr=' . $xchan['xchan_addr'] + '$url' => $url )); return $o; diff --git a/mod/connections.php b/mod/connections.php index a12f51e68..0a2edb4cd 100644 --- a/mod/connections.php +++ b/mod/connections.php @@ -34,7 +34,7 @@ function connections_aside(&$a) { $a->set_widget('follow', follow_widget()); } - $a->set_widget('collections', group_side('connnections','group',false,0,((array_key_exists('abook',$a->data)) ? $a->data['abook']['abook_id'] : ''))); + $a->set_widget('collections', group_side('connnections','group',false,0,((array_key_exists('abook',$a->data)) ? $a->data['abook']['abook_xchan'] : ''))); $a->set_widget('findpeople',findpeople_widget()); } diff --git a/mod/contactgroup.php b/mod/contactgroup.php index bf81afe07..4b46605a6 100644 --- a/mod/contactgroup.php +++ b/mod/contactgroup.php @@ -4,27 +4,27 @@ require_once('include/group.php'); function contactgroup_content(&$a) { - if(! local_user()) { killme(); } - if(($a->argc > 2) && intval($a->argv[1]) && intval($a->argv[2])) { - $r = q("SELECT `id` FROM `contact` WHERE `id` = %d AND `uid` = %d and `self` = 0 and `blocked` = 0 AND `pending` = 0 LIMIT 1", - intval($a->argv[2]), - intval(local_user()) + if((argc() > 2) && (intval(argv(1))) && (argv(2))) { + $r = q("SELECT abook_xchan from abook where abook_xchan = '%s' and abook_channel = %d and not ( abook_flags & %d ) limit 1", + dbesc(argv(2)), + intval(local_user()), + intval(ABOOK_FLAG_SELF) ); - if(count($r)) - $change = intval($a->argv[2]); + if($r) + $change = $r[0]['abook_xchan']; } - if(($a->argc > 1) && (intval($a->argv[1]))) { + if((argc() > 1) && (intval(argv(1)))) { $r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", - intval($a->argv[1]), + intval(argv(1)), intval(local_user()) ); - if(! count($r)) { + if(! $r) { killme(); } @@ -33,7 +33,7 @@ function contactgroup_content(&$a) { $preselected = array(); if(count($members)) { foreach($members as $member) - $preselected[] = $member['id']; + $preselected[] = $member['xchan_hash']; } if($change) { diff --git a/mod/directory.php b/mod/directory.php index c9332f447..f2d9e1e02 100644 --- a/mod/directory.php +++ b/mod/directory.php @@ -38,148 +38,145 @@ function directory_content(&$a) { $dirmode = intval(get_config('system','directory_mode')); -// if(($dirmode == DIRECTORY_MODE_PRIMARY) || ($dirmode == DIRECTORY_MODE_STANDALONE)) { -// $localdir = true; -// return; -// } - -// FIXME -$localdir = true; - - - if(! $localdir) { + if(($dirmode == DIRECTORY_MODE_PRIMARY) || ($dirmode == DIRECTORY_MODE_STANDALONE)) { + $url = z_root() . '/dirsearch'; + } + if(! $url) { $directory = find_upstream_directory($dirmode); if($directory) { $url = $directory['url']; } else { - $url = DIRECTORY_FALLBACK_MASTER . '/post'; + $url = DIRECTORY_FALLBACK_MASTER . '/dirsearch'; } } - - - if($localdir) { + if($url) { + $query = $url . '?f=' ; if($search) - $search = dbesc($search); - $sql_extra = ((strlen($search)) ? " AND MATCH ( xchan_name, xchan_addr, xprof_desc, xprof_locale, xprof_region, xprof_country, xprof_gender, xprof_marital ) AGAINST ('$search' IN BOOLEAN MODE) " : ""); + $query .= '&name=' . urlencode($search); + if(strpos($search,'@')) + $query .= '&address=' . urlencode($search); - // group_concat(xtag_term separator ', ') as tags - $r = q("SELECT COUNT(xchan_hash) AS `total` FROM xchan left join xprof on xchan_hash = xprof_hash $sql_extra"); - if($r) - $a->set_pager_total($r[0]['total']); + if($a->pager['page'] != 1) + $query .= '&p=' . $a->pager['page']; - $order = " ORDER BY `xchan_name` ASC "; + logger('mod_directory: query: ' . $query); + $x = z_fetch_url($query); + logger('directory: return from upstream: ' . print_r($x,true)); - $r = q("SELECT xchan.*, xprof.* from xchan left join xprof on xchan_hash = xprof_hash $sql_extra $order LIMIT %d , %d ", - intval($a->pager['start']), - intval($a->pager['itemspage']) - ); + if($x['success']) { + $t = 0; + $j = json_decode($x['body'],true); + if($j) { + if($j['results']) { - if($r) { + $entries = array(); - $entries = array(); + $photo = 'thumb'; - $photo = 'thumb'; + foreach($j['results'] as $rr) { - foreach($r as $rr) { - - $profile_link = chanlink_hash($rr['xchan_hash']); + $profile_link = chanlink_url($rr['url']); - $pdesc = (($rr['xprof_desc']) ? $rr['xprof_desc'] . '<br />' : ''); - - $details = ''; - if(strlen($rr['xprof_locale'])) - $details .= $rr['xprof_locale']; - if(strlen($rr['xprof_region'])) { - if(strlen($rr['xprof_locale'])) - $details .= ', '; - $details .= $rr['xprof_region']; - } - if(strlen($rr['xprof_country'])) { - if(strlen($details)) - $details .= ', '; - $details .= $rr['xprof_country']; - } - if(strlen($rr['xprof_dob'])) { - if(($years = age($rr['xprof_dob'],'UTC','')) != 0) - $details .= '<br />' . t('Age: ') . $years ; - } - if(strlen($rr['xprof_gender'])) - $details .= '<br />' . t('Gender: ') . $rr['xprof_gender']; - - $page_type = ''; - - $profile = $rr; - - if ((x($profile,'xprof_locale') == 1) - || (x($profile,'xprof_region') == 1) - || (x($profile,'xprof_postcode') == 1) - || (x($profile,'xprof_country') == 1)) - $location = t('Location:'); + $pdesc = (($rr['description']) ? $rr['description'] . '<br />' : ''); + + $details = ''; + if(strlen($rr['locale'])) + $details .= $rr['locale']; + if(strlen($rr['region'])) { + if(strlen($rr['locale'])) + $details .= ', '; + $details .= $rr['region']; + } + if(strlen($rr['country'])) { + if(strlen($details)) + $details .= ', '; + $details .= $rr['country']; + } + if(strlen($rr['birthday'])) { + if(($years = age($rr['birthday'],'UTC','')) != 0) + $details .= '<br />' . t('Age: ') . $years ; + } + if(strlen($rr['gender'])) + $details .= '<br />' . t('Gender: ') . $rr['gender']; + + $page_type = ''; + + $profile = $rr; + + if ((x($profile,'locale') == 1) + || (x($profile,'region') == 1) + || (x($profile,'postcode') == 1) + || (x($profile,'country') == 1)) + $location = t('Location:'); + + $gender = ((x($profile,'gender') == 1) ? t('Gender:') : False); + + $marital = ((x($profile,'marital') == 1) ? t('Status:') : False); + + $homepage = ((x($profile,'homepage') == 1) ? t('Homepage:') : False); - $gender = ((x($profile,'xprof_gender') == 1) ? t('Gender:') : False); + $about = ((x($profile,'about') == 1) ? t('About:') : False); + - $marital = ((x($profile,'marital') == 1) ? t('Status:') : False); + $entry = array( + 'id' => ++$t, + 'profile_link' => $profile_link, + 'photo' => $rr['photo'], + 'alttext' => $rr['name'] . ' ' . $rr['address'], + 'name' => $rr['name'], + 'details' => $pdesc . $details, + 'profile' => $profile, + 'location' => $location, + 'gender' => $gender, + 'pdesc' => $pdesc, + 'marital' => $marital, + 'homepage' => $homepage, + 'about' => $about, - $homepage = ((x($profile,'homepage') == 1) ? t('Homepage:') : False); + ); - $about = ((x($profile,'about') == 1) ? t('About:') : False); - - $t = 0; - - $entry = array( - 'id' => ++$t, - 'profile_link' => $profile_link, - 'photo' => $rr[xchan_photo_m], - 'alttext' => $rr['xchan_name'], - 'name' => $rr['xchan_name'], - 'details' => $pdesc . $details, - 'profile' => $profile, - 'location' => $location, - 'gender' => $gender, - 'pdesc' => $pdesc, - 'marital' => $marital, - 'homepage' => $homepage, - 'about' => $about, - - ); - - $arr = array('contact' => $rr, 'entry' => $entry); - - call_hooks('directory_item', $arr); - - unset($profile); - unset($location); + $arr = array('contact' => $rr, 'entry' => $entry); - $entries[] = $entry; + call_hooks('directory_item', $arr); + + $entries[] = $entry; - } + unset($profile); + unset($location); - logger('entries: ' . print_r($entries,true)); - $o .= replace_macros($tpl, array( - '$search' => $search, - '$desc' => t('Find'), - '$finddsc' => t('Finding:'), - '$safetxt' => htmlspecialchars($search,ENT_QUOTES,'UTF-8'), - '$entries' => $entries, - '$dirlbl' => t('Directory'), - '$submit' => t('Find') - )); + } + logger('mod_directory: entries: ' . print_r($entries,true), LOGGER_DATA); - $o .= paginate($a); + $o .= replace_macros($tpl, array( + '$search' => $search, + '$desc' => t('Find'), + '$finddsc' => t('Finding:'), + '$safetxt' => htmlspecialchars($search,ENT_QUOTES,'UTF-8'), + '$entries' => $entries, + '$dirlbl' => t('Directory'), + '$submit' => t('Find') + )); - } - else - info( t("No entries (some entries may be hidden).") . EOL); + $o .= alt_pager($a,$j['records'], t('more'), t('back')); + } + else { + if($a->pager['page'] == 1 && $j['records'] == 0 && strpos($search,'@')) { + goaway(z_root() . '/chanview/?f=&address=' . $search); + } + info( t("No entries (some entries may be hidden).") . EOL); + } + } + } } - return $o; } + diff --git a/mod/dirsearch.php b/mod/dirsearch.php index 30a1fadae..1dbe60499 100644 --- a/mod/dirsearch.php +++ b/mod/dirsearch.php @@ -4,7 +4,7 @@ require_once('include/dir_fns.php'); function dirsearch_init(&$a) { - $a->set_pager_itemspage(60); + $a->set_pager_itemspage(80); } @@ -14,16 +14,12 @@ function dirsearch_content(&$a) { // If you've got a public directory server, you probably shouldn't block public access - if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) { - $ret['message'] = t('Public access denied.'); - return; - } $dirmode = intval(get_config('system','directory_mode')); if($dirmode == DIRECTORY_MODE_NORMAL) { $ret['message'] = t('This site is not a directory server'); - return; + json_return_and_die($ret); } $name = ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''); @@ -36,49 +32,66 @@ function dirsearch_content(&$a) { $marital = ((x($_REQUEST,'marital')) ? $_REQUEST['marital'] : ''); $keywords = ((x($_REQUEST,'keywords')) ? $_REQUEST['keywords'] : ''); +// TODO - a meta search which joins all of these things to one search string $sql_extra = ''; if($name) - $sql_extra .= " AND xchan_name like '" . protect_sprintf( '%' . dbesc($name) . '%' ) . "' "; - if($addr) - $sql_extra .= " AND xchan_addr like '" . protect_sprintf( '%' . dbesc($addr) . '%' ) . "' "; + $sql_extra .= " OR xchan_name like '" . protect_sprintf( '%' . dbesc($name) . '%' ) . "' "; + if($address) + $sql_extra .= " OR xchan_addr like '" . protect_sprintf( '%' . dbesc($address) . '%' ) . "' "; if($city) - $sql_extra .= " AND xprof_locale like '" . protect_sprintf( '%' . dbesc($city) . '%' ) . "' "; + $sql_extra .= " OR xprof_locale like '" . protect_sprintf( '%' . dbesc($city) . '%' ) . "' "; if($region) - $sql_extra .= " AND xprof_region like '" . protect_sprintf( '%' . dbesc($region) . '%' ) . "' "; + $sql_extra .= " OR xprof_region like '" . protect_sprintf( '%' . dbesc($region) . '%' ) . "' "; if($post) - $sql_extra .= " AND xprof_postcode like '" . protect_sprintf( '%' . dbesc($post) . '%' ) . "' "; + $sql_extra .= " OR xprof_postcode like '" . protect_sprintf( '%' . dbesc($post) . '%' ) . "' "; if($country) - $sql_extra .= " AND xprof_country like '" . protect_sprintf( '%' . dbesc($country) . '%' ) . "' "; + $sql_extra .= " OR xprof_country like '" . protect_sprintf( '%' . dbesc($country) . '%' ) . "' "; if($gender) - $sql_extra .= " AND xprof_gender like '" . protect_sprintf( '%' . dbesc($gender) . '%' ) . "' "; + $sql_extra .= " OR xprof_gender like '" . protect_sprintf( '%' . dbesc($gender) . '%' ) . "' "; if($marital) - $sql_extra .= " AND xprof_marital like '" . protect_sprintf( '%' . dbesc($marital) . '%' ) . "' "; + $sql_extra .= " OR xprof_marital like '" . protect_sprintf( '%' . dbesc($marital) . '%' ) . "' "; if($keywords) - $sql_extra .= " AND xprof_keywords like '" . protect_sprintf( '%' . dbesc($keywords) . '%' ) . "' "; + $sql_extra .= " OR xprof_keywords like '" . protect_sprintf( '%' . dbesc($keywords) . '%' ) . "' "; $perpage = (($_REQUEST['n']) ? $_REQUEST['n'] : 80); $page = (($_REQUEST['p']) ? intval($_REQUEST['p'] - 1) : 0); $startrec = (($page+1) * $perpage) - $perpage; + $limit = (($_REQUEST['limit']) ? intval($_REQUEST['limit']) : 0); + $return_total = ((x($_REQUEST,'return_total')) ? intval($_REQUEST['return_total']) : 0); // ok a separate tag table won't work. // merge them into xprof $ret['success'] = true; - $r = q("SELECT COUNT(xchan_hash) AS `total` FROM xchan left join xprof on xchan_hash = xprof_hash where 1 $sql_extra"); - if($r) { - $ret['total_items'] = $r[0]['total']; + // If &limit=n, return at most n entries + // If &return_total=1, we count matching entries and return that as 'total_items' for use in pagination. + // By default we return one page (default 80 items maximum) and do not count total entries + + $logic = ((strlen($sql_extra)) ? 0 : 1); +dbg(1); + if($limit) + $qlimit = " LIMIT $limit "; + else { + $qlimit = " LIMIT " . intval($startrec) . " , " . intval($perpage); + if($return_total) { + $r = q("SELECT COUNT(xchan_hash) AS `total` FROM xchan left join xprof on xchan_hash = xprof_hash where $logic $sql_extra and not ( xchan_flags & %d) ", + intval(XCHAN_FLAGS_HIDDEN) + ); + if($r) { + $ret['total_items'] = $r[0]['total']; + } + } } - $order = " ORDER BY `xchan_name` ASC "; + $order = " ORDER BY `xchan_name` ASC "; - $r = q("SELECT xchan.*, xprof.* from xchan left join xprof on xchan_hash = xprof_hash where 1 $sql_extra $order LIMIT %d , %d ", - intval($startrec), - intval($perpage) + $r = q("SELECT xchan.*, xprof.* from xchan left join xprof on xchan_hash = xprof_hash where $logic $sql_extra and not ( xchan_flags & %d ) $order $qlimit ", + intval(XCHAN_FLAGS_HIDDEN) ); - +dbg(0); $ret['page'] = $page + 1; $ret['records'] = count($r); diff --git a/mod/group.php b/mod/group.php index 91b9999dc..6c9b8d78c 100644 --- a/mod/group.php +++ b/mod/group.php @@ -201,7 +201,7 @@ function group_content(&$a) { $textmode = (($switchtotext && (count($members) > $switchtotext)) ? true : false); foreach($members as $member) { if($member['xchan_url']) { - $member['click'] = 'groupChangeMember(' . $group['id'] . ',\'' . $member['xchan_hash'] . '\',\'' . $sec_token . '\'); return true;'; + $member['click'] = 'groupChangeMember(' . $group['id'] . ',\'' . $member['xchan_hash'] . '\',\'' . $sec_token . '\'); return false;'; $groupeditor['members'][] = micropro($member,true,'mpgroup', $textmode); } else @@ -219,7 +219,7 @@ function group_content(&$a) { $textmode = (($switchtotext && (count($r) > $switchtotext)) ? true : false); foreach($r as $member) { if(! in_array($member['xchan_hash'],$preselected)) { - $member['click'] = 'groupChangeMember(' . $group['id'] . ',\'' . $member['xchan_hash'] . '\',\'' . $sec_token . '\'); return true;'; + $member['click'] = 'groupChangeMember(' . $group['id'] . ',\'' . $member['xchan_hash'] . '\',\'' . $sec_token . '\'); return false;'; $groupeditor['contacts'][] = micropro($member,true,'mpall', $textmode); } } diff --git a/mod/intro.php b/mod/intro.php index dd98a6c7b..5b660485a 100644 --- a/mod/intro.php +++ b/mod/intro.php @@ -6,9 +6,10 @@ function intro_post(&$a) { if(! intval($_REQUEST['contact_id'])) return; + $approved = false; $flags = 0; if($_REQUEST['submit'] == t('Approve')) { - ; + $approved = true; } elseif($_REQUEST['submit'] == t('Block')) { $flags = ABOOK_FLAG_BLOCKED; @@ -29,6 +30,10 @@ function intro_post(&$a) { else notice( t('Connection update failed.') . EOL); + if($approved) + goaway(z_root() . '/connections/' . $_REQUEST['contact_id']); + + } function intro_aside(&$a) { diff --git a/mod/item.php b/mod/item.php index f42de79f0..48715a0f4 100644 --- a/mod/item.php +++ b/mod/item.php @@ -889,29 +889,33 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) { } } if($tagcid) { //if there was an id + //select contact with that id from the logged in user's contact list - $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_id = %d AND abook_channel = %d LIMIT 1", intval($tagcid), intval($profile_uid) ); + } else { $newname = str_replace('_',' ',$name); //select someone from this user's contacts by name - $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `uid` = %d LIMIT 1", + $r = q("SELECT * FROM abook left join xchan on abook_xchan - xchan_hash + WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1", dbesc($newname), intval($profile_uid) ); if(! $r) { //select someone by attag or nick and the name passed in - $r = q("SELECT * FROM `contact` WHERE `attag` = '%s' OR `nick` = '%s' AND `uid` = %d ORDER BY `attag` DESC LIMIT 1", +/* $r = q("SELECT * FROM `contact` WHERE `attag` = '%s' OR `nick` = '%s' AND `uid` = %d ORDER BY `attag` DESC LIMIT 1", dbesc($name), dbesc($name), intval($profile_uid) ); - } +*/ } } /* } elseif(strstr($name,'_') || strstr($name,' ')) { //no id //get the real name @@ -931,16 +935,8 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) { }*/ //$r is set, if someone could be selected if(count($r)) { - $profile = $r[0]['url']; - //set newname to nick, find alias - if($r[0]['network'] === 'stat') { - $newname = $r[0]['nick']; - $stat = true; - if($r[0]['alias']) - $alias = $r[0]['alias']; - } - else - $newname = $r[0]['name']; + $profile = chanlink_url($r[0]['xchan_url']); + $newname = $r[0]['xchan_name']; //add person's id to $inform if(strlen($inform)) $inform .= ','; @@ -952,7 +948,7 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) { $replaced = true; //create profile link $profile = str_replace(',','%2c',$profile); - $url = $profile; + $url = chanlink_url($profile); $newtag = '@[url=' . $profile . ']' . $newname . '[/url]'; $body = str_replace('@' . $name, $newtag, $body); //append tag to str_tags diff --git a/mod/lockview.php b/mod/lockview.php index 0307103f8..01a6997ee 100644 --- a/mod/lockview.php +++ b/mod/lockview.php @@ -3,12 +3,12 @@ function lockview_content(&$a) { - $type = (($a->argc > 1) ? $a->argv[1] : 0); + $type = ((argc() > 1) ? argv(1) : 0); if (is_numeric($type)) { $item_id = intval($type); $type='item'; } else { - $item_id = (($a->argc > 2) ? intval($a->argv[2]) : 0); + $item_id = ((argc() > 2) ? intval(argv(2)) : 0); } if(! $item_id) @@ -17,20 +17,20 @@ function lockview_content(&$a) { if (!in_array($type, array('item','photo','event'))) killme(); - $r = q("SELECT * FROM `%s` WHERE `id` = %d LIMIT 1", + $r = q("SELECT * FROM %s WHERE id = %d LIMIT 1", dbesc($type), intval($item_id) ); - if(! count($r)) + if(! $r) killme(); + $item = $r[0]; + if($item['uid'] != local_user()) killme(); - - if(($item['private'] == 1) && (! strlen($item['allow_cid'])) && (! strlen($item['allow_gid'])) + if(($item['item_private'] == 1) && (! strlen($item['allow_cid'])) && (! strlen($item['allow_gid'])) && (! strlen($item['deny_cid'])) && (! strlen($item['deny_gid']))) { - echo t('Remote privacy information not available.') . '<br />'; killme(); } @@ -43,40 +43,34 @@ function lockview_content(&$a) { $o = t('Visible to:') . '<br />'; $l = array(); + stringify_array_elms($allowed_groups,true); + stringify_array_elms($allowed_users,true); + stringify_array_elms($deny_groups,true); + stringify_array_elms($deny_users,true); + if(count($allowed_groups)) { - $r = q("SELECT `name` FROM `group` WHERE `id` IN ( %s )", - dbesc(implode(', ', $allowed_groups)) - ); - if(count($r)) + $r = q("SELECT name FROM group WHERE hash IN ( " . implode(', ', $allowed_groups) . " )"); + if($r) foreach($r as $rr) $l[] = '<b>' . $rr['name'] . '</b>'; } if(count($allowed_users)) { - $r = q("SELECT `name` FROM `contact` WHERE `id` IN ( %s )", - dbesc(implode(', ',$allowed_users)) - ); - if(count($r)) + $r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ',$allowed_users) . " )"); + if($r) foreach($r as $rr) - $l[] = $rr['name']; - + $l[] = $rr['xchan_name']; } - if(count($deny_groups)) { - $r = q("SELECT `name` FROM `group` WHERE `id` IN ( %s )", - dbesc(implode(', ', $deny_groups)) - ); - if(count($r)) + $r = q("SELECT name FROM group WHERE hash IN ( " . implode(', ', $deny_groups) . " )"); + if($r) foreach($r as $rr) $l[] = '<b><strike>' . $rr['name'] . '</strike></b>'; } if(count($deny_users)) { - $r = q("SELECT `name` FROM `contact` WHERE `id` IN ( %s )", - dbesc(implode(', ',$deny_users)) - ); - if(count($r)) + $r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ', $deny_users) . " )"); + if($r) foreach($r as $rr) - $l[] = '<strike>' . $rr['name'] . '</strike>'; - + $l[] = '<strike>' . $rr['xchan_name'] . '</strike>'; } echo $o . implode(', ', $l); diff --git a/mod/magic.php b/mod/magic.php index b74130005..c5aeb4c8e 100644 --- a/mod/magic.php +++ b/mod/magic.php @@ -4,58 +4,81 @@ function magic_init(&$a) { - $url = ((x($_REQUEST,'url')) ? $_REQUEST['url'] : ''); $addr = ((x($_REQUEST,'addr')) ? $_REQUEST['addr'] : ''); $hash = ((x($_REQUEST,'hash')) ? $_REQUEST['hash'] : ''); $dest = ((x($_REQUEST,'dest')) ? $_REQUEST['dest'] : ''); + if($hash) { + $x = q("select xchan.xchan_url, hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash + where hublock_hash = '%s' and (hubloc_flags & %d) limit 1", + intval(HUBLOC_FLAGS_PRIMARY) + ); + } + elseif($addr) { + $x = q("select hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash + where xchan_addr = '%s' and (hubloc_flags & %d) limit 1", + dbesc($addr), + intval(HUBLOC_FLAGS_PRIMARY) + ); + } - if(local_user()) { + if(! $x) { - if($hash) { - $x = q("select xchan.xchan_url, hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash - where hublock_hash = '%s' and (hubloc_flags & %d) limit 1", - intval(HUBLOC_FLAGS_PRIMARY) - ); - } - elseif($addr) { - $x = q("select hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash - where xchan_addr = '%s' and (hubloc_flags & %d) limit 1", - dbesc($addr), - intval(HUBLOC_FLAGS_PRIMARY) - ); - } + // Finger them if they've never been seen here before - if(! $x) { - notice( t('Channel not found.') . EOL); - return; + if($addr) { + $ret = zot_finger($addr,null); + if($ret['success']) { + $j = json_decode($ret['body'],true); + if($j) + import_xchan($j); + $x = q("select hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash + where xchan_addr = '%s' and (hubloc_flags & %d) limit 1", + dbesc($addr), + intval(HUBLOC_FLAGS_PRIMARY) + ); + } } + } - if($x[0]['hubloc_url'] === z_root()) { - $webbie = substr($x[0]['hubloc_addr'],0,strpos('@',$x[0]['hubloc_addr'])); - switch($dest) { - case 'channel': - $desturl = z_root() . '/channel/' . $webbie; - break; - case 'photos': - $desturl = z_root() . '/photos/' . $webbie; - break; - case 'profile': - $desturl = z_root() . '/profile/' . $webbie; - break; - default: - $desturl = $dest; - break; - } - // We are already authenticated on this site and a registered observer. - // Just redirect. - goaway($desturl); + if(! $x) { + notice( t('Channel not found.') . EOL); + return; + } + + if($x[0]['hubloc_url'] === z_root()) { + $webbie = substr($x[0]['hubloc_addr'],0,strpos('@',$x[0]['hubloc_addr'])); + switch($dest) { + case 'channel': + $desturl = z_root() . '/channel/' . $webbie; + break; + case 'photos': + $desturl = z_root() . '/photos/' . $webbie; + break; + case 'profile': + $desturl = z_root() . '/profile/' . $webbie; + break; + default: + $desturl = $dest; + break; } + // We are already authenticated on this site and a registered observer. + // Just redirect. + goaway($desturl); + } + + if(local_user()) { + $channel = $a->get_channel(); $token = random_string(); + $token_sig = base64url_encode(rsa_sign($token,$channel['channel_prvkey'])); + + $channel['token'] = $token; + $channel['token_sig'] = $token_sig; + $recip = array(array('guid' => $x[0]['hubloc_guid'],'guid_sig' => $x[0]['hubloc_guid_sig'])); - $channel = $a->get_channel(); + $hash = random_string(); $r = q("insert into verify ( type, channel, token, meta, created) values ('%s','%d','%s','%s','%s')", @@ -66,25 +89,12 @@ function magic_init(&$a) { dbesc(datetime_convert()) ); - $packet = zot_build_packet($channel,'auth',$recip,$x[0]['hubloc_sitekey'],$hash); - $result = zot_zot($x[0]['hubloc_callback'],$packet); - if($result['success']) { - $j = json_decode($result['body'],true); - if($j['iv']) { - $y = aes_unencapsulate($j,$channel['prvkey']); - $j = json_decode($y,true); - } - if($j['token'] && $j['ticket'] && $j['token'] === $token) { - $r = q("delete from verify where token = '%s' and type = '%s' and channel = %d limit 1", - dbesc($token), - dbesc('auth'), - intval($channel['channel_id']) - ); - goaway($x[0]['callback'] . '?f=&ticket=' . $ticket . '&dest=' . $dest); - } - } - goaway($dest); + goaway($x[0]['hubloc_callback'] . '/' . substr($x[0]['hubloc_addr'],0,strpos($x[0]['hubloc_addr'],'@')) + . '/?f=&auth=' . $channel['channel_address'] . '@' . $a->get_hostname() + . '&sec=' . $token . '&dest=' . $dest . '&version=' . ZOT_REVISION); } + if(strpos($dest,'/')) + goaway($dest); goaway(z_root()); } diff --git a/mod/photos.php b/mod/photos.php index 90f436699..eaf35cc20 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -30,7 +30,7 @@ function photos_init(&$a) { $o .= '<div class="vcard">'; $o .= '<div class="fn">' . $a->data['channel']['channel_name'] . '</div>'; - $o .= '<div id="profile-photo-wrapper"><img class="photo" style="width: 175px; height: 175px;" src="' . $a->get_cached_avatar_image($a->get_baseurl() . '/photo/profile/l/' . $a->data['channel']['channel_id']) . '" alt="' . $a->data['channel']['channel_name'] . '" /></div>'; + $o .= '<div id="profile-photo-wrapper"><img class="photo" style="width: 175px; height: 175px;" src="' . $a->get_baseurl() . '/photo/profile/l/' . $a->data['channel']['channel_id'] . '" alt="' . $a->data['channel']['channel_name'] . '" /></div>'; $o .= '</div>'; @@ -790,7 +790,9 @@ function photos_post(&$a) { $photo_hash = photo_new_resource(); - $r = $ph->store($page_owner_uid, $visitor, $photo_hash, $filename, $album, 0 , 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny); + $page_owner_aid = $a->data['channel']['channel_account_id']; + + $r = $ph->store($page_owner_aid, $page_owner_uid, $visitor, $photo_hash, $filename, $album, 0 , 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny); if(! $r) { logger('mod/photos.php: photos_post(): image store failed' , LOGGER_DEBUG); @@ -800,13 +802,13 @@ function photos_post(&$a) { if($width > 640 || $height > 640) { $ph->scaleImage(640); - $ph->store($page_owner_uid, $visitor, $photo_hash, $filename, $album, 1, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny); + $ph->store($page_owner_aid, $page_owner_uid, $visitor, $photo_hash, $filename, $album, 1, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny); $smallest = 1; } if($width > 320 || $height > 320) { $ph->scaleImage(320); - $ph->store($page_owner_uid, $visitor, $photo_hash, $filename, $album, 2, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny); + $ph->store($page_owner_aid, $page_owner_uid, $visitor, $photo_hash, $filename, $album, 2, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny); $smallest = 2; } @@ -928,6 +930,7 @@ function photos_content(&$a) { $contact_id = 0; $owner_uid = $a->data['channel']['channel_id']; + $owner_aid = $a->data['channel']['channel_account_id']; $community_page = (($a->data['user']['page-flags'] == PAGE_COMMUNITY) ? true : false); diff --git a/mod/poco.php b/mod/poco.php index c0dc2e133..f87bd8a68 100644 --- a/mod/poco.php +++ b/mod/poco.php @@ -7,7 +7,6 @@ function poco_init(&$a) { if(intval(get_config('system','block_public'))) http_status_exit(401); - $observer = $a->get_observer(); if(argc() > 1) { @@ -15,7 +14,7 @@ function poco_init(&$a) { } if(! x($user)) { $c = q("select * from pconfig where cat = 'system' and k = 'suggestme' and v = 1"); - if(! count($c)) + if(! $c) http_status_exit(401); $system_mode = true; } diff --git a/mod/post.php b/mod/post.php index 53180e1c1..36b2e1482 100644 --- a/mod/post.php +++ b/mod/post.php @@ -6,6 +6,111 @@ require_once('include/zot.php'); + + +function post_init(&$a) { + + // All other access to this endpoint is via the post method. + // Here we will pick out the magic auth params which arrive + // as a get request. + + if(argc() > 1) { + + $webbie = argv(1); + + if(array_key_exists('auth',$_REQUEST)) { + + $address = $_REQUEST['auth']; + $dest = $_REQUEST['dest']; + $sec = $_REQUEST['sec']; + $version = $_REQUEST['version']; + + switch($dest) { + case 'channel': + $desturl = z_root() . '/channel/' . $webbie; + break; + case 'photos': + $desturl = z_root() . '/photos/' . $webbie; + break; + case 'profile': + $desturl = z_root() . '/profile/' . $webbie; + break; + default: + $desturl = $dest; + break; + } + $c = q("select * from channel where channel_address = '%s' limit 1", + dbesc($webbie) + ); + if(! $c) { + logger('mod_zot: auth: unable to find channel ' . $webbie); + // They'll get a notice when they hit the page, we don't need two. + goaway($desturl); + } + + // Try and find a hubloc for the person attempting to auth + $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' limit 1", + dbesc($address) + ); + + if(! $x) { + // finger them if they can't be found. + $ret = zot_finger($addr,null); + if($ret['success']) { + $j = json_decode($ret['body'],true); + if($j) + import_xchan($j); + $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' limit 1", + dbesc($address) + ); + } + } + if(! $x) + goaway($desturl); + + // check credentials and access + + // Auth packets MUST use ultra top-secret hush-hush mode + + $p = zot_build_packet($c[0],$type = 'auth_check',array(array('guid' => $x[0]['hubloc_guid'],'guid_sig' => $x[0]['hubloc_guid_sig'])), $x[0]['hubloc_sitekey'], $sec); + $result = zot_zot($x[0]['hubloc_callback'],$p); + + if($result['success']) { + $j = json_decode($result['body'],true); + if($j['result']) { + // everything is good... maybe + if(local_user()) { + notice( t('Remote authentication blocked. You are logged into this site locally. Please logout and retry') . EOL); + goaway($desturl); + } + // log them in + $_SESSION['authenticated'] = 1; + $_SESSION['visitor_id'] = $x[0]['xchan_hash']; + $a->set_observer($x[0]); + require_once('include/security.php'); + $a->set_groups(init_groups_visitor($_SESSION['visitor_id'])); + info(sprintf( t('Welcome %s. Remote authentication successful.'),$x[0]['xchan_name'])); + } + } + + + + + + + goaway($desturl); + } + + logger('mod_zot: invalid args: ' . print_r($a->argv,true)); + killme(); + } + + return; +} + + + + function post_post(&$a) { @@ -165,6 +270,51 @@ function post_post(&$a) { } -} + if($msgtype === 'auth_check') { + $arr = $data['sender']; + $sender_hash = base64url_encode(hash('whirlpool',$arr['guid'] . $arr['guid_sig'], true)); + + $y = q("select xchan_pubkey from xchan where xchan_hash = '%s' limit 1", + dbesc($sender_hash) + ); + if((! $y) || (! rsa_verify($data['secret'],base64url_decode($data['secret_sig']),$y[0]['xchan_pubkey']))) { + logger('mod_zot: auth_check: sender not found or secret_sig invalid.'); + json_return_and_die($ret); + } + if($data['recipients']) { + + $arr = $data['recipients'][0]; + $recip_hash = base64url_encode(hash('whirlpool',$arr['guid'] . $arr['guid_sig'], true)); + $c = q("select channel_id from channel where channel_hash = '%s' limit 1", + dbesc($recip_hash) + ); + if(! $c) { + logger('mod_zot: auth_check: recipient channel not found.'); + json_return_and_die($ret); + } + $z = q("select id from verify where channel = %d and type = 'auth' and token = '%s' limit 1", + intval($c[0]['channel_id']), + dbesc($data['secret']) + ); + if(! $z) { + logger('mod_zot: auth_check: verification key not found.'); + json_return_and_die($ret); + } + $r = q("delete from verify where id = %d limit 1", + intval($z[0]['id']) + ); + + $ret['result'] = true; + json_return_and_die($ret); + } + json_return_and_die($ret); + } + + + // catchall + json_return_and_die($ret); + + +} diff --git a/mod/profile_photo.php b/mod/profile_photo.php index d1e24269a..1bee046d1 100644 --- a/mod/profile_photo.php +++ b/mod/profile_photo.php @@ -81,8 +81,9 @@ function profile_photo_post(&$a) { $im = new Photo($base_image['data'], $base_image['type']); if($im->is_valid()) { $im->cropImage(175,$srcX,$srcY,$srcW,$srcH); + $aid = get_account_id(); - $r = $im->store(local_user(), 0, $base_image['resource_id'],$base_image['filename'], + $r = $im->store($aid, local_user(), '', $base_image['resource_id'],$base_image['filename'], t('Profile Photos'), 4, $is_default_profile); if($r === false) @@ -90,7 +91,7 @@ function profile_photo_post(&$a) { $im->scaleImage(80); - $r = $im->store(local_user(), 0, $base_image['resource_id'],$base_image['filename'], + $r = $im->store($aid, local_user(), '', $base_image['resource_id'],$base_image['filename'], t('Profile Photos'), 5, $is_default_profile); if($r === false) @@ -98,7 +99,7 @@ function profile_photo_post(&$a) { $im->scaleImage(48); - $r = $im->store(local_user(), 0, $base_image['resource_id'],$base_image['filename'], + $r = $im->store($aid, local_user(), '', $base_image['resource_id'],$base_image['filename'], t('Profile Photos'), 6, $is_default_profile); if($r === false) @@ -308,7 +309,7 @@ function profile_photo_crop_ui_head(&$a, $ph){ $smallest = 0; - $r = $ph->store(local_user(), 0 , $hash, $filename, t('Profile Photos'), 0 ); + $r = $ph->store(get_account_id(), local_user(), '', $hash, $filename, t('Profile Photos'), 0 ); if($r) info( t('Image uploaded successfully.') . EOL ); @@ -317,7 +318,7 @@ function profile_photo_crop_ui_head(&$a, $ph){ if($width > 640 || $height > 640) { $ph->scaleImage(640); - $r = $ph->store(local_user(), 0 , $hash, $filename, t('Profile Photos'), 1 ); + $r = $ph->store(get_account_id(), local_user(), '' , $hash, $filename, t('Profile Photos'), 1 ); if($r === false) notice( sprintf(t('Image size reduction [%s] failed.'),"640") . EOL ); diff --git a/mod/profiles.php b/mod/profiles.php index 12c86e3a2..e857c4216 100644 --- a/mod/profiles.php +++ b/mod/profiles.php @@ -620,7 +620,7 @@ function profiles_content(&$a) { foreach($r as $rr) { $o .= replace_macros($tpl, array( - '$photo' => $a->get_cached_avatar_image($rr['thumb']), + '$photo' => $rr['thumb'], '$id' => $rr['id'], '$alt' => t('Profile Image'), '$profile_name' => $rr['profile_name'], diff --git a/mod/search.php b/mod/search.php index 6f40ad4b0..7a0f4205d 100644 --- a/mod/search.php +++ b/mod/search.php @@ -113,8 +113,13 @@ function search_content(&$a) { $search = substr($search,1); } if(strpos($search,'@') === 0) { - require_once('mod/dirfind.php'); - return dirfind_content($a); + $search = substr($search,1); + goaway(z_root() . '/directory' . '?f=1&search=' . $search); + } + + // look for a naked webbie + if(strpos($search,'@') !== false) { + goaway(z_root() . '/directory' . '?f=1&search=' . $search); } if(! $search) @@ -186,11 +191,10 @@ function search_content(&$a) { if($load) { $r = q("SELECT distinct(uri), item.* from item WHERE item_restrict = 0 - AND (( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' AND not ( item_flags & %d )) + AND (( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' AND item_private = 0 ) OR ( `item`.`uid` = %d )) $sql_extra group by uri ORDER BY created DESC $pager_sql ", - intval(ITEM_PRIVATE), intval(local_user()), intval(ABOOK_FLAG_BLOCKED) diff --git a/mod/wall_attach.php b/mod/wall_attach.php index 5d9331ed0..865605313 100644 --- a/mod/wall_attach.php +++ b/mod/wall_attach.php @@ -13,13 +13,13 @@ function wall_attach_post(&$a) { $r = q("SELECT channel.* from channel where channel_address = '%s' limit 1", dbesc($nick) ); - if(! ($r && count($r))) - return; + if(! $r) + killme(); $channel = $r[0]; } else - return; + killme(); $can_post = false; @@ -29,43 +29,10 @@ function wall_attach_post(&$a) { $page_owner_uid = $channel['channel_id']; + $observer = $a->get_observer(); -// $page_owner_cid = $r[0]['id']; -// $page_owner_nick = $r[0]['nickname']; -// $community_page = (($r[0]['page-flags'] == PAGE_COMMUNITY) ? true : false); - - if((local_user()) && (local_user() == $page_owner_uid)) - $can_post = true; - -// FIXME for forum and guests -// else { -// if($community_page && remote_user()) { -// $cid = 0; -// if(is_array($_SESSION['remote'])) { -// foreach($_SESSION['remote'] as $v) { -// if($v['uid'] == $page_owner_uid) { -// $cid = $v['cid']; -// break; -// } -// } -// } -// if($cid) {// - -// $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", -// intval($cid), -// intval($page_owner_uid) -// ); -// if(count($r)) { -// $can_post = true; -// $visitor = $cid; -// } -// } -// } -// } - - - if(! $can_post) { - notice( t('Permission denied.') . EOL ); + if(! perm_is_allowed($page_owner_uid,$observer['xchan_hash'],'write_storage')) { + notice( t('Permission denied.') . EOL); killme(); } @@ -81,28 +48,28 @@ function wall_attach_post(&$a) { if(($maxfilesize) && ($filesize > $maxfilesize)) { notice( sprintf(t('File exceeds size limit of %d'), $maxfilesize) . EOL); @unlink($src); - return; + killme(); } - $r = q("select sum(octet_length(data)) as total from attach where uid = %d ", - intval($page_owner_uid) - ); - $limit = service_class_fetch($page_owner_uid,'attach_upload_limit'); - - if(($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { - echo upgrade_message(true) . EOL ; - @unlink($src); - killme(); + if($limit !== false) { + $r = q("select sum(filesize) as total from attach where uid = %d ", + intval($page_owner_uid) + ); + if(($r) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { + echo upgrade_message(true) . EOL ; + @unlink($src); + killme(); + } } - $filedata = @file_get_contents($src); $mimetype = z_mime_content_type($filename); $hash = random_string(); $created = datetime_convert(); - $r = q("INSERT INTO `attach` ( `uid`, `hash`, `filename`, `filetype`, `filesize`, `data`, `created`, `edited`, `allow_cid`, `allow_gid`,`deny_cid`, `deny_gid` ) - VALUES ( %d, '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", + $r = q("INSERT INTO `attach` ( `aid`, `uid`, `hash`, `filename`, `filetype`, `filesize`, `data`, `created`, `edited`, `allow_cid`, `allow_gid`,`deny_cid`, `deny_gid` ) + VALUES ( %d, %d, '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", + intval($channel['channel_account_id']), intval($page_owner_uid), dbesc($hash), dbesc($filename), diff --git a/mod/wall_upload.php b/mod/wall_upload.php index c695f9b3e..a3dcf9a0b 100644 --- a/mod/wall_upload.php +++ b/mod/wall_upload.php @@ -2,72 +2,58 @@ require_once('Photo.php'); + + + function wall_upload_post(&$a) { - if(argc() > 1) { - if(! x($_FILES,'media')) { + $using_api = ((x($_FILES,'media')) ? true : false); + + if($using_api) { + require_once('include/api.php'); + $user_info = api_get_user($a); + $nick = $user_info['screen_name']; + } + else { + if(argc() > 1) $nick = argv(1); - } - else { - $user_info = api_get_user($a); - $nick = $user_info['screen_name']; - } + } + + $channel = null; + + if($nick) { $r = q("SELECT channel.* from channel where channel_address = '%s' limit 1", dbesc($nick) ); - if(! ($r && count($r))) - return; - $channel = $r[0]; + if($r) + $channel = $r[0]; } - else - return; + if(! $channel) { + if($using_api) + return; + else { + notice( t('Channel not found.') . EOL); + killme(); + } + } $can_post = false; $visitor = 0; + $page_owner_uid = $r[0]['channel_id']; -// $default_cid = $r[0]['id']; - - $page_owner_nick = $r[0]['channel_address']; - -// $community_page = (($r[0]['page-flags'] == PAGE_COMMUNITY) ? true : false); - - if((local_user()) && (local_user() == $page_owner_uid)) - $can_post = true; - -// else { -// if($community_page && remote_user()) { -// $cid = 0; -// if(is_array($_SESSION['remote'])) { -// foreach($_SESSION['remote'] as $v) { -// if($v['uid'] == $page_owner_uid) { -// $cid = $v['cid']; -// break; -// } -// } -// } -// if($cid) { - -// $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", -// intval($cid), -// intval($page_owner_uid) -// ); -// if(count($r)) { -// $can_post = true; -// $visitor = $cid; -// } -// } -// } -// } - - if(! $can_post) { - notice( t('Permission denied.') . EOL ); - killme(); - } - - if(! x($_FILES,'userfile') && ! x($_FILES,'media')) - killme(); + + $observer = $a->get_observer(); + + if(! perm_is_allowed($page_owner_uid,$observer['xchan_hash'],'post_photos')) { + if($using_api) + return; + else { + notice( t('Permission denied.') . EOL); + killme(); + } + } if(x($_FILES,'userfile')) { $src = $_FILES['userfile']['tmp_name']; @@ -81,36 +67,58 @@ function wall_upload_post(&$a) { $filesize = intval($_FILES['media']['size']); $filetype = $_FILES['media']['type']; } + else { + if($using_api) + return; + else { + notice( t('Empty upload.') . EOL); + killme(); + } + } + - if ($filetype=="") $filetype=guess_image_type($filename); + if($filetype == "") + $filetype=guess_image_type($filename); $maximagesize = get_config('system','maximagesize'); if(($maximagesize) && ($filesize > $maximagesize)) { - echo sprintf( t('Image exceeds size limit of %d'), $maximagesize) . EOL; @unlink($src); - killme(); + if($using_api) + return; + else { + echo sprintf( t('Image exceeds size limit of %d'), $maximagesize) . EOL; + killme(); + } } - $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", - intval($page_owner_uid) - ); $limit = service_class_fetch($page_owner_uid,'photo_upload_limit'); - - if(($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { - echo upgrade_message(true) . EOL ; - @unlink($src); - killme(); + if($limit !== false) { + $r = q("select sum(size) as total from photo where uid = %d and scale = 0 ", + intval($page_owner_uid) + ); + if(($r) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { + @unlink($src); + if($using_api) + return; + else { + echo upgrade_message(true) . EOL ; + killme(); + } + } } - $imagedata = @file_get_contents($src); $ph = new Photo($imagedata, $filetype); if(! $ph->is_valid()) { - echo ( t('Unable to process image.') . EOL); @unlink($src); - killme(); + if($using_api) + return; + else { + echo ( t('Unable to process image.') . EOL); + killme(); + } } $ph->orient($src); @@ -130,31 +138,36 @@ function wall_upload_post(&$a) { $smallest = 0; $defperm = '<' . $channel['channel_hash'] . '>'; + $aid = $channel['channel_account_id']; + $visitor = ((remote_user()) ? remote_user() : ''); - $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 0, 0, $defperm); + $r = $ph->store($aid, $page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 0, 0, $defperm); if(! $r) { - echo ( t('Image upload failed.') . EOL); - killme(); + if($using_api) + return; + else { + echo ( t('Image upload failed.') . EOL); + killme(); + } } if($width > 640 || $height > 640) { $ph->scaleImage(640); - $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 1, 0, $defperm); + $r = $ph->store($aid, $page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 1, 0, $defperm); if($r) $smallest = 1; } if($width > 320 || $height > 320) { $ph->scaleImage(320); - $r = $ph->store($page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 2, 0, $defperm); + $r = $ph->store($aid, $page_owner_uid, $visitor, $hash, $filename, t('Wall Photos'), 2, 0, $defperm); if($r) $smallest = 2; } $basename = basename($filename); - if($_REQUEST['silent']) { $m = '[url=' . $a->get_baseurl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . $a->get_baseurl() . "/photo/{$hash}-{$smallest}.".$ph->getExt()."[/img][/url]"; return($m); diff --git a/mod/zfinger.php b/mod/zfinger.php index 3452db68c..b7a89b12b 100644 --- a/mod/zfinger.php +++ b/mod/zfinger.php @@ -72,9 +72,9 @@ function zfinger_init(&$a) { $id = $e['channel_id']; $searchable = (($e['channel_pageflags'] & PAGE_HIDDEN) ? false : true); - + if($e['xchan_flags'] & XCHAN_FLAGS_HIDDEN) + $searchable = false; - // This is for birthdays and keywords, but must check access permissions $p = q("select * from profile where uid = %d and is_default = 1", intval($e['channel_id']) @@ -180,7 +180,7 @@ function zfinger_init(&$a) { elseif($dirmode == DIRECTORY_MODE_STANDALONE) $ret['site']['directory_mode'] = 'standalone'; if($dirmode != DIRECTORY_MODE_NORMAL) - $ret['site']['directory_url'] = z_root() . '/dir'; + $ret['site']['directory_url'] = z_root() . '/dirsearch'; json_return_and_die($ret); diff --git a/version.inc b/version.inc index f7f909959..2e853b2e6 100644 --- a/version.inc +++ b/version.inc @@ -1 +1 @@ -2013-01-16.202 +2013-01-22.208 diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css index 21704e21c..fc5f41752 100644 --- a/view/theme/redbasic/css/style.css +++ b/view/theme/redbasic/css/style.css @@ -1,17 +1,22 @@ /** - * duepuntozero Frindika style - * Fabio Comuni <fabrix.xm@gmail.com> + * Redbasic + * + * Based on duepuntozero Friendica style + * by Fabio Comuni <fabrix.xm@gmail.com> */ /* generals */ body { - font-family: helvetica,arial,freesans,clean,sans-serif; + font-family: arial,freesans,clean,sans-serif; font-size: 12px; background-color: #ffffff; color: #000000; margin: 0px; } +.jslider { + font-family: arial,freesans,clean,sans-serif; +} abbr { border-bottom: none; @@ -19,7 +24,7 @@ abbr { aside { border: none; -color: #d00; +color: #0080FF; } /* icons */ @@ -64,7 +69,7 @@ color: #d00; background-image: url("../img/network.png"); min-width: 22px; height: 22px; - margin-top: -4px; + margin-top: -3px; background-position: left center; padding: 1px; } @@ -96,8 +101,13 @@ color: #d00; padding: 1px; } -a, a:visited, a:link, .fakelink, .fakelink:visited, .fakelink:link { color: #dd0000; text-decoration: none; } -a:hover, .fakelink:hover { color: #dd0000; text-decoration: underline; } +a, a:visited, a:link, .fakelink, .fakelink:visited, .fakelink:link { + font-weight: bold; + color: #0080FF; + text-decoration: none; +} + +a:hover, .fakelink:hover { color: #44AAFF; text-decoration: underline; } .fakelink { cursor: pointer; @@ -336,11 +346,6 @@ footer { font-weight: bold; } -div.wall-item-content-wrapper.shiny { - background: #f4f4f4; - border: none; -} - .preview { background: lightyellow; } @@ -660,12 +665,11 @@ input#dfrn-url { padding: 0px 0px 5px 0px; font-size: 120%; font-weight: bold; - color: #dd0000; + color: #0080FF; } .vcard .title { margin-bottom: 5px; - margin-left: 12px; } .vcard dl { @@ -1063,9 +1067,9 @@ input#dfrn-url { margin-top: 10px; position: relative; background: #fff; - border-radius: 5px; +/* border-radius: 5px; */ /* box-shadow: 12px 12px 12px #111; */ - border: 1px solid #eec; + border-left: 1px solid #eec; } .wall-item-content-wrapper.comment { @@ -1266,7 +1270,6 @@ input#dfrn-url { .wall-item-tools { clear: both; - background: #eee; padding: 5px 10px; } @@ -1409,7 +1412,7 @@ input#dfrn-url { font-size: 1.2em; height: auto; width: auto; - background-color: #dd0000; + background-color: #0080FF; border-radius: 5px; border: 2px outset; box-shadow: 5px 5px 5px #666; @@ -1876,7 +1879,7 @@ tr.mceLast { #profile-jot-submit { height: auto; - background-color: #dd0000; + background-color: #0080FF; color: #eeeeec; font-weight: bold; -webkit-border-radius: 5px; @@ -2569,6 +2572,13 @@ aside input[type='text'] { margin-top: 4px; } +#nav-search-spinner { + float: right; + margin-top: 8px; + margin-left: 5px; + margin-right: 5px; +} + #nav-search-text:hover { background-color: #FFF; color: #000; @@ -3584,8 +3594,9 @@ nav .nav-menu { nav .nav-menu.selected { border-bottom: 4px solid #CCCCCC; } + nav .nav-notify { - background-color: #0d0; + background-color: #0080FF; color: #fff; -moz-border-radius: 5px 5px 5px 5px; -webkit-border-radius: 5px 5px 5px 5px; @@ -3622,7 +3633,7 @@ ul.menu-popup { position: absolute; display: none; width: 10em; - background: #dd0000; + background: #0080FF; color: #eec; padding: 0px; list-style: none; @@ -3634,13 +3645,15 @@ ul.menu-popup { } ul.menu-popup a { display: block; - color: #eec; + color: #; padding: 5px 10px; text-decoration: none; } + + ul.menu-popup a:hover { - background-color: #eec; - color: #d00; + background-color: #888888; + color: #000000; } ul.menu-popup .menu-sep { border-top: 1px solid #9eabb0; @@ -3771,4 +3784,102 @@ ul.menu-popup { .tabs-end { clear: both; +} + + + + +#acl-wrapper { + width: 690px; + float:left; +} +#acl-search { + float:right; + background: #ffffff url("../../../../images/search_18.png") no-repeat right center; + padding-right:20px; +} +#acl-showall { + float: left; + display: block; + width: auto; + height: 18px; + background-color: #cccccc; + background-image: url("../../../../images/show_all_off.png"); + background-position: 7px 7px; + background-repeat: no-repeat; + padding: 7px 5px 0px 30px; + -webkit-border-radius: 5px ; + -moz-border-radius: 5px; + border-radius: 5px; + color: #999999; +} +#acl-showall.selected { + color: #000000; + background-color: #ff9900; + background-image: url("../../../../images/show_all_on.png"); +} + +#acl-list { + height: 210px; + border: 1px solid #cccccc; + clear: both; + margin-top: 30px; + overflow: auto; +} +#acl-list-content { + +} +.acl-list-item { + display: block; + width: 150px; + height: 30px; + border: 1px solid #cccccc; + margin: 5px; + float: left; +} +.acl-list-item img{ + width:22px; + height: 22px; + float: left; + margin: 4px; +} +.acl-list-item p { height: 12px; font-size: 10px; margin: 0px; padding: 2px 0px 1px; overflow: hidden;} +.acl-list-item a { + font-size: 8px; + display: block; + width: 40px; + height: 10px; + float: left; + color: #999999; + background-color: #cccccc; + background-position: 3px 3px; + background-repeat: no-repeat; + margin-right: 5px; + -webkit-border-radius: 2px ; + -moz-border-radius: 2px; + border-radius: 2px; + padding-left: 15px; +} +#acl-wrapper a:hover { + text-decoration: none; + color:#000000; +} +.acl-button-show { background-image: url("../../../../images/show_off.png"); } +.acl-button-hide { background-image: url("../../../../images/hide_off.png"); } + +.acl-button-show.selected { + color: #000000; + background-color: #9ade00; + background-image: url("../../../../images/show_on.png"); +} +.acl-button-hide.selected { + color: #000000; + background-color: #ff4141; + background-image: url("../../../../images/hide_on.png"); +} +.acl-list-item.groupshow { border-color: #9ade00; } +.acl-list-item.grouphide { border-color: #ff4141; } + +.contact-block-content { + margin-top: 8px; }
\ No newline at end of file diff --git a/view/theme/redbasic/img/introductions.png b/view/theme/redbasic/img/introductions.png Binary files differindex 18ba5dc81..9e0498227 100644 --- a/view/theme/redbasic/img/introductions.png +++ b/view/theme/redbasic/img/introductions.png diff --git a/view/theme/redbasic/img/network.png b/view/theme/redbasic/img/network.png Binary files differindex c213cee04..f3e45c3ec 100644 --- a/view/theme/redbasic/img/network.png +++ b/view/theme/redbasic/img/network.png diff --git a/view/tpl/jot-header.tpl b/view/tpl/jot-header.tpl index f777e997f..e4fb00b7a 100644 --- a/view/tpl/jot-header.tpl +++ b/view/tpl/jot-header.tpl @@ -134,7 +134,7 @@ function enableOnUser(){ var uploader = new window.AjaxUpload( 'wall-image-upload', - { action: 'wall_upload/$nickname', + { action: '$baseurl/wall_upload/$nickname', name: 'userfile', onSubmit: function(file,ext) { $('#profile-rotator').show(); }, onComplete: function(file,response) { @@ -145,7 +145,7 @@ function enableOnUser(){ ); var file_uploader = new window.AjaxUpload( 'wall-file-upload', - { action: 'wall_attach/$nickname', + { action: '$baseurl/wall_attach/$nickname', name: 'userfile', onSubmit: function(file,ext) { $('#profile-rotator').show(); }, onComplete: function(file,response) { @@ -181,7 +181,7 @@ function enableOnUser(){ if(reply && reply.length) { reply = bin2hex(reply); $('#profile-rotator').show(); - $.get('parse_url?binurl=' + reply, function(data) { + $.get('$baseurl/parse_url?binurl=' + reply, function(data) { addeditortext(data); $('#profile-rotator').hide(); }); @@ -214,7 +214,7 @@ function enableOnUser(){ if ($('#jot-popup').length != 0) $('#jot-popup').show(); $('#like-rotator-' + id).show(); - $.get('share/' + id, function(data) { + $.get('$baseurl/share/' + id, function(data) { if (!editor) $("#profile-jot-text").val(""); initEditor(function(){ addeditortext(data); @@ -238,7 +238,7 @@ function enableOnUser(){ if(reply && reply.length) { reply = bin2hex(reply); $('#profile-rotator').show(); - $.get('parse_url?binurl=' + reply, function(data) { + $.get('$baseurl/parse_url?binurl=' + reply, function(data) { if (!editor) $("#profile-jot-text").val(""); initEditor(function(){ addeditortext(data); @@ -257,7 +257,7 @@ function enableOnUser(){ commentBusy = true; $('body').css('cursor', 'wait'); - $.get('tagger/' + id + '?term=' + reply); + $.get('$baseurl/tagger/' + id + '?term=' + reply); if(timer) clearTimeout(timer); timer = setTimeout(NavUpdate,3000); liking = 1; @@ -284,7 +284,7 @@ function enableOnUser(){ if(reply && reply.length) { commentBusy = true; $('body').css('cursor', 'wait'); - $.get('filer/' + id + '?term=' + reply, NavUpdate); + $.get('$baseurl/filer/' + id + '?term=' + reply, NavUpdate); // if(timer) clearTimeout(timer); // timer = setTimeout(NavUpdate,3000); liking = 1; diff --git a/view/tpl/nav.tpl b/view/tpl/nav.tpl index b0eb098aa..3b997e215 100644 --- a/view/tpl/nav.tpl +++ b/view/tpl/nav.tpl @@ -86,6 +86,7 @@ <li id="nav-site-linkmenu" class="nav-menu-icon"><a href="#" rel="#nav-site-menu"><span class="icon s22 gear">$nav.settings.1</span></a> <ul id="nav-site-menu" class="menu-popup"> {{ if $nav.settings }}<li><a class="$nav.settings.2" href="$nav.settings.0" title="$nav.settings.3">$nav.settings.1</a></li>{{ endif }} + {{ if $nav.directory }}<li><a class="$nav.directory.2" href="$nav.directory.0" title="$nav.directory.3">$nav.directory.1</a></li>{{ endif }} {{ if $nav.admin }}<li><a class="$nav.admin.2" href="$nav.admin.0" title="$nav.admin.3" >$nav.admin.1</a></li>{{ endif }} @@ -133,6 +134,7 @@ <input id="nav-search-text" type="text" value="" placeholder="$nav.search.1" name="search" title="$nav.search.3" onclick="this.submit();" /> </form> </li> + <img src="images/rotator.gif" id="nav-search-spinner" style="display: none;" alt="$pleasewait" /> </ul> </nav> diff --git a/view/tpl/smarty3/nav.tpl b/view/tpl/smarty3/nav.tpl index da50bc7bb..6e441e915 100644 --- a/view/tpl/smarty3/nav.tpl +++ b/view/tpl/smarty3/nav.tpl @@ -86,6 +86,7 @@ <li id="nav-site-linkmenu" class="nav-menu-icon"><a href="#" rel="#nav-site-menu"><span class="icon s22 gear">{{$nav.settings.1}}</span></a> <ul id="nav-site-menu" class="menu-popup"> {{if $nav.settings}}<li><a class="{{$nav.settings.2}}" href="{{$nav.settings.0}}" title="{{$nav.settings.3}}">{{$nav.settings.1}}</a></li>{{/if}} + {{if $nav.directory}}<li><a class="{{$nav.directory.2}}" href="{{$nav.directory.0}}" title="{{$nav.directory.3}}">{{$nav.directory.1}}</a></li>{{/if}} {{if $nav.admin}}<li><a class="{{$nav.admin.2}}" href="{{$nav.admin.0}}" title="{{$nav.admin.3}}" >{{$nav.admin.1}}</a></li>{{/if}} @@ -133,6 +134,7 @@ <input id="nav-search-text" type="text" value="" placeholder="{{$nav.search.1}}" name="search" title="{{$nav.search.3}}" onclick="this.submit();" /> </form> </li> + <img src="images/rotator.gif" id="nav-search-spinner" style="display: none;" alt="{{$pleasewait}}" /> </ul> </nav> |