From 781716277ba382e0415e9188c252c1b79093ed6b Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 12 May 2016 16:45:49 -0700 Subject: SECURITY: a comment to a private post that has been edited (the comment has been edited) loses its privacy settings. This comment isn't visible in the stream but may be visible in feeds. --- include/zot.php | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/zot.php b/include/zot.php index 157354afa..8adc74ffa 100644 --- a/include/zot.php +++ b/include/zot.php @@ -1953,6 +1953,16 @@ function remove_community_tag($sender, $arr, $uid) { */ function update_imported_item($sender, $item, $orig, $uid) { + // If this is a comment being updated, remove any privacy information + // so that item_store_update will set it from the original. + + if($item['mid'] !== $item['parent_mid']) { + unset($item['allow_cid']); + unset($item['allow_gid']); + unset($item['deny_cid']); + unset($item['deny_gid']); + unset($item['item_private']); + } $x = item_store_update($item); -- cgit v1.2.3 From f2fc7d25c5f940135a7d9068f1813c22862b3f19 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 12 May 2016 20:02:16 -0700 Subject: remove the rarely if ever used filter_insecure() function. We will provide this functionality in other ways. --- include/items.php | 41 ----------------------------------------- 1 file changed, 41 deletions(-) (limited to 'include') diff --git a/include/items.php b/include/items.php index bef04237b..10a5b4ab9 100755 --- a/include/items.php +++ b/include/items.php @@ -33,7 +33,6 @@ function collect_recipients($item, &$private_envelope) { $allow_people = expand_acl($item['allow_cid']); $allow_groups = expand_groups(expand_acl($item['allow_gid'])); - $allow_groups = filter_insecure($item['uid'],$allow_groups); $recipients = array_unique(array_merge($allow_people,$allow_groups)); @@ -140,46 +139,6 @@ function collect_recipients($item, &$private_envelope) { return $recipients; } -/** - * If channel is configured to filter insecure members of privacy groups - * (those whose networks leak privacy via email notifications or other criteria) - * remove them from any privacy groups (collections) that were included in a post. - * They can still be addressed individually. - * Networks may need to be added or removed from this list as circumstances change. - * - * Update: this may need to be the default, which will force people to opt-in to - * sending stuff privately to insecure platforms. - * - * @param int $channel_id - * @param array $arr - * @return array containing the sane xchan_hashes - */ -function filter_insecure($channel_id, $arr) { - $insecure_nets = " and not xchan_network in ('diaspora', 'friendica-over-diaspora') "; - - $ret = array(); - - if((! intval(get_pconfig($channel_id, 'system', 'filter_insecure_privacy_groups'))) || (! $arr)) - return $arr; - - $str = ''; - foreach($arr as $rr) { - if(strlen($str)) - $str .= ','; - - $str .= "'" . dbesc($rr) . "'"; - } - $r = q("select xchan_hash from xchan where xchan_hash in ($str) $insecure_nets"); - if($r) { - foreach($r as $rr) { - $ret[] = $rr['xchan_hash']; - } - } - - return $ret; -} - - function comments_are_now_closed($item) { if($item['comments_closed'] !== NULL_DATE) { $d = datetime_convert(); -- cgit v1.2.3 From 522fec5763f35fc8c49ffd5343991b5f365c4d6f Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 12 May 2016 20:21:04 -0700 Subject: split off feed handling stuff from include/items --- include/feedutils.php | 1316 +++++++++++++++++++++++++++++++++++++++++++++++++ include/items.php | 1315 +----------------------------------------------- 2 files changed, 1319 insertions(+), 1312 deletions(-) create mode 100644 include/feedutils.php (limited to 'include') diff --git a/include/feedutils.php b/include/feedutils.php new file mode 100644 index 000000000..2ba5efe22 --- /dev/null +++ b/include/feedutils.php @@ -0,0 +1,1316 @@ + '1', + 'datequery' => $params['end'], + 'datequery2' => $params['begin'], + 'start' => $params['start'], // FIXME + 'records' => $params['records'], // FIXME + 'direction' => $params['direction'], // FIXME + 'pages' => $params['pages'], + 'order' => 'post', + 'top' => $params['top'], + 'cat' => $params['cat'] + ), $channel, $observer_hash, CLIENT_MODE_NORMAL, App::$module); + + + $feed_template = get_markup_template('atom_feed.tpl'); + + $atom = ''; + + $atom .= replace_macros($feed_template, array( + '$version' => xmlify(Zotlabs\Project\System::get_project_version()), + '$red' => xmlify(Zotlabs\Project\System::get_platform_name()), + '$feed_id' => xmlify($channel['xchan_url']), + '$feed_title' => xmlify($channel['channel_name']), + '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now' , ATOM_TIME)) , + '$hub' => '', // feed_hublinks(), + '$salmon' => '', // feed_salmonlinks($channel['channel_address']), + '$name' => xmlify($channel['channel_name']), + '$profile_page' => xmlify($channel['xchan_url']), + '$mimephoto' => xmlify($channel['xchan_photo_mimetype']), + '$photo' => xmlify($channel['xchan_photo_l']), + '$thumb' => xmlify($channel['xchan_photo_m']), + '$picdate' => '', + '$uridate' => '', + '$namdate' => '', + '$birthday' => '', + '$community' => '', + )); + + + call_hooks('atom_feed', $atom); + + if($items) { + $type = 'html'; + foreach($items as $item) { + if($item['item_private']) + continue; + + /** @BUG $owner is undefined in this call */ + $atom .= atom_entry($item, $type, null, $owner, true); + } + } + + call_hooks('atom_feed_end', $atom); + + $atom .= '' . "\r\n"; + + return $atom; +} + +/** + * @brief + * + * @param array $item an associative array with + * * \b string \b verb + * @return string item's verb if set, default ACTIVITY_POST see boot.php + */ +function construct_verb($item) { + if ($item['verb']) + return $item['verb']; + + return ACTIVITY_POST; +} + +function construct_activity_object($item) { + + if($item['object']) { + $o = '' . "\r\n"; + $r = json_decode($item['object'],false); + + if(! $r) + return ''; + if($r->type) + $o .= '' . xmlify($r->type) . '' . "\r\n"; + if($r->id) + $o .= '' . xmlify($r->id) . '' . "\r\n"; + if($r->title) + $o .= '' . xmlify($r->title) . '' . "\r\n"; + if($r->links) { + /** @FIXME!! */ + if(substr($r->link,0,1) === '<') { + $r->link = preg_replace('/\/','',$r->link); + $o .= $r->link; + } + else + $o .= '' . "\r\n"; + } + if($r->content) + $o .= '' . xmlify(bbcode($r->content)) . '' . "\r\n"; + $o .= '' . "\r\n"; + return $o; + } + + return ''; +} + +function construct_activity_target($item) { + + if($item['target']) { + $o = '' . "\r\n"; + $r = json_decode($item['target'],false); + if(! $r) + return ''; + if($r->type) + $o .= '' . xmlify($r->type) . '' . "\r\n"; + if($r->id) + $o .= '' . xmlify($r->id) . '' . "\r\n"; + if($r->title) + $o .= '' . xmlify($r->title) . '' . "\r\n"; + if($r->links) { + /** @FIXME !!! */ + if(substr($r->link,0,1) === '<') { + if(strstr($r->link,'&') && (! strstr($r->link,'&'))) + $r->link = str_replace('&','&', $r->link); + $r->link = preg_replace('/\/','',$r->link); + $o .= $r->link; + } + else + $o .= '' . "\r\n"; + } + if($r->content) + $o .= '' . xmlify(bbcode($r->content)) . '' . "\r\n"; + + $o .= '' . "\r\n"; + + return $o; + } + + return ''; +} + +/** + * @param object $feed + * @param array $item + * @param[out] array $author + * @return multitype:multitype: string NULL number Ambigous Ambigous Ambigous , multitype:multitype:string unknown > multitype:NULL unknown + */ +function get_atom_elements($feed, $item, &$author) { + + //$best_photo = array(); + + $res = array(); + + $found_author = $item->get_author(); + if($found_author) { + $author['author_name'] = unxmlify($found_author->get_name()); + $author['author_link'] = unxmlify($found_author->get_link()); + $author['author_is_feed'] = false; + } + else { + $author['author_name'] = unxmlify($feed->get_title()); + $author['author_link'] = unxmlify($feed->get_permalink()); + $author['author_is_feed'] = true; + } + + if(substr($author['author_link'],-1,1) == '/') + $author['author_link'] = substr($author['author_link'],0,-1); + + $res['mid'] = base64url_encode(unxmlify($item->get_id())); + $res['title'] = unxmlify($item->get_title()); + $res['body'] = unxmlify($item->get_content()); + $res['plink'] = unxmlify($item->get_link(0)); + $res['item_rss'] = 1; + + + // removing the content of the title if its identically to the body + // This helps with auto generated titles e.g. from tumblr + + if (title_is_body($res["title"], $res["body"])) + $res['title'] = ""; + + if($res['plink']) + $base_url = implode('/', array_slice(explode('/',$res['plink']),0,3)); + else + $base_url = ''; + + // look for a photo. We should check media size and find the best one, + // but for now let's just find any author photo + + $rawauthor = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author'); + + if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { + $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; + foreach($base as $link) { + if(!x($author, 'author_photo') || ! $author['author_photo']) { + if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') + $author['author_photo'] = unxmlify($link['attribs']['']['href']); + } + } + } + + $rawactor = $item->get_item_tags(NAMESPACE_ACTIVITY, 'actor'); + + if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['obj_type'][0]['data'],ACTIVITY_OBJ_PERSON)) { + $base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; + if($base && count($base)) { + foreach($base as $link) { + if($link['attribs']['']['rel'] === 'alternate' && (! $res['author_link'])) + $author['author_link'] = unxmlify($link['attribs']['']['href']); + if(!x($author, 'author_photo') || ! $author['author_photo']) { + if($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') + $author['author_photo'] = unxmlify($link['attribs']['']['href']); + } + } + } + } + + // check for a yahoo media element (github etc.) + + if(! $author['author_photo']) { + $rawmedia = $item->get_item_tags(NAMESPACE_YMEDIA,'thumbnail'); + if($rawmedia && $rawmedia[0]['attribs']['']['url']) { + $author['author_photo'] = strip_tags(unxmlify($rawmedia[0]['attribs']['']['url'])); + } + } + + + // No photo/profile-link on the item - look at the feed level + + if((! (x($author,'author_link'))) || (! (x($author,'author_photo')))) { + $rawauthor = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author'); + if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { + $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; + foreach($base as $link) { + if($link['attribs']['']['rel'] === 'alternate' && (! $author['author_link'])) { + $author['author_link'] = unxmlify($link['attribs']['']['href']); + $author['author_is_feed'] = true; + } + if(! $author['author_photo']) { + if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') + $author['author_photo'] = unxmlify($link['attribs']['']['href']); + } + } + } + + $rawactor = $feed->get_feed_tags(NAMESPACE_ACTIVITY, 'subject'); + + if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['obj_type'][0]['data'],ACTIVITY_OBJ_PERSON)) { + $base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; + + if($base && count($base)) { + foreach($base as $link) { + if($link['attribs']['']['rel'] === 'alternate' && (! $res['author_link'])) + $author['author_link'] = unxmlify($link['attribs']['']['href']); + if(! (x($author,'author_photo'))) { + if($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') + $author['author_photo'] = unxmlify($link['attribs']['']['href']); + } + } + } + } + } + + $apps = $item->get_item_tags(NAMESPACE_STATUSNET,'notice_info'); + if($apps && $apps[0]['attribs']['']['source']) { + $res['app'] = strip_tags(unxmlify($apps[0]['attribs']['']['source'])); + } + + /* + * If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it. + */ + + $have_real_body = false; + + $rawenv = $item->get_item_tags(NAMESPACE_DFRN, 'env'); + if($rawenv) { + $have_real_body = true; + $res['body'] = $rawenv[0]['data']; + $res['body'] = str_replace(array(' ',"\t","\r","\n"), array('','','',''),$res['body']); + // make sure nobody is trying to sneak some html tags by us + $res['body'] = notags(base64url_decode($res['body'])); + + // We could probably turn these old Friendica bbcode bookmarks into bookmark tags but we'd have to + // create a term table item for them. For now just make sure they stay as links. + + $res['body'] = preg_replace('/\[bookmark(.*?)\](.*?)\[\/bookmark\]/','[url$1]$2[/url]',$res['body']); + } + + $res['body'] = limit_body_size($res['body']); + + // It isn't certain at this point whether our content is plaintext or html and we'd be foolish to trust + // the content type. Our own network only emits text normally, though it might have been converted to + // html if we used a pubsubhubbub transport. But if we see even one html tag in our text, we will + // have to assume it is all html and needs to be purified. + + // It doesn't matter all that much security wise - because before this content is used anywhere, we are + // going to escape any tags we find regardless, but this lets us import a limited subset of html from + // the wild, by sanitising it and converting supported tags to bbcode before we rip out any remaining + // html. + + if((strpos($res['body'],'<') !== false) && (strpos($res['body'],'>') !== false)) { + + $res['body'] = reltoabs($res['body'],$base_url); + + $res['body'] = html2bb_video($res['body']); + + $res['body'] = oembed_html2bbcode($res['body']); + + $res['body'] = purify_html($res['body']); + + $res['body'] = @html2bbcode($res['body']); + } + elseif(! $have_real_body) { + + // it's not one of our messages and it has no tags + // so it's probably just text. We'll escape it just to be safe. + + $res['body'] = escape_tags($res['body']); + } + + if($res['plink'] && $res['title']) { + $res['body'] = '#^[url=' . $res['plink'] . ']' . $res['title'] . '[/url]' . "\n\n" . $res['body']; + $terms = array(); + $terms[] = array( + 'otype' => TERM_OBJ_POST, + 'type' => TERM_BOOKMARK, + 'url' => $res['plink'], + 'term' => $res['title'], + ); + } + elseif($res['plink']) { + $res['body'] = '#^[url]' . $res['plink'] . '[/url]' . "\n\n" . $res['body']; + $terms = array(); + $terms[] = array( + 'otype' => TERM_OBJ_POST, + 'type' => TERM_BOOKMARK, + 'url' => $res['plink'], + 'term' => $res['plink'], + ); + } + + $private = $item->get_item_tags(NAMESPACE_DFRN,'private'); + if($private && intval($private[0]['data']) > 0) + $res['item_private'] = ((intval($private[0]['data'])) ? 1 : 0); + else + $res['item_private'] = 0; + + $rawlocation = $item->get_item_tags(NAMESPACE_DFRN, 'location'); + if($rawlocation) + $res['location'] = unxmlify($rawlocation[0]['data']); + + $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'published'); + if($rawcreated) + $res['created'] = unxmlify($rawcreated[0]['data']); + + $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'updated'); + if($rawedited) + $res['edited'] = unxmlify($rawedited[0]['data']); + + if((x($res,'edited')) && (! (x($res,'created')))) + $res['created'] = $res['edited']; + + if(! $res['created']) + $res['created'] = $item->get_date('c'); + + if(! $res['edited']) + $res['edited'] = $item->get_date('c'); + + + // Disallow time travelling posts + + $d1 = strtotime($res['created']); + $d2 = strtotime($res['edited']); + $d3 = strtotime('now'); + + if($d1 > $d3) + $res['created'] = datetime_convert(); + if($d2 > $d3) + $res['edited'] = datetime_convert(); + + $res['created'] = datetime_convert('UTC','UTC',$res['created']); + $res['edited'] = datetime_convert('UTC','UTC',$res['edited']); + + $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner'); + if(! $rawowner) + $rawowner = $item->get_item_tags(NAMESPACE_ZOT,'owner'); + + if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']) + $author['owner_name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']); + elseif($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']) + $author['owner_name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']); + if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']) + $author['owner_link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']); + elseif($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']) + $author['owner_link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']); + + if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { + $base = $rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; + + foreach($base as $link) { + if(!x($author, 'owner_photo') || ! $author['owner_photo']) { + if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') + $author['owner_photo'] = unxmlify($link['attribs']['']['href']); + } + } + } + + $rawgeo = $item->get_item_tags(NAMESPACE_GEORSS,'point'); + if($rawgeo) + $res['coord'] = unxmlify($rawgeo[0]['data']); + + + $rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb'); + + // select between supported verbs + + if($rawverb) { + $res['verb'] = unxmlify($rawverb[0]['data']); + } + + // translate OStatus unfollow to activity streams if it happened to get selected + + if((x($res,'verb')) && ($res['verb'] === 'http://ostatus.org/schema/1.0/unfollow')) + $res['verb'] = ACTIVITY_UNFOLLOW; + + $cats = $item->get_categories(); + if($cats) { + if(is_null($terms)) + $terms = array(); + foreach($cats as $cat) { + $term = $cat->get_term(); + if(! $term) + $term = $cat->get_label(); + $scheme = $cat->get_scheme(); + $termurl = ''; + if($scheme && $term && stristr($scheme,'X-DFRN:')) { + $termtype = ((substr($scheme,7,1) === '#') ? TERM_HASHTAG : TERM_MENTION); + $termurl = unxmlify(substr($scheme,9)); + } + else { + $termtype = TERM_CATEGORY; + } + $termterm = notags(trim(unxmlify($term))); + + if($termterm) { + $terms[] = array( + 'otype' => TERM_OBJ_POST, + 'type' => $termtype, + 'url' => $termurl, + 'term' => $termterm, + ); + } + } + } + + if(! is_null($terms)) + $res['term'] = $terms; + + $attach = $item->get_enclosures(); + if($attach) { + $res['attach'] = array(); + foreach($attach as $att) { + $len = intval($att->get_length()); + $link = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_link())))); + $title = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_title())))); + $type = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_type())))); + if(strpos($type,';')) + $type = substr($type,0,strpos($type,';')); + if((! $link) || (strpos($link,'http') !== 0)) + continue; + + if(! $title) + $title = ' '; + if(! $type) + $type = 'application/octet-stream'; + + $res['attach'][] = array('href' => $link, 'length' => $len, 'type' => $type, 'title' => $title ); + } + } + + $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'object'); + + if($rawobj) { + $obj = array(); + + $child = $rawobj[0]['child']; + if($child[NAMESPACE_ACTIVITY]['obj_type'][0]['data']) { + $res['obj_type'] = $child[NAMESPACE_ACTIVITY]['obj_type'][0]['data']; + $obj['type'] = $child[NAMESPACE_ACTIVITY]['obj_type'][0]['data']; + } + if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) { + $res['obj_type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data']; + $obj['type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data']; + } + if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']) + $obj['id'] = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']; + if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) + $obj['link'] = encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']); + if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'title') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']) + $obj['title'] = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']; + if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'content') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) { + $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']; + if(! $body) + $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data']; + // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events + $obj['orig'] = xmlify($body); + if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) { + $body = purify_html($body); + $body = html2bbcode($body); + } + + $obj['content'] = $body; + } + + $res['object'] = $obj; + } + + $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'target'); + + if($rawobj) { + $obj = array(); + + $child = $rawobj[0]['child']; + if($child[NAMESPACE_ACTIVITY]['obj_type'][0]['data']) { + $res['tgt_type'] = $child[NAMESPACE_ACTIVITY]['obj_type'][0]['data']; + $obj['type'] = $child[NAMESPACE_ACTIVITY]['obj_type'][0]['data']; + } + if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) { + $res['tgt_type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data']; + $obj['type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data']; + } + if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']) + $obj['id'] = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']; + if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) + $obj['link'] = encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']); + if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'title') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']) + $obj['title'] = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']; + if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'content') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) { + $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']; + if(! $body) + $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data']; + + // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events + $obj['orig'] = xmlify($body); + if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) { + $body = purify_html($body); + $body = html2bbcode($body); + } + + $obj['content'] = $body; + } + + $res['target'] = $obj; + } + + $arr = array('feed' => $feed, 'item' => $item, 'result' => $res); + + call_hooks('parse_atom', $arr); + logger('get_atom_elements: author: ' . print_r($author,true),LOGGER_DATA); + + logger('get_atom_elements: ' . print_r($res,true),LOGGER_DATA); + + return $res; +} + +function encode_rel_links($links) { + $o = array(); + if(! ((is_array($links)) && (count($links)))) + return $o; + + foreach($links as $link) { + $l = array(); + if($link['attribs']['']['rel']) + $l['rel'] = $link['attribs']['']['rel']; + if($link['attribs']['']['type']) + $l['type'] = $link['attribs']['']['type']; + if($link['attribs']['']['href']) + $l['href'] = $link['attribs']['']['href']; + if( (x($link['attribs'],NAMESPACE_MEDIA)) && $link['attribs'][NAMESPACE_MEDIA]['width']) + $l['width'] = $link['attribs'][NAMESPACE_MEDIA]['width']; + if( (x($link['attribs'],NAMESPACE_MEDIA)) && $link['attribs'][NAMESPACE_MEDIA]['height']) + $l['height'] = $link['attribs'][NAMESPACE_MEDIA]['height']; + + if($l) + $o[] = $l; + } + return $o; +} + +/** + * @brief Process atom feed and update anything/everything we might need to update. + * + * @param array $xml + * The (atom) feed to consume - RSS isn't as fully supported but may work for simple feeds. + * @param $importer + * The contact_record (joined to user_record) of the local user who owns this + * relationship. It is this person's stuff that is going to be updated. + * @param $contact + * The person who is sending us stuff. If not set, we MAY be processing a "follow" activity + * from an external network and MAY create an appropriate contact record. Otherwise, we MUST + * have a contact record. + * @param int $pass by default ($pass = 0) we cannot guarantee that a parent item has been + * imported prior to its children being seen in the stream unless we are certain + * of how the feed is arranged/ordered. + * * With $pass = 1, we only pull parent items out of the stream. + * * With $pass = 2, we only pull children (comments/likes). + * + * So running this twice, first with pass 1 and then with pass 2 will do the right + * thing regardless of feed ordering. This won't be adequate in a fully-threaded + * model where comments can have sub-threads. That would require some massive sorting + * to get all the feed items into a mostly linear ordering, and might still require + * recursion. + */ +function consume_feed($xml, $importer, &$contact, $pass = 0) { + + require_once('library/simplepie/simplepie.inc'); + + if(! strlen($xml)) { + logger('consume_feed: empty input'); + return; + } + + $sys_expire = intval(get_config('system','default_expire_days')); + $chn_expire = intval($importer['channel_expire_days']); + + $expire_days = $sys_expire; + + if(($chn_expire != 0) && ($chn_expire < $sys_expire)) + $expire_days = $chn_expire; + + // logger('expire_days: ' . $expire_days); + + $feed = new SimplePie(); + $feed->set_raw_data($xml); + $feed->init(); + + if($feed->error()) + logger('consume_feed: Error parsing XML: ' . $feed->error()); + + $permalink = $feed->get_permalink(); + + // Check at the feed level for updated contact name and/or photo + + // process any deleted entries + + $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry'); + if(is_array($del_entries) && count($del_entries) && $pass != 2) { + foreach($del_entries as $dentry) { + $deleted = false; + if(isset($dentry['attribs']['']['ref'])) { + $mid = $dentry['attribs']['']['ref']; + $deleted = true; + if(isset($dentry['attribs']['']['when'])) { + $when = $dentry['attribs']['']['when']; + $when = datetime_convert('UTC','UTC', $when, 'Y-m-d H:i:s'); + } + else + $when = datetime_convert('UTC','UTC','now','Y-m-d H:i:s'); + } + + if($deleted && is_array($contact)) { + $r = q("SELECT * from item where mid = '%s' and author_xchan = '%s' and uid = %d limit 1", + dbesc(base64url_encode($mid)), + dbesc($contact['xchan_hash']), + intval($importer['channel_id']) + ); + + if($r) { + $item = $r[0]; + + if(! intval($item['item_deleted'])) { + logger('consume_feed: deleting item ' . $item['id'] . ' mid=' . base64url_decode($item['mid']), LOGGER_DEBUG); + drop_item($item['id'],false); + } + } + } + } + } + + // Now process the feed + + if($feed->get_item_quantity()) { + + logger('consume_feed: feed item count = ' . $feed->get_item_quantity(), LOGGER_DEBUG); + + $items = $feed->get_items(); + + foreach($items as $item) { + + $is_reply = false; + $item_id = base64url_encode($item->get_id()); + + logger('consume_feed: processing ' . $item_id, LOGGER_DEBUG); + + $rawthread = $item->get_item_tags( NAMESPACE_THREAD,'in-reply-to'); + if(isset($rawthread[0]['attribs']['']['ref'])) { + $is_reply = true; + $parent_mid = base64url_encode($rawthread[0]['attribs']['']['ref']); + } + + if($is_reply) { + + if($pass == 1) + continue; + + // Have we seen it? If not, import it. + + $item_id = base64url_encode($item->get_id()); + $author = array(); + $datarray = get_atom_elements($feed,$item,$author); + + if($contact['xchan_network'] === 'rss') { + $datarray['public_policy'] = 'specific'; + $datarray['comment_policy'] = 'none'; + } + + if((! x($author,'author_name')) || ($author['author_is_feed'])) + $author['author_name'] = $contact['xchan_name']; + if((! x($author,'author_link')) || ($author['author_is_feed'])) + $author['author_link'] = $contact['xchan_url']; + if((! x($author,'author_photo'))|| ($author['author_is_feed'])) + $author['author_photo'] = $contact['xchan_photo_m']; + + $datarray['author_xchan'] = ''; + + if($author['author_link'] != $contact['xchan_url']) { + $x = import_author_unknown(array('name' => $author['author_name'],'url' => $author['author_link'],'photo' => array('src' => $author['author_photo']))); + if($x) + $datarray['author_xchan'] = $x; + } + if(! $datarray['author_xchan']) + $datarray['author_xchan'] = $contact['xchan_hash']; + + $datarray['owner_xchan'] = $contact['xchan_hash']; + + $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", + dbesc($item_id), + intval($importer['channel_id']) + ); + + + // Update content if 'updated' changes + + if($r) { + if((x($datarray,'edited') !== false) + && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { + + // do not accept (ignore) an earlier edit than one we currently have. + if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) + continue; + + update_feed_item($importer['channel_id'],$datarray); + } + continue; + } + + $datarray['parent_mid'] = $parent_mid; + $datarray['aid'] = $importer['channel_account_id']; + $datarray['uid'] = $importer['channel_id']; + + logger('consume_feed: ' . print_r($datarray,true),LOGGER_DATA); + + $xx = item_store($datarray); + $r = $xx['item_id']; + continue; + } + else { + + // Head post of a conversation. Have we seen it? If not, import it. + + $item_id = base64url_encode($item->get_id()); + $author = array(); + $datarray = get_atom_elements($feed,$item,$author); + + if($contact['xchan_network'] === 'rss') { + $datarray['public_policy'] = 'specific'; + $datarray['comment_policy'] = 'none'; + } + + + if(is_array($contact)) { + if((! x($author,'author_name')) || ($author['author_is_feed'])) + $author['author_name'] = $contact['xchan_name']; + if((! x($author,'author_link')) || ($author['author_is_feed'])) + $author['author_link'] = $contact['xchan_url']; + if((! x($author,'author_photo'))|| ($author['author_is_feed'])) + $author['author_photo'] = $contact['xchan_photo_m']; + } + + if((! x($author,'author_name')) || (! x($author,'author_link'))) { + logger('consume_feed: no author information! ' . print_r($author,true)); + continue; + } + + $datarray['author_xchan'] = ''; + + if(activity_match($datarray['verb'],ACTIVITY_FOLLOW) && $datarray['obj_type'] === ACTIVITY_OBJ_PERSON) { + $cb = array('item' => $datarray,'channel' => $importer, 'xchan' => null, 'author' => $author, 'caught' => false); + call_hooks('follow_from_feed',$cb); + if($cb['caught']) { + if($cb['return_code']) + http_status_exit($cb['return_code']); + continue; + } + } + + if($author['author_link'] != $contact['xchan_url']) { + $x = import_author_unknown(array('name' => $author['author_name'],'url' => $author['author_link'],'photo' => array('src' => $author['author_photo']))); + if($x) + $datarray['author_xchan'] = $x; + } + if(! $datarray['author_xchan']) + $datarray['author_xchan'] = $contact['xchan_hash']; + + $datarray['owner_xchan'] = $contact['xchan_hash']; + + if(array_key_exists('created',$datarray) && $datarray['created'] != NULL_DATE && $expire_days) { + $t1 = $datarray['created']; + $t2 = datetime_convert('UTC','UTC','now - ' . $expire_days . 'days'); + if($t1 < $t2) { + logger('feed content older than expiration. Ignoring.', LOGGER_DEBUG, LOG_INFO); + continue; + } + } + + + + $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", + dbesc($item_id), + intval($importer['channel_id']) + ); + + // Update content if 'updated' changes + + if($r) { + if((x($datarray,'edited') !== false) + && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { + + // do not accept (ignore) an earlier edit than one we currently have. + if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) + continue; + + update_feed_item($importer['channel_id'],$datarray); + } + + continue; + } + + $datarray['parent_mid'] = $item_id; + $datarray['uid'] = $importer['channel_id']; + $datarray['aid'] = $importer['channel_account_id']; + + if(! link_compare($author['owner_link'],$contact['xchan_url'])) { + logger('consume_feed: Correcting item owner.', LOGGER_DEBUG); + $author['owner_name'] = $contact['name']; + $author['owner_link'] = $contact['url']; + $author['owner_avatar'] = $contact['thumb']; + } + + if(! post_is_importable($datarray,$contact)) + continue; + + logger('consume_feed: author ' . print_r($author,true),LOGGER_DEBUG); + + logger('consume_feed: ' . print_r($datarray,true),LOGGER_DATA); + + $xx = item_store($datarray); + $r = $xx['item_id']; + continue; + } + } + } +} + + +/** + * @brief Process atom feed and return the first post and structure + * + * @param array $xml + * The (atom) feed to consume - RSS isn't as fully supported but may work for simple feeds. + * @param $importer + * The contact_record (joined to user_record) of the local user who owns this + * relationship. It is this person's stuff that is going to be updated. + */ + +function process_salmon_feed($xml, $importer) { + + $ret = array(); + + require_once('library/simplepie/simplepie.inc'); + + if(! strlen($xml)) { + logger('process_feed: empty input'); + return; + } + + $feed = new SimplePie(); + $feed->set_raw_data($xml); + $feed->init(); + + if($feed->error()) + logger('Error parsing XML: ' . $feed->error()); + + $permalink = $feed->get_permalink(); + + if($feed->get_item_quantity()) { + + // this should be exactly one + + logger('feed item count = ' . $feed->get_item_quantity(), LOGGER_DEBUG); + + $items = $feed->get_items(); + + foreach($items as $item) { + + $item_id = base64url_encode($item->get_id()); + + logger('processing ' . $item_id, LOGGER_DEBUG); + + $rawthread = $item->get_item_tags( NAMESPACE_THREAD,'in-reply-to'); + if(isset($rawthread[0]['attribs']['']['ref'])) { + $is_reply = true; + $parent_mid = base64url_encode($rawthread[0]['attribs']['']['ref']); + } + + if($is_reply) + $ret['parent_mid'] = $parent_mid; + + $ret['author'] = array(); + + $datarray = get_atom_elements($feed,$item,$ret['author']); + + // reset policies which are restricted by default for RSS connections + // This item is likely coming from GNU-social via salmon and allows public interaction + $datarray['public_policy'] = ''; + $datarray['comment_policy'] = ''; + + $ret['item'] = $datarray; + } + } + + return $ret; +} + +/* + * Given an xml (atom) feed, find author and hub links + */ + + +function feed_meta($xml) { + require_once('library/simplepie/simplepie.inc'); + + $ret = array(); + + if(! strlen($xml)) { + logger('empty input'); + return $ret; + } + + $feed = new SimplePie(); + $feed->set_raw_data($xml); + $feed->init(); + + if($feed->error()) { + logger('Error parsing XML: ' . $feed->error()); + return $ret; + } + + $ret['hubs'] = $feed->get_links('hub'); + +// logger('consume_feed: hubs: ' . print_r($hubs,true), LOGGER_DATA); + + $author = array(); + + $found_author = $feed->get_author(); + if($found_author) { + $author['author_name'] = unxmlify($found_author->get_name()); + $author['author_link'] = unxmlify($found_author->get_link()); + + $rawauthor = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author'); + logger('rawauthor: ' . print_r($rawauthor,true)); + + if($rawauthor) { + if($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { + $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; + foreach($base as $link) { + if(!x($author, 'author_photo') || ! $author['author_photo']) { + if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') { + $author['author_photo'] = unxmlify($link['attribs']['']['href']); + break; + } + } + } + } + if($rawauthor[0]['child'][NAMESPACE_POCO]['displayName'][0]['data']) + $author['full_name'] = unxmlify($rawauthor[0]['child'][NAMESPACE_POCO]['displayName'][0]['data']); + if($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']) + $author['author_uri'] = unxmlify($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']); + + } + } + + if(substr($author['author_link'],-1,1) == '/') + $author['author_link'] = substr($author['author_link'],0,-1); + + $ret['author'] = $author; + + return $ret; +} + + + +function update_feed_item($uid,$datarray) { + logger('update_feed_item: not implemented! ' . $uid . ' ' . print_r($datarray,true), LOGGER_DATA); +} + + +function handle_feed($uid,$abook_id,$url) { + + require_once('include/Contact.php'); + $channel = channelx_by_n($uid); + if(! $channel) + return; + + $x = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d limit 1", + dbesc($abook_id), + intval($uid) + ); + + $recurse = 0; + $z = z_fetch_url($url,false,$recurse,array('novalidate' => true)); + +//logger('handle_feed:' . print_r($z,true)); + + if($z['success']) { + consume_feed($z['body'],$channel,$x[0],1); + consume_feed($z['body'],$channel,$x[0],2); + } +} + + +function atom_author($tag,$name,$uri,$h,$w,$type,$photo) { + $o = ''; + if(! $tag) + return $o; + + $name = xmlify($name); + $uri = xmlify($uri); + $h = intval($h); + $w = intval($w); + $photo = xmlify($photo); + + $o .= "<$tag>\r\n"; + $o .= "$name\r\n"; + $o .= "$uri\r\n"; + $o .= '' . "\r\n"; + $o .= '' . "\r\n"; + + call_hooks('atom_author', $o); + + $o .= "\r\n"; + + return $o; +} + +function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { + + if(! $item['parent']) + return; + + if($item['deleted']) + return '' . "\r\n"; + + + create_export_photo_body($item); + + if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid']) + $body = fix_private_photos($item['body'],$owner['uid'],$item,$cid); + else + $body = $item['body']; + + $o = "\r\n\r\n\r\n"; + + if(is_array($author)) + $o .= atom_author('author',$author['xchan_name'],$author['xchan_url'],80,80,$author['xchan_photo_mimetype'],$author['xchan_photo_m']); + else + $o .= atom_author('author',$item['author']['xchan_name'],$item['author']['xchan_url'],80,80,$item['author']['xchan_photo_mimetype'], $item['author']['xchan_photo_m']); + + $o .= atom_author('zot:owner',$item['owner']['xchan_name'],$item['owner']['xchan_url'],80,80,$item['owner']['xchan_photo_mimetype'],$item['owner']['xchan_photo_m']); + + if(($item['parent'] != $item['id']) || ($item['parent_mid'] !== $item['mid']) || (($item['thr_parent'] !== '') && ($item['thr_parent'] !== $item['mid']))) { + $parent_item = (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']); + $o .= '' . "\r\n"; + } + + if(activity_match($item['obj_type'],ACTIVITY_OBJ_EVENT) && activity_match($item['verb'],ACTIVITY_POST)) { + $obj = ((is_array($item['obj'])) ? $item['object'] : json_decode($item['object'],true)); + + $o .= '' . xmlify($item['title']) . '' . "\r\n"; + $o .= '' . xmlify(bbcode($obj['title'])) . '' . "\r\n"; + $o .= '' . datetime_convert('UTC','UTC', $obj['start'],'Ymd\\THis' . (($obj['adjust']) ? '\\Z' : '')) . '' . "\r\n"; + $o .= '' . datetime_convert('UTC','UTC', $obj['finish'],'Ymd\\THis' . (($obj['adjust']) ? '\\Z' : '')) . '' . "\r\n"; + $o .= '' . xmlify(bbcode($obj['location'])) . '' . "\r\n"; + $o .= '' . xmlify(bbcode($obj['description'])) . '' . "\r\n"; + } + else { + $o .= '' . xmlify($item['title']) . '' . "\r\n"; + $o .= '' . xmlify(prepare_text($body,$item['mimetype'])) . '' . "\r\n"; + } + + $o .= '' . z_root() . '/display/' . xmlify($item['mid']) . '' . "\r\n"; + $o .= '' . xmlify(datetime_convert('UTC','UTC',$item['created'] . '+00:00',ATOM_TIME)) . '' . "\r\n"; + $o .= '' . xmlify(datetime_convert('UTC','UTC',$item['edited'] . '+00:00',ATOM_TIME)) . '' . "\r\n"; + + $o .= '' . "\r\n"; + + if($item['location']) { + $o .= '' . xmlify($item['location']) . '' . "\r\n"; + $o .= '' . xmlify($item['location']) . '' . "\r\n"; + } + + if($item['coord']) + $o .= '' . xmlify($item['coord']) . '' . "\r\n"; + + if(($item['item_private']) || strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])) + $o .= '' . (($item['item_private']) ? $item['item_private'] : 1) . '' . "\r\n"; + + if($item['app']) + $o .= '' . "\r\n"; + + $verb = construct_verb($item); + $o .= '' . xmlify($verb) . '' . "\r\n"; + $actobj = construct_activity_object($item); + if(strlen($actobj)) + $o .= $actobj; + $actarg = construct_activity_target($item); + if(strlen($actarg)) + $o .= $actarg; + + // FIXME +// $tags = item_getfeedtags($item); +// if(count($tags)) { +// foreach($tags as $t) { +// $o .= '' . "\r\n"; +// } +// } + +// FIXME +// $o .= item_getfeedattach($item); + +// $mentioned = get_mentions($item,$tags); +// if($mentioned) +// $o .= $mentioned; + + call_hooks('atom_entry', $o); + + $o .= '' . "\r\n"; + + return $o; +} + + +function gen_asld($items) { + $ret = array(); + if(! $items) + return $ret; + foreach($items as $item) { + $ret[] = i2asld($item); + } + return $ret; +} + + +function i2asld($i) { + + if(! $i) + return array(); + + $ret = array(); + + $ret['@context'] = array( 'http://www.w3.org/ns/activitystreams', 'zot' => 'http://purl.org/zot/protocol'); + + if($i['verb']) { + if(strpos(dirname($i['verb'],'activitystrea.ms/schema/1.0'))) { + $ret['@type'] = ucfirst(basename($i['verb'])); + } + elseif(strpos(dirname($i['verb'],'purl.org/zot'))) { + $ret['@type'] = 'zot:' . ucfirst(basename($i['verb'])); + } + } + $ret['@id'] = $i['plink']; + + $ret['published'] = datetime_convert('UTC','UTC',$i['created'],ATOM_TIME); + + // we need to pass the parent into this +// if($i['id'] != $i['parent'] && $i['obj_type'] === ACTIVITY_OBJ_NOTE) { +// $ret['inReplyTo'] = asencode_note +// } + + if($i['obj_type'] === ACTIVITY_OBJ_NOTE) + $ret['object'] = asencode_note($i); + + + $ret['actor'] = asencode_person($i['author']); + + + return $ret; + +} + +function asencode_note($i) { + + $ret = array(); + + $ret['@type'] = 'Note'; + $ret['@id'] = $i['plink']; + if($i['title']) + $ret['title'] = bbcode($i['title']); + $ret['content'] = bbcode($i['body']); + $ret['zot:owner'] = asencode_person($i['owner']); + $ret['published'] = datetime_convert('UTC','UTC',$i['created'],ATOM_TIME); + if($i['created'] !== $i['edited']) + $ret['updated'] = datetime_convert('UTC','UTC',$i['edited'],ATOM_TIME); + + return $ret; +} + + +function asencode_person($p) { + $ret = array(); + $ret['@type'] = 'Person'; + $ret['@id'] = 'acct:' . $p['xchan_addr']; + $ret['displayName'] = $p['xchan_name']; + $ret['icon'] = array( + '@type' => 'Link', + 'mediaType' => $p['xchan_photo_mimetype'], + 'href' => $p['xchan_photo_m'] + ); + $ret['url'] = array( + '@type' => 'Link', + 'mediaType' => 'text/html', + 'href' => $p['xchan_url'] + ); + + return $ret; +} diff --git a/include/items.php b/include/items.php index 10a5b4ab9..adc06898d 100755 --- a/include/items.php +++ b/include/items.php @@ -3,12 +3,13 @@ * @file include/items.php */ -/** @todo deprecated in newer SabreDAV releases Sabre\HTTP\URLUtil */ -use Sabre\DAV\URLUtil; +// uncertain if this line is needed and why +use Sabre\HTTP\URLUtil; require_once('include/bbcode.php'); require_once('include/oembed.php'); require_once('include/crypto.php'); +require_once('include/feedutils.php'); require_once('include/photo/photo_driver.php'); require_once('include/permissions.php'); @@ -482,214 +483,6 @@ function validate_item_elements($message,$arr) { -/** - * @brief Generate an Atom feed. - * - * @param array $channel - * @param array $params - */ -function get_public_feed($channel, $params) { - - $type = 'xml'; - $begin = NULL_DATE; - $end = ''; - $start = 0; - $records = 40; - $direction = 'desc'; - $pages = 0; - - if(! $params) - $params = array(); - - $params['type'] = ((x($params,'type')) ? $params['type'] : 'xml'); - $params['begin'] = ((x($params,'begin')) ? $params['begin'] : NULL_DATE); - $params['end'] = ((x($params,'end')) ? $params['end'] : datetime_convert('UTC','UTC','now')); - $params['start'] = ((x($params,'start')) ? $params['start'] : 0); - $params['records'] = ((x($params,'records')) ? $params['records'] : 40); - $params['direction'] = ((x($params,'direction')) ? $params['direction'] : 'desc'); - $params['pages'] = ((x($params,'pages')) ? intval($params['pages']) : 0); - $params['top'] = ((x($params,'top')) ? intval($params['top']) : 0); - $params['cat'] = ((x($params,'cat')) ? $params['cat'] : ''); - - - // put a sane lower limit on feed requests if not specified - -// if($params['begin'] === NULL_DATE) -// $params['begin'] = datetime_convert('UTC','UTC','now - 1 month'); - - switch($params['type']) { - case 'json': - header("Content-type: application/atom+json"); - break; - case 'xml': - default: - header("Content-type: application/atom+xml"); - break; - } - - return get_feed_for($channel, get_observer_hash(), $params); -} - -/** - * @brief - * - * @param array $channel - * @param string $observer_hash - * @param array $params - * @return string - */ -function get_feed_for($channel, $observer_hash, $params) { - - if(! channel) - http_status_exit(401); - - if($params['pages']) { - if(! perm_is_allowed($channel['channel_id'],$observer_hash,'view_pages')) - http_status_exit(403); - } else { - if(! perm_is_allowed($channel['channel_id'],$observer_hash,'view_stream')) - http_status_exit(403); - } - $items = items_fetch(array( - 'wall' => '1', - 'datequery' => $params['end'], - 'datequery2' => $params['begin'], - 'start' => $params['start'], // FIXME - 'records' => $params['records'], // FIXME - 'direction' => $params['direction'], // FIXME - 'pages' => $params['pages'], - 'order' => 'post', - 'top' => $params['top'], - 'cat' => $params['cat'] - ), $channel, $observer_hash, CLIENT_MODE_NORMAL, App::$module); - - - $feed_template = get_markup_template('atom_feed.tpl'); - - $atom = ''; - - $atom .= replace_macros($feed_template, array( - '$version' => xmlify(Zotlabs\Project\System::get_project_version()), - '$red' => xmlify(Zotlabs\Project\System::get_platform_name()), - '$feed_id' => xmlify($channel['xchan_url']), - '$feed_title' => xmlify($channel['channel_name']), - '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now' , ATOM_TIME)) , - '$hub' => '', // feed_hublinks(), - '$salmon' => '', // feed_salmonlinks($channel['channel_address']), - '$name' => xmlify($channel['channel_name']), - '$profile_page' => xmlify($channel['xchan_url']), - '$mimephoto' => xmlify($channel['xchan_photo_mimetype']), - '$photo' => xmlify($channel['xchan_photo_l']), - '$thumb' => xmlify($channel['xchan_photo_m']), - '$picdate' => '', - '$uridate' => '', - '$namdate' => '', - '$birthday' => '', - '$community' => '', - )); - - - call_hooks('atom_feed', $atom); - - if($items) { - $type = 'html'; - foreach($items as $item) { - if($item['item_private']) - continue; - - /** @BUG $owner is undefined in this call */ - $atom .= atom_entry($item, $type, null, $owner, true); - } - } - - call_hooks('atom_feed_end', $atom); - - $atom .= '' . "\r\n"; - - return $atom; -} - -/** - * @brief - * - * @param array $item an associative array with - * * \b string \b verb - * @return string item's verb if set, default ACTIVITY_POST see boot.php - */ -function construct_verb($item) { - if ($item['verb']) - return $item['verb']; - - return ACTIVITY_POST; -} - -function construct_activity_object($item) { - - if($item['object']) { - $o = '' . "\r\n"; - $r = json_decode($item['object'],false); - - if(! $r) - return ''; - if($r->type) - $o .= '' . xmlify($r->type) . '' . "\r\n"; - if($r->id) - $o .= '' . xmlify($r->id) . '' . "\r\n"; - if($r->title) - $o .= '' . xmlify($r->title) . '' . "\r\n"; - if($r->links) { - /** @FIXME!! */ - if(substr($r->link,0,1) === '<') { - $r->link = preg_replace('/\/','',$r->link); - $o .= $r->link; - } - else - $o .= '' . "\r\n"; - } - if($r->content) - $o .= '' . xmlify(bbcode($r->content)) . '' . "\r\n"; - $o .= '' . "\r\n"; - return $o; - } - - return ''; -} - -function construct_activity_target($item) { - - if($item['target']) { - $o = '' . "\r\n"; - $r = json_decode($item['target'],false); - if(! $r) - return ''; - if($r->type) - $o .= '' . xmlify($r->type) . '' . "\r\n"; - if($r->id) - $o .= '' . xmlify($r->id) . '' . "\r\n"; - if($r->title) - $o .= '' . xmlify($r->title) . '' . "\r\n"; - if($r->links) { - /** @FIXME !!! */ - if(substr($r->link,0,1) === '<') { - if(strstr($r->link,'&') && (! strstr($r->link,'&'))) - $r->link = str_replace('&','&', $r->link); - $r->link = preg_replace('/\/','',$r->link); - $o .= $r->link; - } - else - $o .= '' . "\r\n"; - } - if($r->content) - $o .= '' . xmlify(bbcode($r->content)) . '' . "\r\n"; - - $o .= '' . "\r\n"; - - return $o; - } - - return ''; -} - /** * @brief Limit lenght on imported system messages. * @@ -1701,453 +1494,6 @@ function get_profile_elements($x) { return $arr; } -/** - * @param object $feed - * @param array $item - * @param[out] array $author - * @return multitype:multitype: string NULL number Ambigous Ambigous Ambigous , multitype:multitype:string unknown > multitype:NULL unknown - */ -function get_atom_elements($feed, $item, &$author) { - - //$best_photo = array(); - - $res = array(); - - $found_author = $item->get_author(); - if($found_author) { - $author['author_name'] = unxmlify($found_author->get_name()); - $author['author_link'] = unxmlify($found_author->get_link()); - $author['author_is_feed'] = false; - } - else { - $author['author_name'] = unxmlify($feed->get_title()); - $author['author_link'] = unxmlify($feed->get_permalink()); - $author['author_is_feed'] = true; - } - - if(substr($author['author_link'],-1,1) == '/') - $author['author_link'] = substr($author['author_link'],0,-1); - - $res['mid'] = base64url_encode(unxmlify($item->get_id())); - $res['title'] = unxmlify($item->get_title()); - $res['body'] = unxmlify($item->get_content()); - $res['plink'] = unxmlify($item->get_link(0)); - $res['item_rss'] = 1; - - - // removing the content of the title if its identically to the body - // This helps with auto generated titles e.g. from tumblr - - if (title_is_body($res["title"], $res["body"])) - $res['title'] = ""; - - if($res['plink']) - $base_url = implode('/', array_slice(explode('/',$res['plink']),0,3)); - else - $base_url = ''; - - // look for a photo. We should check media size and find the best one, - // but for now let's just find any author photo - - $rawauthor = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author'); - - if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { - $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; - foreach($base as $link) { - if(!x($author, 'author_photo') || ! $author['author_photo']) { - if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') - $author['author_photo'] = unxmlify($link['attribs']['']['href']); - } - } - } - - $rawactor = $item->get_item_tags(NAMESPACE_ACTIVITY, 'actor'); - - if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['obj_type'][0]['data'],ACTIVITY_OBJ_PERSON)) { - $base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; - if($base && count($base)) { - foreach($base as $link) { - if($link['attribs']['']['rel'] === 'alternate' && (! $res['author_link'])) - $author['author_link'] = unxmlify($link['attribs']['']['href']); - if(!x($author, 'author_photo') || ! $author['author_photo']) { - if($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') - $author['author_photo'] = unxmlify($link['attribs']['']['href']); - } - } - } - } - - // check for a yahoo media element (github etc.) - - if(! $author['author_photo']) { - $rawmedia = $item->get_item_tags(NAMESPACE_YMEDIA,'thumbnail'); - if($rawmedia && $rawmedia[0]['attribs']['']['url']) { - $author['author_photo'] = strip_tags(unxmlify($rawmedia[0]['attribs']['']['url'])); - } - } - - - // No photo/profile-link on the item - look at the feed level - - if((! (x($author,'author_link'))) || (! (x($author,'author_photo')))) { - $rawauthor = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author'); - if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { - $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; - foreach($base as $link) { - if($link['attribs']['']['rel'] === 'alternate' && (! $author['author_link'])) { - $author['author_link'] = unxmlify($link['attribs']['']['href']); - $author['author_is_feed'] = true; - } - if(! $author['author_photo']) { - if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') - $author['author_photo'] = unxmlify($link['attribs']['']['href']); - } - } - } - - $rawactor = $feed->get_feed_tags(NAMESPACE_ACTIVITY, 'subject'); - - if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['obj_type'][0]['data'],ACTIVITY_OBJ_PERSON)) { - $base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; - - if($base && count($base)) { - foreach($base as $link) { - if($link['attribs']['']['rel'] === 'alternate' && (! $res['author_link'])) - $author['author_link'] = unxmlify($link['attribs']['']['href']); - if(! (x($author,'author_photo'))) { - if($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') - $author['author_photo'] = unxmlify($link['attribs']['']['href']); - } - } - } - } - } - - $apps = $item->get_item_tags(NAMESPACE_STATUSNET,'notice_info'); - if($apps && $apps[0]['attribs']['']['source']) { - $res['app'] = strip_tags(unxmlify($apps[0]['attribs']['']['source'])); - } - - /* - * If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it. - */ - - $have_real_body = false; - - $rawenv = $item->get_item_tags(NAMESPACE_DFRN, 'env'); - if($rawenv) { - $have_real_body = true; - $res['body'] = $rawenv[0]['data']; - $res['body'] = str_replace(array(' ',"\t","\r","\n"), array('','','',''),$res['body']); - // make sure nobody is trying to sneak some html tags by us - $res['body'] = notags(base64url_decode($res['body'])); - - // We could probably turn these old Friendica bbcode bookmarks into bookmark tags but we'd have to - // create a term table item for them. For now just make sure they stay as links. - - $res['body'] = preg_replace('/\[bookmark(.*?)\](.*?)\[\/bookmark\]/','[url$1]$2[/url]',$res['body']); - } - - $res['body'] = limit_body_size($res['body']); - - // It isn't certain at this point whether our content is plaintext or html and we'd be foolish to trust - // the content type. Our own network only emits text normally, though it might have been converted to - // html if we used a pubsubhubbub transport. But if we see even one html tag in our text, we will - // have to assume it is all html and needs to be purified. - - // It doesn't matter all that much security wise - because before this content is used anywhere, we are - // going to escape any tags we find regardless, but this lets us import a limited subset of html from - // the wild, by sanitising it and converting supported tags to bbcode before we rip out any remaining - // html. - - if((strpos($res['body'],'<') !== false) && (strpos($res['body'],'>') !== false)) { - - $res['body'] = reltoabs($res['body'],$base_url); - - $res['body'] = html2bb_video($res['body']); - - $res['body'] = oembed_html2bbcode($res['body']); - - $res['body'] = purify_html($res['body']); - - $res['body'] = @html2bbcode($res['body']); - } - elseif(! $have_real_body) { - - // it's not one of our messages and it has no tags - // so it's probably just text. We'll escape it just to be safe. - - $res['body'] = escape_tags($res['body']); - } - - if($res['plink'] && $res['title']) { - $res['body'] = '#^[url=' . $res['plink'] . ']' . $res['title'] . '[/url]' . "\n\n" . $res['body']; - $terms = array(); - $terms[] = array( - 'otype' => TERM_OBJ_POST, - 'type' => TERM_BOOKMARK, - 'url' => $res['plink'], - 'term' => $res['title'], - ); - } - elseif($res['plink']) { - $res['body'] = '#^[url]' . $res['plink'] . '[/url]' . "\n\n" . $res['body']; - $terms = array(); - $terms[] = array( - 'otype' => TERM_OBJ_POST, - 'type' => TERM_BOOKMARK, - 'url' => $res['plink'], - 'term' => $res['plink'], - ); - } - - $private = $item->get_item_tags(NAMESPACE_DFRN,'private'); - if($private && intval($private[0]['data']) > 0) - $res['item_private'] = ((intval($private[0]['data'])) ? 1 : 0); - else - $res['item_private'] = 0; - - $rawlocation = $item->get_item_tags(NAMESPACE_DFRN, 'location'); - if($rawlocation) - $res['location'] = unxmlify($rawlocation[0]['data']); - - $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'published'); - if($rawcreated) - $res['created'] = unxmlify($rawcreated[0]['data']); - - $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'updated'); - if($rawedited) - $res['edited'] = unxmlify($rawedited[0]['data']); - - if((x($res,'edited')) && (! (x($res,'created')))) - $res['created'] = $res['edited']; - - if(! $res['created']) - $res['created'] = $item->get_date('c'); - - if(! $res['edited']) - $res['edited'] = $item->get_date('c'); - - - // Disallow time travelling posts - - $d1 = strtotime($res['created']); - $d2 = strtotime($res['edited']); - $d3 = strtotime('now'); - - if($d1 > $d3) - $res['created'] = datetime_convert(); - if($d2 > $d3) - $res['edited'] = datetime_convert(); - - $res['created'] = datetime_convert('UTC','UTC',$res['created']); - $res['edited'] = datetime_convert('UTC','UTC',$res['edited']); - - $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner'); - if(! $rawowner) - $rawowner = $item->get_item_tags(NAMESPACE_ZOT,'owner'); - - if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']) - $author['owner_name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']); - elseif($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']) - $author['owner_name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']); - if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']) - $author['owner_link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']); - elseif($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']) - $author['owner_link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']); - - if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { - $base = $rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; - - foreach($base as $link) { - if(!x($author, 'owner_photo') || ! $author['owner_photo']) { - if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') - $author['owner_photo'] = unxmlify($link['attribs']['']['href']); - } - } - } - - $rawgeo = $item->get_item_tags(NAMESPACE_GEORSS,'point'); - if($rawgeo) - $res['coord'] = unxmlify($rawgeo[0]['data']); - - - $rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb'); - - // select between supported verbs - - if($rawverb) { - $res['verb'] = unxmlify($rawverb[0]['data']); - } - - // translate OStatus unfollow to activity streams if it happened to get selected - - if((x($res,'verb')) && ($res['verb'] === 'http://ostatus.org/schema/1.0/unfollow')) - $res['verb'] = ACTIVITY_UNFOLLOW; - - $cats = $item->get_categories(); - if($cats) { - if(is_null($terms)) - $terms = array(); - foreach($cats as $cat) { - $term = $cat->get_term(); - if(! $term) - $term = $cat->get_label(); - $scheme = $cat->get_scheme(); - $termurl = ''; - if($scheme && $term && stristr($scheme,'X-DFRN:')) { - $termtype = ((substr($scheme,7,1) === '#') ? TERM_HASHTAG : TERM_MENTION); - $termurl = unxmlify(substr($scheme,9)); - } - else { - $termtype = TERM_CATEGORY; - } - $termterm = notags(trim(unxmlify($term))); - - if($termterm) { - $terms[] = array( - 'otype' => TERM_OBJ_POST, - 'type' => $termtype, - 'url' => $termurl, - 'term' => $termterm, - ); - } - } - } - - if(! is_null($terms)) - $res['term'] = $terms; - - $attach = $item->get_enclosures(); - if($attach) { - $res['attach'] = array(); - foreach($attach as $att) { - $len = intval($att->get_length()); - $link = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_link())))); - $title = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_title())))); - $type = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_type())))); - if(strpos($type,';')) - $type = substr($type,0,strpos($type,';')); - if((! $link) || (strpos($link,'http') !== 0)) - continue; - - if(! $title) - $title = ' '; - if(! $type) - $type = 'application/octet-stream'; - - $res['attach'][] = array('href' => $link, 'length' => $len, 'type' => $type, 'title' => $title ); - } - } - - $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'object'); - - if($rawobj) { - $obj = array(); - - $child = $rawobj[0]['child']; - if($child[NAMESPACE_ACTIVITY]['obj_type'][0]['data']) { - $res['obj_type'] = $child[NAMESPACE_ACTIVITY]['obj_type'][0]['data']; - $obj['type'] = $child[NAMESPACE_ACTIVITY]['obj_type'][0]['data']; - } - if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) { - $res['obj_type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data']; - $obj['type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data']; - } - if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']) - $obj['id'] = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']; - if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) - $obj['link'] = encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']); - if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'title') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']) - $obj['title'] = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']; - if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'content') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) { - $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']; - if(! $body) - $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data']; - // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events - $obj['orig'] = xmlify($body); - if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) { - $body = purify_html($body); - $body = html2bbcode($body); - } - - $obj['content'] = $body; - } - - $res['object'] = $obj; - } - - $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'target'); - - if($rawobj) { - $obj = array(); - - $child = $rawobj[0]['child']; - if($child[NAMESPACE_ACTIVITY]['obj_type'][0]['data']) { - $res['tgt_type'] = $child[NAMESPACE_ACTIVITY]['obj_type'][0]['data']; - $obj['type'] = $child[NAMESPACE_ACTIVITY]['obj_type'][0]['data']; - } - if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) { - $res['tgt_type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data']; - $obj['type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data']; - } - if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']) - $obj['id'] = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']; - if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) - $obj['link'] = encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']); - if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'title') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']) - $obj['title'] = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']; - if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'content') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) { - $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']; - if(! $body) - $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data']; - - // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events - $obj['orig'] = xmlify($body); - if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) { - $body = purify_html($body); - $body = html2bbcode($body); - } - - $obj['content'] = $body; - } - - $res['target'] = $obj; - } - - $arr = array('feed' => $feed, 'item' => $item, 'result' => $res); - - call_hooks('parse_atom', $arr); - logger('get_atom_elements: author: ' . print_r($author,true),LOGGER_DATA); - - logger('get_atom_elements: ' . print_r($res,true),LOGGER_DATA); - - return $res; -} - -function encode_rel_links($links) { - $o = array(); - if(! ((is_array($links)) && (count($links)))) - return $o; - - foreach($links as $link) { - $l = array(); - if($link['attribs']['']['rel']) - $l['rel'] = $link['attribs']['']['rel']; - if($link['attribs']['']['type']) - $l['type'] = $link['attribs']['']['type']; - if($link['attribs']['']['href']) - $l['href'] = $link['attribs']['']['href']; - if( (x($link['attribs'],NAMESPACE_MEDIA)) && $link['attribs'][NAMESPACE_MEDIA]['width']) - $l['width'] = $link['attribs'][NAMESPACE_MEDIA]['width']; - if( (x($link['attribs'],NAMESPACE_MEDIA)) && $link['attribs'][NAMESPACE_MEDIA]['height']) - $l['height'] = $link['attribs'][NAMESPACE_MEDIA]['height']; - - if($l) - $o[] = $l; - } - return $o; -} /** * @brief @@ -3718,577 +3064,6 @@ function mail_store($arr) { return $current_post; } -/** - * @brief Process atom feed and update anything/everything we might need to update. - * - * @param array $xml - * The (atom) feed to consume - RSS isn't as fully supported but may work for simple feeds. - * @param $importer - * The contact_record (joined to user_record) of the local user who owns this - * relationship. It is this person's stuff that is going to be updated. - * @param $contact - * The person who is sending us stuff. If not set, we MAY be processing a "follow" activity - * from an external network and MAY create an appropriate contact record. Otherwise, we MUST - * have a contact record. - * @param int $pass by default ($pass = 0) we cannot guarantee that a parent item has been - * imported prior to its children being seen in the stream unless we are certain - * of how the feed is arranged/ordered. - * * With $pass = 1, we only pull parent items out of the stream. - * * With $pass = 2, we only pull children (comments/likes). - * - * So running this twice, first with pass 1 and then with pass 2 will do the right - * thing regardless of feed ordering. This won't be adequate in a fully-threaded - * model where comments can have sub-threads. That would require some massive sorting - * to get all the feed items into a mostly linear ordering, and might still require - * recursion. - */ -function consume_feed($xml, $importer, &$contact, $pass = 0) { - - require_once('library/simplepie/simplepie.inc'); - - if(! strlen($xml)) { - logger('consume_feed: empty input'); - return; - } - - $sys_expire = intval(get_config('system','default_expire_days')); - $chn_expire = intval($importer['channel_expire_days']); - - $expire_days = $sys_expire; - - if(($chn_expire != 0) && ($chn_expire < $sys_expire)) - $expire_days = $chn_expire; - - // logger('expire_days: ' . $expire_days); - - $feed = new SimplePie(); - $feed->set_raw_data($xml); - $feed->init(); - - if($feed->error()) - logger('consume_feed: Error parsing XML: ' . $feed->error()); - - $permalink = $feed->get_permalink(); - - // Check at the feed level for updated contact name and/or photo - - // process any deleted entries - - $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry'); - if(is_array($del_entries) && count($del_entries) && $pass != 2) { - foreach($del_entries as $dentry) { - $deleted = false; - if(isset($dentry['attribs']['']['ref'])) { - $mid = $dentry['attribs']['']['ref']; - $deleted = true; - if(isset($dentry['attribs']['']['when'])) { - $when = $dentry['attribs']['']['when']; - $when = datetime_convert('UTC','UTC', $when, 'Y-m-d H:i:s'); - } - else - $when = datetime_convert('UTC','UTC','now','Y-m-d H:i:s'); - } - - if($deleted && is_array($contact)) { - $r = q("SELECT * from item where mid = '%s' and author_xchan = '%s' and uid = %d limit 1", - dbesc(base64url_encode($mid)), - dbesc($contact['xchan_hash']), - intval($importer['channel_id']) - ); - - if($r) { - $item = $r[0]; - - if(! intval($item['item_deleted'])) { - logger('consume_feed: deleting item ' . $item['id'] . ' mid=' . base64url_decode($item['mid']), LOGGER_DEBUG); - drop_item($item['id'],false); - } - } - } - } - } - - // Now process the feed - - if($feed->get_item_quantity()) { - - logger('consume_feed: feed item count = ' . $feed->get_item_quantity(), LOGGER_DEBUG); - - $items = $feed->get_items(); - - foreach($items as $item) { - - $is_reply = false; - $item_id = base64url_encode($item->get_id()); - - logger('consume_feed: processing ' . $item_id, LOGGER_DEBUG); - - $rawthread = $item->get_item_tags( NAMESPACE_THREAD,'in-reply-to'); - if(isset($rawthread[0]['attribs']['']['ref'])) { - $is_reply = true; - $parent_mid = base64url_encode($rawthread[0]['attribs']['']['ref']); - } - - if($is_reply) { - - if($pass == 1) - continue; - - // Have we seen it? If not, import it. - - $item_id = base64url_encode($item->get_id()); - $author = array(); - $datarray = get_atom_elements($feed,$item,$author); - - if($contact['xchan_network'] === 'rss') { - $datarray['public_policy'] = 'specific'; - $datarray['comment_policy'] = 'none'; - } - - if((! x($author,'author_name')) || ($author['author_is_feed'])) - $author['author_name'] = $contact['xchan_name']; - if((! x($author,'author_link')) || ($author['author_is_feed'])) - $author['author_link'] = $contact['xchan_url']; - if((! x($author,'author_photo'))|| ($author['author_is_feed'])) - $author['author_photo'] = $contact['xchan_photo_m']; - - $datarray['author_xchan'] = ''; - - if($author['author_link'] != $contact['xchan_url']) { - $x = import_author_unknown(array('name' => $author['author_name'],'url' => $author['author_link'],'photo' => array('src' => $author['author_photo']))); - if($x) - $datarray['author_xchan'] = $x; - } - if(! $datarray['author_xchan']) - $datarray['author_xchan'] = $contact['xchan_hash']; - - $datarray['owner_xchan'] = $contact['xchan_hash']; - - $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", - dbesc($item_id), - intval($importer['channel_id']) - ); - - - // Update content if 'updated' changes - - if($r) { - if((x($datarray,'edited') !== false) - && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { - - // do not accept (ignore) an earlier edit than one we currently have. - if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) - continue; - - update_feed_item($importer['channel_id'],$datarray); - } - continue; - } - - $datarray['parent_mid'] = $parent_mid; - $datarray['aid'] = $importer['channel_account_id']; - $datarray['uid'] = $importer['channel_id']; - - logger('consume_feed: ' . print_r($datarray,true),LOGGER_DATA); - - $xx = item_store($datarray); - $r = $xx['item_id']; - continue; - } - else { - - // Head post of a conversation. Have we seen it? If not, import it. - - $item_id = base64url_encode($item->get_id()); - $author = array(); - $datarray = get_atom_elements($feed,$item,$author); - - if($contact['xchan_network'] === 'rss') { - $datarray['public_policy'] = 'specific'; - $datarray['comment_policy'] = 'none'; - } - - - if(is_array($contact)) { - if((! x($author,'author_name')) || ($author['author_is_feed'])) - $author['author_name'] = $contact['xchan_name']; - if((! x($author,'author_link')) || ($author['author_is_feed'])) - $author['author_link'] = $contact['xchan_url']; - if((! x($author,'author_photo'))|| ($author['author_is_feed'])) - $author['author_photo'] = $contact['xchan_photo_m']; - } - - if((! x($author,'author_name')) || (! x($author,'author_link'))) { - logger('consume_feed: no author information! ' . print_r($author,true)); - continue; - } - - $datarray['author_xchan'] = ''; - - if(activity_match($datarray['verb'],ACTIVITY_FOLLOW) && $datarray['obj_type'] === ACTIVITY_OBJ_PERSON) { - $cb = array('item' => $datarray,'channel' => $importer, 'xchan' => null, 'author' => $author, 'caught' => false); - call_hooks('follow_from_feed',$cb); - if($cb['caught']) { - if($cb['return_code']) - http_status_exit($cb['return_code']); - continue; - } - } - - if($author['author_link'] != $contact['xchan_url']) { - $x = import_author_unknown(array('name' => $author['author_name'],'url' => $author['author_link'],'photo' => array('src' => $author['author_photo']))); - if($x) - $datarray['author_xchan'] = $x; - } - if(! $datarray['author_xchan']) - $datarray['author_xchan'] = $contact['xchan_hash']; - - $datarray['owner_xchan'] = $contact['xchan_hash']; - - if(array_key_exists('created',$datarray) && $datarray['created'] != NULL_DATE && $expire_days) { - $t1 = $datarray['created']; - $t2 = datetime_convert('UTC','UTC','now - ' . $expire_days . 'days'); - if($t1 < $t2) { - logger('feed content older than expiration. Ignoring.', LOGGER_DEBUG, LOG_INFO); - continue; - } - } - - - - $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", - dbesc($item_id), - intval($importer['channel_id']) - ); - - // Update content if 'updated' changes - - if($r) { - if((x($datarray,'edited') !== false) - && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) { - - // do not accept (ignore) an earlier edit than one we currently have. - if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited']) - continue; - - update_feed_item($importer['channel_id'],$datarray); - } - - continue; - } - - $datarray['parent_mid'] = $item_id; - $datarray['uid'] = $importer['channel_id']; - $datarray['aid'] = $importer['channel_account_id']; - - if(! link_compare($author['owner_link'],$contact['xchan_url'])) { - logger('consume_feed: Correcting item owner.', LOGGER_DEBUG); - $author['owner_name'] = $contact['name']; - $author['owner_link'] = $contact['url']; - $author['owner_avatar'] = $contact['thumb']; - } - - if(! post_is_importable($datarray,$contact)) - continue; - - logger('consume_feed: author ' . print_r($author,true),LOGGER_DEBUG); - - logger('consume_feed: ' . print_r($datarray,true),LOGGER_DATA); - - $xx = item_store($datarray); - $r = $xx['item_id']; - continue; - } - } - } -} - - -/** - * @brief Process atom feed and return the first post and structure - * - * @param array $xml - * The (atom) feed to consume - RSS isn't as fully supported but may work for simple feeds. - * @param $importer - * The contact_record (joined to user_record) of the local user who owns this - * relationship. It is this person's stuff that is going to be updated. - */ - -function process_salmon_feed($xml, $importer) { - - $ret = array(); - - require_once('library/simplepie/simplepie.inc'); - - if(! strlen($xml)) { - logger('process_feed: empty input'); - return; - } - - $feed = new SimplePie(); - $feed->set_raw_data($xml); - $feed->init(); - - if($feed->error()) - logger('Error parsing XML: ' . $feed->error()); - - $permalink = $feed->get_permalink(); - - if($feed->get_item_quantity()) { - - // this should be exactly one - - logger('feed item count = ' . $feed->get_item_quantity(), LOGGER_DEBUG); - - $items = $feed->get_items(); - - foreach($items as $item) { - - $item_id = base64url_encode($item->get_id()); - - logger('processing ' . $item_id, LOGGER_DEBUG); - - $rawthread = $item->get_item_tags( NAMESPACE_THREAD,'in-reply-to'); - if(isset($rawthread[0]['attribs']['']['ref'])) { - $is_reply = true; - $parent_mid = base64url_encode($rawthread[0]['attribs']['']['ref']); - } - - if($is_reply) - $ret['parent_mid'] = $parent_mid; - - $ret['author'] = array(); - - $datarray = get_atom_elements($feed,$item,$ret['author']); - - // reset policies which are restricted by default for RSS connections - // This item is likely coming from GNU-social via salmon and allows public interaction - $datarray['public_policy'] = ''; - $datarray['comment_policy'] = ''; - - $ret['item'] = $datarray; - } - } - - return $ret; -} - -/* - * Given an xml (atom) feed, find author and hub links - */ - - -function feed_meta($xml) { - require_once('library/simplepie/simplepie.inc'); - - $ret = array(); - - if(! strlen($xml)) { - logger('empty input'); - return $ret; - } - - $feed = new SimplePie(); - $feed->set_raw_data($xml); - $feed->init(); - - if($feed->error()) { - logger('Error parsing XML: ' . $feed->error()); - return $ret; - } - - $ret['hubs'] = $feed->get_links('hub'); - -// logger('consume_feed: hubs: ' . print_r($hubs,true), LOGGER_DATA); - - $author = array(); - - $found_author = $feed->get_author(); - if($found_author) { - $author['author_name'] = unxmlify($found_author->get_name()); - $author['author_link'] = unxmlify($found_author->get_link()); - - $rawauthor = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author'); - logger('rawauthor: ' . print_r($rawauthor,true)); - - if($rawauthor) { - if($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { - $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; - foreach($base as $link) { - if(!x($author, 'author_photo') || ! $author['author_photo']) { - if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') { - $author['author_photo'] = unxmlify($link['attribs']['']['href']); - break; - } - } - } - } - if($rawauthor[0]['child'][NAMESPACE_POCO]['displayName'][0]['data']) - $author['full_name'] = unxmlify($rawauthor[0]['child'][NAMESPACE_POCO]['displayName'][0]['data']); - if($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']) - $author['author_uri'] = unxmlify($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']); - - } - } - - if(substr($author['author_link'],-1,1) == '/') - $author['author_link'] = substr($author['author_link'],0,-1); - - $ret['author'] = $author; - - return $ret; -} - - - -function update_feed_item($uid,$datarray) { - logger('update_feed_item: not implemented! ' . $uid . ' ' . print_r($datarray,true), LOGGER_DATA); -} - - -function handle_feed($uid,$abook_id,$url) { - - require_once('include/Contact.php'); - $channel = channelx_by_n($uid); - if(! $channel) - return; - - $x = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d limit 1", - dbesc($abook_id), - intval($uid) - ); - - $recurse = 0; - $z = z_fetch_url($url,false,$recurse,array('novalidate' => true)); - -//logger('handle_feed:' . print_r($z,true)); - - if($z['success']) { - consume_feed($z['body'],$channel,$x[0],1); - consume_feed($z['body'],$channel,$x[0],2); - } -} - - -function atom_author($tag,$name,$uri,$h,$w,$type,$photo) { - $o = ''; - if(! $tag) - return $o; - - $name = xmlify($name); - $uri = xmlify($uri); - $h = intval($h); - $w = intval($w); - $photo = xmlify($photo); - - $o .= "<$tag>\r\n"; - $o .= "$name\r\n"; - $o .= "$uri\r\n"; - $o .= '' . "\r\n"; - $o .= '' . "\r\n"; - - call_hooks('atom_author', $o); - - $o .= "\r\n"; - - return $o; -} - -function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { - - if(! $item['parent']) - return; - - if($item['deleted']) - return '' . "\r\n"; - - - create_export_photo_body($item); - - if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid']) - $body = fix_private_photos($item['body'],$owner['uid'],$item,$cid); - else - $body = $item['body']; - - $o = "\r\n\r\n\r\n"; - - if(is_array($author)) - $o .= atom_author('author',$author['xchan_name'],$author['xchan_url'],80,80,$author['xchan_photo_mimetype'],$author['xchan_photo_m']); - else - $o .= atom_author('author',$item['author']['xchan_name'],$item['author']['xchan_url'],80,80,$item['author']['xchan_photo_mimetype'], $item['author']['xchan_photo_m']); - - $o .= atom_author('zot:owner',$item['owner']['xchan_name'],$item['owner']['xchan_url'],80,80,$item['owner']['xchan_photo_mimetype'],$item['owner']['xchan_photo_m']); - - if(($item['parent'] != $item['id']) || ($item['parent_mid'] !== $item['mid']) || (($item['thr_parent'] !== '') && ($item['thr_parent'] !== $item['mid']))) { - $parent_item = (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']); - $o .= '' . "\r\n"; - } - - if(activity_match($item['obj_type'],ACTIVITY_OBJ_EVENT) && activity_match($item['verb'],ACTIVITY_POST)) { - $obj = ((is_array($item['obj'])) ? $item['object'] : json_decode($item['object'],true)); - - $o .= '' . xmlify($item['title']) . '' . "\r\n"; - $o .= '' . xmlify(bbcode($obj['title'])) . '' . "\r\n"; - $o .= '' . datetime_convert('UTC','UTC', $obj['start'],'Ymd\\THis' . (($obj['adjust']) ? '\\Z' : '')) . '' . "\r\n"; - $o .= '' . datetime_convert('UTC','UTC', $obj['finish'],'Ymd\\THis' . (($obj['adjust']) ? '\\Z' : '')) . '' . "\r\n"; - $o .= '' . xmlify(bbcode($obj['location'])) . '' . "\r\n"; - $o .= '' . xmlify(bbcode($obj['description'])) . '' . "\r\n"; - } - else { - $o .= '' . xmlify($item['title']) . '' . "\r\n"; - $o .= '' . xmlify(prepare_text($body,$item['mimetype'])) . '' . "\r\n"; - } - - $o .= '' . z_root() . '/display/' . xmlify($item['mid']) . '' . "\r\n"; - $o .= '' . xmlify(datetime_convert('UTC','UTC',$item['created'] . '+00:00',ATOM_TIME)) . '' . "\r\n"; - $o .= '' . xmlify(datetime_convert('UTC','UTC',$item['edited'] . '+00:00',ATOM_TIME)) . '' . "\r\n"; - - $o .= '' . "\r\n"; - - if($item['location']) { - $o .= '' . xmlify($item['location']) . '' . "\r\n"; - $o .= '' . xmlify($item['location']) . '' . "\r\n"; - } - - if($item['coord']) - $o .= '' . xmlify($item['coord']) . '' . "\r\n"; - - if(($item['item_private']) || strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])) - $o .= '' . (($item['item_private']) ? $item['item_private'] : 1) . '' . "\r\n"; - - if($item['app']) - $o .= '' . "\r\n"; - - $verb = construct_verb($item); - $o .= '' . xmlify($verb) . '' . "\r\n"; - $actobj = construct_activity_object($item); - if(strlen($actobj)) - $o .= $actobj; - $actarg = construct_activity_target($item); - if(strlen($actarg)) - $o .= $actarg; - - // FIXME -// $tags = item_getfeedtags($item); -// if(count($tags)) { -// foreach($tags as $t) { -// $o .= '' . "\r\n"; -// } -// } - -// FIXME -// $o .= item_getfeedattach($item); - -// $mentioned = get_mentions($item,$tags); -// if($mentioned) -// $o .= $mentioned; - - call_hooks('atom_entry', $o); - - $o .= '' . "\r\n"; - - return $o; -} function fix_private_photos($s, $uid, $item = null, $cid = 0) { @@ -5471,90 +4246,6 @@ function comment_local_origin($item) { } -function gen_asld($items) { - $ret = array(); - if(! $items) - return $ret; - foreach($items as $item) { - $ret[] = i2asld($item); - } - return $ret; -} - - -function i2asld($i) { - - if(! $i) - return array(); - - $ret = array(); - - $ret['@context'] = array( 'http://www.w3.org/ns/activitystreams', 'zot' => 'http://purl.org/zot/protocol'); - - if($i['verb']) { - if(strpos(dirname($i['verb'],'activitystrea.ms/schema/1.0'))) { - $ret['@type'] = ucfirst(basename($i['verb'])); - } - elseif(strpos(dirname($i['verb'],'purl.org/zot'))) { - $ret['@type'] = 'zot:' . ucfirst(basename($i['verb'])); - } - } - $ret['@id'] = $i['plink']; - - $ret['published'] = datetime_convert('UTC','UTC',$i['created'],ATOM_TIME); - - // we need to pass the parent into this -// if($i['id'] != $i['parent'] && $i['obj_type'] === ACTIVITY_OBJ_NOTE) { -// $ret['inReplyTo'] = asencode_note -// } - - if($i['obj_type'] === ACTIVITY_OBJ_NOTE) - $ret['object'] = asencode_note($i); - - - $ret['actor'] = asencode_person($i['author']); - - - return $ret; - -} - -function asencode_note($i) { - - $ret = array(); - - $ret['@type'] = 'Note'; - $ret['@id'] = $i['plink']; - if($i['title']) - $ret['title'] = bbcode($i['title']); - $ret['content'] = bbcode($i['body']); - $ret['zot:owner'] = asencode_person($i['owner']); - $ret['published'] = datetime_convert('UTC','UTC',$i['created'],ATOM_TIME); - if($i['created'] !== $i['edited']) - $ret['updated'] = datetime_convert('UTC','UTC',$i['edited'],ATOM_TIME); - - return $ret; -} - - -function asencode_person($p) { - $ret = array(); - $ret['@type'] = 'Person'; - $ret['@id'] = 'acct:' . $p['xchan_addr']; - $ret['displayName'] = $p['xchan_name']; - $ret['icon'] = array( - '@type' => 'Link', - 'mediaType' => $p['xchan_photo_mimetype'], - 'href' => $p['xchan_photo_m'] - ); - $ret['url'] = array( - '@type' => 'Link', - 'mediaType' => 'text/html', - 'href' => $p['xchan_url'] - ); - - return $ret; -} function send_profile_photo_activity($channel,$photo,$profile) { -- cgit v1.2.3 From 573dea42d0b71a360d8630ab20783dba13768a49 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Fri, 13 May 2016 16:22:43 +0200 Subject: instead of radio buttons use select to choose between public and restricted acl. if restricted is selected acl is set to default. if there is no default acl will be set to self. if public is selected acl-list will be hidden and acl-info is visible. --- include/acl_selectors.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/acl_selectors.php b/include/acl_selectors.php index ce0a32798..6196be786 100644 --- a/include/acl_selectors.php +++ b/include/acl_selectors.php @@ -271,7 +271,7 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti '$showall' => $showall_caption, '$showallOrigin' => $showall_origin, '$showallIcon' => $showall_icon, - '$showlimited' => t("Limit access:"), + '$showlimited' => t("Restricted"), '$showlimitedDesc' => t('Select "Show" to allow viewing. "Don\'t show" lets you override and limit the scope of "Show".'), '$show' => t("Show"), '$hide' => t("Don't show"), -- cgit v1.2.3 From 1e00fa79b323c6d340b79789bf9be072a9aa629b Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Fri, 13 May 2016 17:38:50 +0200 Subject: change wording restricted -> custom selection and add a label to the select --- include/acl_selectors.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/acl_selectors.php b/include/acl_selectors.php index 6196be786..136f8aa50 100644 --- a/include/acl_selectors.php +++ b/include/acl_selectors.php @@ -271,7 +271,8 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti '$showall' => $showall_caption, '$showallOrigin' => $showall_origin, '$showallIcon' => $showall_icon, - '$showlimited' => t("Restricted"), + '$select_label' => t('Who can see this'), + '$showlimited' => t('Custom selection'), '$showlimitedDesc' => t('Select "Show" to allow viewing. "Don\'t show" lets you override and limit the scope of "Show".'), '$show' => t("Show"), '$hide' => t("Don't show"), -- cgit v1.2.3 From ec81ef7b8d000171f0b01bbc88909083ce5b88be Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 14 May 2016 21:04:19 -0700 Subject: issue #383 --- include/import.php | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/import.php b/include/import.php index 98c70fa19..46c8057b6 100644 --- a/include/import.php +++ b/include/import.php @@ -90,7 +90,6 @@ function import_channel($channel, $account_id, $seize) { set_default_login_identity($account_id,$channel['channel_id'],false); logger('import step 1'); $_SESSION['import_step'] = 1; - ref_session_write(session_id(), serialize($_SESSION)); return $channel; } -- cgit v1.2.3 From 217db8f9b2050510d2d2f2679d325d60d90cdb93 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 15 May 2016 19:16:55 -0700 Subject: provide tools to extract a pdo constructor --- include/dba/dba_driver.php | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php index 8e205a4aa..4a1752672 100755 --- a/include/dba/dba_driver.php +++ b/include/dba/dba_driver.php @@ -25,23 +25,31 @@ function dba_factory($server, $port,$user,$pass,$db,$dbtype,$install = false) { $dba = null; $dbtype = intval($dbtype); + $set_port = $port; if($dbtype == DBTYPE_POSTGRES) { require_once('include/dba/dba_postgres.php'); - if(is_null($port)) $port = 5432; - $dba = new dba_postgres($server, $port, $user, $pass, $db, $install); + if(is_null($port)) $set_port = 5432; + $dba = new dba_postgres($server, $set_port, $user, $pass, $db, $install); } else { if(class_exists('mysqli')) { - if (is_null($port)) $port = ini_get("mysqli.default_port"); + if (is_null($port)) $set_port = ini_get("mysqli.default_port"); require_once('include/dba/dba_mysqli.php'); - $dba = new dba_mysqli($server, $port,$user,$pass,$db,$install); + $dba = new dba_mysqli($server, $set_port,$user,$pass,$db,$install); } else { - if (is_null($port)) $port = "3306"; + if (is_null($port)) $set_port = "3306"; require_once('include/dba/dba_mysql.php'); - $dba = new dba_mysql($server, $port,$user,$pass,$db,$install); + $dba = new dba_mysql($server, $set_port,$user,$pass,$db,$install); } } + if(is_object($dba) && $dba->connected) { + $dns = (($dbtype == DBTYPE_POSTGRES) ? 'postgres' : 'mysql') + . ':host=' . $server . (is_null($port) ? '' : ';port=' . $port) + . ';dbname=' . $db; + $dba->pdo_set(array($dns,$user,$pass)); + } + define('NULL_DATE', $dba->get_null_date()); define('ACTIVE_DBTYPE', $dbtype); return $dba; @@ -60,6 +68,7 @@ abstract class dba_driver { const UTC_NOW = 'UTC_TIMESTAMP()'; protected $db; + protected $pdo = array(); public $debug = 0; public $connected = false; @@ -183,6 +192,15 @@ abstract class dba_driver { function unescapebin($str) { return $str; } + + function pdo_set($x) { + $this->pdo = $x; + } + + function pdo_get() { + return $this->pdo; + } + } // end abstract dba_driver class -- cgit v1.2.3 From 2dcedd69519a40ca0f40bf7b8b86423e98c778c9 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 16 May 2016 17:07:39 -0700 Subject: more work on sessions and cookies, as some anomalies appeared in caldav and firefox which suggested deeper issues --- include/Contact.php | 2 +- include/api.php | 2 +- include/auth.php | 16 ++++++++-------- include/cli_startup.php | 3 ++- 4 files changed, 12 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/Contact.php b/include/Contact.php index e011c60c8..8ad67c28e 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -389,7 +389,7 @@ function channel_remove($channel_id, $local = true, $unset_session=false) { proc_run('php','include/directory.php',$channel_id); if($channel_id == local_channel() && $unset_session) { - \Zotlabs\Web\Session::nuke(); + App::$session->nuke(); goaway(z_root()); } diff --git a/include/api.php b/include/api.php index 3b2c71923..5f4d4bedb 100644 --- a/include/api.php +++ b/include/api.php @@ -486,7 +486,7 @@ require_once('include/api_auth.php'); function api_account_logout(&$a, $type){ require_once('include/auth.php'); - \Zotlabs\Web\Session::nuke(); + App::$session->nuke(); return api_apply_template("user", $type, array('$user' => null)); } diff --git a/include/auth.php b/include/auth.php index 9643da8eb..01fcf0094 100644 --- a/include/auth.php +++ b/include/auth.php @@ -101,7 +101,7 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) && // process logout request $args = array('channel_id' => local_channel()); call_hooks('logging_out', $args); - \Zotlabs\Web\Session::nuke(); + App::$session->nuke(); info( t('Logged out.') . EOL); goaway(z_root()); } @@ -117,7 +117,7 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) && intval(ACCOUNT_ROLE_ADMIN) ); if($x) { - \Zotlabs\Web\Session::new_cookie(60 * 60 * 24); // one day + App::$session->new_cookie(60 * 60 * 24); // one day $_SESSION['last_login_date'] = datetime_convert(); unset($_SESSION['visitor_id']); // no longer a visitor authenticate_success($x[0], true, true); @@ -141,7 +141,7 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) && if(x($_SESSION, 'uid') || x($_SESSION, 'account_id')) { - Zotlabs\Web\Session::return_check(); + App::$session->return_check(); $r = q("select * from account where account_id = %d limit 1", intval($_SESSION['account_id']) @@ -155,14 +155,14 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) && } if(strcmp(datetime_convert('UTC','UTC','now - 12 hours'), $_SESSION['last_login_date']) > 0 ) { $_SESSION['last_login_date'] = datetime_convert(); - Zotlabs\Web\Session::extend_cookie(); + App::$session->extend_cookie(); $login_refresh = true; } authenticate_success($r[0], false, false, false, $login_refresh); } else { $_SESSION['account_id'] = 0; - \Zotlabs\Web\Session::nuke(); + App::$session->nuke(); goaway(z_root()); } } // end logged in user returning @@ -170,7 +170,7 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) && else { if(isset($_SESSION)) { - \Zotlabs\Web\Session::nuke(); + App::$session->nuke(); } // handle a fresh login request @@ -242,11 +242,11 @@ else { if($_POST['remember_me']) { $_SESSION['remember_me'] = 1; - \Zotlabs\Web\Session::new_cookie(31449600); // one year + App::$session->new_cookie(31449600); // one year } else { $_SESSION['remember_me'] = 0; - \Zotlabs\Web\Session::new_cookie(0); // 0 means delete on browser exit + App::$session->new_cookie(0); // 0 means delete on browser exit } // if we haven't failed up this point, log them in. diff --git a/include/cli_startup.php b/include/cli_startup.php index a99164d4c..a33f7acb0 100644 --- a/include/cli_startup.php +++ b/include/cli_startup.php @@ -30,7 +30,8 @@ function cli_startup() { unset($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type); }; - \Zotlabs\Web\Session::init(); + App::$session = new Zotlabs\Web\Session(); + App::$session->init(); load_config('system'); -- cgit v1.2.3 From 883b1ff51355b72a1af2a1ab09877bc444ee905f Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 16 May 2016 19:23:42 -0700 Subject: an issue related to #386 --- include/import.php | 2 +- include/network.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/import.php b/include/import.php index 46c8057b6..00058047e 100644 --- a/include/import.php +++ b/include/import.php @@ -21,7 +21,7 @@ function import_channel($channel, $account_id, $seize) { dbesc($channel['channel_address']) ); - if(($r) || (check_webbie(array($channel['channel_hash'])) !== $channel['channel_hash'])) { + if(($r) || (check_webbie(array($channel['channel_address'])) !== $channel['channel_address'])) { if($r[0]['channel_guid'] === $channel['channel_guid'] || $r[0]['channel_hash'] === $channel['channel_hash']) { logger('mod_import: duplicate channel. ', print_r($channel,true)); notice( t('Cannot create a duplicate channel identifier on this system. Import failed.') . EOL); diff --git a/include/network.php b/include/network.php index 9f68d3df3..f80244f8f 100644 --- a/include/network.php +++ b/include/network.php @@ -1168,6 +1168,10 @@ function discover_by_webbie($webbie) { if(! $x) $probe_old = true; + + if((! $dfrn) && (! $has_salmon)) + $probe_old = true; + if($probe_old) { $y = old_webfinger($webbie); if($y) { -- cgit v1.2.3 From bfbe6c166081608deaa1e388f6287a1bf933c0c6 Mon Sep 17 00:00:00 2001 From: sasiflo Date: Tue, 17 May 2016 12:27:15 +0200 Subject: Synchronization: Directory creation on sync import corrected. --- include/import.php | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/import.php b/include/import.php index 00058047e..a62ec4ed5 100644 --- a/include/import.php +++ b/include/import.php @@ -973,8 +973,11 @@ function sync_files($channel,$files) { $attach_exists = false; $x = attach_by_hash($att['hash']); + logger('sync_files duplicate check: attach_exists=' . $attach_exists, LOGGER_DEBUG); + logger('sync_files duplicate check: att=' . print_r($att,true), LOGGER_DEBUG); + logger('sync_files duplicate check: attach_by_hash() returned ' . print_r($x,true), LOGGER_DEBUG); - if($x) { + if($x['success']) { $attach_exists = true; $attach_id = $x[0]['id']; } @@ -1043,15 +1046,17 @@ function sync_files($channel,$files) { if($attach_exists) { - $str = ''; - foreach($att as $k => $v) { - if($str) - $str .= ","; - $str .= " `" . $k . "` = '" . $v . "' "; - } - $r = dbq("update `attach` set " . $str . " where id = " . intval($attach_id) ); + logger('sync_files attach exists: ' . print_r($att,true), LOGGER_DEBUG); + $str = ''; + foreach($att as $k => $v) { + if($str) + $str .= ","; + $str .= " `" . $k . "` = '" . $v . "' "; + } + $r = dbq("update `attach` set " . $str . " where id = " . intval($attach_id) ); } else { + logger('sync_files attach does not exists: ' . print_r($att,true), LOGGER_DEBUG); $r = dbq("INSERT INTO attach (`" . implode("`, `", array_keys($att)) . "`) VALUES ('" @@ -1064,6 +1069,7 @@ function sync_files($channel,$files) { if($att['filetype'] === 'multipart/mixed' && $att['is_dir']) { os_mkdir($newfname, STORAGE_DEFAULT_PERMISSIONS,true); + $attachment_stored = true; continue; } else { -- cgit v1.2.3 From 20cb4130d47028cbedf09f8da9feb6ccf8f759db Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 17 May 2016 17:46:30 -0700 Subject: support work for a long-term fix for issue #390, essentially one can specify a theme:schema string anywhere a theme is input. It will be honoured unless an existing schema setting over-rides this behaviour. This should also be backward compatible but the theme selection code has been cleaned up slightly and there may be subtle differences in behaviour after this commit. On my site this required a page refresh as the first page load after this change was a bit confused. --- include/plugin.php | 5 +++-- include/smarty.php | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/plugin.php b/include/plugin.php index 8dd67bb0c..89047d4b1 100755 --- a/include/plugin.php +++ b/include/plugin.php @@ -648,12 +648,13 @@ function theme_include($file, $root = '') { else $parent = 'NOPATH'; - $theme = current_theme(); + $theme = Zotlabs\Render\Theme::current(); + $thname = $theme[0]; $ext = substr($file,strrpos($file,'.')+1); $paths = array( - "{$root}view/theme/$theme/$ext/$file", + "{$root}view/theme/$thname/$ext/$file", "{$root}view/theme/$parent/$ext/$file", "{$root}view/site/$ext/$file", "{$root}view/$ext/$file", diff --git a/include/smarty.php b/include/smarty.php index 3812c6021..762efe335 100755 --- a/include/smarty.php +++ b/include/smarty.php @@ -11,13 +11,14 @@ class FriendicaSmarty extends Smarty { parent::__construct(); $a = get_app(); - $theme = current_theme(); + $theme = Zotlabs\Render\Theme::current(); + $thname = $theme[0]; // setTemplateDir can be set to an array, which Smarty will parse in order. // The order is thus very important here - $template_dirs = array('theme' => "view/theme/$theme/tpl/"); + $template_dirs = array('theme' => "view/theme/$thname/tpl/"); if( x(App::$theme_info,"extends") ) - $template_dirs = $template_dirs + array('extends' => "view/theme/".App::$theme_info["extends"]."/tpl/"); + $template_dirs = $template_dirs + array('extends' => "view/theme/" . App::$theme_info["extends"] . "/tpl/"); $template_dirs = $template_dirs + array('base' => 'view/tpl/'); $this->setTemplateDir($template_dirs); -- cgit v1.2.3 From 43c2b22fca908cb5c7bb740855cbd9d04e085d62 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 17 May 2016 19:49:21 -0700 Subject: cli utilities - argc and argv reversed. Not functionally incorrect since it was consistent but aesthetically incorrect. --- include/checksites.php | 4 ++-- include/cli_suggest.php | 7 ++----- include/cronhooks.php | 4 ++-- include/deliver.php | 4 ++-- include/deliver_hooks.php | 4 ++-- include/directory.php | 4 ++-- include/expire.php | 4 ++-- include/externals.php | 4 ++-- include/gprobe.php | 4 ++-- include/importdoc.php | 4 ++-- include/notifier.php | 4 ++-- include/onedirsync.php | 4 ++-- include/onepoll.php | 4 ++-- include/poller.php | 4 ++-- include/queue.php | 4 ++-- include/ratenotif.php | 4 ++-- 16 files changed, 32 insertions(+), 35 deletions(-) (limited to 'include') diff --git a/include/checksites.php b/include/checksites.php index e9c08c202..9d3ca1797 100644 --- a/include/checksites.php +++ b/include/checksites.php @@ -7,7 +7,7 @@ require_once('include/hubloc.php'); -function checksites_run($argv, $argc){ +function checksites_run($argc,$argv){ cli_startup(); @@ -57,6 +57,6 @@ function checksites_run($argv, $argc){ } if (array_search(__file__,get_included_files())===0){ - checksites_run($argv,$argc); + checksites_run($argc,$argv); killme(); } diff --git a/include/cli_suggest.php b/include/cli_suggest.php index 321ffd2e0..94b65f8ee 100644 --- a/include/cli_suggest.php +++ b/include/cli_suggest.php @@ -5,18 +5,15 @@ require_once('include/cli_startup.php'); require_once('include/socgraph.php'); -function cli_suggest_run($argv, $argc){ +function cli_suggest_run($argc,$argv){ cli_startup(); - - $a = get_app(); - update_suggestions(); } if (array_search(__file__,get_included_files())===0){ - cli_suggest_run($argv,$argc); + cli_suggest_run($argc,$argv); killme(); } diff --git a/include/cronhooks.php b/include/cronhooks.php index a314593d2..ae3806984 100644 --- a/include/cronhooks.php +++ b/include/cronhooks.php @@ -4,7 +4,7 @@ require_once('boot.php'); require_once('include/cli_startup.php'); -function cronhooks_run($argv, $argc){ +function cronhooks_run($argc,$argv){ cli_startup(); @@ -18,6 +18,6 @@ function cronhooks_run($argv, $argc){ } if (array_search(__file__,get_included_files())===0){ - cronhooks_run($argv,$argc); + cronhooks_run($argc,$argv); killme(); } diff --git a/include/deliver.php b/include/deliver.php index 40df543d5..12f28d6a9 100644 --- a/include/deliver.php +++ b/include/deliver.php @@ -5,7 +5,7 @@ require_once('include/zot.php'); require_once('include/queue_fn.php'); -function deliver_run($argv, $argc) { +function deliver_run($argc,$argv) { cli_startup(); @@ -82,6 +82,6 @@ function deliver_run($argv, $argc) { } if (array_search(__file__,get_included_files())===0){ - deliver_run($argv,$argc); + deliver_run($argc,$argv); killme(); } diff --git a/include/deliver_hooks.php b/include/deliver_hooks.php index f0d6ba1b1..f8f3bb19b 100644 --- a/include/deliver_hooks.php +++ b/include/deliver_hooks.php @@ -5,7 +5,7 @@ require_once('include/cli_startup.php'); require_once('include/zot.php'); -function deliver_hooks_run($argv, $argc) { +function deliver_hooks_run($argc,$argv) { cli_startup(); @@ -24,6 +24,6 @@ function deliver_hooks_run($argv, $argc) { } if (array_search(__file__,get_included_files())===0){ - deliver_hooks_run($argv,$argc); + deliver_hooks_run($argc,$argv); killme(); } diff --git a/include/directory.php b/include/directory.php index 8792a15e1..5120474a6 100644 --- a/include/directory.php +++ b/include/directory.php @@ -16,7 +16,7 @@ require_once('include/queue_fn.php'); * @param array $argv * @param array $argc */ -function directory_run($argv, $argc){ +function directory_run($argc,$argv){ cli_startup(); @@ -108,6 +108,6 @@ function directory_run($argv, $argc){ } if (array_search(__file__, get_included_files()) === 0) { - directory_run($argv, $argc); + directory_run($argc,$argv); killme(); } diff --git a/include/expire.php b/include/expire.php index e75594b5f..a2468e0f2 100644 --- a/include/expire.php +++ b/include/expire.php @@ -6,7 +6,7 @@ require_once('boot.php'); require_once('include/cli_startup.php'); -function expire_run($argv, $argc){ +function expire_run($argc,$argv){ cli_startup(); @@ -93,6 +93,6 @@ function expire_run($argv, $argc){ } if (array_search(__file__, get_included_files()) === 0){ - expire_run($argv, $argc); + expire_run($argc,$argv); killme(); } diff --git a/include/externals.php b/include/externals.php index 3a3a32420..ddf44dc52 100644 --- a/include/externals.php +++ b/include/externals.php @@ -5,7 +5,7 @@ require_once('include/cli_startup.php'); require_once('include/zot.php'); require_once('include/identity.php'); -function externals_run($argv, $argc){ +function externals_run($argc,$argv){ cli_startup(); $a = get_app(); @@ -98,6 +98,6 @@ function externals_run($argv, $argc){ } if (array_search(__file__,get_included_files())===0){ - externals_run($argv,$argc); + externals_run($argc,$argv); killme(); } diff --git a/include/gprobe.php b/include/gprobe.php index d8d893d9e..bd02ac31b 100644 --- a/include/gprobe.php +++ b/include/gprobe.php @@ -3,7 +3,7 @@ require_once('include/cli_startup.php'); require_once('include/zot.php'); -function gprobe_run($argv, $argc){ +function gprobe_run($argc,$argv){ cli_startup(); @@ -33,6 +33,6 @@ function gprobe_run($argv, $argc){ } if (array_search(__file__,get_included_files())===0){ - gprobe_run($argv,$argc); + gprobe_run($argc,$argv); killme(); } diff --git a/include/importdoc.php b/include/importdoc.php index 90dfb2fc4..7c65037d3 100755 --- a/include/importdoc.php +++ b/include/importdoc.php @@ -5,7 +5,7 @@ require_once('include/cli_startup.php'); -function importdoc_run($argv, $argc){ +function importdoc_run($argc,$argv){ cli_startup(); @@ -16,7 +16,7 @@ function importdoc_run($argv, $argc){ } if (array_search(__file__,get_included_files())===0){ - importdoc_run($argv,$argc); + importdoc_run($argc,$argv); killme(); } diff --git a/include/notifier.php b/include/notifier.php index 708d42bd0..780a8798c 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -74,7 +74,7 @@ require_once('include/bbcode.php'); require_once('include/identity.php'); require_once('include/Contact.php'); -function notifier_run($argv, $argc){ +function notifier_run($argc,$argv){ cli_startup(); @@ -659,6 +659,6 @@ function notifier_run($argv, $argc){ if (array_search(__file__,get_included_files())===0){ - notifier_run($argv,$argc); + notifier_run($argc,$argv); killme(); } diff --git a/include/onedirsync.php b/include/onedirsync.php index ce516da9d..d794fe35e 100644 --- a/include/onedirsync.php +++ b/include/onedirsync.php @@ -6,7 +6,7 @@ require_once('include/zot.php'); require_once('include/dir_fns.php'); -function onedirsync_run($argv, $argc){ +function onedirsync_run($argc,$argv){ cli_startup(); @@ -77,6 +77,6 @@ function onedirsync_run($argv, $argc){ } if (array_search(__file__,get_included_files())===0){ - onedirsync_run($argv,$argc); + onedirsync_run($argc,$argv); killme(); } diff --git a/include/onepoll.php b/include/onepoll.php index fedeb1e95..bfd79feea 100644 --- a/include/onepoll.php +++ b/include/onepoll.php @@ -7,7 +7,7 @@ require_once('include/socgraph.php'); require_once('include/Contact.php'); -function onepoll_run($argv, $argc){ +function onepoll_run($argc,$argv){ cli_startup(); @@ -154,6 +154,6 @@ function onepoll_run($argv, $argc){ } if (array_search(__file__,get_included_files())===0){ - onepoll_run($argv,$argc); + onepoll_run($argc,$argv); killme(); } diff --git a/include/poller.php b/include/poller.php index 808b54ee5..1a5b8508c 100644 --- a/include/poller.php +++ b/include/poller.php @@ -4,7 +4,7 @@ require_once('boot.php'); require_once('include/cli_startup.php'); -function poller_run($argv, $argc){ +function poller_run($argc,$argv){ cli_startup(); @@ -440,6 +440,6 @@ function poller_run($argv, $argc){ } if (array_search(__file__,get_included_files())===0){ - poller_run($argv,$argc); + poller_run($argc,$argv); killme(); } diff --git a/include/queue.php b/include/queue.php index 8a3b2aa58..1159e01a0 100644 --- a/include/queue.php +++ b/include/queue.php @@ -4,7 +4,7 @@ require_once('include/cli_startup.php'); require_once('include/queue_fn.php'); require_once('include/zot.php'); -function queue_run($argv, $argc){ +function queue_run($argc,$argv){ cli_startup(); @@ -90,6 +90,6 @@ function queue_run($argv, $argc){ } if (array_search(__file__,get_included_files())===0){ - queue_run($argv,$argc); + queue_run($argc,$argv); killme(); } diff --git a/include/ratenotif.php b/include/ratenotif.php index 2c636c710..3a5e515ae 100644 --- a/include/ratenotif.php +++ b/include/ratenotif.php @@ -5,7 +5,7 @@ require_once('include/zot.php'); require_once('include/queue_fn.php'); -function ratenotif_run($argv, $argc){ +function ratenotif_run($argc,$argv){ cli_startup(); @@ -114,6 +114,6 @@ function ratenotif_run($argv, $argc){ } if (array_search(__file__,get_included_files())===0){ - ratenotif_run($argv,$argc); + ratenotif_run($argc,$argv); killme(); } -- cgit v1.2.3 From 16f79b70e4e3fd572de4d3fc938802fa8c536bca Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 17 May 2016 22:32:49 -0700 Subject: experimental PDO DBA driver --- include/dba/dba_driver.php | 15 ++++++-- include/dba/dba_pdo.php | 95 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 4 deletions(-) create mode 100755 include/dba/dba_pdo.php (limited to 'include') diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php index 4a1752672..498bfffa7 100755 --- a/include/dba/dba_driver.php +++ b/include/dba/dba_driver.php @@ -32,16 +32,23 @@ function dba_factory($server, $port,$user,$pass,$db,$dbtype,$install = false) { if(is_null($port)) $set_port = 5432; $dba = new dba_postgres($server, $set_port, $user, $pass, $db, $install); } else { +// require_once('include/dba/dba_pdo.php'); +// $dba = new dba_pdo($server, $set_port,$user,$pass,$db,$install); +// } + if(class_exists('mysqli')) { if (is_null($port)) $set_port = ini_get("mysqli.default_port"); require_once('include/dba/dba_mysqli.php'); $dba = new dba_mysqli($server, $set_port,$user,$pass,$db,$install); - } else { - if (is_null($port)) $set_port = "3306"; - require_once('include/dba/dba_mysql.php'); - $dba = new dba_mysql($server, $set_port,$user,$pass,$db,$install); } } + +// else { +// if (is_null($port)) $set_port = "3306"; +// require_once('include/dba/dba_mysql.php'); +// $dba = new dba_mysql($server, $set_port,$user,$pass,$db,$install); +// } +// } if(is_object($dba) && $dba->connected) { $dns = (($dbtype == DBTYPE_POSTGRES) ? 'postgres' : 'mysql') diff --git a/include/dba/dba_pdo.php b/include/dba/dba_pdo.php new file mode 100755 index 000000000..7255a2b66 --- /dev/null +++ b/include/dba/dba_pdo.php @@ -0,0 +1,95 @@ +driver_dbtype = 'mysql'; // (($dbtype == DBTYPE_POSTGRES) ? 'postgres' : 'mysql'); + $dns = $this->driver_dbtype + . ':host=' . $server . (is_null($port) ? '' : ';port=' . $port) + . ';dbname=' . $db; + + + try { + $this->db = new PDO($dns,$user,$pass); + $this->db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); + } + catch(PDOException $e) { + if(file_exists('dbfail.out')) { + file_put_contents('dbfail.out', datetime_convert() . "\nConnect: " . $e->getMessage() . "\n", FILE_APPEND); + } + + return false; + } + + $this->connected = true; + return true; + + } + + function q($sql) { + if((! $this->db) || (! $this->connected)) + return false; + + $this->error = ''; + $select = ((stripos($sql,'select') === 0) ? true : false); + + try { + $result = $this->db->query($sql); + } + catch(PDOException $e) { + + $this->error = $e->getMessage(); + if($this->error) { + db_logger('dba_mysqli: ERROR: ' . printable($sql) . "\n" . $this->error, LOGGER_NORMAL, LOG_ERR); + if(file_exists('dbfail.out')) { + file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . "\n" . $this->error . "\n", FILE_APPEND); + } + } + } + + if(!($select)) { + if($this->debug) { + db_logger('dba_mysqli: DEBUG: ' . printable($sql) . ' returns ' . (($result) ? 'true' : 'false'), LOGGER_NORMAL,(($result) ? LOG_INFO : LOG_ERR)); + } + return $result; + } + + if($this->debug) { + db_logger('dba_mysqli: DEBUG: ' . printable($sql) . ' returned ' . count($result) . ' results.', LOGGER_NORMAL, LOG_INFO); + } + + $r = array(); + if($result) { + foreach($result as $x) { + $r[] = $x; + } + if($this->debug) { + db_logger('dba_pdo: ' . printable(print_r($r,true)), LOGGER_NORMAL, LOG_INFO); + } + } + return $r; + } + + function escape($str) { + if($this->db && $this->connected) { + return substr(substr(@$this->db->quote($str),1),0,-1); + } + } + + function close() { + if($this->db) + $this->db = null; + $this->connected = false; + } + + function getdriver() { + return 'pdo'; + } + +} \ No newline at end of file -- cgit v1.2.3 From c77732b8edfbfa49cd52df4c2ac3b27a55d2ee02 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 18 May 2016 21:23:24 +0200 Subject: only show $showall_origin if permission_role is custom. it does not make much sense otherwise since the member is merely using a preset of permissions. --- include/acl_selectors.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/acl_selectors.php b/include/acl_selectors.php index 136f8aa50..6b727c9a2 100644 --- a/include/acl_selectors.php +++ b/include/acl_selectors.php @@ -230,14 +230,14 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti $allow_cid = $allow_gid = $deny_cid = $deny_gid = false; $showall_origin = ''; $showall_icon = 'fa-globe'; - + $role = get_pconfig(local_channel(),'system','permissions_role'); if(! $emptyACL_description) { $showall_caption = t('Visible to your default audience'); } else if (is_a($emptyACL_description, 'PermissionDescription')) { $showall_caption = $emptyACL_description->get_permission_description(); - $showall_origin = $emptyACL_description->get_permission_origin_description(); + $showall_origin = (($role === 'custom') ? $emptyACL_description->get_permission_origin_description() : ''); $showall_icon = $emptyACL_description->get_permission_icon(); } else { @@ -271,7 +271,7 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti '$showall' => $showall_caption, '$showallOrigin' => $showall_origin, '$showallIcon' => $showall_icon, - '$select_label' => t('Who can see this'), + '$select_label' => t('Who can see this?'), '$showlimited' => t('Custom selection'), '$showlimitedDesc' => t('Select "Show" to allow viewing. "Don\'t show" lets you override and limit the scope of "Show".'), '$show' => t("Show"), -- cgit v1.2.3 From d38851023ec5bac78ece9469c758851e97e01285 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 18 May 2016 16:28:51 -0700 Subject: provide server role on pubsites page --- include/zot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/zot.php b/include/zot.php index 8adc74ffa..5400bd96e 100644 --- a/include/zot.php +++ b/include/zot.php @@ -3944,7 +3944,7 @@ function zotinfo($arr) { $ret['site']['sellpage'] = get_config('system','sellpage'); $ret['site']['location'] = get_config('system','site_location'); $ret['site']['realm'] = get_directory_realm(); - $ret['site']['project'] = Zotlabs\Project\System::get_platform_name(); + $ret['site']['project'] = Zotlabs\Project\System::get_platform_name() . Zotlabs\Project\System::get_server_role(); } -- cgit v1.2.3 From 3355210878c6af1d4ee1719d223e83dd9e086ddc Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 18 May 2016 22:03:43 -0700 Subject: explain what we're doing and where we're going with this. --- include/dba/dba_driver.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php index 498bfffa7..e15e107a8 100755 --- a/include/dba/dba_driver.php +++ b/include/dba/dba_driver.php @@ -32,6 +32,8 @@ function dba_factory($server, $port,$user,$pass,$db,$dbtype,$install = false) { if(is_null($port)) $set_port = 5432; $dba = new dba_postgres($server, $set_port, $user, $pass, $db, $install); } else { + +// Highly experimental at the present time. // require_once('include/dba/dba_pdo.php'); // $dba = new dba_pdo($server, $set_port,$user,$pass,$db,$install); // } @@ -42,13 +44,12 @@ function dba_factory($server, $port,$user,$pass,$db,$dbtype,$install = false) { $dba = new dba_mysqli($server, $set_port,$user,$pass,$db,$install); } } + + // Until we have a proper PDO driver, store the DB connection parameters for + // plugins/addons which use PDO natively (such as cdav). This is wasteful as + // it opens a separate connection to the DB, but saves a lot of effort re-writing + // third-party interfaces that are working and well tested. -// else { -// if (is_null($port)) $set_port = "3306"; -// require_once('include/dba/dba_mysql.php'); -// $dba = new dba_mysql($server, $set_port,$user,$pass,$db,$install); -// } -// } if(is_object($dba) && $dba->connected) { $dns = (($dbtype == DBTYPE_POSTGRES) ? 'postgres' : 'mysql') -- cgit v1.2.3 From 6b69184554d2e24f539d9841a9cb2d851f9aa5a7 Mon Sep 17 00:00:00 2001 From: Treer Date: Thu, 19 May 2016 22:37:21 +1000 Subject: fix permission string --- include/PermissionDescription.php | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/PermissionDescription.php b/include/PermissionDescription.php index 75dd9ecf7..1f7799406 100644 --- a/include/PermissionDescription.php +++ b/include/PermissionDescription.php @@ -117,11 +117,7 @@ class PermissionDescription { case PERMS_NETWORK: return t('Anybody in the $Projectname network'); case PERMS_SITE: return sprintf(t('Any account on %s'), \App::get_hostname()); case PERMS_CONTACTS: return t('Any of my connections'); - case PERMS_SPECIFIC: - // Because we're describing the permissions of an item with an empty ACL, - // the owner will be the only person able to see it if the permissions are - // set to "only specified connections". - return t('Only me (only specified contacts and me)'); + case PERMS_SPECIFIC: return t('Only connections I specifically allow'); case PERMS_AUTHED: return t('Anybody authenticated (could include visitors from other networks)'); case PERMS_PENDING: return t('Any connections including those who haven\'t yet been approved'); default: return $this->fallback_description; @@ -143,11 +139,7 @@ class PermissionDescription { case PERMS_NETWORK: return 'fa-share-alt-square'; // fa-share-alt-square is very similiar to the hubzilla logo, but we should create our own logo class to use case PERMS_SITE: return 'fa-sitemap'; case PERMS_CONTACTS: return 'fa-group'; - case PERMS_SPECIFIC: - // Because we're describing the permissions of an item with an empty ACL, - // the owner will be the only person able to see it if the permissions are - // set to "only specified connections". - return 'fa-eye-slash'; + case PERMS_SPECIFIC: return 'fa-list'; case PERMS_AUTHED: return ''; case PERMS_PENDING: return ''; default: return ''; -- cgit v1.2.3 From 0f5eb6521010b6cd41b07b1f4a1dea2c40d4ebae Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 19 May 2016 23:35:19 +0200 Subject: provide an acl select option for only me --- include/acl_selectors.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/acl_selectors.php b/include/acl_selectors.php index 6b727c9a2..82f419aea 100644 --- a/include/acl_selectors.php +++ b/include/acl_selectors.php @@ -269,6 +269,8 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti $tpl = get_markup_template("acl_selector.tpl"); $o = replace_macros($tpl, array( '$showall' => $showall_caption, + '$onlyme' => t('Only me'), + '$add_others' => t('Add others'), '$showallOrigin' => $showall_origin, '$showallIcon' => $showall_icon, '$select_label' => t('Who can see this?'), -- cgit v1.2.3 From 1f2bd00d93854a23b986a02664c4f11eddf27064 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Thu, 19 May 2016 23:39:05 +0200 Subject: whitespace --- include/acl_selectors.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/acl_selectors.php b/include/acl_selectors.php index 82f419aea..886574714 100644 --- a/include/acl_selectors.php +++ b/include/acl_selectors.php @@ -270,7 +270,7 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti $o = replace_macros($tpl, array( '$showall' => $showall_caption, '$onlyme' => t('Only me'), - '$add_others' => t('Add others'), + '$add_others' => t('Add others'), '$showallOrigin' => $showall_origin, '$showallIcon' => $showall_icon, '$select_label' => t('Who can see this?'), -- cgit v1.2.3 From 6e7d7c50174ffe3db78c5318dde0d9b0b1f416b8 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 19 May 2016 16:48:10 -0700 Subject: minor --- include/environment.php | 2 ++ include/gprobe.php | 3 +++ 2 files changed, 5 insertions(+) (limited to 'include') diff --git a/include/environment.php b/include/environment.php index 47ad241a7..11d465b84 100644 --- a/include/environment.php +++ b/include/environment.php @@ -60,6 +60,8 @@ function phpiniSizeToBytes($val) { $val *= 1024; case 'k': $val *= 1024; + default: + break; } return (int)$val; diff --git a/include/gprobe.php b/include/gprobe.php index bd02ac31b..f3daae9d6 100644 --- a/include/gprobe.php +++ b/include/gprobe.php @@ -3,6 +3,9 @@ require_once('include/cli_startup.php'); require_once('include/zot.php'); +// CLI utility +// performs zot_finger on $argv[1], which is a hex_encoded webbie/reddress + function gprobe_run($argc,$argv){ cli_startup(); -- cgit v1.2.3 From 9cb1ac3de5d0f540bc6e1f5b1f4277b5a5bb9e67 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 19 May 2016 20:36:32 -0700 Subject: daemon master: create some compatibility code --- include/poller.php | 431 +---------------------------------------------------- 1 file changed, 1 insertion(+), 430 deletions(-) (limited to 'include') diff --git a/include/poller.php b/include/poller.php index 1a5b8508c..0946d0ece 100644 --- a/include/poller.php +++ b/include/poller.php @@ -1,442 +1,13 @@ $maxsysload) { - logger('system: load ' . $load . ' too high. Poller deferred to next scheduled run.'); - return; - } - } - - $interval = intval(get_config('system','poll_interval')); - if(! $interval) - $interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval'))); - - // Check for a lockfile. If it exists, but is over an hour old, it's stale. Ignore it. - $lockfile = 'store/[data]/poller'; - if((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600)) - && (! get_config('system','override_poll_lockfile'))) { - logger("poller: Already running"); - return; - } - - // Create a lockfile. Needs two vars, but $x doesn't need to contain anything. - file_put_contents($lockfile, $x); - - logger('poller: start'); - - // run queue delivery process in the background - - proc_run('php',"include/queue.php"); - - - // maintenance for mod sharedwithme - check for updated items and remove them - - require_once('include/sharedwithme.php'); - apply_updates(); - - - // expire any expired mail - - q("delete from mail where expires != '%s' and expires < %s ", - dbesc(NULL_DATE), - db_utcnow() - ); - - // expire any expired items - - $r = q("select id from item where expires != '%s' and expires < %s - and item_deleted = 0 ", - dbesc(NULL_DATE), - db_utcnow() - ); - if($r) { - require_once('include/items.php'); - foreach($r as $rr) - drop_item($rr['id'],false); - } - - - // Ensure that every channel pings a directory server once a month. This way we can discover - // channels and sites that quietly vanished and prevent the directory from accumulating stale - // or dead entries. - - $r = q("select channel_id from channel where channel_dirdate < %s - INTERVAL %s", - db_utcnow(), - db_quoteinterval('30 DAY') - ); - if($r) { - foreach($r as $rr) { - proc_run('php','include/directory.php',$rr['channel_id'],'force'); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - } - } - - // publish any applicable items that were set to be published in the future - // (time travel posts). Restrict to items that have come of age in the last - // couple of days to limit the query to something reasonable. - - $r = q("select id from item where item_delayed = 1 and created <= %s and created > '%s' ", - db_utcnow(), - dbesc(datetime_convert('UTC','UTC','now - 2 days')) - ); - if($r) { - foreach($r as $rr) { - $x = q("update item set item_delayed = 0 where id = %d", - intval($rr['id']) - ); - if($x) { - proc_run('php','include/notifier.php','wall-new',$rr['id']); - } - } - } - - $abandon_days = intval(get_config('system','account_abandon_days')); - if($abandon_days < 1) - $abandon_days = 0; - - - // once daily run birthday_updates and then expire in background - - // FIXME: add birthday updates, both locally and for xprof for use - // by directory servers - - $d1 = intval(get_config('system','last_expire_day')); - $d2 = intval(datetime_convert('UTC','UTC','now','d')); - - // Allow somebody to staggger daily activities if they have more than one site on their server, - // or if it happens at an inconvenient (busy) hour. - - $h1 = intval(get_config('system','cron_hour')); - $h2 = intval(datetime_convert('UTC','UTC','now','G')); - - $dirmode = get_config('system','directory_mode'); - - /** - * Cron Daily - * - * Actions in the following block are executed once per day, not on every poller run - * - */ - - if(($d2 != $d1) && ($h1 == $h2)) { - - require_once('include/dir_fns.php'); - check_upstream_directory(); - - call_hooks('cron_daily',datetime_convert()); - - - $d3 = intval(datetime_convert('UTC','UTC','now','N')); - if($d3 == 7) { - - /** - * Cron Weekly - * - * Actions in the following block are executed once per day only on Sunday (once per week). - * - */ - - - call_hooks('cron_weekly',datetime_convert()); - - - z_check_cert(); - - require_once('include/hubloc.php'); - prune_hub_reinstalls(); - - require_once('include/Contact.php'); - mark_orphan_hubsxchans(); - - - // get rid of really old poco records - - q("delete from xlink where xlink_updated < %s - INTERVAL %s and xlink_static = 0 ", - db_utcnow(), db_quoteinterval('14 DAY') - ); - - $dirmode = intval(get_config('system','directory_mode')); - if($dirmode === DIRECTORY_MODE_SECONDARY || $dirmode === DIRECTORY_MODE_PRIMARY) { - logger('regdir: ' . print_r(z_fetch_url(get_directory_primary() . '/regdir?f=&url=' . urlencode(z_root()) . '&realm=' . urlencode(get_directory_realm())),true)); - } - - // Check for dead sites - proc_run('php', 'include/checksites.php'); - - // update searchable doc indexes - proc_run('php', 'include/importdoc.php'); - - /** - * End Cron Weekly - */ - } - - update_birthdays(); - - //update statistics in config - require_once('include/statistics_fns.php'); - update_channels_total_stat(); - update_channels_active_halfyear_stat(); - update_channels_active_monthly_stat(); - update_local_posts_stat(); - - // expire any read notifications over a month old - - q("delete from notify where seen = 1 and date < %s - INTERVAL %s", - db_utcnow(), db_quoteinterval('30 DAY') - ); - - // expire old delivery reports - - $keep_reports = intval(get_config('system','expire_delivery_reports')); - if($keep_reports === 0) - $keep_reports = 10; - - q("delete from dreport where dreport_time < %s - INTERVAL %s", - db_utcnow(), - db_quoteinterval($keep_reports . ' DAY') - ); - - // expire any expired accounts - downgrade_accounts(); - - // If this is a directory server, request a sync with an upstream - // directory at least once a day, up to once every poll interval. - // Pull remote changes and push local changes. - // potential issue: how do we keep from creating an endless update loop? - - if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) { - require_once('include/dir_fns.php'); - sync_directories($dirmode); - } - - set_config('system','last_expire_day',$d2); - - proc_run('php','include/expire.php'); - proc_run('php','include/cli_suggest.php'); - - require_once('include/hubloc.php'); - remove_obsolete_hublocs(); - - /** - * End Cron Daily - */ - } - - // update any photos which didn't get imported properly - // This should be rare - - $r = q("select xchan_photo_l, xchan_hash from xchan where xchan_photo_l != '' and xchan_photo_m = '' - and xchan_photo_date < %s - INTERVAL %s", - db_utcnow(), - db_quoteinterval('1 DAY') - ); - if($r) { - require_once('include/photo/photo_driver.php'); - foreach($r as $rr) { - $photos = import_xchan_photo($rr['xchan_photo_l'],$rr['xchan_hash']); - $x = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' - where xchan_hash = '%s'", - dbesc($photos[0]), - dbesc($photos[1]), - dbesc($photos[2]), - dbesc($photos[3]), - dbesc($rr['xchan_hash']) - ); - } - } - - - // pull in some public posts - - if(! get_config('system','disable_discover_tab')) - proc_run('php','include/externals.php'); - - - $manual_id = 0; - $generation = 0; - - $force = false; - $restart = false; - - if(($argc > 1) && ($argv[1] == 'force')) - $force = true; - - if(($argc > 1) && ($argv[1] == 'restart')) { - $restart = true; - $generation = intval($argv[2]); - if(! $generation) - killme(); - } - - if(($argc > 1) && intval($argv[1])) { - $manual_id = intval($argv[1]); - $force = true; - } - - - $sql_extra = (($manual_id) ? " AND abook_id = " . intval($manual_id) . " " : ""); - - reload_plugins(); - - $d = datetime_convert(); - - // TODO check to see if there are any cronhooks before wasting a process - - if(! $restart) - proc_run('php','include/cronhooks.php'); - - // Only poll from those with suitable relationships - - $abandon_sql = (($abandon_days) - ? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days).' DAY')) - : '' - ); - - $randfunc = db_getfunc('RAND'); - - $contacts = q("SELECT * FROM abook LEFT JOIN xchan on abook_xchan = xchan_hash - LEFT JOIN account on abook_account = account_id - where abook_self = 0 - $sql_extra - AND (( account_flags = %d ) OR ( account_flags = %d )) $abandon_sql ORDER BY $randfunc", - intval(ACCOUNT_OK), - intval(ACCOUNT_UNVERIFIED) // FIXME - - ); - - if($contacts) { - - foreach($contacts as $contact) { - - $update = false; - - $t = $contact['abook_updated']; - $c = $contact['abook_connected']; - - if(intval($contact['abook_feed'])) { - $min = service_class_fetch($contact['abook_channel'],'minimum_feedcheck_minutes'); - if(! $min) - $min = intval(get_config('system','minimum_feedcheck_minutes')); - if(! $min) - $min = 60; - $x = datetime_convert('UTC','UTC',"now - $min minutes"); - if($c < $x) { - proc_run('php','include/onepoll.php',$contact['abook_id']); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - } - continue; - } - - - if($contact['xchan_network'] !== 'zot') - continue; - - if($c == $t) { - if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) - $update = true; - } - else { - - // if we've never connected with them, start the mark for death countdown from now - - if($c == NULL_DATE) { - $r = q("update abook set abook_connected = '%s' where abook_id = %d", - dbesc(datetime_convert()), - intval($contact['abook_id']) - ); - $c = datetime_convert(); - $update = true; - } - - // He's dead, Jim - - if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 30 day")) > 0) { - $r = q("update abook set abook_archived = 1 where abook_id = %d", - intval($contact['abook_id']) - ); - $update = false; - continue; - } - - if(intval($contact['abook_archived'])) { - $update = false; - continue; - } - - // might be dead, so maybe don't poll quite so often - - // recently deceased, so keep up the regular schedule for 3 days - - if((strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 3 day")) > 0) - && (strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 1 day")) > 0)) - $update = true; - - // After that back off and put them on a morphine drip - - if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 2 day")) > 0) { - $update = true; - } - - } - - if(intval($contact['abook_pending']) || intval($contact['abook_archived']) || intval($contact['abook_ignored']) || intval($contact['abook_blocked'])) - continue; - - if((! $update) && (! $force)) - continue; - - proc_run('php','include/onepoll.php',$contact['abook_id']); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - - } - } - - if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) { - $r = q("SELECT u.ud_addr, u.ud_id, u.ud_last FROM updates AS u INNER JOIN (SELECT ud_addr, max(ud_id) AS ud_id FROM updates WHERE ( ud_flags & %d ) = 0 AND ud_addr != '' AND ( ud_last = '%s' OR ud_last > %s - INTERVAL %s ) GROUP BY ud_addr) AS s ON s.ud_id = u.ud_id ", - intval(UPDATE_FLAGS_UPDATED), - dbesc(NULL_DATE), - db_utcnow(), db_quoteinterval('7 DAY') - ); - if($r) { - foreach($r as $rr) { - - // If they didn't respond when we attempted before, back off to once a day - // After 7 days we won't bother anymore - - if($rr['ud_last'] != NULL_DATE) - if($rr['ud_last'] > datetime_convert('UTC','UTC', 'now - 1 day')) - continue; - proc_run('php','include/onedirsync.php',$rr['ud_id']); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - } - } - } - - set_config('system','lastpoll',datetime_convert()); - - //All done - clear the lockfile - @unlink($lockfile); + \Zotlabs\Daemon\Master::Summon('Poller'); - return; } if (array_search(__file__,get_included_files())===0){ -- cgit v1.2.3 From 853322e7d2734ad459a4e5740f3f1806ed55532e Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 19 May 2016 20:48:40 -0700 Subject: don't try to deliver empty hashes --- include/network.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/network.php b/include/network.php index f80244f8f..a2e655d92 100644 --- a/include/network.php +++ b/include/network.php @@ -1916,6 +1916,9 @@ function do_delivery($deliveries) { $deliver = array(); foreach($deliveries as $d) { + if(! $d) + continue; + $deliver[] = $d; if(count($deliver) >= $deliveries_per_process) { -- cgit v1.2.3 From 39bc0664a773a97ccce276161739f217e3ba7449 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 19 May 2016 21:22:04 -0700 Subject: Separate cron into periodic components and use that as the main interface for scheduled tasks instead of the quaint 'poller'. --- include/poller.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/poller.php b/include/poller.php index 0946d0ece..67a67de12 100644 --- a/include/poller.php +++ b/include/poller.php @@ -5,8 +5,7 @@ require_once('include/cli_startup.php'); function poller_run($argc,$argv){ cli_startup(); - - \Zotlabs\Daemon\Master::Summon('Poller'); + \Zotlabs\Daemon\Master::Summon('Cron'); } -- cgit v1.2.3 From a2cec8899ad191b47d116f4ea124be6bd5b05472 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 19 May 2016 22:26:37 -0700 Subject: daemon conversion continued... --- include/Contact.php | 5 +- include/activities.php | 2 +- include/attach.php | 4 +- include/checksites.php | 62 ----- include/cli_suggest.php | 19 -- include/cronhooks.php | 23 -- include/deliver.php | 87 ------ include/deliver_hooks.php | 29 -- include/directory.php | 113 -------- include/expire.php | 98 ------- include/externals.php | 103 ------- include/follow.php | 2 +- include/gprobe.php | 41 --- include/hubloc.php | 2 +- include/identity.php | 4 +- include/import.php | 6 +- include/importdoc.php | 41 --- include/items.php | 12 +- include/message.php | 2 +- include/network.php | 4 +- include/notifier.php | 664 ---------------------------------------------- include/onedirsync.php | 82 ------ include/onepoll.php | 159 ----------- include/photos.php | 2 +- include/poller.php | 2 +- include/queue.php | 95 ------- include/ratenotif.php | 119 --------- include/zot.php | 16 +- 28 files changed, 31 insertions(+), 1767 deletions(-) delete mode 100644 include/checksites.php delete mode 100644 include/cli_suggest.php delete mode 100644 include/cronhooks.php delete mode 100644 include/deliver.php delete mode 100644 include/deliver_hooks.php delete mode 100644 include/directory.php delete mode 100644 include/expire.php delete mode 100644 include/externals.php delete mode 100644 include/gprobe.php delete mode 100755 include/importdoc.php delete mode 100644 include/notifier.php delete mode 100644 include/onedirsync.php delete mode 100644 include/onepoll.php delete mode 100644 include/queue.php delete mode 100644 include/ratenotif.php (limited to 'include') diff --git a/include/Contact.php b/include/Contact.php index 8ad67c28e..e50670a89 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -303,8 +303,7 @@ function channel_remove($channel_id, $local = true, $unset_session=false) { dbesc($channel['channel_hash']) ); - proc_run('php','include/notifier.php','purge_all',$channel_id); - + Zotlabs\Daemon\Master::Summon(array('Notifier','purge_all',$channel_id)); } q("DELETE FROM `groups` WHERE `uid` = %d", intval($channel_id)); @@ -386,7 +385,7 @@ function channel_remove($channel_id, $local = true, $unset_session=false) { @rrmdir($f); } - proc_run('php','include/directory.php',$channel_id); + Zotlabs\Daemon\Master::Summon(array('Directory',$channel_id)); if($channel_id == local_channel() && $unset_session) { App::$session->nuke(); diff --git a/include/activities.php b/include/activities.php index 9ba191391..5c1e68720 100644 --- a/include/activities.php +++ b/include/activities.php @@ -89,7 +89,7 @@ function profile_activity($changed, $value) { if($i) { // FIXME - limit delivery in notifier.php to those specificed in the perms argument - proc_run('php',"include/notifier.php","activity","$i", 'PERMS_R_PROFILE'); + Zotlabs\Daemon\Master::Summon(array('Notifier','activity', $i, 'PERMS_R_PROFILE'); } } diff --git a/include/attach.php b/include/attach.php index ae4681994..d9cd30f6d 100644 --- a/include/attach.php +++ b/include/attach.php @@ -1591,7 +1591,7 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid, $post = item_store($arr); $item_id = $post['item_id']; if($item_id) { - proc_run('php',"include/notifier.php","activity",$item_id); + Zotlabs\Daemon\Master::Summon(array('Notifier','activity',$item_id)); } call_hooks('post_local_end', $arr); @@ -1627,7 +1627,7 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid, $item_id = $post['item_id']; if($item_id) { - proc_run('php',"include/notifier.php","activity",$item_id); + Zotlabs\Daemon\Master::Summon(array('Notifier','activity',$item_id)); } call_hooks('post_local_end', $arr); diff --git a/include/checksites.php b/include/checksites.php deleted file mode 100644 index 9d3ca1797..000000000 --- a/include/checksites.php +++ /dev/null @@ -1,62 +0,0 @@ - 1) && ($argv[1])) - $site_id = $argv[1]; - - if($site_id) - $sql_options = " and site_url = '" . dbesc($argv[1]) . "' "; - - $days = intval(get_config('system','sitecheckdays')); - if($days < 1) - $days = 30; - - $r = q("select * from site where site_dead = 0 and site_update < %s - INTERVAL %s and site_type = %d $sql_options ", - db_utcnow(), db_quoteinterval($days . ' DAY'), - intval(SITE_TYPE_ZOT) - ); - - if(! $r) - return; - - foreach($r as $rr) { - if(! strcasecmp($rr['site_url'],z_root())) - continue; - - $x = ping_site($rr['site_url']); - if($x['success']) { - logger('checksites: ' . $rr['site_url']); - q("update site set site_update = '%s' where site_url = '%s' ", - dbesc(datetime_convert()), - dbesc($rr['site_url']) - ); - } - else { - logger('marking dead site: ' . $x['message']); - q("update site set site_dead = 1 where site_url = '%s' ", - dbesc($rr['site_url']) - ); - } - } - - return; -} - -if (array_search(__file__,get_included_files())===0){ - checksites_run($argc,$argv); - killme(); -} diff --git a/include/cli_suggest.php b/include/cli_suggest.php deleted file mode 100644 index 94b65f8ee..000000000 --- a/include/cli_suggest.php +++ /dev/null @@ -1,19 +0,0 @@ - json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify,'message' => $mm))))); - zot_import($msg,z_root()); - } - } - else { - $msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify,'message' => $m))))); - $dresult = zot_import($msg,z_root()); - } - - remove_queue_item($r[0]['outq_hash']); - - if($dresult && is_array($dresult)) { - foreach($dresult as $xx) { - if(is_array($xx) && array_key_exists('message_id',$xx)) { - if(delivery_report_is_storable($xx)) { - q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s','%s','%s','%s','%s' ) ", - dbesc($xx['message_id']), - dbesc($xx['location']), - dbesc($xx['recipient']), - dbesc($xx['status']), - dbesc(datetime_convert($xx['date'])), - dbesc($xx['sender']) - ); - } - } - } - } - - q("delete from dreport where dreport_queue = '%s'", - dbesc($argv[$x]) - ); - } - } - - // otherwise it's a remote delivery - call queue_deliver() with the $immediate flag - - queue_deliver($r[0],true); - - } - } -} - -if (array_search(__file__,get_included_files())===0){ - deliver_run($argc,$argv); - killme(); -} diff --git a/include/deliver_hooks.php b/include/deliver_hooks.php deleted file mode 100644 index f8f3bb19b..000000000 --- a/include/deliver_hooks.php +++ /dev/null @@ -1,29 +0,0 @@ - 2) { - if($argv[2] === 'force') - $force = true; - if($argv[2] === 'nopush') - $pushall = false; - } - - logger('directory update', LOGGER_DEBUG); - - $dirmode = get_config('system','directory_mode'); - if($dirmode === false) - $dirmode = DIRECTORY_MODE_NORMAL; - - $x = q("select * from channel where channel_id = %d limit 1", - intval($argv[1]) - ); - if(! $x) - return; - - $channel = $x[0]; - - if($dirmode != DIRECTORY_MODE_NORMAL) { - - // this is an in-memory update and we don't need to send a network packet. - - local_dir_update($argv[1],$force); - - q("update channel set channel_dirdate = '%s' where channel_id = %d", - dbesc(datetime_convert()), - intval($channel['channel_id']) - ); - - // Now update all the connections - if($pushall) - proc_run('php','include/notifier.php','refresh_all',$channel['channel_id']); - - return; - } - - // otherwise send the changes upstream - - $directory = find_upstream_directory($dirmode); - $url = $directory['url'] . '/post'; - - // ensure the upstream directory is updated - - $packet = zot_build_packet($channel,(($force) ? 'force_refresh' : 'refresh')); - $z = zot_zot($url,$packet); - - // re-queue if unsuccessful - - if(! $z['success']) { - - /** @FIXME we aren't updating channel_dirdate if we have to queue - * the directory packet. That means we'll try again on the next poll run. - */ - - $hash = random_string(); - - queue_insert(array( - 'hash' => $hash, - 'account_id' => $channel['channel_account_id'], - 'channel_id' => $channel['channel_id'], - 'posturl' => $url, - 'notify' => $packet, - )); - - } - else { - q("update channel set channel_dirdate = '%s' where channel_id = %d", - dbesc(datetime_convert()), - intval($channel['channel_id']) - ); - } - - // Now update all the connections - if($pushall) - proc_run('php','include/notifier.php','refresh_all',$channel['channel_id']); - -} - -if (array_search(__file__, get_included_files()) === 0) { - directory_run($argc,$argv); - killme(); -} diff --git a/include/expire.php b/include/expire.php deleted file mode 100644 index a2468e0f2..000000000 --- a/include/expire.php +++ /dev/null @@ -1,98 +0,0 @@ - ''); - call_hooks('externals_url_select',$arr); - - if($arr['url']) { - $url = $arr['url']; - } - else { - $randfunc = db_getfunc('RAND'); - - // fixme this query does not deal with directory realms. - - $r = q("select site_url, site_pull from site where site_url != '%s' and site_flags != %d and site_type = %d and site_dead = 0 order by $randfunc limit 1", - dbesc(z_root()), - intval(DIRECTORY_MODE_STANDALONE), - intval(SITE_TYPE_ZOT) - ); - if($r) - $url = $r[0]['site_url']; - } - - $blacklisted = false; - - if(! check_siteallowed($url)) { - logger('blacklisted site: ' . $url); - $blacklisted = true; - } - - $attempts ++; - - // make sure we can eventually break out if somebody blacklists all known sites - - if($blacklisted) { - if($attempts > 20) - break; - $attempts --; - continue; - } - - if($url) { - if($r[0]['site_pull'] !== NULL_DATE) - $mindate = urlencode(datetime_convert('','',$r[0]['site_pull'] . ' - 1 day')); - else { - $days = get_config('externals','since_days'); - if($days === false) - $days = 15; - $mindate = urlencode(datetime_convert('','','now - ' . intval($days) . ' days')); - } - - $feedurl = $url . '/zotfeed?f=&mindate=' . $mindate; - - logger('externals: pulling public content from ' . $feedurl, LOGGER_DEBUG); - - $x = z_fetch_url($feedurl); - if(($x) && ($x['success'])) { - - q("update site set site_pull = '%s' where site_url = '%s'", - dbesc(datetime_convert()), - dbesc($url) - ); - - $j = json_decode($x['body'],true); - if($j['success'] && $j['messages']) { - $sys = get_sys_channel(); - foreach($j['messages'] as $message) { - // on these posts, clear any route info. - $message['route'] = ''; - $results = process_delivery(array('hash' => 'undefined'), get_item_elements($message), - array(array('hash' => $sys['xchan_hash'])), false, true); - $total ++; - } - logger('externals: import_public_posts: ' . $total . ' messages imported', LOGGER_DEBUG); - } - } - } - } -} - -if (array_search(__file__,get_included_files())===0){ - externals_run($argc,$argv); - killme(); -} diff --git a/include/follow.php b/include/follow.php index 70e717cfc..e4f7e8557 100644 --- a/include/follow.php +++ b/include/follow.php @@ -269,7 +269,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) if($r) { $result['abook'] = $r[0]; - proc_run('php', 'include/notifier.php', 'permission_create', $result['abook']['abook_id']); + Zotlabs\Daemon\Master::Summon(array('Notifier', 'permission_create', $result['abook']['abook_id'])); } $arr = array('channel_id' => $uid, 'channel' => $channel, 'abook' => $result['abook']); diff --git a/include/gprobe.php b/include/gprobe.php deleted file mode 100644 index f3daae9d6..000000000 --- a/include/gprobe.php +++ /dev/null @@ -1,41 +0,0 @@ - $tmp_str, 'url' => App::$cmd); call_hooks('zid_init',$arr); if(! local_channel()) { diff --git a/include/import.php b/include/import.php index a62ec4ed5..a94c6c1ac 100644 --- a/include/import.php +++ b/include/import.php @@ -574,7 +574,7 @@ function import_items($channel,$items,$sync = false) { if($sync && $item['item_wall']) { // deliver singletons if we have any if($item_result && $item_result['success']) { - proc_run('php','include/notifier.php','single_activity',$item_result['item_id']); + Zotlabs\Daemon\Master::Summon(array('Notifier','single_activity',$item_result['item_id'])); } } continue; @@ -588,7 +588,7 @@ function import_items($channel,$items,$sync = false) { if($sync && $item['item_wall']) { // deliver singletons if we have any if($item_result && $item_result['success']) { - proc_run('php','include/notifier.php','single_activity',$item_result['item_id']); + Zotlabs\Daemon\Master::Summon(array('Notifier','single_activity',$item_result['item_id'])); } } } @@ -936,7 +936,7 @@ function import_mail($channel,$mails,$sync = false) { $m['uid'] = $channel['channel_id']; $mail_id = mail_store($m); if($sync && $mail_id) { - proc_run('php','include/notifier.php','single_mail',$mail_id); + Zotlabs\Daemon\Master::Summon(array('Notifier','single_mail',$mail_id)); } } } diff --git a/include/importdoc.php b/include/importdoc.php deleted file mode 100755 index 7c65037d3..000000000 --- a/include/importdoc.php +++ /dev/null @@ -1,41 +0,0 @@ -= $deliveries_per_process) { - proc_run('php','include/deliver.php',$deliver); + Zotlabs\Daemon\Master::summon(array('Deliver',$deliver)); $deliver = array(); if($interval) @time_sleep_until(microtime(true) + (float) $interval); @@ -1932,7 +1932,7 @@ function do_delivery($deliveries) { // catch any stragglers if($deliver) - proc_run('php','include/deliver.php',$deliver); + Zotlabs\Daemon\Master::summon(array('Deliver',$deliver)); } diff --git a/include/notifier.php b/include/notifier.php deleted file mode 100644 index 780a8798c..000000000 --- a/include/notifier.php +++ /dev/null @@ -1,664 +0,0 @@ - 3) ? $argv[3] : null); - - if(! $item_id) - return; - - $sys = get_sys_channel(); - - $deliveries = array(); - - $dead_hubs = array(); - - $dh = q("select site_url from site where site_dead = 1"); - if($dh) { - foreach($dh as $dead) { - $dead_hubs[] = $dead['site_url']; - } - } - - - $request = false; - $mail = false; - $top_level = false; - $location = false; - $recipients = array(); - $url_recipients = array(); - $normal_mode = true; - $packet_type = 'undefined'; - - if($cmd === 'mail' || $cmd === 'single_mail') { - $normal_mode = false; - $mail = true; - $private = true; - $message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1", - intval($item_id) - ); - if(! $message) { - return; - } - xchan_mail_query($message[0]); - $uid = $message[0]['channel_id']; - $recipients[] = $message[0]['from_xchan']; // include clones - $recipients[] = $message[0]['to_xchan']; - $item = $message[0]; - - $encoded_item = encode_mail($item); - - $s = q("select * from channel where channel_id = %d limit 1", - intval($item['channel_id']) - ); - if($s) - $channel = $s[0]; - - } - elseif($cmd === 'request') { - $channel_id = $item_id; - $xchan = $argv[3]; - $request_message_id = $argv[4]; - - $s = q("select * from channel where channel_id = %d limit 1", - intval($channel_id) - ); - if($s) - $channel = $s[0]; - - $private = true; - $recipients[] = $xchan; - $packet_type = 'request'; - $normal_mode = false; - } - elseif($cmd == 'permission_update' || $cmd == 'permission_create') { - // Get the (single) recipient - $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_self = 0", - intval($item_id) - ); - if($r) { - $uid = $r[0]['abook_channel']; - // Get the sender - $channel = channelx_by_n($uid); - if($channel) { - $perm_update = array('sender' => $channel, 'recipient' => $r[0], 'success' => false, 'deliveries' => ''); - - if($cmd == 'permission_create') - call_hooks('permissions_create',$perm_update); - else - call_hooks('permissions_update',$perm_update); - - if($perm_update['success']) { - if($perm_update['deliveries']) { - $deliveries[] = $perm_update['deliveries']; - do_delivery($deliveries); - } - return; - } - else { - $recipients[] = $r[0]['abook_xchan']; - $private = false; - $packet_type = 'refresh'; - $packet_recips = array(array('guid' => $r[0]['xchan_guid'],'guid_sig' => $r[0]['xchan_guid_sig'],'hash' => $r[0]['xchan_hash'])); - } - } - } - } - elseif($cmd === 'refresh_all') { - logger('notifier: refresh_all: ' . $item_id); - $uid = $item_id; - $channel = channelx_by_n($item_id); - $r = q("select abook_xchan from abook where abook_channel = %d", - intval($item_id) - ); - if($r) { - foreach($r as $rr) { - $recipients[] = $rr['abook_xchan']; - } - } - $private = false; - $packet_type = 'refresh'; - } - elseif($cmd === 'location') { - logger('notifier: location: ' . $item_id); - $s = q("select * from channel where channel_id = %d limit 1", - intval($item_id) - ); - if($s) - $channel = $s[0]; - $uid = $item_id; - $recipients = array(); - $r = q("select abook_xchan from abook where abook_channel = %d", - intval($item_id) - ); - if($r) { - foreach($r as $rr) { - $recipients[] = $rr['abook_xchan']; - } - } - - $encoded_item = array('locations' => zot_encode_locations($channel),'type' => 'location', 'encoding' => 'zot'); - $target_item = array('aid' => $channel['channel_account_id'],'uid' => $channel['channel_id']); - $private = false; - $packet_type = 'location'; - $location = true; - } - elseif($cmd === 'purge_all') { - logger('notifier: purge_all: ' . $item_id); - $s = q("select * from channel where channel_id = %d limit 1", - intval($item_id) - ); - if($s) - $channel = $s[0]; - $uid = $item_id; - $recipients = array(); - $r = q("select abook_xchan from abook where abook_channel = %d", - intval($item_id) - ); - if($r) { - foreach($r as $rr) { - $recipients[] = $rr['abook_xchan']; - } - } - $private = false; - $packet_type = 'purge'; - } - else { - - // Normal items - - // Fetch the target item - - $r = q("SELECT * FROM item WHERE id = %d and parent != 0 LIMIT 1", - intval($item_id) - ); - - if(! $r) - return; - - xchan_query($r); - - $r = fetch_post_tags($r); - - $target_item = $r[0]; - $deleted_item = false; - - if(intval($target_item['item_deleted'])) { - logger('notifier: target item ITEM_DELETED', LOGGER_DEBUG); - $deleted_item = true; - } - - if(intval($target_item['item_type']) != ITEM_TYPE_POST) { - logger('notifier: target item not forwardable: type ' . $target_item['item_type'], LOGGER_DEBUG); - return; - } - if(intval($target_item['item_unpublished']) || intval($target_item['item_delayed']) || intval($target_item['item_hidden'])) { - logger('notifier: target item not published, so not forwardable', LOGGER_DEBUG); - return; - } - - if(strpos($target_item['postopts'],'nodeliver') !== false) { - logger('notifier: target item is undeliverable', LOGGER_DEBUG); - return; - } - - $s = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", - intval($target_item['uid']) - ); - if($s) - $channel = $s[0]; - - if($channel['channel_hash'] !== $target_item['author_xchan'] && $channel['channel_hash'] !== $target_item['owner_xchan']) { - logger("notifier: Sending channel {$channel['channel_hash']} is not owner {$target_item['owner_xchan']} or author {$target_item['author_xchan']}", LOGGER_NORMAL, LOG_WARNING); - return; - } - - - if($target_item['id'] == $target_item['parent']) { - $parent_item = $target_item; - $top_level_post = true; - } - else { - // fetch the parent item - $r = q("SELECT * from item where id = %d order by id asc", - intval($target_item['parent']) - ); - - if(! $r) - return; - - if(strpos($r[0]['postopts'],'nodeliver') !== false) { - logger('notifier: target item is undeliverable', LOGGER_DEBUG, LOG_NOTICE); - return; - } - - xchan_query($r); - $r = fetch_post_tags($r); - - $parent_item = $r[0]; - $top_level_post = false; - } - - // avoid looping of discover items 12/4/2014 - - if($sys && $parent_item['uid'] == $sys['channel_id']) - return; - - $encoded_item = encode_item($target_item); - - // Send comments to the owner to re-deliver to everybody in the conversation - // We only do this if the item in question originated on this site. This prevents looping. - // To clarify, a site accepting a new comment is responsible for sending it to the owner for relay. - // Relaying should never be initiated on a post that arrived from elsewhere. - - // We should normally be able to rely on ITEM_ORIGIN, but start_delivery_chain() incorrectly set this - // flag on comments for an extended period. So we'll also call comment_local_origin() which looks at - // the hostname in the message_id and provides a second (fallback) opinion. - - $relay_to_owner = (((! $top_level_post) && (intval($target_item['item_origin'])) && comment_local_origin($target_item)) ? true : false); - - - - $uplink = false; - - // $cmd === 'relay' indicates the owner is sending it to the original recipients - // don't allow the item in the relay command to relay to owner under any circumstances, it will loop - - logger('notifier: relay_to_owner: ' . (($relay_to_owner) ? 'true' : 'false'), LOGGER_DATA, LOG_DEBUG); - logger('notifier: top_level_post: ' . (($top_level_post) ? 'true' : 'false'), LOGGER_DATA, LOG_DEBUG); - - // tag_deliver'd post which needs to be sent back to the original author - - if(($cmd === 'uplink') && intval($parent_item['item_uplink']) && (! $top_level_post)) { - logger('notifier: uplink'); - $uplink = true; - } - - if(($relay_to_owner || $uplink) && ($cmd !== 'relay')) { - logger('notifier: followup relay', LOGGER_DEBUG); - $recipients = array(($uplink) ? $parent_item['source_xchan'] : $parent_item['owner_xchan']); - $private = true; - if(! $encoded_item['flags']) - $encoded_item['flags'] = array(); - $encoded_item['flags'][] = 'relay'; - } - else { - logger('notifier: normal distribution', LOGGER_DEBUG); - if($cmd === 'relay') - logger('notifier: owner relay'); - - // if our parent is a tag_delivery recipient, uplink to the original author causing - // a delivery fork. - - if(($parent_item) && intval($parent_item['item_uplink']) && (! $top_level_post) && ($cmd !== 'uplink')) { - // don't uplink a relayed post to the relay owner - if($parent_item['source_xchan'] !== $parent_item['owner_xchan']) { - logger('notifier: uplinking this item'); - proc_run('php','include/notifier.php','uplink',$item_id); - } - } - - $private = false; - $recipients = collect_recipients($parent_item,$private); - - // FIXME add any additional recipients such as mentions, etc. - - // don't send deletions onward for other people's stuff - // TODO verify this is needed - copied logic from same place in old code - - if(intval($target_item['item_deleted']) && (! intval($target_item['item_wall']))) { - logger('notifier: ignoring delete notification for non-wall item', LOGGER_NORMAL, LOG_NOTICE); - return; - } - } - - } - - $walltowall = (($top_level_post && $channel['xchan_hash'] === $target_item['author_xchan']) ? true : false); - - // Generic delivery section, we have an encoded item and recipients - // Now start the delivery process - - $x = $encoded_item; - $x['title'] = 'private'; - $x['body'] = 'private'; - logger('notifier: encoded item: ' . print_r($x,true), LOGGER_DATA, LOG_DEBUG); - - stringify_array_elms($recipients); - if(! $recipients) - return; - -// logger('notifier: recipients: ' . print_r($recipients,true), LOGGER_NORMAL, LOG_DEBUG); - - $env_recips = (($private) ? array() : null); - - $details = q("select xchan_hash, xchan_instance_url, xchan_network, xchan_addr, xchan_guid, xchan_guid_sig from xchan where xchan_hash in (" . implode(',',$recipients) . ")"); - - - $recip_list = array(); - - if($details) { - foreach($details as $d) { - - $recip_list[] = $d['xchan_addr'] . ' (' . $d['xchan_hash'] . ')'; - if($private) - $env_recips[] = array('guid' => $d['xchan_guid'],'guid_sig' => $d['xchan_guid_sig'],'hash' => $d['xchan_hash']); - - if($d['xchan_network'] === 'mail' && $normal_mode) { - $delivery_options = get_xconfig($d['xchan_hash'],'system','delivery_mode'); - if(! $delivery_options) - format_and_send_email($channel,$d,$target_item); - } - } - } - - - $narr = array( - 'channel' => $channel, - 'env_recips' => $env_recips, - 'packet_recips' => $packet_recips, - 'recipients' => $recipients, - 'item' => $item, - 'target_item' => $target_item, - 'top_level_post' => $top_level_post, - 'private' => $private, - 'relay_to_owner' => $relay_to_owner, - 'uplink' => $uplink, - 'cmd' => $cmd, - 'mail' => $mail, - 'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false), - 'location' => $location, - 'request' => $request, - 'normal_mode' => $normal_mode, - 'packet_type' => $packet_type, - 'walltowall' => $walltowall, - 'queued' => array() - ); - - call_hooks('notifier_process', $narr); - if($narr['queued']) { - foreach($narr['queued'] as $pq) - $deliveries[] = $pq; - } - - // notifier_process can alter the recipient list - - $recipients = $narr['recipients']; - $env_recips = $narr['env_recips']; - $packet_recips = $narr['packet_recips']; - - if(($private) && (! $env_recips)) { - // shouldn't happen - logger('notifier: private message with no envelope recipients.' . print_r($argv,true), LOGGER_NORMAL, LOG_NOTICE); - } - - logger('notifier: recipients (may be delivered to more if public): ' . print_r($recip_list,true), LOGGER_DEBUG); - - - // Now we have collected recipients (except for external mentions, FIXME) - // Let's reduce this to a set of hubs. - - $r = q("select * from hubloc where hubloc_hash in (" . implode(',',$recipients) . ") - and hubloc_error = 0 and hubloc_deleted = 0" - ); - - - if(! $r) { - logger('notifier: no hubs', LOGGER_NORMAL, LOG_NOTICE); - return; - } - - $hubs = $r; - - - - /** - * Reduce the hubs to those that are unique. For zot hubs, we need to verify uniqueness by the sitekey, since it may have been - * a re-install which has not yet been detected and pruned. - * For other networks which don't have or require sitekeys, we'll have to use the URL - */ - - - $hublist = array(); // this provides an easily printable list for the logs - $dhubs = array(); // delivery hubs where we store our resulting unique array - $keys = array(); // array of keys to check uniquness for zot hubs - $urls = array(); // array of urls to check uniqueness of hubs from other networks - - - foreach($hubs as $hub) { - if(in_array($hub['hubloc_url'],$dead_hubs)) { - logger('skipping dead hub: ' . $hub['hubloc_url'], LOGGER_DEBUG, LOG_INFO); - continue; - } - - if($hub['hubloc_network'] == 'zot') { - if(! in_array($hub['hubloc_sitekey'],$keys)) { - $hublist[] = $hub['hubloc_host']; - $dhubs[] = $hub; - $keys[] = $hub['hubloc_sitekey']; - } - } - else { - if(! in_array($hub['hubloc_url'],$urls)) { - $hublist[] = $hub['hubloc_host']; - $dhubs[] = $hub; - $urls[] = $hub['hubloc_url']; - } - } - } - - logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist,true), LOGGER_DEBUG, LOG_DEBUG); - - - foreach($dhubs as $hub) { - - if($hub['hubloc_network'] !== 'zot') { - - $narr = array( - 'channel' => $channel, - 'env_recips' => $env_recips, - 'packet_recips' => $packet_recips, - 'recipients' => $recipients, - 'item' => $item, - 'target_item' => $target_item, - 'hub' => $hub, - 'top_level_post' => $top_level_post, - 'private' => $private, - 'relay_to_owner' => $relay_to_owner, - 'uplink' => $uplink, - 'cmd' => $cmd, - 'mail' => $mail, - 'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false), - 'location' => $location, - 'request' => $request, - 'normal_mode' => $normal_mode, - 'packet_type' => $packet_type, - 'walltowall' => $walltowall, - 'queued' => array() - ); - - - call_hooks('notifier_hub',$narr); - if($narr['queued']) { - foreach($narr['queued'] as $pq) - $deliveries[] = $pq; - } - continue; - - } - - // singleton deliveries by definition 'not got zot'. - // Single deliveries are other federated networks (plugins) and we're essentially - // delivering only to those that have this site url in their abook_instance - // and only from within a sync operation. This means if you post from a clone, - // and a connection is connected to one of your other clones; assuming that hub - // is running it will receive a sync packet. On receipt of this sync packet it - // will invoke a delivery to those connections which are connected to just that - // hub instance. - - if($cmd === 'single_mail' || $cmd === 'single_activity') { - continue; - } - - // default: zot protocol - - $hash = random_string(); - $packet = null; - - if($packet_type === 'refresh' || $packet_type === 'purge') { - $packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null)); - } - elseif($packet_type === 'request') { - $packet = zot_build_packet($channel,$packet_type,$env_recips,$hub['hubloc_sitekey'],$hash, - array('message_id' => $request_message_id) - ); - } - - if($packet) { - queue_insert(array( - 'hash' => $hash, - 'account_id' => $channel['channel_account_id'], - 'channel_id' => $channel['channel_id'], - 'posturl' => $hub['hubloc_callback'], - 'notify' => $packet - )); - } - else { - $packet = zot_build_packet($channel,'notify',$env_recips,(($private) ? $hub['hubloc_sitekey'] : null),$hash); - queue_insert(array( - 'hash' => $hash, - 'account_id' => $target_item['aid'], - 'channel_id' => $target_item['uid'], - 'posturl' => $hub['hubloc_callback'], - 'notify' => $packet, - 'msg' => json_encode($encoded_item) - )); - - // only create delivery reports for normal undeleted items - if(is_array($target_item) && array_key_exists('postopts',$target_item) && (! $target_item['item_deleted']) && (! get_config('system','disable_dreport'))) { - q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan, dreport_queue ) values ( '%s','%s','%s','%s','%s','%s','%s' ) ", - dbesc($target_item['mid']), - dbesc($hub['hubloc_host']), - dbesc($hub['hubloc_host']), - dbesc('queued'), - dbesc(datetime_convert()), - dbesc($channel['channel_hash']), - dbesc($hash) - ); - } - } - - $deliveries[] = $hash; - } - - if($normal_mode) { - $x = q("select * from hook where hook = 'notifier_normal'"); - if($x) - proc_run('php','include/deliver_hooks.php', $target_item['id']); - } - - if($deliveries) - do_delivery($deliveries); - - logger('notifier: basic loop complete.', LOGGER_DEBUG); - - call_hooks('notifier_end',$target_item); - - logger('notifer: complete.'); - return; - -} - - -if (array_search(__file__,get_included_files())===0){ - notifier_run($argc,$argv); - killme(); -} diff --git a/include/onedirsync.php b/include/onedirsync.php deleted file mode 100644 index d794fe35e..000000000 --- a/include/onedirsync.php +++ /dev/null @@ -1,82 +0,0 @@ - 1) && (intval($argv[1]))) - $update_id = intval($argv[1]); - - if(! $update_id) { - logger('onedirsync: no update'); - return; - } - - $r = q("select * from updates where ud_id = %d limit 1", - intval($update_id) - ); - - if(! $r) - return; - if(($r[0]['ud_flags'] & UPDATE_FLAGS_UPDATED) || (! $r[0]['ud_addr'])) - return; - - // Have we probed this channel more recently than the other directory server - // (where we received this update from) ? - // If we have, we don't need to do anything except mark any older entries updated - - $x = q("select * from updates where ud_addr = '%s' and ud_date > '%s' and ( ud_flags & %d )>0 order by ud_date desc limit 1", - dbesc($r[0]['ud_addr']), - dbesc($r[0]['ud_date']), - intval(UPDATE_FLAGS_UPDATED) - ); - if($x) { - $y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 and ud_date != '%s'", - intval(UPDATE_FLAGS_UPDATED), - dbesc($r[0]['ud_addr']), - intval(UPDATE_FLAGS_UPDATED), - dbesc($x[0]['ud_date']) - ); - return; - } - - // ignore doing an update if this ud_addr refers to a known dead hubloc - - $h = q("select * from hubloc where hubloc_addr = '%s' limit 1", - dbesc($r[0]['ud_addr']) - ); - if(($h) && ($h[0]['hubloc_status'] & HUBLOC_OFFLINE)) { - $y = q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and ( ud_flags & %d ) = 0 ", - intval(UPDATE_FLAGS_UPDATED), - dbesc($r[0]['ud_addr']), - intval(UPDATE_FLAGS_UPDATED) - ); - - return; - } - - // we might have to pull this out some day, but for now update_directory_entry() - // runs zot_finger() and is kind of zot specific - - if($h && $h[0]['hubloc_network'] !== 'zot') - return; - - update_directory_entry($r[0]); - - return; -} - -if (array_search(__file__,get_included_files())===0){ - onedirsync_run($argc,$argv); - killme(); -} diff --git a/include/onepoll.php b/include/onepoll.php deleted file mode 100644 index bfd79feea..000000000 --- a/include/onepoll.php +++ /dev/null @@ -1,159 +0,0 @@ - 1) && (intval($argv[1]))) - $contact_id = intval($argv[1]); - - if(! $contact_id) { - logger('onepoll: no contact'); - return; - } - - $d = datetime_convert(); - - $contacts = q("SELECT abook.*, xchan.*, account.* - FROM abook LEFT JOIN account on abook_account = account_id left join xchan on xchan_hash = abook_xchan - where abook_id = %d - and abook_pending = 0 and abook_archived = 0 and abook_blocked = 0 and abook_ignored = 0 - AND (( account_flags = %d ) OR ( account_flags = %d )) limit 1", - intval($contact_id), - intval(ACCOUNT_OK), - intval(ACCOUNT_UNVERIFIED) - ); - - if(! $contacts) { - logger('onepoll: abook_id not found: ' . $contact_id); - return; - } - - $contact = $contacts[0]; - - $t = $contact['abook_updated']; - - $importer_uid = $contact['abook_channel']; - - $r = q("SELECT * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", - intval($importer_uid) - ); - - if(! $r) - return; - - $importer = $r[0]; - - logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['xchan_name']}, CONTACT: {$contact['xchan_name']}"); - - $last_update = ((($contact['abook_updated'] === $contact['abook_created']) || ($contact['abook_updated'] === NULL_DATE)) - ? datetime_convert('UTC','UTC','now - 7 days') - : datetime_convert('UTC','UTC',$contact['abook_updated'] . ' - 2 days') - ); - - if($contact['xchan_network'] === 'rss') { - logger('onepoll: processing feed ' . $contact['xchan_name'], LOGGER_DEBUG); - handle_feed($importer['channel_id'],$contact_id,$contact['xchan_hash']); - q("update abook set abook_connected = '%s' where abook_id = %d", - dbesc(datetime_convert()), - intval($contact['abook_id']) - ); - return; - } - - if($contact['xchan_network'] !== 'zot') - return; - - // update permissions - - $x = zot_refresh($contact,$importer); - - $responded = false; - $updated = datetime_convert(); - $connected = datetime_convert(); - if(! $x) { - // mark for death by not updating abook_connected, this is caught in include/poller.php - q("update abook set abook_updated = '%s' where abook_id = %d", - dbesc($updated), - intval($contact['abook_id']) - ); - } - else { - q("update abook set abook_updated = '%s', abook_connected = '%s' where abook_id = %d", - dbesc($updated), - dbesc($connected), - intval($contact['abook_id']) - ); - $responded = true; - } - - if(! $responded) - return; - - if($contact['xchan_connurl']) { - $fetch_feed = true; - $x = null; - - if(! ($contact['abook_their_perms'] & PERMS_R_STREAM )) - $fetch_feed = false; - - if($fetch_feed) { - - $feedurl = str_replace('/poco/','/zotfeed/',$contact['xchan_connurl']); - $feedurl .= '?f=&mindate=' . urlencode($last_update); - - $x = z_fetch_url($feedurl); - - logger('feed_update: ' . print_r($x,true), LOGGER_DATA); - - } - - if(($x) && ($x['success'])) { - $total = 0; - logger('onepoll: feed update ' . $contact['xchan_name'] . ' ' . $feedurl); - - $j = json_decode($x['body'],true); - if($j['success'] && $j['messages']) { - foreach($j['messages'] as $message) { - $results = process_delivery(array('hash' => $contact['xchan_hash']), get_item_elements($message), - array(array('hash' => $importer['xchan_hash'])), false); - logger('onepoll: feed_update: process_delivery: ' . print_r($results,true), LOGGER_DATA); - $total ++; - } - logger("onepoll: $total messages processed"); - } - } - } - - - // update the poco details for this connection - - if($contact['xchan_connurl']) { - $r = q("SELECT xlink_id from xlink - where xlink_xchan = '%s' and xlink_updated > %s - INTERVAL %s and xlink_static = 0 limit 1", - intval($contact['xchan_hash']), - db_utcnow(), db_quoteinterval('1 DAY') - ); - if(! $r) { - poco_load($contact['xchan_hash'],$contact['xchan_connurl']); - } - } - - return; -} - -if (array_search(__file__,get_included_files())===0){ - onepoll_run($argc,$argv); - killme(); -} diff --git a/include/photos.php b/include/photos.php index 73a29d8eb..d8d3d102c 100644 --- a/include/photos.php +++ b/include/photos.php @@ -420,7 +420,7 @@ function photo_upload($channel, $observer, $args) { $item_id = $result['item_id']; if($visible) - proc_run('php', "include/notifier.php", 'wall-new', $item_id); + Zotlabs\Daemon\Master::Summon(array('Notifier', 'wall-new', $item_id)); } $ret['success'] = true; diff --git a/include/poller.php b/include/poller.php index 67a67de12..e72121a8a 100644 --- a/include/poller.php +++ b/include/poller.php @@ -5,7 +5,7 @@ require_once('include/cli_startup.php'); function poller_run($argc,$argv){ cli_startup(); - \Zotlabs\Daemon\Master::Summon('Cron'); + \Zotlabs\Daemon\Master::Summon(array('Cron')); } diff --git a/include/queue.php b/include/queue.php deleted file mode 100644 index 1159e01a0..000000000 --- a/include/queue.php +++ /dev/null @@ -1,95 +0,0 @@ - 1) - $queue_id = argv(1); - else - $queue_id = 0; - - logger('queue: start'); - - // delete all queue items more than 3 days old - // but first mark these sites dead if we haven't heard from them in a month - - $r = q("select outq_posturl from outq where outq_created < %s - INTERVAL %s", - db_utcnow(), db_quoteinterval('3 DAY') - ); - if($r) { - foreach($r as $rr) { - $site_url = ''; - $h = parse_url($rr['outq_posturl']); - $desturl = $h['scheme'] . '://' . $h['host'] . (($h['port']) ? ':' . $h['port'] : ''); - q("update site set site_dead = 1 where site_dead = 0 and site_url = '%s' and site_update < %s - INTERVAL %s", - dbesc($desturl), - db_utcnow(), db_quoteinterval('1 MONTH') - ); - } - } - - $r = q("DELETE FROM outq WHERE outq_created < %s - INTERVAL %s", - db_utcnow(), db_quoteinterval('3 DAY') - ); - - if($queue_id) { - $r = q("SELECT * FROM outq WHERE outq_hash = '%s' LIMIT 1", - dbesc($queue_id) - ); - } - else { - - // For the first 12 hours we'll try to deliver every 15 minutes - // After that, we'll only attempt delivery once per hour. - // This currently only handles the default queue drivers ('zot' or '') which we will group by posturl - // so that we don't start off a thousand deliveries for a couple of dead hubs. - // The zot driver will deliver everything destined for a single hub once contact is made (*if* contact is made). - // Other drivers will have to do something different here and may need their own query. - - // Note: this requires some tweaking as new posts to long dead hubs once a day will keep them in the - // "every 15 minutes" category. We probably need to prioritise them when inserted into the queue - // or just prior to this query based on recent and long-term delivery history. If we have good reason to believe - // the site is permanently down, there's no reason to attempt delivery at all, or at most not more than once - // or twice a day. - - // FIXME: can we sort postgres on outq_priority and maintain the 'distinct' ? - // The order by max(outq_priority) might be a dodgy query because of the group by. - // The desired result is to return a sequence in the order most likely to be delivered in this run. - // If a hub has already been sitting in the queue for a few days, they should be delivered last; - // hence every failure should drop them further down the priority list. - - if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { - $prefix = 'DISTINCT ON (outq_posturl)'; - $suffix = 'ORDER BY outq_posturl'; - } else { - $prefix = ''; - $suffix = 'GROUP BY outq_posturl ORDER BY max(outq_priority)'; - } - $r = q("SELECT $prefix * FROM outq WHERE outq_delivered = 0 and (( outq_created > %s - INTERVAL %s and outq_updated < %s - INTERVAL %s ) OR ( outq_updated < %s - INTERVAL %s )) $suffix", - db_utcnow(), db_quoteinterval('12 HOUR'), - db_utcnow(), db_quoteinterval('15 MINUTE'), - db_utcnow(), db_quoteinterval('1 HOUR') - ); - } - if(! $r) - return; - - foreach($r as $rr) { - queue_deliver($rr); - } -} - -if (array_search(__file__,get_included_files())===0){ - queue_run($argc,$argv); - killme(); -} diff --git a/include/ratenotif.php b/include/ratenotif.php deleted file mode 100644 index 3a5e515ae..000000000 --- a/include/ratenotif.php +++ /dev/null @@ -1,119 +0,0 @@ - 'rating', - 'encoding' => 'zot', - 'target' => $r[0]['xlink_link'], - 'rating' => intval($r[0]['xlink_rating']), - 'rating_text' => $r[0]['xlink_rating_text'], - 'signature' => $r[0]['xlink_sig'], - 'edited' => $r[0]['xlink_updated'] - ); - } - - $channel = channelx_by_hash($r[0]['xlink_xchan']); - if(! $channel) { - logger('no channel'); - return; - } - - - $primary = get_directory_primary(); - - if(! $primary) - return; - - - $interval = ((get_config('system','delivery_interval') !== false) - ? intval(get_config('system','delivery_interval')) : 2 ); - - $deliveries_per_process = intval(get_config('system','delivery_batch_count')); - - if($deliveries_per_process <= 0) - $deliveries_per_process = 1; - - $deliver = array(); - - $x = z_fetch_url($primary . '/regdir'); - if($x['success']) { - $j = json_decode($x['body'],true); - if($j && $j['success'] && is_array($j['directories'])) { - - foreach($j['directories'] as $h) { - if($h == z_root()) - continue; - - $hash = random_string(); - $n = zot_build_packet($channel,'notify',null,null,$hash); - - queue_insert(array( - 'hash' => $hash, - 'account_id' => $channel['channel_account_id'], - 'channel_id' => $channel['channel_id'], - 'posturl' => $h . '/post', - 'notify' => $n, - 'msg' => json_encode($encoded_item) - )); - - $deliver[] = $hash; - - if(count($deliver) >= $deliveries_per_process) { - proc_run('php','include/deliver.php',$deliver); - $deliver = array(); - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - } - } - - // catch any stragglers - - if(count($deliver)) { - proc_run('php','include/deliver.php',$deliver); - } - } - } - - logger('ratenotif: complete.'); - return; - -} - -if (array_search(__file__,get_included_files())===0){ - ratenotif_run($argc,$argv); - killme(); -} diff --git a/include/zot.php b/include/zot.php index 5400bd96e..5884245e9 100644 --- a/include/zot.php +++ b/include/zot.php @@ -453,7 +453,7 @@ function zot_refresh($them, $channel = null, $force = false) { else { // if we were just granted read stream permission and didn't have it before, try to pull in some posts if((! ($r[0]['abook_their_perms'] & PERMS_R_STREAM)) && ($their_perms & PERMS_R_STREAM)) - proc_run('php','include/onepoll.php',$r[0]['abook_id']); + Zotlabs\Daemon\Master::Summon(array('Onepoll',$r[0]['abook_id'])); } } else { @@ -504,7 +504,7 @@ function zot_refresh($them, $channel = null, $force = false) { if($new_connection) { if($new_perms != $previous_perms) - proc_run('php','include/notifier.php','permission_create',$new_connection[0]['abook_id']); + Zotlabs\Daemon\Master::Summon(array('Notifier','permission_create',$new_connection[0]['abook_id'])); require_once('include/enotify.php'); notification(array( 'type' => NOTIFY_INTRO, @@ -516,7 +516,7 @@ function zot_refresh($them, $channel = null, $force = false) { if($their_perms & PERMS_R_STREAM) { if(($channel['channel_w_stream'] & PERMS_PENDING) || (! intval($new_connection[0]['abook_pending'])) ) - proc_run('php','include/onepoll.php',$new_connection[0]['abook_id']); + Zotlabs\Daemon\Master::Summon(array('Onepoll',$new_connection[0]['abook_id'])); } unset($new_connection[0]['abook_id']); @@ -1703,7 +1703,7 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $ if((! $relay) && (! $request) && (! $local_public) && perm_is_allowed($channel['channel_id'],$sender['hash'],'send_stream')) { - proc_run('php', 'include/notifier.php', 'request', $channel['channel_id'], $sender['hash'], $arr['parent_mid']); + Zotlabs\Daemon\Master::Summon(array('Notifier', 'request', $channel['channel_id'], $sender['hash'], $arr['parent_mid'])); } continue; } @@ -1775,7 +1775,7 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $ if($relay && $item_id) { logger('process_delivery: invoking relay'); - proc_run('php','include/notifier.php','relay',intval($item_id)); + Zotlabs\Daemon\Master::Summon(array('Notifier','relay',intval($item_id))); $DR->update('relayed'); $result[] = $DR->get(); } @@ -1858,7 +1858,7 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $ if($relay && $item_id) { logger('process_delivery: invoking relay'); - proc_run('php','include/notifier.php','relay',intval($item_id)); + Zotlabs\Daemon\Master::Summon(array('Notifier','relay',intval($item_id))); $DR->addto_update('relayed'); $result[] = $DR->get(); } @@ -3060,7 +3060,7 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) { 'msg' => json_encode($info) )); - proc_run('php', 'include/deliver.php', $hash); + Zotlabs\Daemon\Master::Summon(array('Deliver', $hash)); $total = $total - 1; if($interval && $total) @@ -3652,7 +3652,7 @@ function zot_reply_message_request($data) { * invoke delivery to send out the notify packet */ - proc_run('php', 'include/deliver.php', $hash); + Zotlabs\Daemon\Master::Summon(array('Deliver', $hash)); } } $ret['success'] = true; -- cgit v1.2.3 From f228bf4555ad8a8bfa87a0905858738dcc172687 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 19 May 2016 22:33:01 -0700 Subject: typo uncovered during tests --- include/activities.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/activities.php b/include/activities.php index 5c1e68720..7b9aa9963 100644 --- a/include/activities.php +++ b/include/activities.php @@ -89,7 +89,7 @@ function profile_activity($changed, $value) { if($i) { // FIXME - limit delivery in notifier.php to those specificed in the perms argument - Zotlabs\Daemon\Master::Summon(array('Notifier','activity', $i, 'PERMS_R_PROFILE'); + Zotlabs\Daemon\Master::Summon(array('Notifier','activity', $i, 'PERMS_R_PROFILE')); } } -- cgit v1.2.3 From cae380f068ce3c06360b430c84b267414dc02fcf Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 20 May 2016 01:21:19 -0700 Subject: case issue --- include/network.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/network.php b/include/network.php index 47b04f007..25307f857 100644 --- a/include/network.php +++ b/include/network.php @@ -1922,7 +1922,7 @@ function do_delivery($deliveries) { $deliver[] = $d; if(count($deliver) >= $deliveries_per_process) { - Zotlabs\Daemon\Master::summon(array('Deliver',$deliver)); + Zotlabs\Daemon\Master::Summon(array('Deliver',$deliver)); $deliver = array(); if($interval) @time_sleep_until(microtime(true) + (float) $interval); @@ -1932,7 +1932,7 @@ function do_delivery($deliveries) { // catch any stragglers if($deliver) - Zotlabs\Daemon\Master::summon(array('Deliver',$deliver)); + Zotlabs\Daemon\Master::Summon(array('Deliver',$deliver)); } -- cgit v1.2.3 From b2f0d2d085c355010f1475269c4beb4fba7b07dc Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 20 May 2016 17:44:26 -0700 Subject: cleanup proc_run after messing it up with debugging yesterday --- include/smarty.php | 5 +++-- include/text.php | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/smarty.php b/include/smarty.php index 762efe335..9d443e269 100755 --- a/include/smarty.php +++ b/include/smarty.php @@ -1,6 +1,7 @@ foo [1] => bar [2] => baz [3] => blip [4] => zob [5] => glob [6] => grip ) + * + */ + +function flatten_array_recursive($arr) { + $ret = array(); + + if(! $arr) + return $ret; + + foreach($arr as $a) { + if(is_array($a)) { + $tmp = flatten_array_recursive($a); + if($tmp) { + $ret = array_merge($ret,$tmp); + } + } + elseif($a) { + $ret[] = $a; + } + } + return($ret); +} -- cgit v1.2.3 From f4da365abdc1ce1da2dde1bb9798f58fc6dc1a9f Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 20 May 2016 19:11:14 -0700 Subject: move template stuff to zotlabs/render --- include/ITemplateEngine.php | 10 -- include/plugin.php | 2 - include/smarty.php | 116 ---------------- include/template_processor.php | 307 ----------------------------------------- include/text.php | 6 +- 5 files changed, 2 insertions(+), 439 deletions(-) delete mode 100755 include/ITemplateEngine.php delete mode 100755 include/smarty.php delete mode 100755 include/template_processor.php (limited to 'include') diff --git a/include/ITemplateEngine.php b/include/ITemplateEngine.php deleted file mode 100755 index 7bd559a63..000000000 --- a/include/ITemplateEngine.php +++ /dev/null @@ -1,10 +0,0 @@ - "view/theme/$thname/tpl/"); - if( x(App::$theme_info,"extends") ) - $template_dirs = $template_dirs + array('extends' => "view/theme/" . App::$theme_info["extends"] . "/tpl/"); - $template_dirs = $template_dirs + array('base' => 'view/tpl/'); - $this->setTemplateDir($template_dirs); - - $basecompiledir = App::$config['system']['smarty3_folder']; - - $this->setCompileDir($basecompiledir.'/compiled/'); - $this->setConfigDir($basecompiledir.'/config/'); - $this->setCacheDir($basecompiledir.'/cache/'); - - $this->left_delimiter = App::get_template_ldelim('smarty3'); - $this->right_delimiter = App::get_template_rdelim('smarty3'); - - // Don't report errors so verbosely - $this->error_reporting = E_ALL & ~E_NOTICE; - } - - function parsed($template = '') { - if($template) { - return $this->fetch('string:' . $template); - } - return $this->fetch('file:' . $this->filename); - } -} - - - -class FriendicaSmartyEngine implements ITemplateEngine { - static $name ="smarty3"; - - public function __construct(){ - $a = get_app(); - - // Cannot use get_config() here because it is called during installation when there is no DB. - // FIXME: this may leak private information such as system pathnames. - - $basecompiledir = ((array_key_exists('smarty3_folder',App::$config['system'])) ? App::$config['system']['smarty3_folder'] : ''); - if (!$basecompiledir) $basecompiledir = dirname(__dir__) . "/" . TEMPLATE_BUILD_PATH; - if (!is_dir($basecompiledir)) { - echo "ERROR: folder $basecompiledir does not exist."; killme(); - } - if(!is_writable($basecompiledir)){ - echo "ERROR: folder $basecompiledir must be writable by webserver."; killme(); - } - App::$config['system']['smarty3_folder'] = $basecompiledir; - } - - // ITemplateEngine interface - public function replace_macros($s, $r) { - $template = ''; - if(gettype($s) === 'string') { - $template = $s; - $s = new FriendicaSmarty(); - } - foreach($r as $key=>$value) { - if($key[0] === '$') { - $key = substr($key, 1); - } - $s->assign($key, $value); - } - return $s->parsed($template); - } - - public function get_markup_template($file, $root=''){ - $template_file = theme_include($file, $root); - if($template_file) { - $template = new FriendicaSmarty(); - $template->filename = $template_file; - - return $template; - } - return ""; - } - - public function get_intltext_template($file, $root='') { - $a = get_app(); - - if(file_exists("view/{App::$language}/$file")) - $template_file = "view/{App::$language}/$file"; - elseif(file_exists("view/en/$file")) - $template_file = "view/en/$file"; - else - $template_file = theme_include($file,$root); - if($template_file) { - $template = new FriendicaSmarty(); - $template->filename = $template_file; - - return $template; - } - return ""; - } - - - -} diff --git a/include/template_processor.php b/include/template_processor.php deleted file mode 100755 index d2bf283e3..000000000 --- a/include/template_processor.php +++ /dev/null @@ -1,307 +0,0 @@ - 5.3, not certain how to code around it for unit tests -// case PREG_BAD_UTF8_OFFSET_ERROR: echo('PREG_BAD_UTF8_OFFSET_ERROR'); break; - default: - //die("Unknown preg error."); - return; - } - echo "
";
-		debug_print_backtrace();
-		die();
-	}
-
-	private function _push_stack() {
-		$this->stack[] = array($this->r, $this->nodes);
-	}
-
-	private function _pop_stack(){
-		list($this->r, $this->nodes) = array_pop($this->stack);
-	}
-
-	private function _get_var($name, $retNoKey=false) {
-		$keys = array_map('trim',explode(".",$name));
-		if ($retNoKey && !array_key_exists($keys[0], $this->r))
-			return KEY_NOT_EXISTS;
-
-		$val = $this->r;
-		foreach($keys as $k) {
-			$val = (isset($val[$k]) ? $val[$k] : null);
-		}
-
-		return template_escape($val);
-	}
-
-	/**
-	 * IF node
-	 * \code
-	 * {{ if <$var> }}...[{{ else }} ...] {{ endif }}
-	 * {{ if <$var>== }}...[{{ else }} ...]{{ endif }}
-	 * {{ if <$var>!= }}...[{{ else }} ...]{{ endif }}
-	 * \endcode
-	 */
-	private function _replcb_if($args) {
-		if (strpos($args[2],"==")>0){
-			list($a,$b) = array_map("trim",explode("==",$args[2]));
-			$a = $this->_get_var($a);
-			if ($b[0]=="$") $b =  $this->_get_var($b);
-			$val = ($a == $b);
-		} else if (strpos($args[2],"!=")>0){
-			list($a,$b) = array_map("trim", explode("!=",$args[2]));
-			$a = $this->_get_var($a);
-			if ($b[0]=="$") $b =  $this->_get_var($b);
-			$val = ($a != $b);
-		} else {
-			$val = $this->_get_var($args[2]);
-		}
-		$x = preg_split("|{{ *else *}}|", $args[3]);
-
-		return ( ($val) ? $x[0] : (isset($x[1]) ? $x[1] : ""));
-	}
-
-	/**
-	 * FOR node
-	 * \code
-	 * {{ for <$var> as $name }}...{{ endfor }}
-	 * {{ for <$var> as $key=>$name }}...{{ endfor }}
-	 * \endcode
-	 */
-	private function _replcb_for($args) {
-		$m = array_map('trim', explode(" as ", $args[2]));
-		$x = explode("=>",$m[1]);
-		if (count($x) == 1) {
-			$varname = $x[0];
-			$keyname = "";
-		} else {
-			list($keyname, $varname) = $x;
-		}
-		if ($m[0]=="" || $varname=="" || is_null($varname)) die("template error: 'for ".$m[0]." as ".$varname."'") ;
-		//$vals = $this->r[$m[0]];
-		$vals = $this->_get_var($m[0]);
-		$ret="";
-		if (!is_array($vals)) return $ret;
-
-		foreach ($vals as $k=>$v){
-			$this->_push_stack();
-			$r = $this->r;
-			$r[$varname] = $v;
-			if ($keyname!='') $r[$keyname] = (($k === 0) ? '0' : $k);
-			$ret .=  $this->replace($args[3], $r);
-			$this->_pop_stack();
-		}
-
-		return $ret;
-	}
-
-	/**
-	 * INC node
-	 * \code
-	 * {{ inc  [with $var1=$var2] }}{{ endinc }}
-	 * \endcode
-	 */
-	private function _replcb_inc($args) {
-		if (strpos($args[2],"with")) {
-			list($tplfile, $newctx) = array_map('trim', explode("with",$args[2]));
-		} else {
-			$tplfile = trim($args[2]);
-			$newctx = null;
-		}
-
-		if ($tplfile[0]=="$") $tplfile = $this->_get_var($tplfile);
-
-		$this->_push_stack();
-		$r = $this->r;
-		if (!is_null($newctx)) {
-			list($a,$b) = array_map('trim', explode("=",$newctx));
-			$r[$a] = $this->_get_var($b); 
-		}
-		$this->nodes = Array();
-		$tpl = get_markup_template($tplfile);
-		$ret = $this->replace($tpl, $r);
-		$this->_pop_stack();
-
-		return $ret;
-	}
-
-	/**
-	 * DEBUG node
-	 * \code
-	 * {{ debug $var [$var [$var [...]]] }}{{ enddebug }}
-	 * \endcode
-	 * replace node with 
var_dump($var, $var, ...);
- */ - private function _replcb_debug($args) { - $vars = array_map('trim', explode(" ",$args[2])); - $vars[] = $args[1]; - - $ret = "
";
-		foreach ($vars as $var){
-			$ret .= htmlspecialchars(var_export( $this->_get_var($var), true ));
-			$ret .= "\n";
-		}
-		$ret .= "
"; - - return $ret; - } - - private function _replcb_node($m) { - $node = $this->nodes[$m[1]]; - if (method_exists($this, "_replcb_".$node[1])){ - $s = call_user_func(array($this, "_replcb_".$node[1]), $node); - } else { - $s = ""; - } - $s = preg_replace_callback('/\|\|([0-9]+)\|\|/', array($this, "_replcb_node"), $s); - - return $s; - } - - private function _replcb($m) { - //var_dump(array_map('htmlspecialchars', $m)); - $this->done = false; - $this->nodes[] = (array) $m; - - return "||". (count($this->nodes)-1) ."||"; - } - - private function _build_nodes($s) { - $this->done = false; - while (!$this->done) { - $this->done=true; - $s = preg_replace_callback('|{{ *([a-z]*) *([^}]*)}}([^{]*({{ *else *}}[^{]*)?){{ *end\1 *}}|', array($this, "_replcb"), $s); - if ($s==Null) $this->_preg_error(); - } - //({{ *else *}}[^{]*)? - krsort($this->nodes); - - return $s; - } - - private function var_replace($s) { - $m = array(); - /** regexp: - * \$ literal $ - * (\[)? optional open square bracket - * ([a-zA-Z0-9-_]+\.?)+ var name, followed by optional - * dot, repeated at least 1 time - * (?(1)\]) if there was opened square bracket - * (subgrup 1), match close bracket - */ - if (preg_match_all('/\$(\[)?([a-zA-Z0-9-_]+\.?)+(?(1)\])/', $s,$m)) { - foreach ($m[0] as $var) { - $exp = str_replace(array("[", "]"), array("", ""), $var); - $exptks = explode("|", $exp); - - $varn = $exptks[0]; - unset($exptks[0]); - $val = $this->_get_var($varn, true); - if ($val != KEY_NOT_EXISTS) { - /* run filters */ - /* - * Filter are in form of: - * filtername:arg:arg:arg - * - * "filtername" is function name - * "arg"s are optional, var value is appended to the end - * if one "arg"==='x' , is replaced with var value - * - * examples: - * $item.body|htmlspecialchars // escape html chars - * $item.body|htmlspecialchars|strtoupper // escape html and uppercase result - * $item.created|date:%Y %M %j // format date (created is a timestamp) - * $item.body|str_replace:cat:dog // replace all "cat" with "dog" - * $item.body|str_replace:cat:dog:x:1 // replace one "cat" with "dog" - */ - foreach ($exptks as $filterstr) { - $filter = explode(":", $filterstr); - $filtername = $filter[0]; - unset($filter[0]); - $valkey = array_search("x", $filter); - if ($valkey === false) { - $filter[] = $val; - } else { - $filter[$valkey] = $val; - } - if (function_exists($filtername)) { - $val = call_user_func_array($filtername, $filter); - } - } - $s = str_replace($var, $val, $s); - } - } - } - - return $s; - } - - private function replace($s, $r) { - $this->replace_macros($s, $r); - } - - // TemplateEngine interface - public function replace_macros($s, $r) { - $this->r = $r; - - $s = $this->_build_nodes($s); - - $s = preg_replace_callback('/\|\|([0-9]+)\|\|/', array($this, "_replcb_node"), $s); - if ($s == Null) - $this->_preg_error(); - - // remove comments block - $s = preg_replace('/{#[^#]*#}/', "" , $s); - - //$t2 = dba_timer(); - - // replace strings recursively (limit to 10 loops) - $os = ""; - $count=0; - while (($os !== $s) && $count<10) { - $os=$s; - $count++; - $s = $this->var_replace($s); - } - - return $s; - } - - public function get_markup_template($file, $root='') { - $template_file = theme_include($file, $root); - if ($template_file) { - $content = file_get_contents($template_file); - } - - return $content; - } -} - - -function template_escape($s) { - return str_replace(array('$','{{'),array('!_Doll^Ars1Az_!','!_DoubLe^BraceS4Rw_!'),$s); -} - -function template_unescape($s) { - return str_replace(array('!_Doll^Ars1Az_!','!_DoubLe^BraceS4Rw_!'),array('$','{{'),$s); -} diff --git a/include/text.php b/include/text.php index 554518e32..df6dac056 100644 --- a/include/text.php +++ b/include/text.php @@ -3,8 +3,6 @@ * @file include/text.php */ -require_once("include/template_processor.php"); -require_once("include/smarty.php"); require_once("include/bbcode.php"); // random string, there are 86 characters max in text mode, 128 for hex @@ -16,8 +14,8 @@ define('RANDOM_STRING_TEXT', 0x01 ); /** * @brief This is our template processor. * - * @param string|FriendicaSmarty $s the string requiring macro substitution, - * or an instance of FriendicaSmarty + * @param string|SmartyEngine $s the string requiring macro substitution, + * or an instance of SmartyEngine * @param array $r key value pairs (search => replace) * @return string substituted string */ -- cgit v1.2.3 From 019250eff879d86577157ad6136a3613b61cacb8 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 20 May 2016 22:13:20 -0700 Subject: consolidate include/*_selectors.php (not touching acl_selectors for the moment, as it will likely end up with a different disposition) --- include/contact_selectors.php | 97 -------------------------- include/network.php | 26 +++++++ include/profile_selectors.php | 110 ------------------------------ include/selectors.php | 154 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 180 insertions(+), 207 deletions(-) delete mode 100644 include/contact_selectors.php delete mode 100644 include/profile_selectors.php create mode 100644 include/selectors.php (limited to 'include') diff --git a/include/contact_selectors.php b/include/contact_selectors.php deleted file mode 100644 index 0de4ece00..000000000 --- a/include/contact_selectors.php +++ /dev/null @@ -1,97 +0,0 @@ -\r\n"; - - $r = q("SELECT profile_guid, profile_name FROM `profile` WHERE `uid` = %d", - intval($_SESSION['uid'])); - - if($r) { - foreach($r as $rr) { - $selected = (($rr['profile_guid'] == $current) ? " selected=\"selected\" " : ""); - $o .= "\r\n"; - } - } - $o .= "\r\n"; - return $o; -} - -/* unused currently - -function contact_reputation($current) { - - $o = ''; - $o .= "\r\n"; - return $o; -} - -*/ - -function contact_poll_interval($current, $disabled = false) { - - $dis = (($disabled) ? ' disabled="disabled" ' : ''); - $o = ''; - $o .= "\r\n"; - return $o; -} - - -function network_to_name($s) { - - $nets = array( - NETWORK_DFRN => t('Friendica'), - NETWORK_FRND => t('Friendica'), - NETWORK_OSTATUS => t('OStatus'), - NETWORK_GNUSOCIAL => t('GNU-Social'), - NETWORK_FEED => t('RSS/Atom'), - NETWORK_MAIL => t('Email'), - NETWORK_DIASPORA => t('Diaspora'), - NETWORK_FACEBOOK => t('Facebook'), - NETWORK_ZOT => t('Zot'), - NETWORK_LINKEDIN => t('LinkedIn'), - NETWORK_XMPP => t('XMPP/IM'), - NETWORK_MYSPACE => t('MySpace'), - ); - - call_hooks('network_to_name', $nets); - - $search = array_keys($nets); - $replace = array_values($nets); - - return str_replace($search,$replace,$s); - -} diff --git a/include/network.php b/include/network.php index 25307f857..f38f8d548 100644 --- a/include/network.php +++ b/include/network.php @@ -2150,3 +2150,29 @@ function get_repository_version($branch = 'master') { return '?.?'; } + +function network_to_name($s) { + + $nets = array( + NETWORK_DFRN => t('Friendica'), + NETWORK_FRND => t('Friendica'), + NETWORK_OSTATUS => t('OStatus'), + NETWORK_GNUSOCIAL => t('GNU-Social'), + NETWORK_FEED => t('RSS/Atom'), + NETWORK_MAIL => t('Email'), + NETWORK_DIASPORA => t('Diaspora'), + NETWORK_FACEBOOK => t('Facebook'), + NETWORK_ZOT => t('Zot'), + NETWORK_LINKEDIN => t('LinkedIn'), + NETWORK_XMPP => t('XMPP/IM'), + NETWORK_MYSPACE => t('MySpace'), + ); + + call_hooks('network_to_name', $nets); + + $search = array_keys($nets); + $replace = array_values($nets); + + return str_replace($search,$replace,$s); + +} diff --git a/include/profile_selectors.php b/include/profile_selectors.php deleted file mode 100644 index 9f993f803..000000000 --- a/include/profile_selectors.php +++ /dev/null @@ -1,110 +0,0 @@ -"; - foreach($select as $selection) { - if($selection !== 'NOTRANSLATION') { - $selected = (($selection == $current) ? ' selected="selected" ' : ''); - $o .= ""; - } - } - $o .= ''; - return $o; -} - -function gender_selector_min($current="",$suffix="") { - $o = ''; - $select = array('', t('Male'), t('Female'), t('Other')); - - call_hooks('gender_selector_min', $select); - - $o .= "'; - return $o; -} - - - -function sexpref_selector($current="",$suffix="") { - $o = ''; - $select = array('', t('Males'), t('Females'), t('Gay'), t('Lesbian'), t('No Preference'), t('Bisexual'), t('Autosexual'), t('Abstinent'), t('Virgin'), t('Deviant'), t('Fetish'), t('Oodles'), t('Nonsexual')); - - - call_hooks('sexpref_selector', $select); - - $o .= "'; - return $o; -} - - -function sexpref_selector_min($current="",$suffix="") { - $o = ''; - $select = array('', t('Males'), t('Females'), t('Other')); - - call_hooks('sexpref_selector_min', $select); - - $o .= "'; - return $o; -} - - - -function marital_selector($current="",$suffix="") { - $o = ''; - $select = array('', t('Single'), t('Lonely'), t('Available'), t('Unavailable'), t('Has crush'), t('Infatuated'), t('Dating'), t('Unfaithful'), t('Sex Addict'), t('Friends'), t('Friends/Benefits'), t('Casual'), t('Engaged'), t('Married'), t('Imaginarily married'), t('Partners'), t('Cohabiting'), t('Common law'), t('Happy'), t('Not looking'), t('Swinger'), t('Betrayed'), t('Separated'), t('Unstable'), t('Divorced'), t('Imaginarily divorced'), t('Widowed'), t('Uncertain'), t('It\'s complicated'), t('Don\'t care'), t('Ask me') ); - - call_hooks('marital_selector', $select); - - $o .= "'; - return $o; -} - -function marital_selector_min($current="",$suffix="") { - $o = ''; - $select = array('', t('Single'), t('Dating'), t('Cohabiting'), t('Married'), t('Separated'), t('Divorced'), t('Widowed'), t('It\'s complicated'), t('Other')); - - call_hooks('marital_selector_min', $select); - - $o .= "'; - return $o; -} diff --git a/include/selectors.php b/include/selectors.php new file mode 100644 index 000000000..d7d070d31 --- /dev/null +++ b/include/selectors.php @@ -0,0 +1,154 @@ +\r\n"; + + $r = q("SELECT profile_guid, profile_name FROM `profile` WHERE `uid` = %d", + intval($_SESSION['uid'])); + + if($r) { + foreach($r as $rr) { + $selected = (($rr['profile_guid'] == $current) ? " selected=\"selected\" " : ""); + $o .= "\r\n"; + } + } + $o .= "\r\n"; + return $o; +} + +function contact_poll_interval($current, $disabled = false) { + + $dis = (($disabled) ? ' disabled="disabled" ' : ''); + $o = ''; + $o .= "\r\n"; + return $o; +} + + +function gender_selector($current="",$suffix="") { + $o = ''; + $select = array('', t('Male'), t('Female'), t('Currently Male'), t('Currently Female'), t('Mostly Male'), t('Mostly Female'), t('Transgender'), t('Intersex'), t('Transsexual'), t('Hermaphrodite'), t('Neuter'), t('Non-specific'), t('Other'), t('Undecided')); + + call_hooks('gender_selector', $select); + + $o .= "'; + return $o; +} + +function gender_selector_min($current="",$suffix="") { + $o = ''; + $select = array('', t('Male'), t('Female'), t('Other')); + + call_hooks('gender_selector_min', $select); + + $o .= "'; + return $o; +} + + + +function sexpref_selector($current="",$suffix="") { + $o = ''; + $select = array('', t('Males'), t('Females'), t('Gay'), t('Lesbian'), t('No Preference'), t('Bisexual'), t('Autosexual'), t('Abstinent'), t('Virgin'), t('Deviant'), t('Fetish'), t('Oodles'), t('Nonsexual')); + + + call_hooks('sexpref_selector', $select); + + $o .= "'; + return $o; +} + + +function sexpref_selector_min($current="",$suffix="") { + $o = ''; + $select = array('', t('Males'), t('Females'), t('Other')); + + call_hooks('sexpref_selector_min', $select); + + $o .= "'; + return $o; +} + + + +function marital_selector($current="",$suffix="") { + $o = ''; + $select = array('', t('Single'), t('Lonely'), t('Available'), t('Unavailable'), t('Has crush'), t('Infatuated'), t('Dating'), t('Unfaithful'), t('Sex Addict'), t('Friends'), t('Friends/Benefits'), t('Casual'), t('Engaged'), t('Married'), t('Imaginarily married'), t('Partners'), t('Cohabiting'), t('Common law'), t('Happy'), t('Not looking'), t('Swinger'), t('Betrayed'), t('Separated'), t('Unstable'), t('Divorced'), t('Imaginarily divorced'), t('Widowed'), t('Uncertain'), t('It\'s complicated'), t('Don\'t care'), t('Ask me') ); + + call_hooks('marital_selector', $select); + + $o .= "'; + return $o; +} + +function marital_selector_min($current="",$suffix="") { + $o = ''; + $select = array('', t('Single'), t('Dating'), t('Cohabiting'), t('Married'), t('Separated'), t('Divorced'), t('Widowed'), t('It\'s complicated'), t('Other')); + + call_hooks('marital_selector_min', $select); + + $o .= "'; + return $o; +} + -- cgit v1.2.3 From d8ace38041ad3ef161cf9c727c94b6ce2a00ce75 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 20 May 2016 22:52:47 -0700 Subject: rework the conversation object stuff at a high level - still needs a bit of refactoring --- include/BaseObject.php | 38 -- include/ConversationObject.php | 225 ------------ include/ItemObject.php | 773 ----------------------------------------- include/api.php | 10 +- include/conversation.php | 7 +- include/enotify.php | 2 +- include/event.php | 2 +- include/feedutils.php | 4 +- include/identity.php | 2 +- include/language.php | 2 +- include/network.php | 10 +- include/zot.php | 4 +- 12 files changed, 20 insertions(+), 1059 deletions(-) delete mode 100644 include/BaseObject.php delete mode 100644 include/ConversationObject.php delete mode 100644 include/ItemObject.php (limited to 'include') diff --git a/include/BaseObject.php b/include/BaseObject.php deleted file mode 100644 index a88978a83..000000000 --- a/include/BaseObject.php +++ /dev/null @@ -1,38 +0,0 @@ -set_mode($mode); - $this->preview = $preview; - $this->prepared_item = $prepared_item; - $c = ((local_channel()) ? get_pconfig(local_channel(),'system','default_cipher') : ''); - if($c) - $this->cipher = $c; - } - - /** - * Set the mode we'll be displayed on - */ - private function set_mode($mode) { - if($this->get_mode() == $mode) - return; - - $a = $this->get_app(); - - $this->observer = App::get_observer(); - $ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : ''); - - switch($mode) { - case 'network': - $this->profile_owner = local_channel(); - $this->writable = true; - break; - case 'channel': - $this->profile_owner = App::$profile['profile_uid']; - $this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments'); - break; - case 'display': - // in this mode we set profile_owner after initialisation (from conversation()) and then - // pull some trickery which allows us to re-invoke this function afterward - // it's an ugly hack so FIXME - $this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments'); - break; - case 'page': - $this->profile_owner = App::$profile['uid']; - $this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments'); - break; - default: - logger('[ERROR] Conversation::set_mode : Unhandled mode ('. $mode .').', LOGGER_DEBUG); - return false; - break; - } - $this->mode = $mode; - } - - /** - * Get mode - */ - public function get_mode() { - return $this->mode; - } - - /** - * Check if page is writable - */ - public function is_writable() { - return $this->writable; - } - - public function is_commentable() { - return $this->commentable; - } - - /** - * Check if page is a preview - */ - public function is_preview() { - return $this->preview; - } - - /** - * Get profile owner - */ - public function get_profile_owner() { - return $this->profile_owner; - } - - public function set_profile_owner($uid) { - $this->profile_owner = $uid; - $mode = $this->get_mode(); - $this->mode = null; - $this->set_mode($mode); - } - - public function get_observer() { - return $this->observer; - } - - public function get_cipher() { - return $this->cipher; - } - - - /** - * Add a thread to the conversation - * - * Returns: - * _ The inserted item on success - * _ false on failure - */ - public function add_thread($item) { - $item_id = $item->get_id(); - if(!$item_id) { - logger('Item has no ID!!', LOGGER_DEBUG, LOG_ERR); - return false; - } - if($this->get_thread($item->get_id())) { - logger('Thread already exists ('. $item->get_id() .').', LOGGER_DEBUG, LOG_WARNING); - return false; - } - - /* - * Only add things that will be displayed - */ - - - if(($item->get_data_value('id') != $item->get_data_value('parent')) && (activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE))) { - return false; - } - - $item->set_commentable(false); - $ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : ''); - - if(! comments_are_now_closed($item->get_data())) { - if(($item->get_data_value('author_xchan') === $ob_hash) || ($item->get_data_value('owner_xchan') === $ob_hash)) - $item->set_commentable(true); - - if(intval($item->get_data_value('item_nocomment'))) { - $item->set_commentable(false); - } - elseif(($this->observer) && (! $item->is_commentable())) { - if((array_key_exists('owner',$item->data)) && intval($item->data['owner']['abook_self'])) - $item->set_commentable(perm_is_allowed($this->profile_owner,$this->observer['xchan_hash'],'post_comments')); - else - $item->set_commentable(can_comment_on_post($this->observer['xchan_hash'],$item->data)); - } - } - require_once('include/identity.php'); - - $item->set_conversation($this); - $this->threads[] = $item; - return end($this->threads); - } - - /** - * Get data in a form usable by a conversation template - * - * We should find a way to avoid using those arguments (at least most of them) - * - * Returns: - * _ The data requested on success - * _ false on failure - */ - public function get_template_data($conv_responses) { - $result = array(); - - foreach($this->threads as $item) { - - if(($item->get_data_value('id') == $item->get_data_value('parent')) && $this->prepared_item) { - $item_data = $this->prepared_item; - } - else { - $item_data = $item->get_template_data($conv_responses); - } - if(!$item_data) { - logger('Failed to get item template data ('. $item->get_id() .').', LOGGER_DEBUG, LOG_ERR); - return false; - } - $result[] = $item_data; - } - - return $result; - } - - /** - * Get a thread based on its item id - * - * Returns: - * _ The found item on success - * _ false on failure - */ - private function get_thread($id) { - foreach($this->threads as $item) { - if($item->get_id() == $id) - return $item; - } - - return false; - } -} diff --git a/include/ItemObject.php b/include/ItemObject.php deleted file mode 100644 index 019fa87ad..000000000 --- a/include/ItemObject.php +++ /dev/null @@ -1,773 +0,0 @@ -get_app(); - - $this->data = $data; - $this->toplevel = ($this->get_id() == $this->get_data_value('parent')); - - // Prepare the children - if(count($data['children'])) { - foreach($data['children'] as $item) { - - /* - * Only add those that will be displayed - */ - - if((! visible_activity($item)) || array_key_exists('author_blocked',$item)) { - continue; - } - - $child = new Item($item); - $this->add_child($child); - } - } - } - - /** - * Get data in a form usable by a conversation template - * - * Returns: - * _ The data requested on success - * _ false on failure - */ - - public function get_template_data($conv_responses, $thread_level=1) { - - $result = array(); - - $a = $this->get_app(); - $item = $this->get_data(); - - $commentww = ''; - $sparkle = ''; - $buttons = ''; - $dropping = false; - $star = false; - $isstarred = "unstarred fa-star-o"; - $indent = ''; - $osparkle = ''; - $total_children = $this->count_descendants(); - $unseen_comments = (($item['real_uid']) ? 0 : $this->count_unseen_descendants()); - - $conv = $this->get_conversation(); - $observer = $conv->get_observer(); - - $lock = ((($item['item_private'] == 1) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) - || strlen($item['deny_cid']) || strlen($item['deny_gid'])))) - ? t('Private Message') - : false); - $shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && ($item['item_private'] != 1)) ? true : false); - - // allow an exemption for sharing stuff from your private feeds - if($item['author']['xchan_network'] === 'rss') - $shareable = true; - - $mode = $conv->get_mode(); - - if(local_channel() && $observer['xchan_hash'] === $item['author_xchan']) - $edpost = array(z_root()."/editpost/".$item['id'], t("Edit")); - else - $edpost = false; - - - if($observer['xchan_hash'] == $this->get_data_value('author_xchan') - || $observer['xchan_hash'] == $this->get_data_value('owner_xchan') - || $this->get_data_value('uid') == local_channel()) - $dropping = true; - - - if(array_key_exists('real_uid',$item)) { - $edpost = false; - $dropping = false; - } - - - if($dropping) { - $drop = array( - 'dropping' => $dropping, - 'delete' => t('Delete'), - ); - } -// FIXME - if($observer_is_pageowner) { - $multidrop = array( - 'select' => t('Select'), - ); - } - - $filer = ((($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) ? t("Save to Folder") : false); - - $profile_avatar = $item['author']['xchan_photo_m']; - $profile_link = chanlink_url($item['author']['xchan_url']); - $profile_name = $item['author']['xchan_name']; - - $location = format_location($item); - $isevent = false; - $attend = null; - $canvote = false; - - // process action responses - e.g. like/dislike/attend/agree/whatever - $response_verbs = array('like'); - if(feature_enabled($conv->get_profile_owner(),'dislike')) - $response_verbs[] = 'dislike'; - if($item['obj_type'] === ACTIVITY_OBJ_EVENT) { - $response_verbs[] = 'attendyes'; - $response_verbs[] = 'attendno'; - $response_verbs[] = 'attendmaybe'; - if($this->is_commentable()) { - $isevent = true; - $attend = array( t('I will attend'), t('I will not attend'), t('I might attend')); - } - } - - $consensus = (intval($item['item_consensus']) ? true : false); - if($consensus) { - $response_verbs[] = 'agree'; - $response_verbs[] = 'disagree'; - $response_verbs[] = 'abstain'; - if($this->is_commentable()) { - $conlabels = array( t('I agree'), t('I disagree'), t('I abstain')); - $canvote = true; - } - } - - if(! feature_enabled($conv->get_profile_owner(),'dislike')) - unset($conv_responses['dislike']); - - $responses = get_responses($conv_responses,$response_verbs,$this,$item); - - $like_count = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid']] : ''); - $like_list = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid'] . '-l'] : ''); - if (count($like_list) > MAX_LIKERS) { - $like_list_part = array_slice($like_list, 0, MAX_LIKERS); - array_push($like_list_part, '' . t('View all') . ''); - } else { - $like_list_part = ''; - } - $like_button_label = tt('Like','Likes',$like_count,'noun'); - - if (feature_enabled($conv->get_profile_owner(),'dislike')) { - $dislike_count = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid']] : ''); - $dislike_list = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid'] . '-l'] : ''); - $dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun'); - if (count($dislike_list) > MAX_LIKERS) { - $dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS); - array_push($dislike_list_part, '' . t('View all') . ''); - } else { - $dislike_list_part = ''; - } - } - - $showlike = ((x($conv_responses['like'],$item['mid'])) ? format_like($conv_responses['like'][$item['mid']],$conv_responses['like'][$item['mid'] . '-l'],'like',$item['mid']) : ''); - $showdislike = ((x($conv_responses['dislike'],$item['mid']) && feature_enabled($conv->get_profile_owner(),'dislike')) - ? format_like($conv_responses['dislike'][$item['mid']],$conv_responses['dislike'][$item['mid'] . '-l'],'dislike',$item['mid']) : ''); - - /* - * We should avoid doing this all the time, but it depends on the conversation mode - * And the conv mode may change when we change the conv, or it changes its mode - * Maybe we should establish a way to be notified about conversation changes - */ - - $this->check_wall_to_wall(); - - if($this->is_toplevel()) { - // FIXME check this permission - if(($conv->get_profile_owner() == local_channel()) && (! array_key_exists('real_uid',$item))) { - -// FIXME we don't need all this stuff, some can be done in the template - - $star = array( - 'do' => t("Add Star"), - 'undo' => t("Remove Star"), - 'toggle' => t("Toggle Star Status"), - 'classdo' => (intval($item['item_starred']) ? "hidden" : ""), - 'classundo' => (intval($item['item_starred']) ? "" : "hidden"), - 'isstarred' => (intval($item['item_starred']) ? "starred fa-star" : "unstarred fa-star-o"), - 'starred' => t('starred'), - ); - - } - } else { - $indent = 'comment'; - } - - - $verified = (intval($item['item_verified']) ? t('Message signature validated') : ''); - $forged = ((($item['sig']) && (! intval($item['item_verified']))) ? t('Message signature incorrect') : ''); - $unverified = '' ; // (($this->is_wall_to_wall() && (! intval($item['item_verified']))) ? t('Message cannot be verified') : ''); - - - - // FIXME - check this permission - if($conv->get_profile_owner() == local_channel()) { - $tagger = array( - 'tagit' => t("Add Tag"), - 'classtagger' => "", - ); - } - - $has_bookmarks = false; - if(is_array($item['term'])) { - foreach($item['term'] as $t) { - if(!UNO && $t['type'] == TERM_BOOKMARK) - $has_bookmarks = true; - } - } - - $has_event = false; - if(($item['obj_type'] === ACTIVITY_OBJ_EVENT) && $conv->get_profile_owner() == local_channel()) - $has_event = true; - - if($this->is_commentable()) { - $like = array( t("I like this \x28toggle\x29"), t("like")); - $dislike = array( t("I don't like this \x28toggle\x29"), t("dislike")); - } - - if ($shareable) - $share = array( t('Share This'), t('share')); - - $dreport = ''; - - $keep_reports = intval(get_config('system','expire_delivery_reports')); - if($keep_reports === 0) - $keep_reports = 30; - - if((! get_config('system','disable_dreport')) && strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC',"now - $keep_reports days")) > 0) - $dreport = t('Delivery Report'); - - if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0) - $indent .= ' shiny'; - - - localize_item($item); - - $body = prepare_body($item,true); - - // $viewthread (below) is only valid in list mode. If this is a channel page, build the thread viewing link - // since we can't depend on llink or plink pointing to the right local location. - - $owner_address = substr($item['owner']['xchan_addr'],0,strpos($item['owner']['xchan_addr'],'@')); - $viewthread = $item['llink']; - if($conv->get_mode() === 'channel') - $viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . $item['mid']; - - $comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children ); - $list_unseen_txt = (($unseen_comments) ? sprintf('%d unseen',$unseen_comments) : ''); - - - - - - $children = $this->get_children(); - - $has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false); - - $tmp_item = array( - 'template' => $this->get_template(), - 'mode' => $mode, - 'type' => implode("",array_slice(explode("/",$item['verb']),-1)), - 'body' => $body['html'], - 'tags' => $body['tags'], - 'categories' => $body['categories'], - 'mentions' => $body['mentions'], - 'attachments' => $body['attachments'], - 'folders' => $body['folders'], - 'text' => strip_tags($body['html']), - 'id' => $this->get_id(), - 'mid' => $item['mid'], - 'isevent' => $isevent, - 'attend' => $attend, - 'consensus' => $consensus, - 'conlabels' => $conlabels, - 'canvote' => $canvote, - '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']), - 'llink' => $item['llink'], - 'viewthread' => $viewthread, - 'to' => t('to'), - 'via' => t('via'), - 'wall' => t('Wall-to-Wall'), - 'vwall' => t('via Wall-To-Wall:'), - 'profile_url' => $profile_link, - 'item_photo_menu' => item_photo_menu($item), - 'dreport' => $dreport, - 'name' => $profile_name, - 'thumb' => $profile_avatar, - 'osparkle' => $osparkle, - 'sparkle' => $sparkle, - 'title' => $item['title'], - 'title_tosource' => get_pconfig($conv->get_profile_owner(),'system','title_tosource'), - 'ago' => relative_date($item['created']), - 'app' => $item['app'], - 'str_app' => sprintf( t('from %s'), $item['app']), - 'isotime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'c'), - 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'), - 'editedtime' => (($item['edited'] != $item['created']) ? sprintf( t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''), - 'expiretime' => (($item['expires'] !== NULL_DATE) ? sprintf( t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')):''), - 'lock' => $lock, - 'verified' => $verified, - 'unverified' => $unverified, - 'forged' => $forged, - 'location' => $location, - 'indent' => $indent, - 'owner_url' => $this->get_owner_url(), - 'owner_photo' => $this->get_owner_photo(), - 'owner_name' => $this->get_owner_name(), - 'photo' => $body['photo'], - 'event' => $body['event'], - 'has_tags' => $has_tags, - -// Item toolbar buttons - 'like' => $like, - 'dislike' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike : ''), - 'share' => $share, - 'rawmid' => $item['mid'], - 'plink' => get_plink($item), - 'edpost' => $edpost, // ((feature_enabled($conv->get_profile_owner(),'edit_posts')) ? $edpost : ''), - 'star' => ((feature_enabled($conv->get_profile_owner(),'star_posts')) ? $star : ''), - 'tagger' => ((feature_enabled($conv->get_profile_owner(),'commtag')) ? $tagger : ''), - 'filer' => ((feature_enabled($conv->get_profile_owner(),'filing')) ? $filer : ''), - 'bookmark' => (($conv->get_profile_owner() == local_channel() && local_channel() && $has_bookmarks) ? t('Save Bookmarks') : ''), - 'addtocal' => (($has_event) ? t('Add to Calendar') : ''), - 'drop' => $drop, - 'multidrop' => ((feature_enabled($conv->get_profile_owner(),'multi_delete')) ? $multidrop : ''), -// end toolbar buttons - - 'unseen_comments' => $unseen_comments, - 'comment_count' => $total_children, - 'comment_count_txt' => $comment_count_txt, - 'list_unseen_txt' => $list_unseen_txt, - 'markseen' => t('Mark all seen'), - 'responses' => $responses, - 'like_count' => $like_count, - 'like_list' => $like_list, - 'like_list_part' => $like_list_part, - 'like_button_label' => $like_button_label, - 'like_modal_title' => t('Likes','noun'), - 'dislike_modal_title' => t('Dislikes','noun'), - 'dislike_count' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_count : ''), - 'dislike_list' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list : ''), - 'dislike_list_part' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_list_part : ''), - 'dislike_button_label' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike_button_label : ''), - 'modal_dismiss' => t('Close'), - 'showlike' => $showlike, - 'showdislike' => $showdislike, - 'comment' => $this->get_comment_box($indent), - 'previewing' => ($conv->is_preview() ? ' preview ' : ''), - 'wait' => t('Please wait'), - 'thread_level' => $thread_level - ); - - $arr = array('item' => $item, 'output' => $tmp_item); - call_hooks('display_item', $arr); - - $result = $arr['output']; - - $result['children'] = array(); - $nb_children = count($children); - - $visible_comments = get_config('system','expanded_comments'); - if($visible_comments === false) - $visible_comments = 3; - - if(($this->get_display_mode() === 'normal') && ($nb_children > 0)) { - foreach($children as $child) { - $result['children'][] = $child->get_template_data($conv_responses, $thread_level + 1); - } - // Collapse - if(($nb_children > $visible_comments) || ($thread_level > 1)) { - $result['children'][0]['comment_firstcollapsed'] = true; - $result['children'][0]['num_comments'] = $comment_count_txt; - $result['children'][0]['hide_text'] = t('[+] show all'); - if($thread_level > 1) { - $result['children'][$nb_children - 1]['comment_lastcollapsed'] = true; - } - else { - $result['children'][$nb_children - ($visible_comments + 1)]['comment_lastcollapsed'] = true; - } - } - } - - $result['private'] = $item['item_private']; - $result['toplevel'] = ($this->is_toplevel() ? 'toplevel_item' : ''); - - if($this->is_threaded()) { - $result['flatten'] = false; - $result['threaded'] = true; - } - else { - $result['flatten'] = true; - $result['threaded'] = false; - } - - return $result; - } - - public function get_id() { - return $this->get_data_value('id'); - } - - public function get_display_mode() { - return $this->display_mode; - } - - public function set_display_mode($mode) { - $this->display_mode = $mode; - } - - public function is_threaded() { - return $this->threaded; - } - - public function set_commentable($val) { - $this->commentable = $val; - foreach($this->get_children() as $child) - $child->set_commentable($val); - } - - public function is_commentable() { - return $this->commentable; - } - - /** - * Add a child item - */ - public function add_child($item) { - $item_id = $item->get_id(); - if(!$item_id) { - logger('[ERROR] Item::add_child : Item has no ID!!', LOGGER_DEBUG); - return false; - } - if($this->get_child($item->get_id())) { - logger('[WARN] Item::add_child : Item already exists ('. $item->get_id() .').', LOGGER_DEBUG); - return false; - } - /* - * Only add what will be displayed - */ - - if(activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE)) { - return false; - } - - $item->set_parent($this); - $this->children[] = $item; - return end($this->children); - } - - /** - * Get a child by its ID - */ - public function get_child($id) { - foreach($this->get_children() as $child) { - if($child->get_id() == $id) - return $child; - } - return null; - } - - /** - * Get all our children - */ - public function get_children() { - return $this->children; - } - - /** - * Set our parent - */ - protected function set_parent($item) { - $parent = $this->get_parent(); - if($parent) { - $parent->remove_child($this); - } - $this->parent = $item; - $this->set_conversation($item->get_conversation()); - } - - /** - * Remove our parent - */ - protected function remove_parent() { - $this->parent = null; - $this->conversation = null; - } - - /** - * Remove a child - */ - public function remove_child($item) { - $id = $item->get_id(); - foreach($this->get_children() as $key => $child) { - if($child->get_id() == $id) { - $child->remove_parent(); - unset($this->children[$key]); - // Reindex the array, in order to make sure there won't be any trouble on loops using count() - $this->children = array_values($this->children); - return true; - } - } - logger('[WARN] Item::remove_child : Item is not a child ('. $id .').', LOGGER_DEBUG); - return false; - } - - /** - * Get parent item - */ - protected function get_parent() { - return $this->parent; - } - - /** - * set conversation - */ - public function set_conversation($conv) { - $previous_mode = ($this->conversation ? $this->conversation->get_mode() : ''); - - $this->conversation = $conv; - - // Set it on our children too - foreach($this->get_children() as $child) - $child->set_conversation($conv); - } - - /** - * get conversation - */ - public function get_conversation() { - return $this->conversation; - } - - /** - * Get raw data - * - * We shouldn't need this - */ - public function get_data() { - return $this->data; - } - - /** - * Get a data value - * - * Returns: - * _ value on success - * _ false on failure - */ - public function get_data_value($name) { - if(!isset($this->data[$name])) { -// logger('[ERROR] Item::get_data_value : Item has no value name "'. $name .'".', LOGGER_DEBUG); - return false; - } - - return $this->data[$name]; - } - - /** - * Get template - */ - public function get_template() { - return $this->template; - } - - - public function set_template($t) { - $this->template = $t; - } - - /** - * Check if this is a toplevel post - */ - private function is_toplevel() { - return $this->toplevel; - } - - /** - * Count the total of our descendants - */ - private function count_descendants() { - $children = $this->get_children(); - $total = count($children); - if($total > 0) { - foreach($children as $child) { - $total += $child->count_descendants(); - } - } - return $total; - } - - private function count_unseen_descendants() { - $children = $this->get_children(); - $total = count($children); - if($total > 0) { - $total = 0; - foreach($children as $child) { - if((! visible_activity($child->data)) || array_key_exists('author_blocked',$child->data)) { - continue; - } - if(intval($child->data['item_unseen'])) - $total ++; - } - } - return $total; - } - - - /** - * Get the template for the comment box - */ - private function get_comment_box_template() { - return $this->comment_box_template; - } - - /** - * Get the comment box - * - * Returns: - * _ The comment box string (empty if no comment box) - * _ false on failure - */ - private function get_comment_box($indent) { - - if(!$this->is_toplevel() && !get_config('system','thread_allow')) { - return ''; - } - - $comment_box = ''; - $conv = $this->get_conversation(); - -// logger('Commentable conv: ' . $conv->is_commentable()); - - if(! $this->is_commentable()) - return; - - $template = get_markup_template($this->get_comment_box_template()); - - $a = $this->get_app(); - $observer = $conv->get_observer(); - - $qc = ((local_channel()) ? get_pconfig(local_channel(),'system','qcomment') : null); - $qcomment = (($qc) ? explode("\n",$qc) : null); - - $arr = array('comment_buttons' => '','id' => $this->get_id()); - call_hooks('comment_buttons',$arr); - $comment_buttons = $arr['comment_buttons']; - - - $comment_box = replace_macros($template,array( - '$return_path' => '', - '$threaded' => $this->is_threaded(), - '$jsreload' => '', //(($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''), - '$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'), - '$id' => $this->get_id(), - '$parent' => $this->get_id(), - '$qcomment' => $qcomment, - '$comment_buttons' => $comment_buttons, - '$profile_uid' => $conv->get_profile_owner(), - '$mylink' => $observer['xchan_url'], - '$mytitle' => t('This is you'), - '$myphoto' => $observer['xchan_photo_s'], - '$comment' => t('Comment'), - '$submit' => t('Submit'), - '$edbold' => t('Bold'), - '$editalic' => t('Italic'), - '$eduline' => t('Underline'), - '$edquote' => t('Quote'), - '$edcode' => t('Code'), - '$edimg' => t('Image'), - '$edurl' => t('Insert Link'), - '$edvideo' => t('Video'), - '$preview' => t('Preview'), // ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''), - '$indent' => $indent, - '$feature_encrypt' => ((feature_enabled($conv->get_profile_owner(),'content_encrypt')) ? true : false), - '$encrypt' => t('Encrypt text'), - '$cipher' => $conv->get_cipher(), - '$sourceapp' => App::$sourcename - - )); - - return $comment_box; - } - - private function get_redirect_url() { - return $this->redirect_url; - } - - /** - * Check if we are a wall to wall item and set the relevant properties - */ - protected function check_wall_to_wall() { - $conv = $this->get_conversation(); - $this->wall_to_wall = false; - $this->owner_url = ''; - $this->owner_photo = ''; - $this->owner_name = ''; - - if($conv->get_mode() === 'channel') - return; - - if($this->is_toplevel() && ($this->get_data_value('author_xchan') != $this->get_data_value('owner_xchan'))) { - $this->owner_url = chanlink_url($this->data['owner']['xchan_url']); - $this->owner_photo = $this->data['owner']['xchan_photo_m']; - $this->owner_name = $this->data['owner']['xchan_name']; - $this->wall_to_wall = true; - } - } - - private function is_wall_to_wall() { - return $this->wall_to_wall; - } - - private function get_owner_url() { - return $this->owner_url; - } - - private function get_owner_photo() { - return $this->owner_photo; - } - - private function get_owner_name() { - return $this->owner_name; - } - - private function is_visiting() { - return $this->visiting; - } - - - - -} - diff --git a/include/api.php b/include/api.php index 5f4d4bedb..4a462d1e8 100644 --- a/include/api.php +++ b/include/api.php @@ -2107,10 +2107,10 @@ require_once('include/api_auth.php'); 'private' => $private, 'textlimit' => $textlimit, 'sslserver' => $sslserver, 'ssl' => $ssl, 'shorturllength' => '30', 'hubzilla' => array( - 'PLATFORM_NAME' => Zotlabs\Project\System::get_platform_name(), - 'STD_VERSION' => Zotlabs\Project\System::get_project_version(), + 'PLATFORM_NAME' => Zotlabs\Lib\System::get_platform_name(), + 'STD_VERSION' => Zotlabs\Lib\System::get_project_version(), 'ZOT_REVISION' => ZOT_REVISION, - 'DB_UPDATE_VERSION' => Zotlabs\Project\System::get_update_version() + 'DB_UPDATE_VERSION' => Zotlabs\Lib\System::get_update_version() ) )); @@ -2143,12 +2143,12 @@ require_once('include/api_auth.php'); if($type === 'xml') { header("Content-type: application/xml"); - echo '' . "\r\n" . '' . Zotlabs\Project\System::get_project_version() . '' . "\r\n"; + echo '' . "\r\n" . '' . Zotlabs\Lib\System::get_project_version() . '' . "\r\n"; killme(); } elseif($type === 'json') { header("Content-type: application/json"); - echo '"' . Zotlabs\Project\System::get_project_version() . '"'; + echo '"' . Zotlabs\Lib\System::get_project_version() . '"'; killme(); } } diff --git a/include/conversation.php b/include/conversation.php index 8be0557e7..fca07a91d 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -754,10 +754,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ // Normal View // logger('conv: items: ' . print_r($items,true)); - require_once('include/ConversationObject.php'); - require_once('include/ItemObject.php'); - - $conv = new Conversation($mode, $preview, $prepared_item); + $conv = new Zotlabs\Lib\ThreadStream($mode, $preview, $prepared_item); // In the display mode we don't have a profile owner. @@ -806,7 +803,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ if($item['id'] == $item['parent']) { - $item_object = new Item($item); + $item_object = new Zotlabs\Lib\ThreadItem($item); $conv->add_thread($item_object); if($page_mode === 'list') { $item_object->set_template('conv_list.tpl'); diff --git a/include/enotify.php b/include/enotify.php index d87c5af11..bd8698606 100644 --- a/include/enotify.php +++ b/include/enotify.php @@ -529,7 +529,7 @@ function notification($params) { $tpl = get_markup_template('email_notify_html.tpl'); $email_html_body = replace_macros($tpl,array( '$banner' => $datarray['banner'], - '$notify_icon' => Zotlabs\Project\System::get_notify_icon(), + '$notify_icon' => Zotlabs\Lib\System::get_notify_icon(), '$product' => $datarray['product'], '$preamble' => $datarray['preamble'], '$sitename' => $datarray['sitename'], diff --git a/include/event.php b/include/event.php index e41bf2db7..29ca5bb79 100644 --- a/include/event.php +++ b/include/event.php @@ -67,7 +67,7 @@ function ical_wrapper($ev) { $o .= "BEGIN:VCALENDAR"; $o .= "\r\nVERSION:2.0"; $o .= "\r\nMETHOD:PUBLISH"; - $o .= "\r\nPRODID:-//" . get_config('system','sitename') . "//" . Zotlabs\Project\System::get_platform_name() . "//" . strtoupper(App::$language). "\r\n"; + $o .= "\r\nPRODID:-//" . get_config('system','sitename') . "//" . Zotlabs\Lib\System::get_platform_name() . "//" . strtoupper(App::$language). "\r\n"; if(array_key_exists('start', $ev)) $o .= format_event_ical($ev); else { diff --git a/include/feedutils.php b/include/feedutils.php index 2ba5efe22..700198ff8 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -88,8 +88,8 @@ function get_feed_for($channel, $observer_hash, $params) { $atom = ''; $atom .= replace_macros($feed_template, array( - '$version' => xmlify(Zotlabs\Project\System::get_project_version()), - '$red' => xmlify(Zotlabs\Project\System::get_platform_name()), + '$version' => xmlify(Zotlabs\Lib\System::get_project_version()), + '$red' => xmlify(Zotlabs\Lib\System::get_platform_name()), '$feed_id' => xmlify($channel['xchan_url']), '$feed_title' => xmlify($channel['channel_name']), '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now' , ATOM_TIME)) , diff --git a/include/identity.php b/include/identity.php index 206dad084..4ef1105ea 100644 --- a/include/identity.php +++ b/include/identity.php @@ -491,7 +491,7 @@ function identity_basic_export($channel_id, $items = false) { // use constants here as otherwise we will have no idea if we can import from a site // with a non-standard platform and version. - $ret['compatibility'] = array('project' => PLATFORM_NAME, 'version' => STD_VERSION, 'database' => DB_UPDATE_VERSION, 'server_role' => Zotlabs\Project\System::get_server_role()); + $ret['compatibility'] = array('project' => PLATFORM_NAME, 'version' => STD_VERSION, 'database' => DB_UPDATE_VERSION, 'server_role' => Zotlabs\Lib\System::get_server_role()); $r = q("select * from channel where channel_id = %d limit 1", intval($channel_id) diff --git a/include/language.php b/include/language.php index d6b7606ca..14139e90c 100644 --- a/include/language.php +++ b/include/language.php @@ -189,7 +189,7 @@ function t($s, $ctx = '') { function translate_projectname($s) { - return str_replace(array('$projectname','$Projectname'),array(Zotlabs\Project\System::get_platform_name(),ucfirst(Zotlabs\Project\System::get_platform_name())),$s); + return str_replace(array('$projectname','$Projectname'),array(Zotlabs\Lib\System::get_platform_name(),ucfirst(Zotlabs\Lib\System::get_platform_name())),$s); } diff --git a/include/network.php b/include/network.php index f38f8d548..3e5263d3e 100644 --- a/include/network.php +++ b/include/network.php @@ -1839,7 +1839,7 @@ function format_and_send_email($sender,$xchan,$item) { $tpl = get_markup_template('email_notify_html.tpl'); $email_html_body = replace_macros($tpl,array( '$banner' => $banner, - '$notify_icon' => Zotlabs\Project\System::get_notify_icon(), + '$notify_icon' => Zotlabs\Lib\System::get_notify_icon(), '$product' => $product, '$preamble' => '', '$sitename' => $sitename, @@ -1990,8 +1990,8 @@ function get_site_info() { $site_info = get_config('system','info'); $site_name = get_config('system','sitename'); if(! get_config('system','hidden_version_siteinfo')) { - $version = Zotlabs\Project\System::get_project_version(); - $tag = Zotlabs\Project\System::get_std_version(); + $version = Zotlabs\Lib\System::get_project_version(); + $tag = Zotlabs\Lib\System::get_std_version(); if(@is_dir('.git') && function_exists('shell_exec')) { $commit = trim( @shell_exec('git log -1 --format="%h"')); @@ -2027,7 +2027,7 @@ function get_site_info() { $data = Array( 'version' => $version, 'version_tag' => $tag, - 'server_role' => Zotlabs\Project\System::get_server_role(), + 'server_role' => Zotlabs\Lib\System::get_server_role(), 'commit' => $commit, 'url' => z_root(), 'plugins' => $visible_plugins, @@ -2041,7 +2041,7 @@ function get_site_info() { 'locked_features' => $locked_features, 'admin' => $admin, 'site_name' => (($site_name) ? $site_name : ''), - 'platform' => Zotlabs\Project\System::get_platform_name(), + 'platform' => Zotlabs\Lib\System::get_platform_name(), 'dbdriver' => $db->getdriver(), 'lastpoll' => get_config('system','lastpoll'), 'info' => (($site_info) ? $site_info : ''), diff --git a/include/zot.php b/include/zot.php index 5884245e9..54a3fe640 100644 --- a/include/zot.php +++ b/include/zot.php @@ -3924,7 +3924,7 @@ function zotinfo($arr) { $ret['site']['channels'] = channel_total(); - $ret['site']['version'] = Zotlabs\Project\System::get_platform_name() . ' ' . STD_VERSION . '[' . DB_UPDATE_VERSION . ']'; + $ret['site']['version'] = Zotlabs\Lib\System::get_platform_name() . ' ' . STD_VERSION . '[' . DB_UPDATE_VERSION . ']'; $ret['site']['admin'] = get_config('system','admin_email'); @@ -3944,7 +3944,7 @@ function zotinfo($arr) { $ret['site']['sellpage'] = get_config('system','sellpage'); $ret['site']['location'] = get_config('system','site_location'); $ret['site']['realm'] = get_directory_realm(); - $ret['site']['project'] = Zotlabs\Project\System::get_platform_name() . Zotlabs\Project\System::get_server_role(); + $ret['site']['project'] = Zotlabs\Lib\System::get_platform_name() . Zotlabs\Lib\System::get_server_role(); } -- cgit v1.2.3 From bf050121506aa4cb487d9efd9cfdaa501ada3b1a Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 20 May 2016 23:12:06 -0700 Subject: relocate the (unused currently) protocol driver --- include/ProtoDriver.php | 43 ------------------------------------------- 1 file changed, 43 deletions(-) delete mode 100644 include/ProtoDriver.php (limited to 'include') diff --git a/include/ProtoDriver.php b/include/ProtoDriver.php deleted file mode 100644 index 7585a0135..000000000 --- a/include/ProtoDriver.php +++ /dev/null @@ -1,43 +0,0 @@ - Date: Sat, 21 May 2016 14:56:42 -0400 Subject: Trying to fix wiki branch starting fresh from dev --- include/widgets.php | 27 ++++++++++++++++++ include/wiki.php | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 include/wiki.php (limited to 'include') diff --git a/include/widgets.php b/include/widgets.php index 2641a718e..acbd9bcd3 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -857,6 +857,33 @@ function widget_chatroom_members() { return $o; } +function widget_wiki_list($arr) { + + require_once("include/wiki.php"); + $r = wiki_list(App::$profile['channel_hash']); + + if($r) { + return replace_macros(get_markup_template('wikilist.tpl'), array( + '$header' => t('Wiki List'), + '$read' => $r['read'], + '$write' => $r['write'] + )); + } +} + +function widget_wiki_pages($arr) { + + require_once("include/wiki.php"); + $r = wiki_pages(App::$profile['channel_hash']); + + if($r) { + return replace_macros(get_markup_template('wiki_page_list.tpl'), array( + '$header' => t('Wiki Pages'), + '$pages' => $r['pages'] + )); + } +} + function widget_bookmarkedchats($arr) { if(! feature_enabled(App::$profile['profile_uid'],'ajaxchat')) diff --git a/include/wiki.php b/include/wiki.php new file mode 100644 index 000000000..4f4d978e1 --- /dev/null +++ b/include/wiki.php @@ -0,0 +1,82 @@ + array('wiki1'), 'read' => array('wiki1', 'wiki2')); +} + +function wiki_pages() { + // TODO: scan wiki folder for pages + return array('pages' => array('page1.md', 'page2.md')); +} + +function wiki_create_wiki($channel, $name, $acl) { + + // Generate unique resource_id using the same method as item_message_id() + do { + $dups = false; + $resource_id = random_string(); + $r = q("SELECT mid FROM item WHERE resource_id = '%s' AND resource_type = '%s' AND uid = %d LIMIT 1", + dbesc($resource_id), + dbesc(WIKI_ITEM_RESOURCE_TYPE), + intval($channel['channel_id']) + ); + if (count($r)) + $dups = true; + } while ($dups == true); + $ac = $acl->get(); + $mid = item_message_id(); + $arr = array(); // Initialize the array of parameters for the post + $perms = $acl->get(); + $allow_cid = expand_acl($perms['allow_cid']); + $players = array($channel['channel_hash'], $allow_cid[0]); + + $item_hidden = 0; // TODO: Allow form creator to send post to ACL about new game automatically + $game_url = z_root() . '/chess/' . $channel['channel_address'] . '/' . $resource_id; + $arr['aid'] = $channel['channel_account_id']; + $arr['uid'] = $channel['channel_id']; + $arr['mid'] = $mid; + $arr['parent_mid'] = $mid; + $arr['item_hidden'] = $item_hidden; + $arr['resource_type'] = WIKI_ITEM_RESOURCE_TYPE; + $arr['resource_id'] = $resource_id; + $arr['owner_xchan'] = $channel['channel_hash']; + $arr['author_xchan'] = $channel['channel_hash']; + // Store info about the type of chess item using the "title" field + // Other types include 'move' for children items but may in the future include + // additional types that will determine how the "object" field is interpreted + $arr['title'] = $name; + $arr['allow_cid'] = $ac['allow_cid']; + $arr['item_wall'] = 1; + $arr['item_origin'] = 1; + $arr['item_thread_top'] = 1; + $arr['item_private'] = intval($acl->is_private()); + $arr['verb'] = ACTIVITY_CREATE; + $arr['obj_type'] = ACTIVITY_OBJ_WIKI; + $arr['object'] = $object; + $arr['body'] = '[table][tr][td][h1]New Chess Game[/h1][/td][/tr][tr][td][zrl='.$game_url.']Click here to play[/zrl][/td][/tr][/table]'; + + $post = item_store($arr); + $item_id = $post['item_id']; + + if ($item_id) { + proc_run('php', "include/notifier.php", "activity", $item_id); + return array('item' => $arr, 'status' => true); + } else { + return array('item' => null, 'status' => false); + } +} \ No newline at end of file -- cgit v1.2.3 From 049147a9d78b981482297c3daf48c67f31754259 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 21 May 2016 19:02:23 -0400 Subject: Successful new wiki git repo and item table record --- include/wiki.php | 129 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 54 deletions(-) (limited to 'include') diff --git a/include/wiki.php b/include/wiki.php index 4f4d978e1..32caa98e8 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -4,6 +4,7 @@ * @brief Wiki related functions. */ +use \Zotlabs\Storage\GitRepo as GitRepo; define ( 'WIKI_ITEM_RESOURCE_TYPE', 'wiki' ); function wiki_create() { @@ -24,59 +25,79 @@ function wiki_pages() { return array('pages' => array('page1.md', 'page2.md')); } -function wiki_create_wiki($channel, $name, $acl) { +function wiki_init_wiki($channel, $name) { + // Store the path as a relative path, but pass absolute path to mkdir + $path = 'store/[data]/git/'.$channel['channel_address'].'/wiki/'.$name; + if (!mkdir(__DIR__ . '/../' . $path, 0770, true)) { + logger('Error creating wiki path: ' . $name); + return null; + } + // Create GitRepo object + $git = new GitRepo($channel['channel_address'], null, false, $name, __DIR__ . '/../' . $path); + if(!$git->initRepo()) { + logger('Error creating new git repo in ' . $git->path); + return null; + } + + return array('path' => $path); +} - // Generate unique resource_id using the same method as item_message_id() - do { - $dups = false; - $resource_id = random_string(); - $r = q("SELECT mid FROM item WHERE resource_id = '%s' AND resource_type = '%s' AND uid = %d LIMIT 1", - dbesc($resource_id), - dbesc(WIKI_ITEM_RESOURCE_TYPE), - intval($channel['channel_id']) - ); - if (count($r)) - $dups = true; - } while ($dups == true); - $ac = $acl->get(); - $mid = item_message_id(); - $arr = array(); // Initialize the array of parameters for the post - $perms = $acl->get(); - $allow_cid = expand_acl($perms['allow_cid']); - $players = array($channel['channel_hash'], $allow_cid[0]); - - $item_hidden = 0; // TODO: Allow form creator to send post to ACL about new game automatically - $game_url = z_root() . '/chess/' . $channel['channel_address'] . '/' . $resource_id; - $arr['aid'] = $channel['channel_account_id']; - $arr['uid'] = $channel['channel_id']; - $arr['mid'] = $mid; - $arr['parent_mid'] = $mid; - $arr['item_hidden'] = $item_hidden; - $arr['resource_type'] = WIKI_ITEM_RESOURCE_TYPE; - $arr['resource_id'] = $resource_id; - $arr['owner_xchan'] = $channel['channel_hash']; - $arr['author_xchan'] = $channel['channel_hash']; - // Store info about the type of chess item using the "title" field - // Other types include 'move' for children items but may in the future include - // additional types that will determine how the "object" field is interpreted - $arr['title'] = $name; - $arr['allow_cid'] = $ac['allow_cid']; - $arr['item_wall'] = 1; - $arr['item_origin'] = 1; - $arr['item_thread_top'] = 1; - $arr['item_private'] = intval($acl->is_private()); - $arr['verb'] = ACTIVITY_CREATE; - $arr['obj_type'] = ACTIVITY_OBJ_WIKI; - $arr['object'] = $object; - $arr['body'] = '[table][tr][td][h1]New Chess Game[/h1][/td][/tr][tr][td][zrl='.$game_url.']Click here to play[/zrl][/td][/tr][/table]'; - - $post = item_store($arr); - $item_id = $post['item_id']; +function wiki_create_wiki($channel, $observer_hash, $name, $acl) { + $wikiinit = wiki_init_wiki($channel, $name); + if (!$wikiinit['path']) { + notice('Error creating wiki'); + return array('item' => null, 'success' => false); + } + $path = $wikiinit['path']; + // Generate unique resource_id using the same method as item_message_id() + do { + $dups = false; + $resource_id = random_string(); + $r = q("SELECT mid FROM item WHERE resource_id = '%s' AND resource_type = '%s' AND uid = %d LIMIT 1", + dbesc($resource_id), + dbesc(WIKI_ITEM_RESOURCE_TYPE), + intval($channel['channel_id']) + ); + if (count($r)) + $dups = true; + } while ($dups == true); + $ac = $acl->get(); + $mid = item_message_id(); + $arr = array(); // Initialize the array of parameters for the post + $item_hidden = 0; // TODO: Allow form creator to send post to ACL about new game automatically + $wiki_url = z_root() . '/wiki/' . $channel['channel_address'] . '/' . $name; + $arr['aid'] = $channel['channel_account_id']; + $arr['uid'] = $channel['channel_id']; + $arr['mid'] = $mid; + $arr['parent_mid'] = $mid; + $arr['item_hidden'] = $item_hidden; + $arr['resource_type'] = WIKI_ITEM_RESOURCE_TYPE; + $arr['resource_id'] = $resource_id; + $arr['owner_xchan'] = $channel['channel_hash']; + $arr['author_xchan'] = $observer_hash; + $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid']; + $arr['llink'] = $arr['plink']; + $arr['title'] = $name; // name of new wiki; + $arr['allow_cid'] = $ac['allow_cid']; + $arr['allow_gid'] = $ac['allow_gid']; + $arr['deny_cid'] = $ac['deny_cid']; + $arr['deny_gid'] = $ac['deny_gid']; + $arr['item_wall'] = 1; + $arr['item_origin'] = 1; + $arr['item_thread_top'] = 1; + $arr['item_private'] = intval($acl->is_private()); + $arr['verb'] = ACTIVITY_CREATE; + $arr['obj_type'] = ACTIVITY_OBJ_WIKI; + $arr['object'] = array('path' => $path); + $arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $name . '[/zrl][/td][/tr][/table]'; - if ($item_id) { - proc_run('php', "include/notifier.php", "activity", $item_id); - return array('item' => $arr, 'status' => true); - } else { - return array('item' => null, 'status' => false); - } -} \ No newline at end of file + $post = item_store($arr); + $item_id = $post['item_id']; + + if ($item_id) { + proc_run('php', "include/notifier.php", "activity", $item_id); + return array('item' => $arr, 'success' => true); + } else { + return array('item' => null, 'success' => false); + } +} -- cgit v1.2.3 From ed56b6e67b27900e2ff413a7781c9095aa8251a0 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 21 May 2016 18:02:14 -0700 Subject: first cut at zot-finger request signatures --- include/zot.php | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/zot.php b/include/zot.php index 54a3fe640..f5fb87e12 100644 --- a/include/zot.php +++ b/include/zot.php @@ -3672,6 +3672,8 @@ function zotinfo($arr) { $zsig = ((x($arr,'target_sig')) ? $arr['target_sig'] : ''); $zkey = ((x($arr,'key')) ? $arr['key'] : ''); $mindate = ((x($arr,'mindate')) ? $arr['mindate'] : ''); + $token = ((x($arr,'token')) ? $arr['token'] : ''); + $feed = ((x($arr,'feed')) ? intval($arr['feed']) : 0); if($ztarget) { @@ -3816,6 +3818,10 @@ function zotinfo($arr) { // Communication details + if($token) + $ret['signed_token'] = base64url_encode(rsa_sign($token,$e['channel_prvkey'])); + + $ret['guid'] = $e['xchan_guid']; $ret['guid_sig'] = $e['xchan_guid_sig']; $ret['key'] = $e['xchan_pubkey']; -- cgit v1.2.3 From 1cb311cef9848178780e3fd52814bf3a64ed0556 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 21 May 2016 18:18:33 -0700 Subject: finish updating zot_finger instances --- include/dir_fns.php | 5 ++--- include/follow.php | 6 +++--- include/socgraph.php | 8 +++----- 3 files changed, 8 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/dir_fns.php b/include/dir_fns.php index 1c3149081..4e300663c 100644 --- a/include/dir_fns.php +++ b/include/dir_fns.php @@ -69,9 +69,8 @@ function check_upstream_directory() { if ($directory) { $h = parse_url($directory); if ($h) { - $x = zot_finger('[system]@' . $h['host']); - if ($x['success']) { - $j = json_decode($x['body'], true); + $j = Zotlabs\Zot\Finger::run('[system]@' . $h['host']); + if ($j['success']) { if (array_key_exists('site', $j) && array_key_exists('directory_mode', $j['site'])) { if ($j['site']['directory_mode'] === 'normal') { $isadir = false; diff --git a/include/follow.php b/include/follow.php index e4f7e8557..dd43c7c4c 100644 --- a/include/follow.php +++ b/include/follow.php @@ -56,11 +56,11 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) if($arr['channel']['success']) $ret = $arr['channel']; elseif(! $is_http) - $ret = zot_finger($url,$channel); + $ret = Zotlabs\Zot\Finger::run($url,$channel); - if($ret && $ret['success']) { + if($ret && is_array($ret) && $ret['success']) { $is_red = true; - $j = json_decode($ret['body'],true); + $j = $ret; } $my_perms = get_channel_default_perms($uid); diff --git a/include/socgraph.php b/include/socgraph.php index 1b1bccf20..dffaa8923 100644 --- a/include/socgraph.php +++ b/include/socgraph.php @@ -152,11 +152,9 @@ function poco_load($xchan = '', $url = null) { if(($x !== false) && (! count($x))) { if($address) { if($network === 'zot') { - $z = zot_finger($address,null); - if($z['success']) { - $j = json_decode($z['body'],true); - if($j) - import_xchan($j); + $j = Zotlabs\Zot\Finger::run($address,null); + if($j['success']) { + import_xchan($j); } $x = q("select xchan_hash from xchan where xchan_hash = '%s' limit 1", dbesc($hash) -- cgit v1.2.3 From a36bef7979aecd72751d319f85b7037991979e35 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 21 May 2016 21:55:09 -0400 Subject: List of wikis populates with links according to observer permissions. --- include/widgets.php | 14 ++++++++++---- include/wiki.php | 12 ++++++++++-- 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/widgets.php b/include/widgets.php index acbd9bcd3..cff58d225 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -860,13 +860,19 @@ function widget_chatroom_members() { function widget_wiki_list($arr) { require_once("include/wiki.php"); - $r = wiki_list(App::$profile['channel_hash']); + if(argc()>1) { + $nick = argv(1); + } else { + $channel = \App::get_channel(); + $nick = $channel['channel_address']; + } + $wikis = wiki_list($nick, get_observer_hash()); - if($r) { + if($wikis) { return replace_macros(get_markup_template('wikilist.tpl'), array( '$header' => t('Wiki List'), - '$read' => $r['read'], - '$write' => $r['write'] + '$channel' => $nick, + '$wikis' => $wikis['wikis'] )); } } diff --git a/include/wiki.php b/include/wiki.php index 32caa98e8..7cd838f95 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -15,9 +15,17 @@ function wiki_delete() { } -function wiki_list($observer_hash) { +function wiki_list($nick, $observer_hash) { + if (local_channel() || remote_channel()) { + $sql_extra = item_permissions_sql(get_channel_by_nick($nick)['channel_id'], $observer_hash); + } else { + $sql_extra = " AND item_private = 0 "; + } + $wikis = q("SELECT * FROM item WHERE resource_type = '%s' AND mid = parent_mid AND item_deleted = 0 $sql_extra", + dbesc(WIKI_ITEM_RESOURCE_TYPE) + ); // TODO: query db for wikis the observer can access. Return with two lists, for read and write access - return array('write' => array('wiki1'), 'read' => array('wiki1', 'wiki2')); + return array('wikis' => $wikis); } function wiki_pages() { -- cgit v1.2.3 From de006771c7fe92a889d759c2c75c1473c420ad47 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 22 May 2016 16:54:30 -0700 Subject: renamed include files identity.php (channel.php) and Contact.php (connections.php) --- include/Contact.php | 636 -------------- include/account.php | 2 +- include/api.php | 2 +- include/apps.php | 2 +- include/channel.php | 1947 ++++++++++++++++++++++++++++++++++++++++++ include/connections.php | 636 ++++++++++++++ include/contact_widgets.php | 8 - include/conversation.php | 3 +- include/feedutils.php | 1 - include/identity.php | 1949 ------------------------------------------- include/items.php | 2 +- include/text.php | 6 +- include/widgets.php | 5 +- include/zot.php | 6 +- 14 files changed, 2595 insertions(+), 2610 deletions(-) delete mode 100644 include/Contact.php create mode 100644 include/channel.php create mode 100644 include/connections.php delete mode 100644 include/identity.php (limited to 'include') diff --git a/include/Contact.php b/include/Contact.php deleted file mode 100644 index e50670a89..000000000 --- a/include/Contact.php +++ /dev/null @@ -1,636 +0,0 @@ - $xchan['xchan_name'], - '$photo' => ((is_array(App::$profile) && array_key_exists('photo',App::$profile)) ? App::$profile['photo'] : $xchan['xchan_photo_l']), - '$follow' => $xchan['xchan_addr'], - '$link' => zid($xchan['xchan_url']), - '$connect' => $connect, - '$newwin' => (($mode === 'chanview') ? t('New window') : ''), - '$newtit' => t('Open the selected location in a different window or browser tab'), - '$url' => $url, - )); -} - -function abook_toggle_flag($abook,$flag) { - - $field = ''; - - switch($flag) { - case ABOOK_FLAG_BLOCKED: - $field = 'abook_blocked'; - break; - case ABOOK_FLAG_IGNORED: - $field = 'abook_ignored'; - break; - case ABOOK_FLAG_HIDDEN: - $field = 'abook_hidden'; - break; - case ABOOK_FLAG_ARCHIVED: - $field = 'abook_archived'; - break; - case ABOOK_FLAG_PENDING: - $field = 'abook_pending'; - break; - case ABOOK_FLAG_UNCONNECTED: - $field = 'abook_unconnected'; - break; - case ABOOK_FLAG_SELF: - $field = 'abook_self'; - break; - case ABOOK_FLAG_FEED: - $field = 'abook_feed'; - break; - default: - break; - } - if(! $field) - return; - - $r = q("UPDATE abook set $field = (1 - $field) where abook_id = %d and abook_channel = %d", - intval($abook['abook_id']), - intval($abook['abook_channel']) - ); - - - // if unsetting the archive bit, update the timestamps so we'll try to connect for an additional 30 days. - - if(($flag === ABOOK_FLAG_ARCHIVED) && (intval($abook['abook_archived']))) { - $r = q("update abook set abook_connected = '%s', abook_updated = '%s' - where abook_id = %d and abook_channel = %d", - dbesc(datetime_convert()), - dbesc(datetime_convert()), - intval($abook['abook_id']), - intval($abook['abook_channel']) - ); - } - - return $r; - -} - - -// Included here for completeness, but this is a very dangerous operation. -// It is the caller's responsibility to confirm the requestor's intent and -// authorisation to do this. - -function user_remove($uid) { - -} - -function account_remove($account_id,$local = true,$unset_session=true) { - - logger('account_remove: ' . $account_id); - - if(! intval($account_id)) { - logger('account_remove: no account.'); - return false; - } - - // Don't let anybody nuke the only admin account. - - $r = q("select account_id from account where (account_roles & %d)>0", - intval(ACCOUNT_ROLE_ADMIN) - ); - - if($r !== false && count($r) == 1 && $r[0]['account_id'] == $account_id) { - logger("Unable to remove the only remaining admin account"); - return false; - } - - $r = q("select * from account where account_id = %d limit 1", - intval($account_id) - ); - $account_email=$r[0]['account_email']; - - if(! $r) { - logger('account_remove: No account with id: ' . $account_id); - return false; - } - - $x = q("select channel_id from channel where channel_account_id = %d", - intval($account_id) - ); - if($x) { - foreach($x as $xx) { - channel_remove($xx['channel_id'],$local,false); - } - } - - $r = q("delete from account where account_id = %d", - intval($account_id) - ); - - - if ($unset_session) { - unset($_SESSION['authenticated']); - unset($_SESSION['uid']); - notice( sprintf(t("User '%s' deleted"),$account_email) . EOL); - goaway(z_root()); - } - return $r; - -} -// recursively delete a directory -function rrmdir($path) -{ - if (is_dir($path) === true) - { - $files = array_diff(scandir($path), array('.', '..')); - - foreach ($files as $file) - { - rrmdir(realpath($path) . '/' . $file); - } - - return rmdir($path); - } - - else if (is_file($path) === true) - { - return unlink($path); - } - - return false; -} - -function channel_remove($channel_id, $local = true, $unset_session=false) { - - if(! $channel_id) - return; - $a = get_app(); - logger('Removing channel: ' . $channel_id); - logger('channel_remove: local only: ' . intval($local)); - - $r = q("select * from channel where channel_id = %d limit 1", intval($channel_id)); - if(! $r) { - logger('channel_remove: channel not found: ' . $channel_id); - return; - } - - $channel = $r[0]; - - call_hooks('channel_remove',$r[0]); - - if(! $local) { - - $r = q("update channel set channel_deleted = '%s', channel_removed = 1, channel_r_stream = 0, channel_r_profile = 0, - channel_r_photos = 0, channel_r_abook = 0, channel_w_stream = 0, channel_w_wall = 0, channel_w_tagwall = 0, - channel_w_comment = 0, channel_w_mail = 0, channel_w_photos = 0, channel_w_chat = 0, channel_a_delegate = 0, - channel_r_storage = 0, channel_w_storage = 0, channel_r_pages = 0, channel_w_pages = 0, channel_a_republish = 0 - where channel_id = %d", - dbesc(datetime_convert()), - intval($channel_id) - ); - - logger('deleting hublocs',LOGGER_DEBUG); - - $r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s'", - dbesc($channel['channel_hash']) - ); - - - $r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s'", - dbesc($channel['channel_hash']) - ); - - Zotlabs\Daemon\Master::Summon(array('Notifier','purge_all',$channel_id)); - } - - q("DELETE FROM `groups` WHERE `uid` = %d", intval($channel_id)); - q("DELETE FROM `group_member` WHERE `uid` = %d", intval($channel_id)); - q("DELETE FROM `event` WHERE `uid` = %d", intval($channel_id)); - q("DELETE FROM `item` WHERE `uid` = %d", intval($channel_id)); - q("DELETE FROM `item_id` WHERE `uid` = %d", intval($channel_id)); - q("DELETE FROM `mail` WHERE `channel_id` = %d", intval($channel_id)); - q("DELETE FROM `notify` WHERE `uid` = %d", intval($channel_id)); - q("DELETE FROM `photo` WHERE `uid` = %d", intval($channel_id)); - q("DELETE FROM `attach` WHERE `uid` = %d", intval($channel_id)); - q("DELETE FROM `profile` WHERE `uid` = %d", intval($channel_id)); - q("DELETE FROM `pconfig` WHERE `uid` = %d", intval($channel_id)); - q("DELETE FROM `spam` WHERE `uid` = %d", intval($channel_id)); - - // @FIXME At this stage we need to remove the file resources located under /store/$nickname - - - q("delete from abook where abook_xchan = '%s' and abook_self = 1 ", - dbesc($channel['channel_hash']) - ); - - $r = q("update channel set channel_deleted = '%s', channel_removed = 1 where channel_id = %d", - dbesc(datetime_convert()), - intval($channel_id) - ); - - // if this was the default channel, set another one as default - if(App::$account['account_default_channel'] == $channel_id) { - $r = q("select channel_id from channel where channel_account_id = %d and channel_removed = 0 limit 1", - intval(App::$account['account_id']), - intval(PAGE_REMOVED)); - if ($r) { - $rr = q("update account set account_default_channel = %d where account_id = %d", - intval($r[0]['channel_id']), - intval(App::$account['account_id'])); - logger("Default channel deleted, changing default to channel_id " . $r[0]['channel_id']); - } - else { - $rr = q("update account set account_default_channel = 0 where account_id = %d", - intval(App::$account['account_id']) - ); - } - } - - logger('deleting hublocs',LOGGER_DEBUG); - - $r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s' and hubloc_url = '%s' ", - dbesc($channel['channel_hash']), - dbesc(z_root()) - ); - - // Do we have any valid hublocs remaining? - - $hublocs = 0; - - $r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0", - dbesc($channel['channel_hash']) - ); - if($r) - $hublocs = count($r); - - if(! $hublocs) { - $r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s' ", - dbesc($channel['channel_hash']) - ); - } - - //remove from file system - $r = q("select channel_address from channel where channel_id = %d limit 1", - intval($channel_id) - ); - if($r) - $channel_address = $r[0]['channel_address'] ; - if ($channel_address !== '') { - $f = 'store/' . $channel_address.'/'; - logger ('delete '. $f); - if(is_dir($f)) - @rrmdir($f); - } - - Zotlabs\Daemon\Master::Summon(array('Directory',$channel_id)); - - if($channel_id == local_channel() && $unset_session) { - App::$session->nuke(); - goaway(z_root()); - } - -} - -/** - * mark any hubs "offline" that haven't been heard from in more than 30 days - * Allow them to redeem themselves if they come back later. - * Then go through all those that are newly marked and see if any other hubs - * are attached to the controlling xchan that are still alive. - * If not, they're dead (although they could come back some day). - */ - - -function mark_orphan_hubsxchans() { - - $dirmode = intval(get_config('system','directory_mode')); - if($dirmode == DIRECTORY_MODE_NORMAL) - return; - - $r = q("update hubloc set hubloc_error = 1 where hubloc_error = 0 - and hubloc_network = 'zot' and hubloc_connected < %s - interval %s", - db_utcnow(), db_quoteinterval('36 day') - ); - -// $realm = get_directory_realm(); -// if($realm == DIRECTORY_REALM) { -// $r = q("select * from site where site_access != 0 and site_register !=0 and ( site_realm = '%s' or site_realm = '') order by rand()", -// dbesc($realm) -// ); -// } -// else { -// $r = q("select * from site where site_access != 0 and site_register !=0 and site_realm = '%s' order by rand()", -// dbesc($realm) -// ); -// } - - - $r = q("select hubloc_id, hubloc_hash from hubloc where hubloc_error = 0 and hubloc_orphancheck = 0"); - - if($r) { - foreach($r as $rr) { - - // see if any other hublocs are still alive for this channel - - $x = q("select * from hubloc where hubloc_hash = '%s' and hubloc_error = 0", - dbesc($rr['hubloc_hash']) - ); - if($x) { - - // yes - if the xchan was marked as an orphan, undo it - - $y = q("update xchan set xchan_orphan = 0 where xchan_orphan = 1 and xchan_hash = '%s'", - dbesc($rr['hubloc_hash']) - ); - - } - else { - - // nope - mark the xchan as an orphan - - $y = q("update xchan set xchan_orphan = 1 where xchan_hash = '%s'", - dbesc($rr['hubloc_hash']) - ); - } - - // mark that we've checked this entry so we don't need to do it again - - $y = q("update hubloc set hubloc_orphancheck = 1 where hubloc_id = %d", - dbesc($rr['hubloc_id']) - ); - } - } - -} - - - - -function remove_all_xchan_resources($xchan, $channel_id = 0) { - - if(intval($channel_id)) { - - - - } - else { - - $dirmode = intval(get_config('system','directory_mode')); - - - $r = q("delete from photo where xchan = '%s'", - dbesc($xchan) - ); - $r = q("select resource_id, resource_type, uid, id from item where ( author_xchan = '%s' or owner_xchan = '%s' ) ", - dbesc($xchan), - dbesc($xchan) - ); - if($r) { - foreach($r as $rr) { - drop_item($rr,false); - } - } - $r = q("delete from event where event_xchan = '%s'", - dbesc($xchan) - ); - $r = q("delete from group_member where xchan = '%s'", - dbesc($xchan) - ); - $r = q("delete from mail where ( from_xchan = '%s' or to_xchan = '%s' )", - dbesc($xchan), - dbesc($xchan) - ); - $r = q("delete from xlink where ( xlink_xchan = '%s' or xlink_link = '%s' )", - dbesc($xchan), - dbesc($xchan) - ); - - $r = q("delete from abook where abook_xchan = '%s'", - dbesc($xchan) - ); - - - if($dirmode === false || $dirmode == DIRECTORY_MODE_NORMAL) { - - $r = q("delete from xchan where xchan_hash = '%s'", - dbesc($xchan) - ); - $r = q("delete from hubloc where hubloc_hash = '%s'", - dbesc($xchan) - ); - - } - else { - - // directory servers need to keep the record around for sync purposes - mark it deleted - - $r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s'", - dbesc($xchan) - ); - - $r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s'", - dbesc($xchan) - ); - } - } -} - - -function contact_remove($channel_id, $abook_id) { - - if((! $channel_id) || (! $abook_id)) - return false; - - logger('removing contact ' . $abook_id . ' for channel ' . $channel_id,LOGGER_DEBUG); - - $archive = get_pconfig($channel_id, 'system','archive_removed_contacts'); - if($archive) { - q("update abook set abook_archived = 1 where abook_id = %d and abook_channel = %d", - intval($abook_id), - intval($channel_id) - ); - return true; - } - - $r = q("select * from abook where abook_id = %d and abook_channel = %d limit 1", - intval($abook_id), - intval($channel_id) - ); - - if(! $r) - return false; - - $abook = $r[0]; - - if(intval($abook['abook_self'])) - return false; - - - $r = q("select * from item where author_xchan = '%s' and uid = %d", - dbesc($abook['abook_xchan']), - intval($channel_id) - ); - if($r) { - foreach($r as $rr) { - drop_item($rr['id'],false); - } - } - - q("delete from abook where abook_id = %d and abook_channel = %d", - intval($abook['abook_id']), - intval($channel_id) - ); - - $r = q("delete from event where event_xchan = '%s' and uid = %d", - dbesc($abook['abook_xchan']), - intval($channel_id) - ); - - $r = q("delete from group_member where xchan = '%s' and uid = %d", - dbesc($abook['abook_xchan']), - intval($channel_id) - ); - - $r = q("delete from mail where ( from_xchan = '%s' or to_xchan = '%s' ) and channel_id = %d ", - dbesc($abook['abook_xchan']), - dbesc($abook['abook_xchan']), - intval($channel_id) - ); - - return true; -} - - - -function random_profile() { - $randfunc = db_getfunc('rand'); - - $checkrandom = get_config('randprofile','check'); // False by default - $retryrandom = intval(get_config('randprofile','retry')); - if($retryrandom == 0) $retryrandom = 5; - - for($i = 0; $i < $retryrandom; $i++) { - - $r = q("select xchan_url from xchan left join hubloc on hubloc_hash = xchan_hash where hubloc_connected > %s - interval %s order by $randfunc limit 1", - db_utcnow(), db_quoteinterval('30 day') - ); - - if(!$r) return ''; // Couldn't get a random channel - - if($checkrandom) { - $x = z_fetch_url($r[0]['xchan_url']); - if($x['success']) - return $r[0]['xchan_url']; - else - logger('Random channel turned out to be bad.'); - } - else { - return $r[0]['xchan_url']; - } - - } - return ''; -} - diff --git a/include/account.php b/include/account.php index 5998609d4..e367e002d 100644 --- a/include/account.php +++ b/include/account.php @@ -11,7 +11,7 @@ require_once('include/text.php'); require_once('include/language.php'); require_once('include/datetime.php'); require_once('include/crypto.php'); -require_once('include/identity.php'); +require_once('include/channel.php'); function check_account_email($email) { diff --git a/include/api.php b/include/api.php index 4a462d1e8..ba36cc01a 100644 --- a/include/api.php +++ b/include/api.php @@ -514,7 +514,7 @@ require_once('include/api_auth.php'); return false; } - require_once('include/identity.php'); + require_once('include/channel.php'); json_return_and_die(identity_basic_export(api_user(),(($_REQUEST['posts']) ? intval($_REQUEST['posts']) : 0 ))); } diff --git a/include/apps.php b/include/apps.php index 7439be6d4..e300bc50d 100644 --- a/include/apps.php +++ b/include/apps.php @@ -6,7 +6,7 @@ */ require_once('include/plugin.php'); -require_once('include/identity.php'); +require_once('include/channel.php'); function get_system_apps($translate = true) { diff --git a/include/channel.php b/include/channel.php new file mode 100644 index 000000000..050c4824b --- /dev/null +++ b/include/channel.php @@ -0,0 +1,1947 @@ + false, 'message' => ''); + + $r = q("select count(channel_id) as total from channel where channel_account_id = %d and channel_removed = 0 ", + intval($account_id) + ); + if(! ($r && count($r))) { + $ret['total_identities'] = 0; + $ret['message'] = t('Unable to obtain identity information from database'); + return $ret; + } + + $ret['total_identities'] = intval($r[0]['total']); + + if (! account_service_class_allows($account_id, 'total_identities', $r[0]['total'])) { + $ret['message'] .= upgrade_message(); + return $ret; + } + + $ret['success'] = true; + + return $ret; +} + + +/** + * @brief Determine if the channel name is allowed when creating a new channel. + * + * This action is pluggable. + * We're currently only checking for an empty name or one that exceeds our + * storage limit (255 chars). 255 chars is probably going to create a mess on + * some pages. + * Plugins can set additional policies such as full name requirements, character + * sets, multi-byte length, etc. + * + * @param string $name + * + * @returns nil return if name is valid, or string describing the error state. + */ +function validate_channelname($name) { + + if (! $name) + return t('Empty name'); + + if (strlen($name) > 255) + return t('Name too long'); + + $arr = array('name' => $name); + call_hooks('validate_channelname', $arr); + + if (x($arr, 'message')) + return $arr['message']; +} + + +/** + * @brief Create a system channel - which has no account attached. + * + */ +function create_sys_channel() { + if (get_sys_channel()) + return; + + // Ensure that there is a host keypair. + + if ((! get_config('system', 'pubkey')) && (! get_config('system', 'prvkey'))) { + require_once('include/crypto.php'); + $hostkey = new_keypair(4096); + set_config('system', 'pubkey', $hostkey['pubkey']); + set_config('system', 'prvkey', $hostkey['prvkey']); + } + + create_identity(array( + 'account_id' => 'xxx', // This will create an identity with an (integer) account_id of 0, but account_id is required + 'nickname' => 'sys', + 'name' => 'System', + 'pageflags' => 0, + 'publish' => 0, + 'system' => 1 + )); +} + + +/** + * @brief Returns the sys channel. + * + * @return array|boolean + */ +function get_sys_channel() { + $r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_system = 1 limit 1"); + + if ($r) + return $r[0]; + + return false; +} + + +/** + * @brief Checks if $channel_id is sys channel. + * + * @param int $channel_id + * @return boolean + */ +function is_sys_channel($channel_id) { + $r = q("select channel_system from channel where channel_id = %d and channel_system = 1 limit 1", + intval($channel_id) + ); + + if($r) + return true; + + return false; +} + + +/** + * @brief Return the total number of channels on this site. + * + * No filtering is performed except to check PAGE_REMOVED. + * + * @returns int|booleean + * on error returns boolean false + */ +function channel_total() { + $r = q("select channel_id from channel where channel_removed = 0"); + + if (is_array($r)) + return count($r); + + return false; +} + + +/** + * @brief Create a new channel. + * + * Also creates the related xchan, hubloc, profile, and "self" abook records, + * and an empty "Friends" group/collection for the new channel. + * + * @param array $arr assoziative array with: + * * \e string \b name full name of channel + * * \e string \b nickname "email/url-compliant" nickname + * * \e int \b account_id to attach with this channel + * * [other identity fields as desired] + * + * @returns array + * 'success' => boolean true or false + * 'message' => optional error text if success is false + * 'channel' => if successful the created channel array + */ +function create_identity($arr) { + + $ret = array('success' => false); + + if(! $arr['account_id']) { + $ret['message'] = t('No account identifier'); + return $ret; + } + $ret = identity_check_service_class($arr['account_id']); + if (!$ret['success']) { + return $ret; + } + // save this for auto_friending + $total_identities = $ret['total_identities']; + + $nick = mb_strtolower(trim($arr['nickname'])); + if(! $nick) { + $ret['message'] = t('Nickname is required.'); + return $ret; + } + + $name = escape_tags($arr['name']); + $pageflags = ((x($arr,'pageflags')) ? intval($arr['pageflags']) : PAGE_NORMAL); + $system = ((x($arr,'system')) ? intval($arr['system']) : 0); + $name_error = validate_channelname($arr['name']); + if($name_error) { + $ret['message'] = $name_error; + return $ret; + } + + if($nick === 'sys' && (! $system)) { + $ret['message'] = t('Reserved nickname. Please choose another.'); + return $ret; + } + + if(check_webbie(array($nick)) !== $nick) { + $ret['message'] = t('Nickname has unsupported characters or is already being used on this site.'); + return $ret; + } + + $guid = zot_new_uid($nick); + $key = new_keypair(4096); + + $sig = base64url_encode(rsa_sign($guid,$key['prvkey'])); + $hash = make_xchan_hash($guid,$sig); + + // Force a few things on the short term until we can provide a theme or app with choice + + $publish = 1; + + if(array_key_exists('publish', $arr)) + $publish = intval($arr['publish']); + + $primary = true; + + if(array_key_exists('primary', $arr)) + $primary = intval($arr['primary']); + + $role_permissions = null; + $global_perms = get_perms(); + + if(array_key_exists('permissions_role',$arr) && $arr['permissions_role']) { + $role_permissions = get_role_perms($arr['permissions_role']); + + if($role_permissions) { + foreach($role_permissions as $p => $v) { + if(strpos($p,'channel_') !== false) { + $perms_keys .= ', ' . $p; + $perms_vals .= ', ' . intval($v); + } + if($p === 'directory_publish') + $publish = intval($v); + } + } + } + else { + $defperms = site_default_perms(); + foreach($defperms as $p => $v) { + $perms_keys .= ', ' . $global_perms[$p][0]; + $perms_vals .= ', ' . intval($v); + } + } + + $expire = 0; + + $r = q("insert into channel ( channel_account_id, channel_primary, + channel_name, channel_address, channel_guid, channel_guid_sig, + channel_hash, channel_prvkey, channel_pubkey, channel_pageflags, channel_system, channel_expire_days, channel_timezone $perms_keys ) + values ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s' $perms_vals ) ", + + intval($arr['account_id']), + intval($primary), + dbesc($name), + dbesc($nick), + dbesc($guid), + dbesc($sig), + dbesc($hash), + dbesc($key['prvkey']), + dbesc($key['pubkey']), + intval($pageflags), + intval($system), + intval($expire), + dbesc(App::$timezone) + ); + + $r = q("select * from channel where channel_account_id = %d + and channel_guid = '%s' limit 1", + intval($arr['account_id']), + dbesc($guid) + ); + + if(! $r) { + $ret['message'] = t('Unable to retrieve created identity'); + return $ret; + } + + $ret['channel'] = $r[0]; + + if(intval($arr['account_id'])) + set_default_login_identity($arr['account_id'],$ret['channel']['channel_id'],false); + + // Create a verified hub location pointing to this site. + + $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary, + hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network ) + values ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )", + dbesc($guid), + dbesc($sig), + dbesc($hash), + dbesc($ret['channel']['channel_address'] . '@' . App::get_hostname()), + intval($primary), + dbesc(z_root()), + dbesc(base64url_encode(rsa_sign(z_root(),$ret['channel']['channel_prvkey']))), + dbesc(App::get_hostname()), + dbesc(z_root() . '/post'), + dbesc(get_config('system','pubkey')), + dbesc('zot') + ); + if(! $r) + logger('create_identity: Unable to store hub location'); + + $newuid = $ret['channel']['channel_id']; + + $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_system ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", + dbesc($hash), + dbesc($guid), + dbesc($sig), + dbesc($key['pubkey']), + dbesc(z_root() . "/photo/profile/l/{$newuid}"), + dbesc(z_root() . "/photo/profile/m/{$newuid}"), + dbesc(z_root() . "/photo/profile/s/{$newuid}"), + dbesc($ret['channel']['channel_address'] . '@' . App::get_hostname()), + dbesc(z_root() . '/channel/' . $ret['channel']['channel_address']), + dbesc(z_root() . '/follow?f=&url=%s'), + dbesc(z_root() . '/poco/' . $ret['channel']['channel_address']), + dbesc($ret['channel']['channel_name']), + dbesc('zot'), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + intval($system) + ); + + // Not checking return value. + // It's ok for this to fail if it's an imported channel, and therefore the hash is a duplicate + + $r = q("INSERT INTO profile ( aid, uid, profile_guid, profile_name, is_default, publish, name, photo, thumb) + VALUES ( %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s') ", + intval($ret['channel']['channel_account_id']), + intval($newuid), + dbesc(random_string()), + t('Default Profile'), + 1, + $publish, + dbesc($ret['channel']['channel_name']), + dbesc(z_root() . "/photo/profile/l/{$newuid}"), + dbesc(z_root() . "/photo/profile/m/{$newuid}") + ); + + if($role_permissions) { + $myperms = ((array_key_exists('perms_accept',$role_permissions)) ? intval($role_permissions['perms_accept']) : 0); + } + else + $myperms = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK + |PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT + |PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE; + + $r = q("insert into abook ( abook_account, abook_channel, abook_xchan, abook_closeness, abook_created, abook_updated, abook_self, abook_my_perms ) + values ( %d, %d, '%s', %d, '%s', '%s', %d, %d ) ", + intval($ret['channel']['channel_account_id']), + intval($newuid), + dbesc($hash), + intval(0), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + intval(1), + intval($myperms) + ); + + if(intval($ret['channel']['channel_account_id'])) { + + // Save our permissions role so we can perhaps call it up and modify it later. + + if($role_permissions) { + set_pconfig($newuid,'system','permissions_role',$arr['permissions_role']); + if(array_key_exists('online',$role_permissions)) + set_pconfig($newuid,'system','hide_presence',1-intval($role_permissions['online'])); + if(array_key_exists('perms_auto',$role_permissions)) + set_pconfig($newuid,'system','autoperms',(($role_permissions['perms_auto']) ? $role_permissions['perms_accept'] : 0)); + } + + // Create a group with yourself as a member. 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')); + group_add_member($newuid,t('Friends'),$ret['channel']['channel_hash']); + + // if our role_permissions indicate that we're using a default collection ACL, add it. + + if(is_array($role_permissions) && $role_permissions['default_collection']) { + $r = q("select hash from groups where uid = %d and name = '%s' limit 1", + intval($newuid), + dbesc( t('Friends') ) + ); + if($r) { + q("update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d", + dbesc($r[0]['hash']), + dbesc('<' . $r[0]['hash'] . '>'), + intval($newuid) + ); + } + } + + if(! $system) { + set_pconfig($ret['channel']['channel_id'],'system','photo_path', '%Y-%m'); + set_pconfig($ret['channel']['channel_id'],'system','attach_path','%Y-%m'); + } + + // UNO: channel defaults, incl addons (addons specific pconfig will only work after the relevant addon is enabled by the admin). It's located here, so members can modify these defaults after the channel is created. + if(UNO) { + //diaspora protocol addon + set_pconfig($ret['channel']['channel_id'],'system','diaspora_allowed', '1'); + set_pconfig($ret['channel']['channel_id'],'system','diaspora_public_comments', '1'); + set_pconfig($ret['channel']['channel_id'],'system','prevent_tag_hijacking', '0'); + } + + // auto-follow any of the hub's pre-configured channel choices. + // Only do this if it's the first channel for this account; + // otherwise it could get annoying. Don't make this list too big + // or it will impact registration time. + + $accts = get_config('system','auto_follow'); + if(($accts) && (! $total_identities)) { + require_once('include/follow.php'); + if(! is_array($accts)) + $accts = array($accts); + foreach($accts as $acct) { + if(trim($acct)) + new_contact($newuid,trim($acct),$ret['channel'],false); + } + } + + call_hooks('create_identity', $newuid); + + Zotlabs\Daemon\Master::Summon(array('Directory', $ret['channel']['channel_id'])); + } + + $ret['success'] = true; + return $ret; +} + +/** + * @brief Set default channel to be used on login. + * + * @param int $account_id + * login account + * @param int $channel_id + * channel id to set as default for this account + * @param boolean $force + * if true, set this default unconditionally + * if $force is false only do this if there is no existing default + */ +function set_default_login_identity($account_id, $channel_id, $force = true) { + $r = q("select account_default_channel from account where account_id = %d limit 1", + intval($account_id) + ); + if ($r) { + if ((intval($r[0]['account_default_channel']) == 0) || ($force)) { + $r = q("update account set account_default_channel = %d where account_id = %d", + intval($channel_id), + intval($account_id) + ); + } + } +} + +/** + * @brief Create an array representing the important channel information + * which would be necessary to create a nomadic identity clone. This includes + * most channel resources and connection information with the exception of content. + * + * @param int $channel_id + * Channel_id to export + * @param boolean $items + * Include channel posts (wall items), default false + * + * @returns array + * See function for details + */ +function identity_basic_export($channel_id, $items = false) { + + /* + * Red basic channel export + */ + + $ret = array(); + + // use constants here as otherwise we will have no idea if we can import from a site + // with a non-standard platform and version. + $ret['compatibility'] = array('project' => PLATFORM_NAME, 'version' => STD_VERSION, 'database' => DB_UPDATE_VERSION, 'server_role' => Zotlabs\Lib\System::get_server_role()); + + $r = q("select * from channel where channel_id = %d limit 1", + intval($channel_id) + ); + if($r) + $ret['channel'] = $r[0]; + + $r = q("select * from profile where uid = %d", + intval($channel_id) + ); + if($r) + $ret['profile'] = $r; + + $xchans = array(); + $r = q("select * from abook where abook_channel = %d ", + intval($channel_id) + ); + if($r) { + $ret['abook'] = $r; + + for($x = 0; $x < count($ret['abook']); $x ++) { + $xchans[] = $ret['abook'][$x]['abook_chan']; + $abconfig = load_abconfig($ret['channel']['channel_hash'],$ret['abook'][$x]['abook_xchan']); + if($abconfig) + $ret['abook'][$x]['abconfig'] = $abconfig; + } + stringify_array_elms($xchans); + } + + if($xchans) { + $r = q("select * from xchan where xchan_hash in ( " . implode(',',$xchans) . " ) "); + if($r) + $ret['xchan'] = $r; + + $r = q("select * from hubloc where hubloc_hash in ( " . implode(',',$xchans) . " ) "); + if($r) + $ret['hubloc'] = $r; + } + + $r = q("select * from `groups` where uid = %d ", + intval($channel_id) + ); + + if($r) + $ret['group'] = $r; + + $r = q("select * from group_member where uid = %d ", + intval($channel_id) + ); + if($r) + $ret['group_member'] = $r; + + $r = q("select * from pconfig where uid = %d", + intval($channel_id) + ); + if($r) + $ret['config'] = $r; + + $r = q("select type, data, os_storage from photo where scale = 4 and photo_usage = %d and uid = %d limit 1", + intval(PHOTO_PROFILE), + intval($channel_id) + ); + + if($r) { + $ret['photo'] = array('type' => $r[0]['type'], 'data' => (($r[0]['os_storage']) ? base64url_encode(file_get_contents($r[0]['data'])) : base64url_encode($r[0]['data']))); + } + + // All other term types will be included in items, if requested. + + $r = q("select * from term where type in (%d,%d) and uid = %d", + intval(TERM_SAVEDSEARCH), + intval(TERM_THING), + intval($channel_id) + ); + if($r) + $ret['term'] = $r; + + + // add psuedo-column obj_baseurl to aid in relocations + + $r = q("select obj.*, '%s' as obj_baseurl from obj where obj_channel = %d", + dbesc(z_root()), + intval($channel_id) + ); + + if($r) + $ret['obj'] = $r; + + $r = q("select * from app where app_channel = %d and app_system = 0", + intval($channel_id) + ); + if($r) { + for($x = 0; $x < count($r); $x ++) { + $r[$x]['term'] = q("select * from term where otype = %d and oid = %d", + intval(TERM_OBJ_APP), + intval($r[$x]['id']) + ); + } + $ret['app'] = $r; + } + + $r = q("select * from chatroom where cr_uid = %d", + intval($channel_id) + ); + if($r) + $ret['chatroom'] = $r; + + + $r = q("select * from event where uid = %d", + intval($channel_id) + ); + if($r) + $ret['event'] = $r; + + $r = q("select * from item where resource_type = 'event' and uid = %d", + intval($channel_id) + ); + if($r) { + $ret['event_item'] = array(); + xchan_query($r); + $r = fetch_post_tags($r,true); + foreach($r as $rr) + $ret['event_item'][] = encode_item($rr,true); + } + + $x = menu_list($channel_id); + if($x) { + $ret['menu'] = array(); + for($y = 0; $y < count($x); $y ++) { + $m = menu_fetch($x[$y]['menu_name'],$channel_id,$ret['channel']['channel_hash']); + if($m) + $ret['menu'][] = menu_element($m); + } + } + + $x = menu_list($channel_id); + if($x) { + $ret['menu'] = array(); + for($y = 0; $y < count($x); $y ++) { + $m = menu_fetch($x[$y]['menu_name'],$channel_id,$ret['channel']['channel_hash']); + if($m) + $ret['menu'][] = menu_element($m); + } + } + + $addon = array('channel_id' => $channel_id,'data' => $ret); + call_hooks('identity_basic_export',$addon); + $ret = $addon['data']; + + + if(! $items) + return $ret; + + $r = q("select * from likes where channel_id = %d", + intval($channel_id) + ); + + if($r) + $ret['likes'] = $r; + + + $r = q("select * from conv where uid = %d", + intval($channel_id) + ); + if($r) { + for($x = 0; $x < count($r); $x ++) { + $r[$x]['subject'] = base64url_decode(str_rot47($r[$x]['subject'])); + } + $ret['conv'] = $r; + } + + + $r = q("select * from mail where mail.uid = %d", + intval($channel_id) + ); + if($r) { + $m = array(); + foreach($r as $rr) { + xchan_mail_query($rr); + $m[] = mail_encode($rr,true); + } + $ret['mail'] = $m; + } + + $r = q("select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item_id.uid = %d", + intval($channel_id) + ); + + if($r) + $ret['item_id'] = $r; + + //$key = get_config('system','prvkey'); + + /** @warning this may run into memory limits on smaller systems */ + + + /** export three months of posts. If you want to export and import all posts you have to start with + * the first year and export/import them in ascending order. + * + * Don't export linked resource items. we'll have to pull those out separately. + */ + + $r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created > %s - INTERVAL %s and resource_type = '' order by created", + intval($channel_id), + db_utcnow(), + db_quoteinterval('3 MONTH') + ); + if($r) { + $ret['item'] = array(); + xchan_query($r); + $r = fetch_post_tags($r,true); + foreach($r as $rr) + $ret['item'][] = encode_item($rr,true); + } + + return $ret; +} + + +function identity_export_year($channel_id,$year,$month = 0) { + + if(! $year) + return array(); + + if($month && $month <= 12) { + $target_month = sprintf('%02d',$month); + $target_month_plus = sprintf('%02d',$month+1); + } + else + $target_month = '01'; + + $ret = array(); + + $mindate = datetime_convert('UTC','UTC',$year . '-' . $target_month . '-01 00:00:00'); + if($month && $month < 12) + $maxdate = datetime_convert('UTC','UTC',$year . '-' . $target_month_plus . '-01 00:00:00'); + else + $maxdate = datetime_convert('UTC','UTC',$year+1 . '-01-01 00:00:00'); + + $r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created < '%s' and resource_type = '' order by created", + intval(ITEM_TYPE_POST), + intval($channel_id), + dbesc($mindate), + dbesc($maxdate) + ); + + if($r) { + $ret['item'] = array(); + xchan_query($r); + $r = fetch_post_tags($r,true); + foreach($r as $rr) + $ret['item'][] = encode_item($rr,true); + } + + $r = q("select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item_id.uid = %d + and item.created >= '%s' and item.created < '%s' order by created ", + intval($channel_id), + dbesc($mindate), + dbesc($maxdate) + ); + + if($r) + $ret['item_id'] = $r; + + + return $ret; +} + + +/** + * @brief Loads a profile into the App structure. + * + * The function requires a writeable copy of the main App structure, and the + * nickname of a valid channel. + * + * Permissions of the current observer are checked. If a restricted profile is available + * to the current observer, that will be loaded instead of the channel default profile. + * + * The channel owner can set $profile to a valid profile_guid to preview that profile. + * + * The channel default theme is also selected for use, unless over-riden elsewhere. + * + * @param[in,out] App &$a + * @param string $nickname + * @param string $profile + */ +function profile_load(&$a, $nickname, $profile = '') { + +// logger('profile_load: ' . $nickname . (($profile) ? ' profile: ' . $profile : '')); + + $user = q("select channel_id from channel where channel_address = '%s' and channel_removed = 0 limit 1", + dbesc($nickname) + ); + + if(! $user) { + logger('profile error: ' . App::$query_string, LOGGER_DEBUG); + notice( t('Requested channel is not available.') . EOL ); + App::$error = 404; + return; + } + + // get the current observer + $observer = App::get_observer(); + + $can_view_profile = true; + + // Can the observer see our profile? + require_once('include/permissions.php'); + if(! perm_is_allowed($user[0]['channel_id'],$observer['xchan_hash'],'view_profile')) { + $can_view_profile = false; + } + + if(! $profile) { + $r = q("SELECT abook_profile FROM abook WHERE abook_xchan = '%s' and abook_channel = '%d' limit 1", + dbesc($observer['xchan_hash']), + intval($user[0]['channel_id']) + ); + if($r) + $profile = $r[0]['abook_profile']; + } + $p = null; + + if($profile) { + $p = q("SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile + LEFT JOIN channel ON profile.uid = channel.channel_id + WHERE channel.channel_address = '%s' AND profile.profile_guid = '%s' LIMIT 1", + dbesc($nickname), + dbesc($profile) + ); + } + + if(! $p) { + $p = q("SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile + LEFT JOIN channel ON profile.uid = channel.channel_id + WHERE channel.channel_address = '%s' and channel_removed = 0 + AND profile.is_default = 1 LIMIT 1", + dbesc($nickname) + ); + } + + if(! $p) { + logger('profile error: ' . App::$query_string, LOGGER_DEBUG); + notice( t('Requested profile is not available.') . EOL ); + App::$error = 404; + return; + } + + $q = q("select * from profext where hash = '%s' and channel_id = %d", + dbesc($p[0]['profile_guid']), + intval($p[0]['profile_uid']) + ); + if($q) { + + $extra_fields = array(); + + require_once('include/channel.php'); + $profile_fields_basic = get_profile_fields_basic(); + $profile_fields_advanced = get_profile_fields_advanced(); + + $advanced = ((feature_enabled(local_channel(),'advanced_profiles')) ? true : false); + if($advanced) + $fields = $profile_fields_advanced; + else + $fields = $profile_fields_basic; + + foreach($q as $qq) { + foreach($fields as $k => $f) { + if($k == $qq['k']) { + $p[0][$k] = $qq['v']; + $extra_fields[] = $k; + break; + } + } + } + } + + $p[0]['extra_fields'] = $extra_fields; + + $z = q("select xchan_photo_date, xchan_addr from xchan where xchan_hash = '%s' limit 1", + dbesc($p[0]['channel_hash']) + ); + if($z) { + $p[0]['picdate'] = $z[0]['xchan_photo_date']; + $p[0]['reddress'] = str_replace('@','@',$z[0]['xchan_addr']); + } + + // fetch user tags if this isn't the default profile + + if(! $p[0]['is_default']) { + $x = q("select `keywords` from `profile` where uid = %d and `is_default` = 1 limit 1", + intval($p[0]['profile_uid']) + ); + if($x && $can_view_profile) + $p[0]['keywords'] = $x[0]['keywords']; + } + + if($p[0]['keywords']) { + $keywords = str_replace(array('#',',',' ',',,'),array('',' ',',',','),$p[0]['keywords']); + if(strlen($keywords) && $can_view_profile) + App::$page['htmlhead'] .= '' . "\r\n" ; + } + + App::$profile = $p[0]; + App::$profile_uid = $p[0]['profile_uid']; + App::$page['title'] = App::$profile['channel_name'] . " - " . App::$profile['channel_address'] . "@" . App::get_hostname(); + + App::$profile['permission_to_view'] = $can_view_profile; + + if($can_view_profile) { + $online = get_online_status($nickname); + App::$profile['online_status'] = $online['result']; + } + + if(local_channel()) { + App::$profile['channel_mobile_theme'] = get_pconfig(local_channel(),'system', 'mobile_theme'); + $_SESSION['mobile_theme'] = App::$profile['channel_mobile_theme']; + } + + /* + * load/reload current theme info + */ + + $_SESSION['theme'] = $p[0]['channel_theme']; + +} + +function profile_edit_menu($uid) { + + $ret = array(); + + $is_owner = (($uid == local_channel()) ? true : false); + + // show edit profile to profile owner + if($is_owner) { + $ret['menu'] = array( + 'chg_photo' => t('Change profile photo'), + 'entries' => array(), + ); + + $multi_profiles = feature_enabled(local_channel(), 'multi_profiles'); + if($multi_profiles) { + $ret['multi'] = 1; + $ret['edit'] = array(z_root(). '/profiles', t('Edit Profiles'), '', t('Edit')); + $ret['menu']['cr_new'] = t('Create New Profile'); + } + else { + $ret['edit'] = array(z_root() . '/profiles/' . $uid, t('Edit Profile'), '', t('Edit')); + } + + $r = q("SELECT * FROM profile WHERE uid = %d", + local_channel() + ); + + if($r) { + foreach($r as $rr) { + if(!($multi_profiles || $rr['is_default'])) + continue; + $ret['menu']['entries'][] = array( + 'photo' => $rr['thumb'], + 'id' => $rr['id'], + 'alt' => t('Profile Image'), + 'profile_name' => $rr['profile_name'], + 'isdefault' => $rr['is_default'], + 'visible_to_everybody' => t('Visible to everybody'), + 'edit_visibility' => t('Edit visibility'), + ); + } + } + } + + return $ret; + +} + +/** + * @brief Formats a profile for display in the sidebar. + * + * It is very difficult to templatise the HTML completely + * because of all the conditional logic. + * + * @param array $profile + * @param int $block + * @param boolean $show_connect + * + * @return HTML string suitable for sidebar inclusion + * Exceptions: Returns empty string if passed $profile is wrong type or not populated + */ +function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = false) { + + $observer = App::get_observer(); + + $o = ''; + $location = false; + $pdesc = true; + $reddress = true; + + if(! perm_is_allowed($profile['uid'],((is_array($observer)) ? $observer['xchan_hash'] : ''),'view_profile')) { + $block = true; + } + + if((! is_array($profile)) && (! count($profile))) + return $o; + + head_set_icon($profile['thumb']); + + if(is_sys_channel($profile['uid'])) + $show_connect = false; + + $profile['picdate'] = urlencode($profile['picdate']); + + call_hooks('profile_sidebar_enter', $profile); + + if($show_connect) { + + // This will return an empty string if we're already connected. + + $connect_url = rconnect_url($profile['uid'],get_observer_hash()); + $connect = (($connect_url) ? t('Connect') : ''); + if($connect_url) + $connect_url = sprintf($connect_url,urlencode($profile['channel_address'] . '@' . App::get_hostname())); + + // premium channel - over-ride + + if($profile['channel_pageflags'] & PAGE_PREMIUM) + $connect_url = z_root() . '/connect/' . $profile['channel_address']; + } + + if((x($profile,'address') == 1) + || (x($profile,'locality') == 1) + || (x($profile,'region') == 1) + || (x($profile,'postal_code') == 1) + || (x($profile,'country_name') == 1)) + $location = t('Location:'); + + $profile['homepage'] = linkify($profile['homepage'],true); + + $gender = ((x($profile,'gender') == 1) ? t('Gender:') : False); + $marital = ((x($profile,'marital') == 1) ? t('Status:') : False); + $homepage = ((x($profile,'homepage') == 1) ? t('Homepage:') : False); + $profile['online'] = (($profile['online_status'] === 'online') ? t('Online Now') : False); + +// logger('online: ' . $profile['online']); + + + if(($profile['hidewall'] && (! local_channel()) && (! remote_channel())) || $block ) { + $location = $reddress = $pdesc = $gender = $marital = $homepage = False; + } + + $firstname = ((strpos($profile['channel_name'],' ')) + ? trim(substr($profile['channel_name'],0,strpos($profile['channel_name'],' '))) : $profile['channel_name']); + $lastname = (($firstname === $profile['channel_name']) ? '' : trim(substr($profile['channel_name'],strlen($firstname)))); + + $diaspora = array( + 'podloc' => z_root(), + 'searchable' => (($block) ? 'false' : 'true'), + 'nickname' => $profile['channel_address'], + 'fullname' => $profile['channel_name'], + 'firstname' => $firstname, + 'lastname' => $lastname, + 'photo300' => z_root() . '/photo/profile/300/' . $profile['uid'] . '.jpg', + 'photo100' => z_root() . '/photo/profile/100/' . $profile['uid'] . '.jpg', + 'photo50' => z_root() . '/photo/profile/50/' . $profile['uid'] . '.jpg', + ); + + $contact_block = contact_block(); + + $channel_menu = false; + $menu = get_pconfig($profile['uid'],'system','channel_menu'); + if($menu && ! $block) { + require_once('include/menu.php'); + $m = menu_fetch($menu,$profile['uid'],$observer['xchan_hash']); + if($m) + $channel_menu = menu_render($m); + } + $menublock = get_pconfig($profile['uid'],'system','channel_menublock'); + if ($menublock && (! $block)) { + $comanche = new Zotlabs\Render\Comanche(); + $channel_menu .= $comanche->block($menublock); + } + + if($zcard) + $tpl = get_markup_template('profile_vcard_short.tpl'); + else + $tpl = get_markup_template('profile_vcard.tpl'); + + require_once('include/widgets.php'); + + if(! feature_enabled($profile['uid'],'hide_rating')) + $z = widget_rating(array('target' => $profile['channel_hash'])); + + $o .= replace_macros($tpl, array( + '$zcard' => $zcard, + '$profile' => $profile, + '$connect' => $connect, + '$connect_url' => $connect_url, + '$location' => $location, + '$gender' => $gender, + '$pdesc' => $pdesc, + '$marital' => $marital, + '$homepage' => $homepage, + '$chanmenu' => $channel_menu, + '$diaspora' => $diaspora, + '$reddress' => $reddress, + '$rating' => $z, + '$contact_block' => $contact_block, + '$editmenu' => profile_edit_menu($profile['uid']) + )); + + $arr = array('profile' => &$profile, 'entry' => &$o); + + call_hooks('profile_sidebar', $arr); + + return $o; +} + + +/** + * @FIXME or remove + */ + function get_birthdays() { + + $o = ''; + + if(! local_channel()) + return $o; + + $bd_format = t('g A l F d') ; // 8 AM Friday January 18 + $bd_short = t('F d'); + + $r = q("SELECT `event`.*, `event`.`id` AS `eid`, `contact`.* FROM `event` + LEFT JOIN `contact` ON `contact`.`id` = `event`.`cid` + WHERE `event`.`uid` = %d AND `type` = 'birthday' AND `start` < '%s' AND `finish` > '%s' + ORDER BY `start` ASC ", + intval(local_channel()), + dbesc(datetime_convert('UTC','UTC','now + 6 days')), + dbesc(datetime_convert('UTC','UTC','now')) + ); + + if($r && count($r)) { + $total = 0; + $now = strtotime('now'); + $cids = array(); + + $istoday = false; + foreach($r as $rr) { + if(strlen($rr['name'])) + $total ++; + if((strtotime($rr['start'] . ' +00:00') < $now) && (strtotime($rr['finish'] . ' +00:00') > $now)) + $istoday = true; + } + $classtoday = $istoday ? ' birthday-today ' : ''; + if($total) { + foreach($r as &$rr) { + if(! strlen($rr['name'])) + continue; + + // avoid duplicates + + if(in_array($rr['cid'],$cids)) + continue; + $cids[] = $rr['cid']; + + $today = (((strtotime($rr['start'] . ' +00:00') < $now) && (strtotime($rr['finish'] . ' +00:00') > $now)) ? true : false); + $sparkle = ''; + $url = $rr['url']; + if($rr['network'] === NETWORK_DFRN) { + $sparkle = " sparkle"; + $url = z_root() . '/redir/' . $rr['cid']; + } + + $rr['link'] = $url; + $rr['title'] = $rr['name']; + $rr['date'] = day_translate(datetime_convert('UTC', App::$timezone, $rr['start'], $rr['adjust'] ? $bd_format : $bd_short)) . (($today) ? ' ' . t('[today]') : ''); + $rr['startime'] = Null; + $rr['today'] = $today; + } + } + } + $tpl = get_markup_template("birthdays_reminder.tpl"); + return replace_macros($tpl, array( + '$baseurl' => z_root(), + '$classtoday' => $classtoday, + '$count' => $total, + '$event_reminders' => t('Birthday Reminders'), + '$event_title' => t('Birthdays this week:'), + '$events' => $r, + '$lbr' => '{', // raw brackets mess up if/endif macro processing + '$rbr' => '}' + )); + } + + +/** + * @FIXME + */ + function get_events() { + + require_once('include/bbcode.php'); + + if(! local_channel()) + return $o; + + $bd_format = t('g A l F d') ; // 8 AM Friday January 18 + $bd_short = t('F d'); + + $r = q("SELECT `event`.* FROM `event` + WHERE `event`.`uid` = %d AND `type` != 'birthday' AND `start` < '%s' AND `start` > '%s' + ORDER BY `start` ASC ", + intval(local_channel()), + dbesc(datetime_convert('UTC','UTC','now + 6 days')), + dbesc(datetime_convert('UTC','UTC','now - 1 days')) + ); + + if($r && count($r)) { + $now = strtotime('now'); + $istoday = false; + foreach($r as $rr) { + if(strlen($rr['name'])) + $total ++; + + $strt = datetime_convert('UTC',$rr['convert'] ? App::$timezone : 'UTC',$rr['start'],'Y-m-d'); + if($strt === datetime_convert('UTC',App::$timezone,'now','Y-m-d')) + $istoday = true; + } + $classtoday = (($istoday) ? 'event-today' : ''); + + foreach($r as &$rr) { + if($rr['adjust']) + $md = datetime_convert('UTC',App::$timezone,$rr['start'],'Y/m'); + else + $md = datetime_convert('UTC','UTC',$rr['start'],'Y/m'); + $md .= "/#link-".$rr['id']; + + $title = substr(strip_tags(bbcode($rr['desc'])),0,32) . '... '; + if(! $title) + $title = t('[No description]'); + + $strt = datetime_convert('UTC',$rr['convert'] ? App::$timezone : 'UTC',$rr['start']); + $today = ((substr($strt,0,10) === datetime_convert('UTC',App::$timezone,'now','Y-m-d')) ? true : false); + + $rr['link'] = $md; + $rr['title'] = $title; + $rr['date'] = day_translate(datetime_convert('UTC', $rr['adjust'] ? App::$timezone : 'UTC', $rr['start'], $bd_format)) . (($today) ? ' ' . t('[today]') : ''); + $rr['startime'] = $strt; + $rr['today'] = $today; + } + } + + $tpl = get_markup_template("events_reminder.tpl"); + return replace_macros($tpl, array( + '$baseurl' => z_root(), + '$classtoday' => $classtoday, + '$count' => count($r), + '$event_reminders' => t('Event Reminders'), + '$event_title' => t('Events this week:'), + '$events' => $r, + )); + } + + +function advanced_profile(&$a) { + require_once('include/text.php'); + if(! perm_is_allowed(App::$profile['profile_uid'],get_observer_hash(),'view_profile')) + return ''; + + if(App::$profile['name']) { + + $profile_fields_basic = get_profile_fields_basic(); + $profile_fields_advanced = get_profile_fields_advanced(); + + $advanced = ((feature_enabled(App::$profile['profile_uid'],'advanced_profiles')) ? true : false); + if($advanced) + $fields = $profile_fields_advanced; + else + $fields = $profile_fields_basic; + + $clean_fields = array(); + if($fields) { + foreach($fields as $k => $v) { + $clean_fields[] = trim($k); + } + } + + + + $tpl = get_markup_template('profile_advanced.tpl'); + + $profile = array(); + + $profile['fullname'] = array( t('Full Name:'), App::$profile['name'] ) ; + + if(App::$profile['gender']) $profile['gender'] = array( t('Gender:'), App::$profile['gender'] ); + + $ob_hash = get_observer_hash(); + if($ob_hash && perm_is_allowed(App::$profile['profile_uid'],$ob_hash,'post_like')) { + $profile['canlike'] = true; + $profile['likethis'] = t('Like this channel'); + $profile['profile_guid'] = App::$profile['profile_guid']; + } + + $likers = q("select liker, xchan.* from likes left join xchan on liker = xchan_hash where channel_id = %d and target_type = '%s' and verb = '%s'", + intval(App::$profile['profile_uid']), + dbesc(ACTIVITY_OBJ_PROFILE), + dbesc(ACTIVITY_LIKE) + ); + $profile['likers'] = array(); + $profile['like_count'] = count($likers); + $profile['like_button_label'] = tt('Like','Likes',$profile['like_count'],'noun'); + if($likers) { + foreach($likers as $l) + $profile['likers'][] = array('name' => $l['xchan_name'],'photo' => zid($l['xchan_photo_s']), 'url' => zid($l['xchan_url'])); + } + + if((App::$profile['dob']) && (App::$profile['dob'] != '0000-00-00')) { + + $val = ''; + + if((substr(App::$profile['dob'],5,2) === '00') || (substr(App::$profile['dob'],8,2) === '00')) + $val = substr(App::$profile['dob'],0,4); + + $year_bd_format = t('j F, Y'); + $short_bd_format = t('j F'); + + if(! $val) { + $val = ((intval(App::$profile['dob'])) + ? day_translate(datetime_convert('UTC','UTC',App::$profile['dob'] . ' 00:00 +00:00',$year_bd_format)) + : day_translate(datetime_convert('UTC','UTC','2001-' . substr(App::$profile['dob'],5) . ' 00:00 +00:00',$short_bd_format))); + } + $profile['birthday'] = array( t('Birthday:'), $val); + } + + if($age = age(App::$profile['dob'],App::$profile['timezone'],'')) + $profile['age'] = array( t('Age:'), $age ); + + if(App::$profile['marital']) + $profile['marital'] = array( t('Status:'), App::$profile['marital']); + + if(App::$profile['with']) + $profile['marital']['with'] = bbcode(App::$profile['with']); + + if(strlen(App::$profile['howlong']) && App::$profile['howlong'] !== NULL_DATE) { + $profile['howlong'] = relative_date(App::$profile['howlong'], t('for %1$d %2$s')); + } + + if(App::$profile['sexual']) $profile['sexual'] = array( t('Sexual Preference:'), App::$profile['sexual'] ); + + if(App::$profile['homepage']) $profile['homepage'] = array( t('Homepage:'), linkify(App::$profile['homepage']) ); + + if(App::$profile['hometown']) $profile['hometown'] = array( t('Hometown:'), linkify(App::$profile['hometown']) ); + + if(App::$profile['keywords']) $profile['keywords'] = array( t('Tags:'), App::$profile['keywords']); + + if(App::$profile['politic']) $profile['politic'] = array( t('Political Views:'), App::$profile['politic']); + + if(App::$profile['religion']) $profile['religion'] = array( t('Religion:'), App::$profile['religion']); + + if($txt = prepare_text(App::$profile['about'])) $profile['about'] = array( t('About:'), $txt ); + + if($txt = prepare_text(App::$profile['interest'])) $profile['interest'] = array( t('Hobbies/Interests:'), $txt); + + if($txt = prepare_text(App::$profile['likes'])) $profile['likes'] = array( t('Likes:'), $txt); + + if($txt = prepare_text(App::$profile['dislikes'])) $profile['dislikes'] = array( t('Dislikes:'), $txt); + + if($txt = prepare_text(App::$profile['contact'])) $profile['contact'] = array( t('Contact information and Social Networks:'), $txt); + + if($txt = prepare_text(App::$profile['channels'])) $profile['channels'] = array( t('My other channels:'), $txt); + + if($txt = prepare_text(App::$profile['music'])) $profile['music'] = array( t('Musical interests:'), $txt); + + if($txt = prepare_text(App::$profile['book'])) $profile['book'] = array( t('Books, literature:'), $txt); + + if($txt = prepare_text(App::$profile['tv'])) $profile['tv'] = array( t('Television:'), $txt); + + if($txt = prepare_text(App::$profile['film'])) $profile['film'] = array( t('Film/dance/culture/entertainment:'), $txt); + + if($txt = prepare_text(App::$profile['romance'])) $profile['romance'] = array( t('Love/Romance:'), $txt); + + if($txt = prepare_text(App::$profile['work'])) $profile['work'] = array( t('Work/employment:'), $txt); + + if($txt = prepare_text(App::$profile['education'])) $profile['education'] = array( t('School/education:'), $txt ); + + if(App::$profile['extra_fields']) { + foreach(App::$profile['extra_fields'] as $f) { + $x = q("select * from profdef where field_name = '%s' limit 1", + dbesc($f) + ); + if($x && $txt = prepare_text(App::$profile[$f])) + $profile[$f] = array( $x[0]['field_desc'] . ':',$txt); + } + $profile['extra_fields'] = App::$profile['extra_fields']; + } + + $things = get_things(App::$profile['profile_guid'],App::$profile['profile_uid']); + +// logger('mod_profile: things: ' . print_r($things,true), LOGGER_DATA); + + return replace_macros($tpl, array( + '$title' => t('Profile'), + '$canlike' => (($profile['canlike'])? true : false), + '$likethis' => t('Like this thing'), + '$profile' => $profile, + '$fields' => $clean_fields, + '$editmenu' => profile_edit_menu(App::$profile['profile_uid']), + '$things' => $things + )); + } + + return ''; +} + + +function get_my_url() { + if(x($_SESSION, 'zrl_override')) + return $_SESSION['zrl_override']; + if(x($_SESSION, 'my_url')) + return $_SESSION['my_url']; + + return false; +} + +function get_my_address() { + if(x($_SESSION, 'zid_override')) + return $_SESSION['zid_override']; + if(x($_SESSION, 'my_address')) + return $_SESSION['my_address']; + + return false; +} + +/** + * @brief + * + * If somebody arrives at our site using a zid, add their xchan to our DB if we don't have it already. + * And if they aren't already authenticated here, attempt reverse magic auth. + * + * @param App &$a + * + * @hooks 'zid_init' + * string 'zid' - their zid + * string 'url' - the destination url + */ +function zid_init(&$a) { + $tmp_str = get_my_address(); + if(validate_email($tmp_str)) { + Zotlabs\Daemon\Master::Summon(array('Gprobe',bin2hex($tmp_str))); + $arr = array('zid' => $tmp_str, 'url' => App::$cmd); + call_hooks('zid_init',$arr); + if(! local_channel()) { + $r = q("select * from hubloc where hubloc_addr = '%s' order by hubloc_connected desc limit 1", + dbesc($tmp_str) + ); + if($r && remote_channel() && remote_channel() === $r[0]['hubloc_hash']) + return; + logger('zid_init: not authenticated. Invoking reverse magic-auth for ' . $tmp_str); + // try to avoid recursion - but send them home to do a proper magic auth + $query = App::$query_string; + $query = str_replace(array('?zid=','&zid='),array('?rzid=','&rzid='),$query); + $dest = '/' . urlencode($query); + if($r && ($r[0]['hubloc_url'] != z_root()) && (! strstr($dest,'/magic')) && (! strstr($dest,'/rmagic'))) { + goaway($r[0]['hubloc_url'] . '/magic' . '?f=&rev=1&dest=' . z_root() . $dest); + } + else + logger('zid_init: no hubloc found.'); + } + } +} + +/** + * @brief Adds a zid parameter to a url. + * + * @param string $s + * The url to accept the zid + * @param boolean $address + * $address to use instead of session environment + * @return string + * + * @hooks 'zid' + * string url - url to accept zid + * string zid - urlencoded zid + * string result - the return string we calculated, change it if you want to return something else + */ +function zid($s,$address = '') { + if (! strlen($s) || strpos($s,'zid=')) + return $s; + + $has_params = ((strpos($s,'?')) ? true : false); + $num_slashes = substr_count($s, '/'); + if (! $has_params) + $has_params = ((strpos($s, '&')) ? true : false); + + $achar = strpos($s,'?') ? '&' : '?'; + + $mine = get_my_url(); + $myaddr = (($address) ? $address : get_my_address()); + + /** @FIXME checking against our own channel url is no longer reliable. We may have a lot + * of urls attached to out channel. Should probably match against our site, since we + * will not need to remote authenticate on our own site anyway. + */ + + if ($mine && $myaddr && (! link_compare($mine,$s))) + $zurl = $s . (($num_slashes >= 3) ? '' : '/') . $achar . 'zid=' . urlencode($myaddr); + else + $zurl = $s; + + $arr = array('url' => $s, 'zid' => urlencode($myaddr), 'result' => $zurl); + call_hooks('zid', $arr); + + return $arr['result']; +} + +// Used from within PCSS themes to set theme parameters. If there's a +// puid request variable, that is the "page owner" and normally their theme +// settings take precedence; unless a local user sets the "always_my_theme" +// system pconfig, which means they don't want to see anybody else's theme +// settings except their own while on this site. + +function get_theme_uid() { + $uid = (($_REQUEST['puid']) ? intval($_REQUEST['puid']) : 0); + if(local_channel()) { + if((get_pconfig(local_channel(),'system','always_my_theme')) || (! $uid)) + return local_channel(); + } + if(! $uid) { + $x = get_sys_channel(); + if($x) + return $x['channel_id']; + } + + return $uid; +} + +/** +* @brief Retrieves the path of the default_profile_photo for this system +* with the specified size. +* +* @param int $size +* one of (300, 80, 48) +* @returns string +*/ +function get_default_profile_photo($size = 300) { + $scheme = get_config('system','default_profile_photo'); + if(! $scheme) + $scheme = 'rainbow_man'; + + return 'images/default_profile_photos/' . $scheme . '/' . $size . '.png'; +} + +/** + * @brief Test whether a given identity is NOT a member of the Hubzilla. + * + * @param string $s; + * xchan_hash of the identity in question + * @returns boolean true or false + */ +function is_foreigner($s) { + return((strpbrk($s, '.:@')) ? true : false); +} + +/** + * @brief Test whether a given identity is a member of the Hubzilla. + * + * @param string $s; + * xchan_hash of the identity in question + * @returns boolean true or false + */ +function is_member($s) { + return((is_foreigner($s)) ? false : true); +} + +function get_online_status($nick) { + + $ret = array('result' => false); + + if(get_config('system','block_public') && ! local_channel() && ! remote_channel()) + return $ret; + + $r = q("select channel_id, channel_hash from channel where channel_address = '%s' limit 1", + dbesc(argv(1)) + ); + if($r) { + $hide = get_pconfig($r[0]['channel_id'],'system','hide_online_status'); + if($hide) + return $ret; + $x = q("select cp_status from chatpresence where cp_xchan = '%s' and cp_room = 0 limit 1", + dbesc($r[0]['channel_hash']) + ); + if($x) + $ret['result'] = $x[0]['cp_status']; + } + + return $ret; +} + + +function remote_online_status($webbie) { + + $result = false; + $r = q("select * from hubloc where hubloc_addr = '%s' limit 1", + dbesc($webbie) + ); + if(! $r) + return $result; + + $url = $r[0]['hubloc_url'] . '/online/' . substr($webbie,0,strpos($webbie,'@')); + + $x = z_fetch_url($url); + if($x['success']) { + $j = json_decode($x['body'],true); + if($j) + $result = (($j['result']) ? $j['result'] : false); + } + + return $result; +} + + +function get_channel_by_nick($nick) { + $r = q("select * from channel where channel_address = '%s' limit 1", + dbesc($nick) + ); + return(($r) ? $r[0] : false); + +} + +/** + * @brief + * + * @return string + */ +function identity_selector() { + if (local_channel()) { + $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel.channel_account_id = %d and channel_removed = 0 order by channel_name ", + intval(get_account_id()) + ); + if (count($r) > 1) { + //$account = App::get_account(); + $o = replace_macros(get_markup_template('channel_id_select.tpl'), array( + '$channels' => $r, + '$selected' => local_channel() + )); + return $o; + } + } + + return ''; +} + + +function is_public_profile() { + if(! local_channel()) + return false; + if(intval(get_config('system','block_public'))) + return false; + $channel = App::get_channel(); + if($channel && $channel['channel_r_profile'] == PERMS_PUBLIC) + return true; + + return false; +} + +function get_profile_fields_basic($filter = 0) { + + $profile_fields_basic = (($filter == 0) ? get_config('system','profile_fields_basic') : null); + if(! $profile_fields_basic) + $profile_fields_basic = array('name','pdesc','chandesc','gender','dob','dob_tz','address','locality','region','postal_code','country_name','marital','sexual','homepage','hometown','keywords','about','contact'); + + $x = array(); + if($profile_fields_basic) + foreach($profile_fields_basic as $f) + $x[$f] = 1; + + return $x; +} + + +function get_profile_fields_advanced($filter = 0) { + $basic = get_profile_fields_basic($filter); + $profile_fields_advanced = (($filter == 0) ? get_config('system','profile_fields_advanced') : null); + if(! $profile_fields_advanced) + $profile_fields_advanced = array('with','howlong','politic','religion','likes','dislikes','interest','channels','music','book','film','tv','romance','work','education'); + + $x = array(); + if($basic) + foreach($basic as $f => $v) + $x[$f] = $v; + + if($profile_fields_advanced) + foreach($profile_fields_advanced as $f) + $x[$f] = 1; + + return $x; +} + +/** + * @brief Clear notifyflags for a channel. + * + * Most likely during bulk import of content or other activity that is likely + * to generate huge amounts of undesired notifications. + * + * @param int $channel_id + * The channel to disable notifications for + * @returns int + * Current notification flag value. Send this to notifications_on() to restore the channel settings when finished + * with the activity requiring notifications_off(); + */ +function notifications_off($channel_id) { + $r = q("select channel_notifyflags from channel where channel_id = %d limit 1", + intval($channel_id) + ); + q("update channel set channel_notifyflags = 0 where channel_id = %d", + intval($channel_id) + ); + + return intval($r[0]['channel_notifyflags']); +} + + +function notifications_on($channel_id,$value) { + $x = q("update channel set channel_notifyflags = %d where channel_id = %d", + intval($value), + intval($channel_id) + ); + return $x; +} + + +function get_channel_default_perms($uid) { + + $r = q("select abook_my_perms from abook where abook_channel = %d and abook_self = 1 limit 1", + intval($uid) + ); + if($r) + return $r[0]['abook_my_perms']; + + return 0; +} + + +function profiles_build_sync($channel_id) { + + $r = q("select * from profile where uid = %d", + intval($channel_id) + ); + if($r) { + build_sync_packet($channel_id,array('profile' => $r)); + } +} + + +function auto_channel_create($account_id) { + + if(! $account_id) + return false; + + $arr = array(); + $arr['account_id'] = $account_id; + $arr['name'] = get_aconfig($account_id,'register','channel_name'); + $arr['nickname'] = legal_webbie(get_aconfig($account_id,'register','channel_address')); + $arr['permissions_role'] = get_aconfig($account_id,'register','permissions_role'); + + del_aconfig($account_id,'register','channel_name'); + del_aconfig($account_id,'register','channel_address'); + del_aconfig($account_id,'register','permissions_role'); + + if((! $arr['name']) || (! $arr['nickname'])) { + $x = q("select * from account where account_id = %d limit 1", + intval($account_id) + ); + if($x) { + if(! $arr['name']) + $arr['name'] = substr($x[0]['account_email'],0,strpos($x[0]['account_email'],'@')); + if(! $arr['nickname']) + $arr['nickname'] = legal_webbie(substr($x[0]['account_email'],0,strpos($x[0]['account_email'],'@'))); + } + } + if(! $arr['permissions_role']) + $arr['permissions_role'] = 'social'; + + if(validate_channelname($arr['name'])) + return false; + if($arr['nickname'] === 'sys') + $arr['nickname'] = $arr['nickname'] . mt_rand(1000,9999); + + $arr['nickname'] = check_webbie(array($arr['nickname'], $arr['nickname'] . mt_rand(1000,9999))); + + return create_identity($arr); + +} + +function get_cover_photo($channel_id,$format = 'bbcode', $res = PHOTO_RES_COVER_1200) { + + $r = q("select height, width, resource_id, type from photo where uid = %d and scale = %d and photo_usage = %d", + intval($channel_id), + intval($res), + intval(PHOTO_COVER) + ); + if(! $r) + return false; + + $output = false; + + $url = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $res ; + + switch($format) { + case 'bbcode': + $output = '[zrl=' . $r[0]['width'] . 'x' . $r[0]['height'] . ']' . $url . '[/zrl]'; + break; + case 'html': + $output = '' . t('cover photo') . ''; + break; + case 'array': + default: + $output = array( + 'width' => $r[0]['width'], + 'height' => $r[0]['type'], + 'type' => $r[0]['type'], + 'url' => $url + ); + break; + } + + return $output; + +} + +function get_zcard($channel,$observer_hash = '',$args = array()) { + + logger('get_zcard'); + + $maxwidth = (($args['width']) ? intval($args['width']) : 0); + $maxheight = (($args['height']) ? intval($args['height']) : 0); + + + if(($maxwidth > 1200) || ($maxwidth < 1)) + $maxwidth = 1200; + + if($maxwidth <= 425) { + $width = 425; + $size = 'hz_small'; + $cover_size = PHOTO_RES_COVER_425; + $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']); + } + elseif($maxwidth <= 900) { + $width = 900; + $size = 'hz_medium'; + $cover_size = PHOTO_RES_COVER_850; + $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']); + } + elseif($maxwidth <= 1200) { + $width = 1200; + $size = 'hz_large'; + $cover_size = PHOTO_RES_COVER_1200; + $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']); + } + +// $scale = (float) $maxwidth / $width; +// $translate = intval(($scale / 1.0) * 100); + + + $channel['channel_addr'] = $channel['channel_address'] . '@' . App::get_hostname(); + $zcard = array('chan' => $channel); + + $r = q("select height, width, resource_id, scale, type from photo where uid = %d and scale = %d and photo_usage = %d", + intval($channel['channel_id']), + intval($cover_size), + intval(PHOTO_COVER) + ); + + if($r) { + $cover = $r[0]; + $cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['scale']; + } + else { + $cover = $pphoto; + } + + $o .= replace_macros(get_markup_template('zcard.tpl'),array( + '$maxwidth' => $maxwidth, + '$scale' => $scale, + '$translate' => $translate, + '$size' => $size, + '$cover' => $cover, + '$pphoto' => $pphoto, + '$zcard' => $zcard + )); + + return $o; + +} + + +function get_zcard_embed($channel,$observer_hash = '',$args = array()) { + + logger('get_zcard_embed'); + + $maxwidth = (($args['width']) ? intval($args['width']) : 0); + $maxheight = (($args['height']) ? intval($args['height']) : 0); + + + if(($maxwidth > 1200) || ($maxwidth < 1)) + $maxwidth = 1200; + + if($maxwidth <= 425) { + $width = 425; + $size = 'hz_small'; + $cover_size = PHOTO_RES_COVER_425; + $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']); + } + elseif($maxwidth <= 900) { + $width = 900; + $size = 'hz_medium'; + $cover_size = PHOTO_RES_COVER_850; + $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']); + } + elseif($maxwidth <= 1200) { + $width = 1200; + $size = 'hz_large'; + $cover_size = PHOTO_RES_COVER_1200; + $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']); + } + + $channel['channel_addr'] = $channel['channel_address'] . '@' . App::get_hostname(); + $zcard = array('chan' => $channel); + + $r = q("select height, width, resource_id, scale, type from photo where uid = %d and scale = %d and photo_usage = %d", + intval($channel['channel_id']), + intval($cover_size), + intval(PHOTO_COVER) + ); + + if($r) { + $cover = $r[0]; + $cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['scale']; + } + else { + $cover = $pphoto; + } + + $o .= replace_macros(get_markup_template('zcard_embed.tpl'),array( + '$maxwidth' => $maxwidth, + '$scale' => $scale, + '$translate' => $translate, + '$size' => $size, + '$cover' => $cover, + '$pphoto' => $pphoto, + '$zcard' => $zcard + )); + + return $o; + +} diff --git a/include/connections.php b/include/connections.php new file mode 100644 index 000000000..c55ffd817 --- /dev/null +++ b/include/connections.php @@ -0,0 +1,636 @@ + $xchan['xchan_name'], + '$photo' => ((is_array(App::$profile) && array_key_exists('photo',App::$profile)) ? App::$profile['photo'] : $xchan['xchan_photo_l']), + '$follow' => $xchan['xchan_addr'], + '$link' => zid($xchan['xchan_url']), + '$connect' => $connect, + '$newwin' => (($mode === 'chanview') ? t('New window') : ''), + '$newtit' => t('Open the selected location in a different window or browser tab'), + '$url' => $url, + )); +} + +function abook_toggle_flag($abook,$flag) { + + $field = ''; + + switch($flag) { + case ABOOK_FLAG_BLOCKED: + $field = 'abook_blocked'; + break; + case ABOOK_FLAG_IGNORED: + $field = 'abook_ignored'; + break; + case ABOOK_FLAG_HIDDEN: + $field = 'abook_hidden'; + break; + case ABOOK_FLAG_ARCHIVED: + $field = 'abook_archived'; + break; + case ABOOK_FLAG_PENDING: + $field = 'abook_pending'; + break; + case ABOOK_FLAG_UNCONNECTED: + $field = 'abook_unconnected'; + break; + case ABOOK_FLAG_SELF: + $field = 'abook_self'; + break; + case ABOOK_FLAG_FEED: + $field = 'abook_feed'; + break; + default: + break; + } + if(! $field) + return; + + $r = q("UPDATE abook set $field = (1 - $field) where abook_id = %d and abook_channel = %d", + intval($abook['abook_id']), + intval($abook['abook_channel']) + ); + + + // if unsetting the archive bit, update the timestamps so we'll try to connect for an additional 30 days. + + if(($flag === ABOOK_FLAG_ARCHIVED) && (intval($abook['abook_archived']))) { + $r = q("update abook set abook_connected = '%s', abook_updated = '%s' + where abook_id = %d and abook_channel = %d", + dbesc(datetime_convert()), + dbesc(datetime_convert()), + intval($abook['abook_id']), + intval($abook['abook_channel']) + ); + } + + return $r; + +} + + +// Included here for completeness, but this is a very dangerous operation. +// It is the caller's responsibility to confirm the requestor's intent and +// authorisation to do this. + +function user_remove($uid) { + +} + +function account_remove($account_id,$local = true,$unset_session=true) { + + logger('account_remove: ' . $account_id); + + if(! intval($account_id)) { + logger('account_remove: no account.'); + return false; + } + + // Don't let anybody nuke the only admin account. + + $r = q("select account_id from account where (account_roles & %d) > 0", + intval(ACCOUNT_ROLE_ADMIN) + ); + + if($r !== false && count($r) == 1 && $r[0]['account_id'] == $account_id) { + logger("Unable to remove the only remaining admin account"); + return false; + } + + $r = q("select * from account where account_id = %d limit 1", + intval($account_id) + ); + $account_email=$r[0]['account_email']; + + if(! $r) { + logger('account_remove: No account with id: ' . $account_id); + return false; + } + + $x = q("select channel_id from channel where channel_account_id = %d", + intval($account_id) + ); + if($x) { + foreach($x as $xx) { + channel_remove($xx['channel_id'],$local,false); + } + } + + $r = q("delete from account where account_id = %d", + intval($account_id) + ); + + + if ($unset_session) { + unset($_SESSION['authenticated']); + unset($_SESSION['uid']); + notice( sprintf(t("User '%s' deleted"),$account_email) . EOL); + goaway(z_root()); + } + return $r; + +} +// recursively delete a directory +function rrmdir($path) +{ + if (is_dir($path) === true) + { + $files = array_diff(scandir($path), array('.', '..')); + + foreach ($files as $file) + { + rrmdir(realpath($path) . '/' . $file); + } + + return rmdir($path); + } + + else if (is_file($path) === true) + { + return unlink($path); + } + + return false; +} + +function channel_remove($channel_id, $local = true, $unset_session=false) { + + if(! $channel_id) + return; + $a = get_app(); + logger('Removing channel: ' . $channel_id); + logger('channel_remove: local only: ' . intval($local)); + + $r = q("select * from channel where channel_id = %d limit 1", intval($channel_id)); + if(! $r) { + logger('channel_remove: channel not found: ' . $channel_id); + return; + } + + $channel = $r[0]; + + call_hooks('channel_remove',$r[0]); + + if(! $local) { + + $r = q("update channel set channel_deleted = '%s', channel_removed = 1, channel_r_stream = 0, channel_r_profile = 0, + channel_r_photos = 0, channel_r_abook = 0, channel_w_stream = 0, channel_w_wall = 0, channel_w_tagwall = 0, + channel_w_comment = 0, channel_w_mail = 0, channel_w_photos = 0, channel_w_chat = 0, channel_a_delegate = 0, + channel_r_storage = 0, channel_w_storage = 0, channel_r_pages = 0, channel_w_pages = 0, channel_a_republish = 0 + where channel_id = %d", + dbesc(datetime_convert()), + intval($channel_id) + ); + + logger('deleting hublocs',LOGGER_DEBUG); + + $r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s'", + dbesc($channel['channel_hash']) + ); + + + $r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s'", + dbesc($channel['channel_hash']) + ); + + Zotlabs\Daemon\Master::Summon(array('Notifier','purge_all',$channel_id)); + } + + q("DELETE FROM `groups` WHERE `uid` = %d", intval($channel_id)); + q("DELETE FROM `group_member` WHERE `uid` = %d", intval($channel_id)); + q("DELETE FROM `event` WHERE `uid` = %d", intval($channel_id)); + q("DELETE FROM `item` WHERE `uid` = %d", intval($channel_id)); + q("DELETE FROM `item_id` WHERE `uid` = %d", intval($channel_id)); + q("DELETE FROM `mail` WHERE `channel_id` = %d", intval($channel_id)); + q("DELETE FROM `notify` WHERE `uid` = %d", intval($channel_id)); + q("DELETE FROM `photo` WHERE `uid` = %d", intval($channel_id)); + q("DELETE FROM `attach` WHERE `uid` = %d", intval($channel_id)); + q("DELETE FROM `profile` WHERE `uid` = %d", intval($channel_id)); + q("DELETE FROM `pconfig` WHERE `uid` = %d", intval($channel_id)); + q("DELETE FROM `spam` WHERE `uid` = %d", intval($channel_id)); + + // @FIXME At this stage we need to remove the file resources located under /store/$nickname + + + q("delete from abook where abook_xchan = '%s' and abook_self = 1 ", + dbesc($channel['channel_hash']) + ); + + $r = q("update channel set channel_deleted = '%s', channel_removed = 1 where channel_id = %d", + dbesc(datetime_convert()), + intval($channel_id) + ); + + // if this was the default channel, set another one as default + if(App::$account['account_default_channel'] == $channel_id) { + $r = q("select channel_id from channel where channel_account_id = %d and channel_removed = 0 limit 1", + intval(App::$account['account_id']), + intval(PAGE_REMOVED)); + if ($r) { + $rr = q("update account set account_default_channel = %d where account_id = %d", + intval($r[0]['channel_id']), + intval(App::$account['account_id'])); + logger("Default channel deleted, changing default to channel_id " . $r[0]['channel_id']); + } + else { + $rr = q("update account set account_default_channel = 0 where account_id = %d", + intval(App::$account['account_id']) + ); + } + } + + logger('deleting hublocs',LOGGER_DEBUG); + + $r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s' and hubloc_url = '%s' ", + dbesc($channel['channel_hash']), + dbesc(z_root()) + ); + + // Do we have any valid hublocs remaining? + + $hublocs = 0; + + $r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0", + dbesc($channel['channel_hash']) + ); + if($r) + $hublocs = count($r); + + if(! $hublocs) { + $r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s' ", + dbesc($channel['channel_hash']) + ); + } + + //remove from file system + $r = q("select channel_address from channel where channel_id = %d limit 1", + intval($channel_id) + ); + if($r) + $channel_address = $r[0]['channel_address'] ; + if ($channel_address !== '') { + $f = 'store/' . $channel_address.'/'; + logger ('delete '. $f); + if(is_dir($f)) + @rrmdir($f); + } + + Zotlabs\Daemon\Master::Summon(array('Directory',$channel_id)); + + if($channel_id == local_channel() && $unset_session) { + App::$session->nuke(); + goaway(z_root()); + } + +} + +/** + * mark any hubs "offline" that haven't been heard from in more than 30 days + * Allow them to redeem themselves if they come back later. + * Then go through all those that are newly marked and see if any other hubs + * are attached to the controlling xchan that are still alive. + * If not, they're dead (although they could come back some day). + */ + + +function mark_orphan_hubsxchans() { + + $dirmode = intval(get_config('system','directory_mode')); + if($dirmode == DIRECTORY_MODE_NORMAL) + return; + + $r = q("update hubloc set hubloc_error = 1 where hubloc_error = 0 + and hubloc_network = 'zot' and hubloc_connected < %s - interval %s", + db_utcnow(), db_quoteinterval('36 day') + ); + +// $realm = get_directory_realm(); +// if($realm == DIRECTORY_REALM) { +// $r = q("select * from site where site_access != 0 and site_register !=0 and ( site_realm = '%s' or site_realm = '') order by rand()", +// dbesc($realm) +// ); +// } +// else { +// $r = q("select * from site where site_access != 0 and site_register !=0 and site_realm = '%s' order by rand()", +// dbesc($realm) +// ); +// } + + + $r = q("select hubloc_id, hubloc_hash from hubloc where hubloc_error = 0 and hubloc_orphancheck = 0"); + + if($r) { + foreach($r as $rr) { + + // see if any other hublocs are still alive for this channel + + $x = q("select * from hubloc where hubloc_hash = '%s' and hubloc_error = 0", + dbesc($rr['hubloc_hash']) + ); + if($x) { + + // yes - if the xchan was marked as an orphan, undo it + + $y = q("update xchan set xchan_orphan = 0 where xchan_orphan = 1 and xchan_hash = '%s'", + dbesc($rr['hubloc_hash']) + ); + + } + else { + + // nope - mark the xchan as an orphan + + $y = q("update xchan set xchan_orphan = 1 where xchan_hash = '%s'", + dbesc($rr['hubloc_hash']) + ); + } + + // mark that we've checked this entry so we don't need to do it again + + $y = q("update hubloc set hubloc_orphancheck = 1 where hubloc_id = %d", + dbesc($rr['hubloc_id']) + ); + } + } + +} + + + + +function remove_all_xchan_resources($xchan, $channel_id = 0) { + + if(intval($channel_id)) { + + + + } + else { + + $dirmode = intval(get_config('system','directory_mode')); + + + $r = q("delete from photo where xchan = '%s'", + dbesc($xchan) + ); + $r = q("select resource_id, resource_type, uid, id from item where ( author_xchan = '%s' or owner_xchan = '%s' ) ", + dbesc($xchan), + dbesc($xchan) + ); + if($r) { + foreach($r as $rr) { + drop_item($rr,false); + } + } + $r = q("delete from event where event_xchan = '%s'", + dbesc($xchan) + ); + $r = q("delete from group_member where xchan = '%s'", + dbesc($xchan) + ); + $r = q("delete from mail where ( from_xchan = '%s' or to_xchan = '%s' )", + dbesc($xchan), + dbesc($xchan) + ); + $r = q("delete from xlink where ( xlink_xchan = '%s' or xlink_link = '%s' )", + dbesc($xchan), + dbesc($xchan) + ); + + $r = q("delete from abook where abook_xchan = '%s'", + dbesc($xchan) + ); + + + if($dirmode === false || $dirmode == DIRECTORY_MODE_NORMAL) { + + $r = q("delete from xchan where xchan_hash = '%s'", + dbesc($xchan) + ); + $r = q("delete from hubloc where hubloc_hash = '%s'", + dbesc($xchan) + ); + + } + else { + + // directory servers need to keep the record around for sync purposes - mark it deleted + + $r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s'", + dbesc($xchan) + ); + + $r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s'", + dbesc($xchan) + ); + } + } +} + + +function contact_remove($channel_id, $abook_id) { + + if((! $channel_id) || (! $abook_id)) + return false; + + logger('removing contact ' . $abook_id . ' for channel ' . $channel_id,LOGGER_DEBUG); + + $archive = get_pconfig($channel_id, 'system','archive_removed_contacts'); + if($archive) { + q("update abook set abook_archived = 1 where abook_id = %d and abook_channel = %d", + intval($abook_id), + intval($channel_id) + ); + return true; + } + + $r = q("select * from abook where abook_id = %d and abook_channel = %d limit 1", + intval($abook_id), + intval($channel_id) + ); + + if(! $r) + return false; + + $abook = $r[0]; + + if(intval($abook['abook_self'])) + return false; + + + $r = q("select * from item where author_xchan = '%s' and uid = %d", + dbesc($abook['abook_xchan']), + intval($channel_id) + ); + if($r) { + foreach($r as $rr) { + drop_item($rr['id'],false); + } + } + + q("delete from abook where abook_id = %d and abook_channel = %d", + intval($abook['abook_id']), + intval($channel_id) + ); + + $r = q("delete from event where event_xchan = '%s' and uid = %d", + dbesc($abook['abook_xchan']), + intval($channel_id) + ); + + $r = q("delete from group_member where xchan = '%s' and uid = %d", + dbesc($abook['abook_xchan']), + intval($channel_id) + ); + + $r = q("delete from mail where ( from_xchan = '%s' or to_xchan = '%s' ) and channel_id = %d ", + dbesc($abook['abook_xchan']), + dbesc($abook['abook_xchan']), + intval($channel_id) + ); + + return true; +} + + + +function random_profile() { + $randfunc = db_getfunc('rand'); + + $checkrandom = get_config('randprofile','check'); // False by default + $retryrandom = intval(get_config('randprofile','retry')); + if($retryrandom == 0) $retryrandom = 5; + + for($i = 0; $i < $retryrandom; $i++) { + + $r = q("select xchan_url from xchan left join hubloc on hubloc_hash = xchan_hash where hubloc_connected > %s - interval %s order by $randfunc limit 1", + db_utcnow(), db_quoteinterval('30 day') + ); + + if(!$r) return ''; // Couldn't get a random channel + + if($checkrandom) { + $x = z_fetch_url($r[0]['xchan_url']); + if($x['success']) + return $r[0]['xchan_url']; + else + logger('Random channel turned out to be bad.'); + } + else { + return $r[0]['xchan_url']; + } + + } + return ''; +} + diff --git a/include/contact_widgets.php b/include/contact_widgets.php index e62d57aa2..14d26e257 100644 --- a/include/contact_widgets.php +++ b/include/contact_widgets.php @@ -3,9 +3,6 @@ function findpeople_widget() { - require_once('include/Contact.php'); - - $a = get_app(); if(get_config('system','invitation_only')) { $x = get_pconfig(local_channel(),'system','invites_remaining'); @@ -37,7 +34,6 @@ function findpeople_widget() { function fileas_widget($baseurl,$selected = '') { - $a = get_app(); if(! local_channel()) return ''; @@ -65,8 +61,6 @@ function fileas_widget($baseurl,$selected = '') { } function categories_widget($baseurl,$selected = '') { - - $a = get_app(); if(! feature_enabled(App::$profile['profile_uid'],'categories')) return ''; @@ -108,8 +102,6 @@ function categories_widget($baseurl,$selected = '') { function common_friends_visitor_widget($profile_uid) { - $a = get_app(); - if(local_channel() == $profile_uid) return; diff --git a/include/conversation.php b/include/conversation.php index fca07a91d..ca73a7a07 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -1107,7 +1107,6 @@ function status_editor($a, $x, $popup = false) { $o = ''; - require_once('include/Contact.php'); $c = channelx_by_n($x['profile_uid']); if($c && $c['channel_moved']) return $o; @@ -1160,7 +1159,7 @@ function status_editor($a, $x, $popup = false) { $layoutselect = ''; if(array_key_exists('channel_select',$x) && $x['channel_select']) { - require_once('include/identity.php'); + require_once('include/channel.php'); $id_select = identity_selector(); } else diff --git a/include/feedutils.php b/include/feedutils.php index 700198ff8..f370c540a 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -1087,7 +1087,6 @@ function update_feed_item($uid,$datarray) { function handle_feed($uid,$abook_id,$url) { - require_once('include/Contact.php'); $channel = channelx_by_n($uid); if(! $channel) return; diff --git a/include/identity.php b/include/identity.php deleted file mode 100644 index 4ef1105ea..000000000 --- a/include/identity.php +++ /dev/null @@ -1,1949 +0,0 @@ - false, 'message' => ''); - - $r = q("select count(channel_id) as total from channel where channel_account_id = %d and channel_removed = 0 ", - intval($account_id) - ); - if(! ($r && count($r))) { - $ret['total_identities'] = 0; - $ret['message'] = t('Unable to obtain identity information from database'); - return $ret; - } - - $ret['total_identities'] = intval($r[0]['total']); - - if (! account_service_class_allows($account_id, 'total_identities', $r[0]['total'])) { - $ret['message'] .= upgrade_message(); - return $ret; - } - - $ret['success'] = true; - - return $ret; -} - - -/** - * @brief Determine if the channel name is allowed when creating a new channel. - * - * This action is pluggable. - * We're currently only checking for an empty name or one that exceeds our - * storage limit (255 chars). 255 chars is probably going to create a mess on - * some pages. - * Plugins can set additional policies such as full name requirements, character - * sets, multi-byte length, etc. - * - * @param string $name - * - * @returns nil return if name is valid, or string describing the error state. - */ -function validate_channelname($name) { - - if (! $name) - return t('Empty name'); - - if (strlen($name) > 255) - return t('Name too long'); - - $arr = array('name' => $name); - call_hooks('validate_channelname', $arr); - - if (x($arr, 'message')) - return $arr['message']; -} - - -/** - * @brief Create a system channel - which has no account attached. - * - */ -function create_sys_channel() { - if (get_sys_channel()) - return; - - // Ensure that there is a host keypair. - - if ((! get_config('system', 'pubkey')) && (! get_config('system', 'prvkey'))) { - require_once('include/crypto.php'); - $hostkey = new_keypair(4096); - set_config('system', 'pubkey', $hostkey['pubkey']); - set_config('system', 'prvkey', $hostkey['prvkey']); - } - - create_identity(array( - 'account_id' => 'xxx', // This will create an identity with an (integer) account_id of 0, but account_id is required - 'nickname' => 'sys', - 'name' => 'System', - 'pageflags' => 0, - 'publish' => 0, - 'system' => 1 - )); -} - - -/** - * @brief Returns the sys channel. - * - * @return array|boolean - */ -function get_sys_channel() { - $r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_system = 1 limit 1"); - - if ($r) - return $r[0]; - - return false; -} - - -/** - * @brief Checks if $channel_id is sys channel. - * - * @param int $channel_id - * @return boolean - */ -function is_sys_channel($channel_id) { - $r = q("select channel_system from channel where channel_id = %d and channel_system = 1 limit 1", - intval($channel_id) - ); - - if($r) - return true; - - return false; -} - - -/** - * @brief Return the total number of channels on this site. - * - * No filtering is performed except to check PAGE_REMOVED. - * - * @returns int|booleean - * on error returns boolean false - */ -function channel_total() { - $r = q("select channel_id from channel where channel_removed = 0"); - - if (is_array($r)) - return count($r); - - return false; -} - - -/** - * @brief Create a new channel. - * - * Also creates the related xchan, hubloc, profile, and "self" abook records, - * and an empty "Friends" group/collection for the new channel. - * - * @param array $arr assoziative array with: - * * \e string \b name full name of channel - * * \e string \b nickname "email/url-compliant" nickname - * * \e int \b account_id to attach with this channel - * * [other identity fields as desired] - * - * @returns array - * 'success' => boolean true or false - * 'message' => optional error text if success is false - * 'channel' => if successful the created channel array - */ -function create_identity($arr) { - - $ret = array('success' => false); - - if(! $arr['account_id']) { - $ret['message'] = t('No account identifier'); - return $ret; - } - $ret = identity_check_service_class($arr['account_id']); - if (!$ret['success']) { - return $ret; - } - // save this for auto_friending - $total_identities = $ret['total_identities']; - - $nick = mb_strtolower(trim($arr['nickname'])); - if(! $nick) { - $ret['message'] = t('Nickname is required.'); - return $ret; - } - - $name = escape_tags($arr['name']); - $pageflags = ((x($arr,'pageflags')) ? intval($arr['pageflags']) : PAGE_NORMAL); - $system = ((x($arr,'system')) ? intval($arr['system']) : 0); - $name_error = validate_channelname($arr['name']); - if($name_error) { - $ret['message'] = $name_error; - return $ret; - } - - if($nick === 'sys' && (! $system)) { - $ret['message'] = t('Reserved nickname. Please choose another.'); - return $ret; - } - - if(check_webbie(array($nick)) !== $nick) { - $ret['message'] = t('Nickname has unsupported characters or is already being used on this site.'); - return $ret; - } - - $guid = zot_new_uid($nick); - $key = new_keypair(4096); - - $sig = base64url_encode(rsa_sign($guid,$key['prvkey'])); - $hash = make_xchan_hash($guid,$sig); - - // Force a few things on the short term until we can provide a theme or app with choice - - $publish = 1; - - if(array_key_exists('publish', $arr)) - $publish = intval($arr['publish']); - - $primary = true; - - if(array_key_exists('primary', $arr)) - $primary = intval($arr['primary']); - - $role_permissions = null; - $global_perms = get_perms(); - - if(array_key_exists('permissions_role',$arr) && $arr['permissions_role']) { - $role_permissions = get_role_perms($arr['permissions_role']); - - if($role_permissions) { - foreach($role_permissions as $p => $v) { - if(strpos($p,'channel_') !== false) { - $perms_keys .= ', ' . $p; - $perms_vals .= ', ' . intval($v); - } - if($p === 'directory_publish') - $publish = intval($v); - } - } - } - else { - $defperms = site_default_perms(); - foreach($defperms as $p => $v) { - $perms_keys .= ', ' . $global_perms[$p][0]; - $perms_vals .= ', ' . intval($v); - } - } - - $expire = 0; - - $r = q("insert into channel ( channel_account_id, channel_primary, - channel_name, channel_address, channel_guid, channel_guid_sig, - channel_hash, channel_prvkey, channel_pubkey, channel_pageflags, channel_system, channel_expire_days, channel_timezone $perms_keys ) - values ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s' $perms_vals ) ", - - intval($arr['account_id']), - intval($primary), - dbesc($name), - dbesc($nick), - dbesc($guid), - dbesc($sig), - dbesc($hash), - dbesc($key['prvkey']), - dbesc($key['pubkey']), - intval($pageflags), - intval($system), - intval($expire), - dbesc(App::$timezone) - ); - - $r = q("select * from channel where channel_account_id = %d - and channel_guid = '%s' limit 1", - intval($arr['account_id']), - dbesc($guid) - ); - - if(! $r) { - $ret['message'] = t('Unable to retrieve created identity'); - return $ret; - } - - $ret['channel'] = $r[0]; - - if(intval($arr['account_id'])) - set_default_login_identity($arr['account_id'],$ret['channel']['channel_id'],false); - - // Create a verified hub location pointing to this site. - - $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary, - hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network ) - values ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )", - dbesc($guid), - dbesc($sig), - dbesc($hash), - dbesc($ret['channel']['channel_address'] . '@' . App::get_hostname()), - intval($primary), - dbesc(z_root()), - dbesc(base64url_encode(rsa_sign(z_root(),$ret['channel']['channel_prvkey']))), - dbesc(App::get_hostname()), - dbesc(z_root() . '/post'), - dbesc(get_config('system','pubkey')), - dbesc('zot') - ); - if(! $r) - logger('create_identity: Unable to store hub location'); - - $newuid = $ret['channel']['channel_id']; - - $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_system ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", - dbesc($hash), - dbesc($guid), - dbesc($sig), - dbesc($key['pubkey']), - dbesc(z_root() . "/photo/profile/l/{$newuid}"), - dbesc(z_root() . "/photo/profile/m/{$newuid}"), - dbesc(z_root() . "/photo/profile/s/{$newuid}"), - dbesc($ret['channel']['channel_address'] . '@' . App::get_hostname()), - dbesc(z_root() . '/channel/' . $ret['channel']['channel_address']), - dbesc(z_root() . '/follow?f=&url=%s'), - dbesc(z_root() . '/poco/' . $ret['channel']['channel_address']), - dbesc($ret['channel']['channel_name']), - dbesc('zot'), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - intval($system) - ); - - // Not checking return value. - // It's ok for this to fail if it's an imported channel, and therefore the hash is a duplicate - - $r = q("INSERT INTO profile ( aid, uid, profile_guid, profile_name, is_default, publish, name, photo, thumb) - VALUES ( %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s') ", - intval($ret['channel']['channel_account_id']), - intval($newuid), - dbesc(random_string()), - t('Default Profile'), - 1, - $publish, - dbesc($ret['channel']['channel_name']), - dbesc(z_root() . "/photo/profile/l/{$newuid}"), - dbesc(z_root() . "/photo/profile/m/{$newuid}") - ); - - if($role_permissions) { - $myperms = ((array_key_exists('perms_accept',$role_permissions)) ? intval($role_permissions['perms_accept']) : 0); - } - else - $myperms = PERMS_R_STREAM|PERMS_R_PROFILE|PERMS_R_PHOTOS|PERMS_R_ABOOK - |PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT - |PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE; - - $r = q("insert into abook ( abook_account, abook_channel, abook_xchan, abook_closeness, abook_created, abook_updated, abook_self, abook_my_perms ) - values ( %d, %d, '%s', %d, '%s', '%s', %d, %d ) ", - intval($ret['channel']['channel_account_id']), - intval($newuid), - dbesc($hash), - intval(0), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - intval(1), - intval($myperms) - ); - - if(intval($ret['channel']['channel_account_id'])) { - - // Save our permissions role so we can perhaps call it up and modify it later. - - if($role_permissions) { - set_pconfig($newuid,'system','permissions_role',$arr['permissions_role']); - if(array_key_exists('online',$role_permissions)) - set_pconfig($newuid,'system','hide_presence',1-intval($role_permissions['online'])); - if(array_key_exists('perms_auto',$role_permissions)) - set_pconfig($newuid,'system','autoperms',(($role_permissions['perms_auto']) ? $role_permissions['perms_accept'] : 0)); - } - - // Create a group with yourself as a member. 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')); - group_add_member($newuid,t('Friends'),$ret['channel']['channel_hash']); - - // if our role_permissions indicate that we're using a default collection ACL, add it. - - if(is_array($role_permissions) && $role_permissions['default_collection']) { - $r = q("select hash from groups where uid = %d and name = '%s' limit 1", - intval($newuid), - dbesc( t('Friends') ) - ); - if($r) { - q("update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d", - dbesc($r[0]['hash']), - dbesc('<' . $r[0]['hash'] . '>'), - intval($newuid) - ); - } - } - - if(! $system) { - set_pconfig($ret['channel']['channel_id'],'system','photo_path', '%Y-%m'); - set_pconfig($ret['channel']['channel_id'],'system','attach_path','%Y-%m'); - } - - // UNO: channel defaults, incl addons (addons specific pconfig will only work after the relevant addon is enabled by the admin). It's located here, so members can modify these defaults after the channel is created. - if(UNO) { - //diaspora protocol addon - set_pconfig($ret['channel']['channel_id'],'system','diaspora_allowed', '1'); - set_pconfig($ret['channel']['channel_id'],'system','diaspora_public_comments', '1'); - set_pconfig($ret['channel']['channel_id'],'system','prevent_tag_hijacking', '0'); - } - - // auto-follow any of the hub's pre-configured channel choices. - // Only do this if it's the first channel for this account; - // otherwise it could get annoying. Don't make this list too big - // or it will impact registration time. - - $accts = get_config('system','auto_follow'); - if(($accts) && (! $total_identities)) { - require_once('include/follow.php'); - if(! is_array($accts)) - $accts = array($accts); - foreach($accts as $acct) { - if(trim($acct)) - new_contact($newuid,trim($acct),$ret['channel'],false); - } - } - - call_hooks('create_identity', $newuid); - - Zotlabs\Daemon\Master::Summon(array('Directory', $ret['channel']['channel_id'])); - } - - $ret['success'] = true; - return $ret; -} - -/** - * @brief Set default channel to be used on login. - * - * @param int $account_id - * login account - * @param int $channel_id - * channel id to set as default for this account - * @param boolean $force - * if true, set this default unconditionally - * if $force is false only do this if there is no existing default - */ -function set_default_login_identity($account_id, $channel_id, $force = true) { - $r = q("select account_default_channel from account where account_id = %d limit 1", - intval($account_id) - ); - if ($r) { - if ((intval($r[0]['account_default_channel']) == 0) || ($force)) { - $r = q("update account set account_default_channel = %d where account_id = %d", - intval($channel_id), - intval($account_id) - ); - } - } -} - -/** - * @brief Create an array representing the important channel information - * which would be necessary to create a nomadic identity clone. This includes - * most channel resources and connection information with the exception of content. - * - * @param int $channel_id - * Channel_id to export - * @param boolean $items - * Include channel posts (wall items), default false - * - * @returns array - * See function for details - */ -function identity_basic_export($channel_id, $items = false) { - - /* - * Red basic channel export - */ - - $ret = array(); - - // use constants here as otherwise we will have no idea if we can import from a site - // with a non-standard platform and version. - $ret['compatibility'] = array('project' => PLATFORM_NAME, 'version' => STD_VERSION, 'database' => DB_UPDATE_VERSION, 'server_role' => Zotlabs\Lib\System::get_server_role()); - - $r = q("select * from channel where channel_id = %d limit 1", - intval($channel_id) - ); - if($r) - $ret['channel'] = $r[0]; - - $r = q("select * from profile where uid = %d", - intval($channel_id) - ); - if($r) - $ret['profile'] = $r; - - $xchans = array(); - $r = q("select * from abook where abook_channel = %d ", - intval($channel_id) - ); - if($r) { - $ret['abook'] = $r; - - for($x = 0; $x < count($ret['abook']); $x ++) { - $xchans[] = $ret['abook'][$x]['abook_chan']; - $abconfig = load_abconfig($ret['channel']['channel_hash'],$ret['abook'][$x]['abook_xchan']); - if($abconfig) - $ret['abook'][$x]['abconfig'] = $abconfig; - } - stringify_array_elms($xchans); - } - - if($xchans) { - $r = q("select * from xchan where xchan_hash in ( " . implode(',',$xchans) . " ) "); - if($r) - $ret['xchan'] = $r; - - $r = q("select * from hubloc where hubloc_hash in ( " . implode(',',$xchans) . " ) "); - if($r) - $ret['hubloc'] = $r; - } - - $r = q("select * from `groups` where uid = %d ", - intval($channel_id) - ); - - if($r) - $ret['group'] = $r; - - $r = q("select * from group_member where uid = %d ", - intval($channel_id) - ); - if($r) - $ret['group_member'] = $r; - - $r = q("select * from pconfig where uid = %d", - intval($channel_id) - ); - if($r) - $ret['config'] = $r; - - $r = q("select type, data, os_storage from photo where scale = 4 and photo_usage = %d and uid = %d limit 1", - intval(PHOTO_PROFILE), - intval($channel_id) - ); - - if($r) { - $ret['photo'] = array('type' => $r[0]['type'], 'data' => (($r[0]['os_storage']) ? base64url_encode(file_get_contents($r[0]['data'])) : base64url_encode($r[0]['data']))); - } - - // All other term types will be included in items, if requested. - - $r = q("select * from term where type in (%d,%d) and uid = %d", - intval(TERM_SAVEDSEARCH), - intval(TERM_THING), - intval($channel_id) - ); - if($r) - $ret['term'] = $r; - - - // add psuedo-column obj_baseurl to aid in relocations - - $r = q("select obj.*, '%s' as obj_baseurl from obj where obj_channel = %d", - dbesc(z_root()), - intval($channel_id) - ); - - if($r) - $ret['obj'] = $r; - - $r = q("select * from app where app_channel = %d and app_system = 0", - intval($channel_id) - ); - if($r) { - for($x = 0; $x < count($r); $x ++) { - $r[$x]['term'] = q("select * from term where otype = %d and oid = %d", - intval(TERM_OBJ_APP), - intval($r[$x]['id']) - ); - } - $ret['app'] = $r; - } - - $r = q("select * from chatroom where cr_uid = %d", - intval($channel_id) - ); - if($r) - $ret['chatroom'] = $r; - - - $r = q("select * from event where uid = %d", - intval($channel_id) - ); - if($r) - $ret['event'] = $r; - - $r = q("select * from item where resource_type = 'event' and uid = %d", - intval($channel_id) - ); - if($r) { - $ret['event_item'] = array(); - xchan_query($r); - $r = fetch_post_tags($r,true); - foreach($r as $rr) - $ret['event_item'][] = encode_item($rr,true); - } - - $x = menu_list($channel_id); - if($x) { - $ret['menu'] = array(); - for($y = 0; $y < count($x); $y ++) { - $m = menu_fetch($x[$y]['menu_name'],$channel_id,$ret['channel']['channel_hash']); - if($m) - $ret['menu'][] = menu_element($m); - } - } - - $x = menu_list($channel_id); - if($x) { - $ret['menu'] = array(); - for($y = 0; $y < count($x); $y ++) { - $m = menu_fetch($x[$y]['menu_name'],$channel_id,$ret['channel']['channel_hash']); - if($m) - $ret['menu'][] = menu_element($m); - } - } - - $addon = array('channel_id' => $channel_id,'data' => $ret); - call_hooks('identity_basic_export',$addon); - $ret = $addon['data']; - - - if(! $items) - return $ret; - - $r = q("select * from likes where channel_id = %d", - intval($channel_id) - ); - - if($r) - $ret['likes'] = $r; - - - $r = q("select * from conv where uid = %d", - intval($channel_id) - ); - if($r) { - for($x = 0; $x < count($r); $x ++) { - $r[$x]['subject'] = base64url_decode(str_rot47($r[$x]['subject'])); - } - $ret['conv'] = $r; - } - - - $r = q("select * from mail where mail.uid = %d", - intval($channel_id) - ); - if($r) { - $m = array(); - foreach($r as $rr) { - xchan_mail_query($rr); - $m[] = mail_encode($rr,true); - } - $ret['mail'] = $m; - } - - $r = q("select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item_id.uid = %d", - intval($channel_id) - ); - - if($r) - $ret['item_id'] = $r; - - //$key = get_config('system','prvkey'); - - /** @warning this may run into memory limits on smaller systems */ - - - /** export three months of posts. If you want to export and import all posts you have to start with - * the first year and export/import them in ascending order. - * - * Don't export linked resource items. we'll have to pull those out separately. - */ - - $r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created > %s - INTERVAL %s and resource_type = '' order by created", - intval($channel_id), - db_utcnow(), - db_quoteinterval('3 MONTH') - ); - if($r) { - $ret['item'] = array(); - xchan_query($r); - $r = fetch_post_tags($r,true); - foreach($r as $rr) - $ret['item'][] = encode_item($rr,true); - } - - return $ret; -} - - -function identity_export_year($channel_id,$year,$month = 0) { - - if(! $year) - return array(); - - if($month && $month <= 12) { - $target_month = sprintf('%02d',$month); - $target_month_plus = sprintf('%02d',$month+1); - } - else - $target_month = '01'; - - $ret = array(); - - $mindate = datetime_convert('UTC','UTC',$year . '-' . $target_month . '-01 00:00:00'); - if($month && $month < 12) - $maxdate = datetime_convert('UTC','UTC',$year . '-' . $target_month_plus . '-01 00:00:00'); - else - $maxdate = datetime_convert('UTC','UTC',$year+1 . '-01-01 00:00:00'); - - $r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created < '%s' and resource_type = '' order by created", - intval(ITEM_TYPE_POST), - intval($channel_id), - dbesc($mindate), - dbesc($maxdate) - ); - - if($r) { - $ret['item'] = array(); - xchan_query($r); - $r = fetch_post_tags($r,true); - foreach($r as $rr) - $ret['item'][] = encode_item($rr,true); - } - - $r = q("select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item_id.uid = %d - and item.created >= '%s' and item.created < '%s' order by created ", - intval($channel_id), - dbesc($mindate), - dbesc($maxdate) - ); - - if($r) - $ret['item_id'] = $r; - - - return $ret; -} - - -/** - * @brief Loads a profile into the App structure. - * - * The function requires a writeable copy of the main App structure, and the - * nickname of a valid channel. - * - * Permissions of the current observer are checked. If a restricted profile is available - * to the current observer, that will be loaded instead of the channel default profile. - * - * The channel owner can set $profile to a valid profile_guid to preview that profile. - * - * The channel default theme is also selected for use, unless over-riden elsewhere. - * - * @param[in,out] App &$a - * @param string $nickname - * @param string $profile - */ -function profile_load(&$a, $nickname, $profile = '') { - -// logger('profile_load: ' . $nickname . (($profile) ? ' profile: ' . $profile : '')); - - $user = q("select channel_id from channel where channel_address = '%s' and channel_removed = 0 limit 1", - dbesc($nickname) - ); - - if(! $user) { - logger('profile error: ' . App::$query_string, LOGGER_DEBUG); - notice( t('Requested channel is not available.') . EOL ); - App::$error = 404; - return; - } - - // get the current observer - $observer = App::get_observer(); - - $can_view_profile = true; - - // Can the observer see our profile? - require_once('include/permissions.php'); - if(! perm_is_allowed($user[0]['channel_id'],$observer['xchan_hash'],'view_profile')) { - $can_view_profile = false; - } - - if(! $profile) { - $r = q("SELECT abook_profile FROM abook WHERE abook_xchan = '%s' and abook_channel = '%d' limit 1", - dbesc($observer['xchan_hash']), - intval($user[0]['channel_id']) - ); - if($r) - $profile = $r[0]['abook_profile']; - } - $p = null; - - if($profile) { - $p = q("SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile - LEFT JOIN channel ON profile.uid = channel.channel_id - WHERE channel.channel_address = '%s' AND profile.profile_guid = '%s' LIMIT 1", - dbesc($nickname), - dbesc($profile) - ); - } - - if(! $p) { - $p = q("SELECT profile.uid AS profile_uid, profile.*, channel.* FROM profile - LEFT JOIN channel ON profile.uid = channel.channel_id - WHERE channel.channel_address = '%s' and channel_removed = 0 - AND profile.is_default = 1 LIMIT 1", - dbesc($nickname) - ); - } - - if(! $p) { - logger('profile error: ' . App::$query_string, LOGGER_DEBUG); - notice( t('Requested profile is not available.') . EOL ); - App::$error = 404; - return; - } - - $q = q("select * from profext where hash = '%s' and channel_id = %d", - dbesc($p[0]['profile_guid']), - intval($p[0]['profile_uid']) - ); - if($q) { - - $extra_fields = array(); - - require_once('include/identity.php'); - $profile_fields_basic = get_profile_fields_basic(); - $profile_fields_advanced = get_profile_fields_advanced(); - - $advanced = ((feature_enabled(local_channel(),'advanced_profiles')) ? true : false); - if($advanced) - $fields = $profile_fields_advanced; - else - $fields = $profile_fields_basic; - - foreach($q as $qq) { - foreach($fields as $k => $f) { - if($k == $qq['k']) { - $p[0][$k] = $qq['v']; - $extra_fields[] = $k; - break; - } - } - } - } - - $p[0]['extra_fields'] = $extra_fields; - - $z = q("select xchan_photo_date, xchan_addr from xchan where xchan_hash = '%s' limit 1", - dbesc($p[0]['channel_hash']) - ); - if($z) { - $p[0]['picdate'] = $z[0]['xchan_photo_date']; - $p[0]['reddress'] = str_replace('@','@',$z[0]['xchan_addr']); - } - - // fetch user tags if this isn't the default profile - - if(! $p[0]['is_default']) { - $x = q("select `keywords` from `profile` where uid = %d and `is_default` = 1 limit 1", - intval($p[0]['profile_uid']) - ); - if($x && $can_view_profile) - $p[0]['keywords'] = $x[0]['keywords']; - } - - if($p[0]['keywords']) { - $keywords = str_replace(array('#',',',' ',',,'),array('',' ',',',','),$p[0]['keywords']); - if(strlen($keywords) && $can_view_profile) - App::$page['htmlhead'] .= '' . "\r\n" ; - } - - App::$profile = $p[0]; - App::$profile_uid = $p[0]['profile_uid']; - App::$page['title'] = App::$profile['channel_name'] . " - " . App::$profile['channel_address'] . "@" . App::get_hostname(); - - App::$profile['permission_to_view'] = $can_view_profile; - - if($can_view_profile) { - $online = get_online_status($nickname); - App::$profile['online_status'] = $online['result']; - } - - if(local_channel()) { - App::$profile['channel_mobile_theme'] = get_pconfig(local_channel(),'system', 'mobile_theme'); - $_SESSION['mobile_theme'] = App::$profile['channel_mobile_theme']; - } - - /* - * load/reload current theme info - */ - - $_SESSION['theme'] = $p[0]['channel_theme']; - -} - -function profile_edit_menu($uid) { - - $ret = array(); - - $is_owner = (($uid == local_channel()) ? true : false); - - // show edit profile to profile owner - if($is_owner) { - $ret['menu'] = array( - 'chg_photo' => t('Change profile photo'), - 'entries' => array(), - ); - - $multi_profiles = feature_enabled(local_channel(), 'multi_profiles'); - if($multi_profiles) { - $ret['multi'] = 1; - $ret['edit'] = array(z_root(). '/profiles', t('Edit Profiles'), '', t('Edit')); - $ret['menu']['cr_new'] = t('Create New Profile'); - } - else { - $ret['edit'] = array(z_root() . '/profiles/' . $uid, t('Edit Profile'), '', t('Edit')); - } - - $r = q("SELECT * FROM profile WHERE uid = %d", - local_channel() - ); - - if($r) { - foreach($r as $rr) { - if(!($multi_profiles || $rr['is_default'])) - continue; - $ret['menu']['entries'][] = array( - 'photo' => $rr['thumb'], - 'id' => $rr['id'], - 'alt' => t('Profile Image'), - 'profile_name' => $rr['profile_name'], - 'isdefault' => $rr['is_default'], - 'visible_to_everybody' => t('Visible to everybody'), - 'edit_visibility' => t('Edit visibility'), - ); - } - } - } - - return $ret; - -} - -/** - * @brief Formats a profile for display in the sidebar. - * - * It is very difficult to templatise the HTML completely - * because of all the conditional logic. - * - * @param array $profile - * @param int $block - * @param boolean $show_connect - * - * @return HTML string suitable for sidebar inclusion - * Exceptions: Returns empty string if passed $profile is wrong type or not populated - */ -function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = false) { - - $observer = App::get_observer(); - - $o = ''; - $location = false; - $pdesc = true; - $reddress = true; - - if(! perm_is_allowed($profile['uid'],((is_array($observer)) ? $observer['xchan_hash'] : ''),'view_profile')) { - $block = true; - } - - if((! is_array($profile)) && (! count($profile))) - return $o; - - head_set_icon($profile['thumb']); - - if(is_sys_channel($profile['uid'])) - $show_connect = false; - - $profile['picdate'] = urlencode($profile['picdate']); - - call_hooks('profile_sidebar_enter', $profile); - - require_once('include/Contact.php'); - - if($show_connect) { - - // This will return an empty string if we're already connected. - - $connect_url = rconnect_url($profile['uid'],get_observer_hash()); - $connect = (($connect_url) ? t('Connect') : ''); - if($connect_url) - $connect_url = sprintf($connect_url,urlencode($profile['channel_address'] . '@' . App::get_hostname())); - - // premium channel - over-ride - - if($profile['channel_pageflags'] & PAGE_PREMIUM) - $connect_url = z_root() . '/connect/' . $profile['channel_address']; - } - - if((x($profile,'address') == 1) - || (x($profile,'locality') == 1) - || (x($profile,'region') == 1) - || (x($profile,'postal_code') == 1) - || (x($profile,'country_name') == 1)) - $location = t('Location:'); - - $profile['homepage'] = linkify($profile['homepage'],true); - - $gender = ((x($profile,'gender') == 1) ? t('Gender:') : False); - $marital = ((x($profile,'marital') == 1) ? t('Status:') : False); - $homepage = ((x($profile,'homepage') == 1) ? t('Homepage:') : False); - $profile['online'] = (($profile['online_status'] === 'online') ? t('Online Now') : False); - -// logger('online: ' . $profile['online']); - - - if(($profile['hidewall'] && (! local_channel()) && (! remote_channel())) || $block ) { - $location = $reddress = $pdesc = $gender = $marital = $homepage = False; - } - - $firstname = ((strpos($profile['channel_name'],' ')) - ? trim(substr($profile['channel_name'],0,strpos($profile['channel_name'],' '))) : $profile['channel_name']); - $lastname = (($firstname === $profile['channel_name']) ? '' : trim(substr($profile['channel_name'],strlen($firstname)))); - - $diaspora = array( - 'podloc' => z_root(), - 'searchable' => (($block) ? 'false' : 'true'), - 'nickname' => $profile['channel_address'], - 'fullname' => $profile['channel_name'], - 'firstname' => $firstname, - 'lastname' => $lastname, - 'photo300' => z_root() . '/photo/profile/300/' . $profile['uid'] . '.jpg', - 'photo100' => z_root() . '/photo/profile/100/' . $profile['uid'] . '.jpg', - 'photo50' => z_root() . '/photo/profile/50/' . $profile['uid'] . '.jpg', - ); - - $contact_block = contact_block(); - - $channel_menu = false; - $menu = get_pconfig($profile['uid'],'system','channel_menu'); - if($menu && ! $block) { - require_once('include/menu.php'); - $m = menu_fetch($menu,$profile['uid'],$observer['xchan_hash']); - if($m) - $channel_menu = menu_render($m); - } - $menublock = get_pconfig($profile['uid'],'system','channel_menublock'); - if ($menublock && (! $block)) { - $comanche = new Zotlabs\Render\Comanche(); - $channel_menu .= $comanche->block($menublock); - } - - if($zcard) - $tpl = get_markup_template('profile_vcard_short.tpl'); - else - $tpl = get_markup_template('profile_vcard.tpl'); - - require_once('include/widgets.php'); - - if(! feature_enabled($profile['uid'],'hide_rating')) - $z = widget_rating(array('target' => $profile['channel_hash'])); - - $o .= replace_macros($tpl, array( - '$zcard' => $zcard, - '$profile' => $profile, - '$connect' => $connect, - '$connect_url' => $connect_url, - '$location' => $location, - '$gender' => $gender, - '$pdesc' => $pdesc, - '$marital' => $marital, - '$homepage' => $homepage, - '$chanmenu' => $channel_menu, - '$diaspora' => $diaspora, - '$reddress' => $reddress, - '$rating' => $z, - '$contact_block' => $contact_block, - '$editmenu' => profile_edit_menu($profile['uid']) - )); - - $arr = array('profile' => &$profile, 'entry' => &$o); - - call_hooks('profile_sidebar', $arr); - - return $o; -} - - -/** - * @FIXME or remove - */ - function get_birthdays() { - - $o = ''; - - if(! local_channel()) - return $o; - - $bd_format = t('g A l F d') ; // 8 AM Friday January 18 - $bd_short = t('F d'); - - $r = q("SELECT `event`.*, `event`.`id` AS `eid`, `contact`.* FROM `event` - LEFT JOIN `contact` ON `contact`.`id` = `event`.`cid` - WHERE `event`.`uid` = %d AND `type` = 'birthday' AND `start` < '%s' AND `finish` > '%s' - ORDER BY `start` ASC ", - intval(local_channel()), - dbesc(datetime_convert('UTC','UTC','now + 6 days')), - dbesc(datetime_convert('UTC','UTC','now')) - ); - - if($r && count($r)) { - $total = 0; - $now = strtotime('now'); - $cids = array(); - - $istoday = false; - foreach($r as $rr) { - if(strlen($rr['name'])) - $total ++; - if((strtotime($rr['start'] . ' +00:00') < $now) && (strtotime($rr['finish'] . ' +00:00') > $now)) - $istoday = true; - } - $classtoday = $istoday ? ' birthday-today ' : ''; - if($total) { - foreach($r as &$rr) { - if(! strlen($rr['name'])) - continue; - - // avoid duplicates - - if(in_array($rr['cid'],$cids)) - continue; - $cids[] = $rr['cid']; - - $today = (((strtotime($rr['start'] . ' +00:00') < $now) && (strtotime($rr['finish'] . ' +00:00') > $now)) ? true : false); - $sparkle = ''; - $url = $rr['url']; - if($rr['network'] === NETWORK_DFRN) { - $sparkle = " sparkle"; - $url = z_root() . '/redir/' . $rr['cid']; - } - - $rr['link'] = $url; - $rr['title'] = $rr['name']; - $rr['date'] = day_translate(datetime_convert('UTC', App::$timezone, $rr['start'], $rr['adjust'] ? $bd_format : $bd_short)) . (($today) ? ' ' . t('[today]') : ''); - $rr['startime'] = Null; - $rr['today'] = $today; - } - } - } - $tpl = get_markup_template("birthdays_reminder.tpl"); - return replace_macros($tpl, array( - '$baseurl' => z_root(), - '$classtoday' => $classtoday, - '$count' => $total, - '$event_reminders' => t('Birthday Reminders'), - '$event_title' => t('Birthdays this week:'), - '$events' => $r, - '$lbr' => '{', // raw brackets mess up if/endif macro processing - '$rbr' => '}' - )); - } - - -/** - * @FIXME - */ - function get_events() { - - require_once('include/bbcode.php'); - - if(! local_channel()) - return $o; - - $bd_format = t('g A l F d') ; // 8 AM Friday January 18 - $bd_short = t('F d'); - - $r = q("SELECT `event`.* FROM `event` - WHERE `event`.`uid` = %d AND `type` != 'birthday' AND `start` < '%s' AND `start` > '%s' - ORDER BY `start` ASC ", - intval(local_channel()), - dbesc(datetime_convert('UTC','UTC','now + 6 days')), - dbesc(datetime_convert('UTC','UTC','now - 1 days')) - ); - - if($r && count($r)) { - $now = strtotime('now'); - $istoday = false; - foreach($r as $rr) { - if(strlen($rr['name'])) - $total ++; - - $strt = datetime_convert('UTC',$rr['convert'] ? App::$timezone : 'UTC',$rr['start'],'Y-m-d'); - if($strt === datetime_convert('UTC',App::$timezone,'now','Y-m-d')) - $istoday = true; - } - $classtoday = (($istoday) ? 'event-today' : ''); - - foreach($r as &$rr) { - if($rr['adjust']) - $md = datetime_convert('UTC',App::$timezone,$rr['start'],'Y/m'); - else - $md = datetime_convert('UTC','UTC',$rr['start'],'Y/m'); - $md .= "/#link-".$rr['id']; - - $title = substr(strip_tags(bbcode($rr['desc'])),0,32) . '... '; - if(! $title) - $title = t('[No description]'); - - $strt = datetime_convert('UTC',$rr['convert'] ? App::$timezone : 'UTC',$rr['start']); - $today = ((substr($strt,0,10) === datetime_convert('UTC',App::$timezone,'now','Y-m-d')) ? true : false); - - $rr['link'] = $md; - $rr['title'] = $title; - $rr['date'] = day_translate(datetime_convert('UTC', $rr['adjust'] ? App::$timezone : 'UTC', $rr['start'], $bd_format)) . (($today) ? ' ' . t('[today]') : ''); - $rr['startime'] = $strt; - $rr['today'] = $today; - } - } - - $tpl = get_markup_template("events_reminder.tpl"); - return replace_macros($tpl, array( - '$baseurl' => z_root(), - '$classtoday' => $classtoday, - '$count' => count($r), - '$event_reminders' => t('Event Reminders'), - '$event_title' => t('Events this week:'), - '$events' => $r, - )); - } - - -function advanced_profile(&$a) { - require_once('include/text.php'); - if(! perm_is_allowed(App::$profile['profile_uid'],get_observer_hash(),'view_profile')) - return ''; - - if(App::$profile['name']) { - - $profile_fields_basic = get_profile_fields_basic(); - $profile_fields_advanced = get_profile_fields_advanced(); - - $advanced = ((feature_enabled(App::$profile['profile_uid'],'advanced_profiles')) ? true : false); - if($advanced) - $fields = $profile_fields_advanced; - else - $fields = $profile_fields_basic; - - $clean_fields = array(); - if($fields) { - foreach($fields as $k => $v) { - $clean_fields[] = trim($k); - } - } - - - - $tpl = get_markup_template('profile_advanced.tpl'); - - $profile = array(); - - $profile['fullname'] = array( t('Full Name:'), App::$profile['name'] ) ; - - if(App::$profile['gender']) $profile['gender'] = array( t('Gender:'), App::$profile['gender'] ); - - $ob_hash = get_observer_hash(); - if($ob_hash && perm_is_allowed(App::$profile['profile_uid'],$ob_hash,'post_like')) { - $profile['canlike'] = true; - $profile['likethis'] = t('Like this channel'); - $profile['profile_guid'] = App::$profile['profile_guid']; - } - - $likers = q("select liker, xchan.* from likes left join xchan on liker = xchan_hash where channel_id = %d and target_type = '%s' and verb = '%s'", - intval(App::$profile['profile_uid']), - dbesc(ACTIVITY_OBJ_PROFILE), - dbesc(ACTIVITY_LIKE) - ); - $profile['likers'] = array(); - $profile['like_count'] = count($likers); - $profile['like_button_label'] = tt('Like','Likes',$profile['like_count'],'noun'); - if($likers) { - foreach($likers as $l) - $profile['likers'][] = array('name' => $l['xchan_name'],'photo' => zid($l['xchan_photo_s']), 'url' => zid($l['xchan_url'])); - } - - if((App::$profile['dob']) && (App::$profile['dob'] != '0000-00-00')) { - - $val = ''; - - if((substr(App::$profile['dob'],5,2) === '00') || (substr(App::$profile['dob'],8,2) === '00')) - $val = substr(App::$profile['dob'],0,4); - - $year_bd_format = t('j F, Y'); - $short_bd_format = t('j F'); - - if(! $val) { - $val = ((intval(App::$profile['dob'])) - ? day_translate(datetime_convert('UTC','UTC',App::$profile['dob'] . ' 00:00 +00:00',$year_bd_format)) - : day_translate(datetime_convert('UTC','UTC','2001-' . substr(App::$profile['dob'],5) . ' 00:00 +00:00',$short_bd_format))); - } - $profile['birthday'] = array( t('Birthday:'), $val); - } - - if($age = age(App::$profile['dob'],App::$profile['timezone'],'')) - $profile['age'] = array( t('Age:'), $age ); - - if(App::$profile['marital']) - $profile['marital'] = array( t('Status:'), App::$profile['marital']); - - if(App::$profile['with']) - $profile['marital']['with'] = bbcode(App::$profile['with']); - - if(strlen(App::$profile['howlong']) && App::$profile['howlong'] !== NULL_DATE) { - $profile['howlong'] = relative_date(App::$profile['howlong'], t('for %1$d %2$s')); - } - - if(App::$profile['sexual']) $profile['sexual'] = array( t('Sexual Preference:'), App::$profile['sexual'] ); - - if(App::$profile['homepage']) $profile['homepage'] = array( t('Homepage:'), linkify(App::$profile['homepage']) ); - - if(App::$profile['hometown']) $profile['hometown'] = array( t('Hometown:'), linkify(App::$profile['hometown']) ); - - if(App::$profile['keywords']) $profile['keywords'] = array( t('Tags:'), App::$profile['keywords']); - - if(App::$profile['politic']) $profile['politic'] = array( t('Political Views:'), App::$profile['politic']); - - if(App::$profile['religion']) $profile['religion'] = array( t('Religion:'), App::$profile['religion']); - - if($txt = prepare_text(App::$profile['about'])) $profile['about'] = array( t('About:'), $txt ); - - if($txt = prepare_text(App::$profile['interest'])) $profile['interest'] = array( t('Hobbies/Interests:'), $txt); - - if($txt = prepare_text(App::$profile['likes'])) $profile['likes'] = array( t('Likes:'), $txt); - - if($txt = prepare_text(App::$profile['dislikes'])) $profile['dislikes'] = array( t('Dislikes:'), $txt); - - if($txt = prepare_text(App::$profile['contact'])) $profile['contact'] = array( t('Contact information and Social Networks:'), $txt); - - if($txt = prepare_text(App::$profile['channels'])) $profile['channels'] = array( t('My other channels:'), $txt); - - if($txt = prepare_text(App::$profile['music'])) $profile['music'] = array( t('Musical interests:'), $txt); - - if($txt = prepare_text(App::$profile['book'])) $profile['book'] = array( t('Books, literature:'), $txt); - - if($txt = prepare_text(App::$profile['tv'])) $profile['tv'] = array( t('Television:'), $txt); - - if($txt = prepare_text(App::$profile['film'])) $profile['film'] = array( t('Film/dance/culture/entertainment:'), $txt); - - if($txt = prepare_text(App::$profile['romance'])) $profile['romance'] = array( t('Love/Romance:'), $txt); - - if($txt = prepare_text(App::$profile['work'])) $profile['work'] = array( t('Work/employment:'), $txt); - - if($txt = prepare_text(App::$profile['education'])) $profile['education'] = array( t('School/education:'), $txt ); - - if(App::$profile['extra_fields']) { - foreach(App::$profile['extra_fields'] as $f) { - $x = q("select * from profdef where field_name = '%s' limit 1", - dbesc($f) - ); - if($x && $txt = prepare_text(App::$profile[$f])) - $profile[$f] = array( $x[0]['field_desc'] . ':',$txt); - } - $profile['extra_fields'] = App::$profile['extra_fields']; - } - - $things = get_things(App::$profile['profile_guid'],App::$profile['profile_uid']); - -// logger('mod_profile: things: ' . print_r($things,true), LOGGER_DATA); - - return replace_macros($tpl, array( - '$title' => t('Profile'), - '$canlike' => (($profile['canlike'])? true : false), - '$likethis' => t('Like this thing'), - '$profile' => $profile, - '$fields' => $clean_fields, - '$editmenu' => profile_edit_menu(App::$profile['profile_uid']), - '$things' => $things - )); - } - - return ''; -} - - -function get_my_url() { - if(x($_SESSION, 'zrl_override')) - return $_SESSION['zrl_override']; - if(x($_SESSION, 'my_url')) - return $_SESSION['my_url']; - - return false; -} - -function get_my_address() { - if(x($_SESSION, 'zid_override')) - return $_SESSION['zid_override']; - if(x($_SESSION, 'my_address')) - return $_SESSION['my_address']; - - return false; -} - -/** - * @brief - * - * If somebody arrives at our site using a zid, add their xchan to our DB if we don't have it already. - * And if they aren't already authenticated here, attempt reverse magic auth. - * - * @param App &$a - * - * @hooks 'zid_init' - * string 'zid' - their zid - * string 'url' - the destination url - */ -function zid_init(&$a) { - $tmp_str = get_my_address(); - if(validate_email($tmp_str)) { - Zotlabs\Daemon\Master::Summon(array('Gprobe',bin2hex($tmp_str))); - $arr = array('zid' => $tmp_str, 'url' => App::$cmd); - call_hooks('zid_init',$arr); - if(! local_channel()) { - $r = q("select * from hubloc where hubloc_addr = '%s' order by hubloc_connected desc limit 1", - dbesc($tmp_str) - ); - if($r && remote_channel() && remote_channel() === $r[0]['hubloc_hash']) - return; - logger('zid_init: not authenticated. Invoking reverse magic-auth for ' . $tmp_str); - // try to avoid recursion - but send them home to do a proper magic auth - $query = App::$query_string; - $query = str_replace(array('?zid=','&zid='),array('?rzid=','&rzid='),$query); - $dest = '/' . urlencode($query); - if($r && ($r[0]['hubloc_url'] != z_root()) && (! strstr($dest,'/magic')) && (! strstr($dest,'/rmagic'))) { - goaway($r[0]['hubloc_url'] . '/magic' . '?f=&rev=1&dest=' . z_root() . $dest); - } - else - logger('zid_init: no hubloc found.'); - } - } -} - -/** - * @brief Adds a zid parameter to a url. - * - * @param string $s - * The url to accept the zid - * @param boolean $address - * $address to use instead of session environment - * @return string - * - * @hooks 'zid' - * string url - url to accept zid - * string zid - urlencoded zid - * string result - the return string we calculated, change it if you want to return something else - */ -function zid($s,$address = '') { - if (! strlen($s) || strpos($s,'zid=')) - return $s; - - $has_params = ((strpos($s,'?')) ? true : false); - $num_slashes = substr_count($s, '/'); - if (! $has_params) - $has_params = ((strpos($s, '&')) ? true : false); - - $achar = strpos($s,'?') ? '&' : '?'; - - $mine = get_my_url(); - $myaddr = (($address) ? $address : get_my_address()); - - /** @FIXME checking against our own channel url is no longer reliable. We may have a lot - * of urls attached to out channel. Should probably match against our site, since we - * will not need to remote authenticate on our own site anyway. - */ - - if ($mine && $myaddr && (! link_compare($mine,$s))) - $zurl = $s . (($num_slashes >= 3) ? '' : '/') . $achar . 'zid=' . urlencode($myaddr); - else - $zurl = $s; - - $arr = array('url' => $s, 'zid' => urlencode($myaddr), 'result' => $zurl); - call_hooks('zid', $arr); - - return $arr['result']; -} - -// Used from within PCSS themes to set theme parameters. If there's a -// puid request variable, that is the "page owner" and normally their theme -// settings take precedence; unless a local user sets the "always_my_theme" -// system pconfig, which means they don't want to see anybody else's theme -// settings except their own while on this site. - -function get_theme_uid() { - $uid = (($_REQUEST['puid']) ? intval($_REQUEST['puid']) : 0); - if(local_channel()) { - if((get_pconfig(local_channel(),'system','always_my_theme')) || (! $uid)) - return local_channel(); - } - if(! $uid) { - $x = get_sys_channel(); - if($x) - return $x['channel_id']; - } - - return $uid; -} - -/** -* @brief Retrieves the path of the default_profile_photo for this system -* with the specified size. -* -* @param int $size -* one of (300, 80, 48) -* @returns string -*/ -function get_default_profile_photo($size = 300) { - $scheme = get_config('system','default_profile_photo'); - if(! $scheme) - $scheme = 'rainbow_man'; - - return 'images/default_profile_photos/' . $scheme . '/' . $size . '.png'; -} - -/** - * @brief Test whether a given identity is NOT a member of the Hubzilla. - * - * @param string $s; - * xchan_hash of the identity in question - * @returns boolean true or false - */ -function is_foreigner($s) { - return((strpbrk($s, '.:@')) ? true : false); -} - -/** - * @brief Test whether a given identity is a member of the Hubzilla. - * - * @param string $s; - * xchan_hash of the identity in question - * @returns boolean true or false - */ -function is_member($s) { - return((is_foreigner($s)) ? false : true); -} - -function get_online_status($nick) { - - $ret = array('result' => false); - - if(get_config('system','block_public') && ! local_channel() && ! remote_channel()) - return $ret; - - $r = q("select channel_id, channel_hash from channel where channel_address = '%s' limit 1", - dbesc(argv(1)) - ); - if($r) { - $hide = get_pconfig($r[0]['channel_id'],'system','hide_online_status'); - if($hide) - return $ret; - $x = q("select cp_status from chatpresence where cp_xchan = '%s' and cp_room = 0 limit 1", - dbesc($r[0]['channel_hash']) - ); - if($x) - $ret['result'] = $x[0]['cp_status']; - } - - return $ret; -} - - -function remote_online_status($webbie) { - - $result = false; - $r = q("select * from hubloc where hubloc_addr = '%s' limit 1", - dbesc($webbie) - ); - if(! $r) - return $result; - - $url = $r[0]['hubloc_url'] . '/online/' . substr($webbie,0,strpos($webbie,'@')); - - $x = z_fetch_url($url); - if($x['success']) { - $j = json_decode($x['body'],true); - if($j) - $result = (($j['result']) ? $j['result'] : false); - } - - return $result; -} - - -function get_channel_by_nick($nick) { - $r = q("select * from channel where channel_address = '%s' limit 1", - dbesc($nick) - ); - return(($r) ? $r[0] : false); - -} - -/** - * @brief - * - * @return string - */ -function identity_selector() { - if (local_channel()) { - $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel.channel_account_id = %d and channel_removed = 0 order by channel_name ", - intval(get_account_id()) - ); - if (count($r) > 1) { - //$account = App::get_account(); - $o = replace_macros(get_markup_template('channel_id_select.tpl'), array( - '$channels' => $r, - '$selected' => local_channel() - )); - return $o; - } - } - - return ''; -} - - -function is_public_profile() { - if(! local_channel()) - return false; - if(intval(get_config('system','block_public'))) - return false; - $channel = App::get_channel(); - if($channel && $channel['channel_r_profile'] == PERMS_PUBLIC) - return true; - - return false; -} - -function get_profile_fields_basic($filter = 0) { - - $profile_fields_basic = (($filter == 0) ? get_config('system','profile_fields_basic') : null); - if(! $profile_fields_basic) - $profile_fields_basic = array('name','pdesc','chandesc','gender','dob','dob_tz','address','locality','region','postal_code','country_name','marital','sexual','homepage','hometown','keywords','about','contact'); - - $x = array(); - if($profile_fields_basic) - foreach($profile_fields_basic as $f) - $x[$f] = 1; - - return $x; -} - - -function get_profile_fields_advanced($filter = 0) { - $basic = get_profile_fields_basic($filter); - $profile_fields_advanced = (($filter == 0) ? get_config('system','profile_fields_advanced') : null); - if(! $profile_fields_advanced) - $profile_fields_advanced = array('with','howlong','politic','religion','likes','dislikes','interest','channels','music','book','film','tv','romance','work','education'); - - $x = array(); - if($basic) - foreach($basic as $f => $v) - $x[$f] = $v; - - if($profile_fields_advanced) - foreach($profile_fields_advanced as $f) - $x[$f] = 1; - - return $x; -} - -/** - * @brief Clear notifyflags for a channel. - * - * Most likely during bulk import of content or other activity that is likely - * to generate huge amounts of undesired notifications. - * - * @param int $channel_id - * The channel to disable notifications for - * @returns int - * Current notification flag value. Send this to notifications_on() to restore the channel settings when finished - * with the activity requiring notifications_off(); - */ -function notifications_off($channel_id) { - $r = q("select channel_notifyflags from channel where channel_id = %d limit 1", - intval($channel_id) - ); - q("update channel set channel_notifyflags = 0 where channel_id = %d", - intval($channel_id) - ); - - return intval($r[0]['channel_notifyflags']); -} - - -function notifications_on($channel_id,$value) { - $x = q("update channel set channel_notifyflags = %d where channel_id = %d", - intval($value), - intval($channel_id) - ); - return $x; -} - - -function get_channel_default_perms($uid) { - - $r = q("select abook_my_perms from abook where abook_channel = %d and abook_self = 1 limit 1", - intval($uid) - ); - if($r) - return $r[0]['abook_my_perms']; - - return 0; -} - - -function profiles_build_sync($channel_id) { - - $r = q("select * from profile where uid = %d", - intval($channel_id) - ); - if($r) { - build_sync_packet($channel_id,array('profile' => $r)); - } -} - - -function auto_channel_create($account_id) { - - if(! $account_id) - return false; - - $arr = array(); - $arr['account_id'] = $account_id; - $arr['name'] = get_aconfig($account_id,'register','channel_name'); - $arr['nickname'] = legal_webbie(get_aconfig($account_id,'register','channel_address')); - $arr['permissions_role'] = get_aconfig($account_id,'register','permissions_role'); - - del_aconfig($account_id,'register','channel_name'); - del_aconfig($account_id,'register','channel_address'); - del_aconfig($account_id,'register','permissions_role'); - - if((! $arr['name']) || (! $arr['nickname'])) { - $x = q("select * from account where account_id = %d limit 1", - intval($account_id) - ); - if($x) { - if(! $arr['name']) - $arr['name'] = substr($x[0]['account_email'],0,strpos($x[0]['account_email'],'@')); - if(! $arr['nickname']) - $arr['nickname'] = legal_webbie(substr($x[0]['account_email'],0,strpos($x[0]['account_email'],'@'))); - } - } - if(! $arr['permissions_role']) - $arr['permissions_role'] = 'social'; - - if(validate_channelname($arr['name'])) - return false; - if($arr['nickname'] === 'sys') - $arr['nickname'] = $arr['nickname'] . mt_rand(1000,9999); - - $arr['nickname'] = check_webbie(array($arr['nickname'], $arr['nickname'] . mt_rand(1000,9999))); - - return create_identity($arr); - -} - -function get_cover_photo($channel_id,$format = 'bbcode', $res = PHOTO_RES_COVER_1200) { - - $r = q("select height, width, resource_id, type from photo where uid = %d and scale = %d and photo_usage = %d", - intval($channel_id), - intval($res), - intval(PHOTO_COVER) - ); - if(! $r) - return false; - - $output = false; - - $url = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $res ; - - switch($format) { - case 'bbcode': - $output = '[zrl=' . $r[0]['width'] . 'x' . $r[0]['height'] . ']' . $url . '[/zrl]'; - break; - case 'html': - $output = '' . t('cover photo') . ''; - break; - case 'array': - default: - $output = array( - 'width' => $r[0]['width'], - 'height' => $r[0]['type'], - 'type' => $r[0]['type'], - 'url' => $url - ); - break; - } - - return $output; - -} - -function get_zcard($channel,$observer_hash = '',$args = array()) { - - logger('get_zcard'); - - $maxwidth = (($args['width']) ? intval($args['width']) : 0); - $maxheight = (($args['height']) ? intval($args['height']) : 0); - - - if(($maxwidth > 1200) || ($maxwidth < 1)) - $maxwidth = 1200; - - if($maxwidth <= 425) { - $width = 425; - $size = 'hz_small'; - $cover_size = PHOTO_RES_COVER_425; - $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']); - } - elseif($maxwidth <= 900) { - $width = 900; - $size = 'hz_medium'; - $cover_size = PHOTO_RES_COVER_850; - $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']); - } - elseif($maxwidth <= 1200) { - $width = 1200; - $size = 'hz_large'; - $cover_size = PHOTO_RES_COVER_1200; - $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']); - } - -// $scale = (float) $maxwidth / $width; -// $translate = intval(($scale / 1.0) * 100); - - - $channel['channel_addr'] = $channel['channel_address'] . '@' . App::get_hostname(); - $zcard = array('chan' => $channel); - - $r = q("select height, width, resource_id, scale, type from photo where uid = %d and scale = %d and photo_usage = %d", - intval($channel['channel_id']), - intval($cover_size), - intval(PHOTO_COVER) - ); - - if($r) { - $cover = $r[0]; - $cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['scale']; - } - else { - $cover = $pphoto; - } - - $o .= replace_macros(get_markup_template('zcard.tpl'),array( - '$maxwidth' => $maxwidth, - '$scale' => $scale, - '$translate' => $translate, - '$size' => $size, - '$cover' => $cover, - '$pphoto' => $pphoto, - '$zcard' => $zcard - )); - - return $o; - -} - - -function get_zcard_embed($channel,$observer_hash = '',$args = array()) { - - logger('get_zcard_embed'); - - $maxwidth = (($args['width']) ? intval($args['width']) : 0); - $maxheight = (($args['height']) ? intval($args['height']) : 0); - - - if(($maxwidth > 1200) || ($maxwidth < 1)) - $maxwidth = 1200; - - if($maxwidth <= 425) { - $width = 425; - $size = 'hz_small'; - $cover_size = PHOTO_RES_COVER_425; - $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']); - } - elseif($maxwidth <= 900) { - $width = 900; - $size = 'hz_medium'; - $cover_size = PHOTO_RES_COVER_850; - $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']); - } - elseif($maxwidth <= 1200) { - $width = 1200; - $size = 'hz_large'; - $cover_size = PHOTO_RES_COVER_1200; - $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']); - } - - $channel['channel_addr'] = $channel['channel_address'] . '@' . App::get_hostname(); - $zcard = array('chan' => $channel); - - $r = q("select height, width, resource_id, scale, type from photo where uid = %d and scale = %d and photo_usage = %d", - intval($channel['channel_id']), - intval($cover_size), - intval(PHOTO_COVER) - ); - - if($r) { - $cover = $r[0]; - $cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['scale']; - } - else { - $cover = $pphoto; - } - - $o .= replace_macros(get_markup_template('zcard_embed.tpl'),array( - '$maxwidth' => $maxwidth, - '$scale' => $scale, - '$translate' => $translate, - '$size' => $size, - '$cover' => $cover, - '$pphoto' => $pphoto, - '$zcard' => $zcard - )); - - return $o; - -} diff --git a/include/items.php b/include/items.php index a25be72b3..de0941c3c 100755 --- a/include/items.php +++ b/include/items.php @@ -77,7 +77,7 @@ function collect_recipients($item, &$private_envelope) { // by the directives in $item['public_policy']. $private_envelope = false; - require_once('include/identity.php'); + require_once('include/channel.php'); //$sys = get_sys_channel(); if(array_key_exists('public_policy',$item) && $item['public_policy'] !== 'self') { diff --git a/include/text.php b/include/text.php index df6dac056..91aeae989 100644 --- a/include/text.php +++ b/include/text.php @@ -1319,7 +1319,7 @@ function theme_attachments(&$item) { $title = t('Size') . ' ' . (($r['length']) ? userReadableSize($r['length']) : t('unknown')); - require_once('include/identity.php'); + require_once('include/channel.php'); if(is_foreigner($item['author_xchan'])) $url = $r['href']; else @@ -1486,7 +1486,7 @@ function format_event($jobject) { } function prepare_body(&$item,$attach = false) { - require_once('include/identity.php'); + require_once('include/channel.php'); call_hooks('prepare_body_init', $item); @@ -2261,7 +2261,7 @@ function design_tools() { $sys = false; if(App::$is_sys && is_site_admin()) { - require_once('include/identity.php'); + require_once('include/channel.php'); $channel = get_sys_channel(); $sys = true; } diff --git a/include/widgets.php b/include/widgets.php index 2641a718e..a158633ad 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -8,7 +8,7 @@ require_once('include/dir_fns.php'); require_once('include/contact_widgets.php'); require_once('include/attach.php'); -require_once('include/Contact.php'); + function widget_profile($args) { @@ -806,7 +806,6 @@ function widget_photo_albums($arr) { function widget_vcard($arr) { - require_once ('include/Contact.php'); return vcard_from_xchan('', App::get_observer()); } @@ -1052,7 +1051,7 @@ function widget_photo($arr) { function widget_cover_photo($arr) { - require_once('include/identity.php'); + require_once('include/channel.php'); $o = ''; if(App::$module == 'channel' && $_REQUEST['mid']) diff --git a/include/zot.php b/include/zot.php index f5fb87e12..4b780db2a 100644 --- a/include/zot.php +++ b/include/zot.php @@ -1332,7 +1332,7 @@ function zot_import($arr, $sender_url) { */ function public_recips($msg) { - require_once('include/identity.php'); + require_once('include/channel.php'); $check_mentions = false; $include_sys = false; @@ -3222,7 +3222,6 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { $clean = array(); if($abook['abook_xchan'] && $abook['entry_deleted']) { logger('process_channel_sync_delivery: removing abook entry for ' . $abook['abook_xchan']); - require_once('include/Contact.php'); $r = q("select abook_id, abook_feed from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1", dbesc($abook['abook_xchan']), @@ -3926,7 +3925,7 @@ function zotinfo($arr) { $ret['site']['accounts'] = account_total(); - require_once('include/identity.php'); + require_once('include/channel.php'); $ret['site']['channels'] = channel_total(); @@ -4421,7 +4420,6 @@ function zot_reply_purge($sender,$recipients) { $arr = $sender; $sender_hash = make_xchan_hash($arr['guid'],$arr['guid_sig']); - require_once('include/Contact.php'); remove_all_xchan_resources($sender_hash); $ret['success'] = true; -- cgit v1.2.3 From 5e0698ba8731e7e4659a24c0ab4fa9c4a1aef173 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 22 May 2016 17:52:30 -0700 Subject: turn the oft-repeated block_public ... check into a function observer_prohibited() --- include/channel.php | 2 +- include/socgraph.php | 2 +- include/widgets.php | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/channel.php b/include/channel.php index 050c4824b..8f93ca16f 100644 --- a/include/channel.php +++ b/include/channel.php @@ -1567,7 +1567,7 @@ function get_online_status($nick) { $ret = array('result' => false); - if(get_config('system','block_public') && ! local_channel() && ! remote_channel()) + if(observer_prohibited()) return $ret; $r = q("select channel_id, channel_hash from channel where channel_address = '%s' limit 1", diff --git a/include/socgraph.php b/include/socgraph.php index dffaa8923..4cb5600ec 100644 --- a/include/socgraph.php +++ b/include/socgraph.php @@ -402,7 +402,7 @@ function poco($a,$extended = false) { $system_mode = false; - if(intval(get_config('system','block_public')) && (! local_channel()) && (! remote_channel())) { + if(observer_prohibited()) { logger('mod_poco: block_public'); http_status_exit(401); } diff --git a/include/widgets.php b/include/widgets.php index a158633ad..27f50e9be 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -12,13 +12,13 @@ require_once('include/attach.php'); function widget_profile($args) { - $block = (((get_config('system', 'block_public')) && (! local_channel()) && (! remote_channel())) ? true : false); + $block = observer_prohibited(); return profile_sidebar(App::$profile, $block, true); } function widget_zcard($args) { - $block = (((get_config('system', 'block_public')) && (! local_channel()) && (! remote_channel())) ? true : false); + $block = observer_prohibited(); $channel = channelx_by_n(App::$profile_uid); return get_zcard($channel,get_observer_hash(),array('width' => 875)); } @@ -369,7 +369,7 @@ function widget_fullprofile($arr) { if(! App::$profile['profile_uid']) return; - $block = (((get_config('system', 'block_public')) && (! local_channel()) && (! remote_channel())) ? true : false); + $block = observer_prohibited(); return profile_sidebar(App::$profile, $block); } @@ -379,7 +379,7 @@ function widget_shortprofile($arr) { if(! App::$profile['profile_uid']) return; - $block = (((get_config('system', 'block_public')) && (! local_channel()) && (! remote_channel())) ? true : false); + $block = observer_prohibited(); return profile_sidebar(App::$profile, $block, true, true); } -- cgit v1.2.3 From 2d06663490c5fd63b0ebbae141d0b2bbd5a4a8ca Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 22 May 2016 19:25:27 -0700 Subject: move apps to zlib --- include/apps.php | 658 ----------------------------------------------------- include/bbcode.php | 5 +- 2 files changed, 2 insertions(+), 661 deletions(-) delete mode 100644 include/apps.php (limited to 'include') diff --git a/include/apps.php b/include/apps.php deleted file mode 100644 index e300bc50d..000000000 --- a/include/apps.php +++ /dev/null @@ -1,658 +0,0 @@ - $v) { - if(strpos($v,'http') === 0) - $ret[$k] = zid($v); - } - - if(array_key_exists('desc',$ret)) - $ret['desc'] = str_replace(array('\'','"'),array(''','&dquot;'),$ret['desc']); - - if(array_key_exists('target',$ret)) - $ret['target'] = str_replace(array('\'','"'),array(''','&dquot;'),$ret['target']); - - if(array_key_exists('requires',$ret)) { - $requires = explode(',',$ret['requires']); - foreach($requires as $require) { - $require = trim(strtolower($require)); - switch($require) { - case 'nologin': - if(local_channel()) - unset($ret); - break; - case 'admin': - if(! is_site_admin()) - unset($ret); - break; - case 'local_channel': - if(! local_channel()) - unset($ret); - break; - case 'public_profile': - if(! is_public_profile()) - unset($ret); - break; - case 'observer': - if(! $observer) - unset($ret); - break; - default: - if(! (local_channel() && feature_enabled(local_channel(),$require))) - unset($ret); - break; - - } - } - } - if($ret) { - if($translate) - translate_system_apps($ret); - return $ret; - } - return false; -} - - -function translate_system_apps(&$arr) { - $apps = array( - 'Site Admin' => t('Site Admin'), - 'Bug Report' => t('Bug Report'), - 'View Bookmarks' => t('View Bookmarks'), - 'My Chatrooms' => t('My Chatrooms'), - 'Connections' => t('Connections'), - 'Firefox Share' => t('Firefox Share'), - 'Remote Diagnostics' => t('Remote Diagnostics'), - 'Suggest Channels' => t('Suggest Channels'), - 'Login' => t('Login'), - 'Channel Manager' => t('Channel Manager'), - 'Grid' => t('Grid'), - 'Settings' => t('Settings'), - 'Files' => t('Files'), - 'Webpages' => t('Webpages'), - 'Channel Home' => t('Channel Home'), - 'View Profile' => t('View Profile'), - 'Photos' => t('Photos'), - 'Events' => t('Events'), - 'Directory' => t('Directory'), - 'Help' => t('Help'), - 'Mail' => t('Mail'), - 'Mood' => t('Mood'), - 'Poke' => t('Poke'), - 'Chat' => t('Chat'), - 'Search' => t('Search'), - 'Probe' => t('Probe'), - 'Suggest' => t('Suggest'), - 'Random Channel' => t('Random Channel'), - 'Invite' => t('Invite'), - 'Features' => t('Features'), - 'Language' => t('Language'), - 'Post' => t('Post'), - 'Profile Photo' => t('Profile Photo') - ); - - if(array_key_exists($arr['name'],$apps)) - $arr['name'] = $apps[$arr['name']]; - -} - - -// papp is a portable app - -function app_render($papp,$mode = 'view') { - - /** - * modes: - * view: normal mode for viewing an app via bbcode from a conversation or page - * provides install/update button if you're logged in locally - * list: normal mode for viewing an app on the app page - * no buttons are shown - * edit: viewing the app page in editing mode provides a delete button - */ - - $installed = false; - - if(! $papp) - return; - - if(! $papp['photo']) - $papp['photo'] = z_root() . '/' . get_default_profile_photo(80); - - - - $papp['papp'] = papp_encode($papp); - - if(! strstr($papp['url'],'://')) - $papp['url'] = z_root() . ((strpos($papp['url'],'/') === 0) ? '' : '/') . $papp['url']; - - foreach($papp as $k => $v) { - if(strpos($v,'http') === 0 && $k != 'papp') - $papp[$k] = zid($v); - if($k === 'desc') - $papp['desc'] = str_replace(array('\'','"'),array(''','&dquot;'),$papp['desc']); - - if($k === 'requires') { - $requires = explode(',',$v); - foreach($requires as $require) { - $require = trim(strtolower($require)); - switch($require) { - case 'nologin': - if(local_channel()) - return ''; - break; - case 'admin': - if(! is_site_admin()) - return ''; - break; - case 'local_channel': - if(! local_channel()) - return ''; - break; - case 'public_profile': - if(! is_public_profile()) - return ''; - break; - case 'observer': - $observer = App::get_observer(); - if(! $observer) - return ''; - break; - default: - if(! (local_channel() && feature_enabled(local_channel(),$require))) - return ''; - break; - - } - } - - } - } - - $hosturl = ''; - - if(local_channel()) { - $installed = app_installed(local_channel(),$papp); - $hosturl = z_root() . '/'; - } - elseif(remote_channel()) { - $observer = App::get_observer(); - if($observer && $observer['xchan_network'] === 'zot') { - // some folks might have xchan_url redirected offsite, use the connurl - $x = parse_url($observer['xchan_connurl']); - if($x) { - $hosturl = $x['scheme'] . '://' . $x['host'] . '/'; - } - } - } - - $install_action = (($installed) ? t('Update') : t('Install')); - - return replace_macros(get_markup_template('app.tpl'),array( - '$app' => $papp, - '$hosturl' => $hosturl, - '$purchase' => (($papp['page'] && (! $installed)) ? t('Purchase') : ''), - '$install' => (($hosturl && $mode == 'view') ? $install_action : ''), - '$edit' => ((local_channel() && $installed && $mode == 'edit') ? t('Edit') : ''), - '$delete' => ((local_channel() && $installed && $mode == 'edit') ? t('Delete') : '') - )); -} - - -function app_install($uid,$app) { - $app['uid'] = $uid; - - if(app_installed($uid,$app)) - $x = app_update($app); - else - $x = app_store($app); - - if($x['success']) { - $r = q("select * from app where app_id = '%s' and app_channel = %d limit 1", - dbesc($x['app_id']), - intval($uid) - ); - if($r) { - if(! $r[0]['app_system']) { - if($app['categories'] && (! $app['term'])) { - $r[0]['term'] = q("select * from term where otype = %d and oid = d", - intval(TERM_OBJ_APP), - intval($r[0]['id']) - ); - build_sync_packet($uid,array('app' => $r[0])); - } - } - } - return $x['app_id']; - } - return false; -} - -function app_destroy($uid,$app) { - - - if($uid && $app['guid']) { - - $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1", - dbesc($app['guid']), - intval($uid) - ); - if($x) { - $x[0]['app_deleted'] = 1; - q("delete from term where otype = %d and oid = %d", - intval(TERM_OBJ_APP), - intval($x[0]['id']) - ); - if($x[0]['app_system']) { - $r = q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d", - dbesc($app['guid']), - intval($uid) - ); - } - else { - $r = q("delete from app where app_id = '%s' and app_channel = %d", - dbesc($app['guid']), - intval($uid) - ); - - // we don't sync system apps - they may be completely different on the other system - build_sync_packet($uid,array('app' => $x)); - } - } - } -} - - -function app_installed($uid,$app) { - - $r = q("select id from app where app_id = '%s' and app_version = '%s' and app_channel = %d limit 1", - dbesc((array_key_exists('guid',$app)) ? $app['guid'] : ''), - dbesc((array_key_exists('version',$app)) ? $app['version'] : ''), - intval($uid) - ); - return(($r) ? true : false); - -} - - -function app_list($uid, $deleted = false, $cat = '') { - if($deleted) - $sql_extra = " and app_deleted = 1 "; - else - $sql_extra = " and app_deleted = 0 "; - - if($cat) { - $r = q("select oid from term where otype = %d and term = '%s'", - intval(TERM_OBJ_APP), - dbesc($cat) - ); - if(! $r) - return $r; - $sql_extra .= " and app.id in ( "; - $s = ''; - foreach($r as $rr) { - if($s) - $s .= ','; - $s .= intval($rr['oid']); - } - $sql_extra .= $s . ') '; - } - - $r = q("select * from app where app_channel = %d $sql_extra order by app_name asc", - intval($uid) - ); - if($r) { - for($x = 0; $x < count($r); $x ++) { - if(! $r[$x]['app_system']) - $r[$x]['type'] = 'personal'; - $r[$x]['term'] = q("select * from term where otype = %d and oid = %d", - intval(TERM_OBJ_APP), - intval($r[$x]['id']) - ); - } - } - return($r); -} - - -function app_decode($s) { - $x = base64_decode(str_replace(array('
',"\r","\n",' '),array('','','',''),$s)); - return json_decode($x,true); -} - - -function app_store($arr) { - - // logger('app_store: ' . print_r($arr,true)); - - $darray = array(); - $ret = array('success' => false); - - $darray['app_url'] = ((x($arr,'url')) ? $arr['url'] : ''); - $darray['app_channel'] = ((x($arr,'uid')) ? $arr['uid'] : 0); - - if((! $darray['app_url']) || (! $darray['app_channel'])) - return $ret; - - if($arr['photo'] && ! strstr($arr['photo'],z_root())) { - $x = import_xchan_photo($arr['photo'],get_observer_hash(),true); - $arr['photo'] = $x[1]; - } - - - $darray['app_id'] = ((x($arr,'guid')) ? $arr['guid'] : random_string(). '.' . App::get_hostname()); - $darray['app_sig'] = ((x($arr,'sig')) ? $arr['sig'] : ''); - $darray['app_author'] = ((x($arr,'author')) ? $arr['author'] : get_observer_hash()); - $darray['app_name'] = ((x($arr,'name')) ? escape_tags($arr['name']) : t('Unknown')); - $darray['app_desc'] = ((x($arr,'desc')) ? escape_tags($arr['desc']) : ''); - $darray['app_photo'] = ((x($arr,'photo')) ? $arr['photo'] : z_root() . '/' . get_default_profile_photo(80)); - $darray['app_version'] = ((x($arr,'version')) ? escape_tags($arr['version']) : ''); - $darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : ''); - $darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : ''); - $darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : ''); - $darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : ''); - $darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0); - $darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0); - - $created = datetime_convert(); - - $r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited, app_system, app_deleted ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )", - dbesc($darray['app_id']), - dbesc($darray['app_sig']), - dbesc($darray['app_author']), - dbesc($darray['app_name']), - dbesc($darray['app_desc']), - dbesc($darray['app_url']), - dbesc($darray['app_photo']), - dbesc($darray['app_version']), - intval($darray['app_channel']), - dbesc($darray['app_addr']), - dbesc($darray['app_price']), - dbesc($darray['app_page']), - dbesc($darray['app_requires']), - dbesc($created), - dbesc($created), - intval($darray['app_system']), - intval($darray['app_deleted']) - ); - if($r) { - $ret['success'] = true; - $ret['app_id'] = $darray['app_id']; - } - if($arr['categories']) { - $x = q("select id from app where app_id = '%s' and app_channel = %d limit 1", - dbesc($darray['app_id']), - intval($darray['app_channel']) - ); - $y = explode(',',$arr['categories']); - if($y) { - foreach($y as $t) { - $t = trim($t); - if($t) { - store_item_tag($darray['app_channel'],$x[0]['id'],TERM_OBJ_APP,TERM_CATEGORY,escape_tags($t),escape_tags(z_root() . '/apps/?f=&cat=' . escape_tags($t))); - } - } - } - } - - return $ret; -} - - -function app_update($arr) { - - $darray = array(); - $ret = array('success' => false); - - $darray['app_url'] = ((x($arr,'url')) ? $arr['url'] : ''); - $darray['app_channel'] = ((x($arr,'uid')) ? $arr['uid'] : 0); - $darray['app_id'] = ((x($arr,'guid')) ? $arr['guid'] : 0); - - if((! $darray['app_url']) || (! $darray['app_channel']) || (! $darray['app_id'])) - return $ret; - - if($arr['photo'] && ! strstr($arr['photo'],z_root())) { - $x = import_xchan_photo($arr['photo'],get_observer_hash(),true); - $arr['photo'] = $x[1]; - } - - $darray['app_sig'] = ((x($arr,'sig')) ? $arr['sig'] : ''); - $darray['app_author'] = ((x($arr,'author')) ? $arr['author'] : get_observer_hash()); - $darray['app_name'] = ((x($arr,'name')) ? escape_tags($arr['name']) : t('Unknown')); - $darray['app_desc'] = ((x($arr,'desc')) ? escape_tags($arr['desc']) : ''); - $darray['app_photo'] = ((x($arr,'photo')) ? $arr['photo'] : z_root() . '/' . get_default_profile_photo(80)); - $darray['app_version'] = ((x($arr,'version')) ? escape_tags($arr['version']) : ''); - $darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : ''); - $darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : ''); - $darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : ''); - $darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : ''); - $darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0); - $darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0); - - $edited = datetime_convert(); - - $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s', app_system = %d, app_deleted = %d where app_id = '%s' and app_channel = %d", - dbesc($darray['app_sig']), - dbesc($darray['app_author']), - dbesc($darray['app_name']), - dbesc($darray['app_desc']), - dbesc($darray['app_url']), - dbesc($darray['app_photo']), - dbesc($darray['app_version']), - dbesc($darray['app_addr']), - dbesc($darray['app_price']), - dbesc($darray['app_page']), - dbesc($darray['app_requires']), - dbesc($edited), - intval($darray['app_system']), - intval($darray['app_deleted']), - dbesc($darray['app_id']), - intval($darray['app_channel']) - ); - if($r) { - $ret['success'] = true; - $ret['app_id'] = $darray['app_id']; - } - - $x = q("select id from app where app_id = '%s' and app_channel = %d limit 1", - dbesc($darray['app_id']), - intval($darray['app_channel']) - ); - if($x) { - q("delete from term where otype = %d and oid = %d", - intval(TERM_OBJ_APP), - intval($x[0]['id']) - ); - if($arr['categories']) { - $y = explode(',',$arr['categories']); - if($y) { - foreach($y as $t) { - $t = trim($t); - if($t) { - store_item_tag($darray['app_channel'],$x[0]['id'],TERM_OBJ_APP,TERM_CATEGORY,escape_tags($t),escape_tags(z_root() . '/apps/?f=&cat=' . escape_tags($t))); - } - } - } - } - } - - return $ret; - -} - - -function app_encode($app,$embed = false) { - - $ret = array(); - - $ret['type'] = 'personal'; - - if($app['app_id']) - $ret['guid'] = $app['app_id']; - - if($app['app_id']) - $ret['guid'] = $app['app_id']; - - if($app['app_sig']) - $ret['sig'] = $app['app_sig']; - - if($app['app_author']) - $ret['author'] = $app['app_author']; - - if($app['app_name']) - $ret['name'] = $app['app_name']; - - if($app['app_desc']) - $ret['desc'] = $app['app_desc']; - - if($app['app_url']) - $ret['url'] = $app['app_url']; - - if($app['app_photo']) - $ret['photo'] = $app['app_photo']; - - if($app['app_version']) - $ret['version'] = $app['app_version']; - - if($app['app_addr']) - $ret['addr'] = $app['app_addr']; - - if($app['app_price']) - $ret['price'] = $app['app_price']; - - if($app['app_page']) - $ret['page'] = $app['app_page']; - - if($app['app_requires']) - $ret['requires'] = $app['app_requires']; - - if($app['app_system']) - $ret['system'] = $app['app_system']; - - if($app['app_deleted']) - $ret['deleted'] = $app['app_deleted']; - - if($app['term']) { - $s = ''; - foreach($app['term'] as $t) { - if($s) - $s .= ','; - $s .= $t['term']; - } - $ret['categories'] = $s; - } - - - if(! $embed) - return $ret; - - if(array_key_exists('categories',$ret)) - unset($ret['categories']); - - $j = json_encode($ret); - return '[app]' . chunk_split(base64_encode($j),72,"\n") . '[/app]'; - -} - - -function papp_encode($papp) { - return chunk_split(base64_encode(json_encode($papp)),72,"\n"); - -} - - diff --git a/include/bbcode.php b/include/bbcode.php index fd2d2f97a..ba35050e8 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -165,11 +165,10 @@ function bb_parse_crypt($match) { } function bb_parse_app($match) { - require_once('include/apps.php'); - $app = app_decode($match[1]); + $app = Zotlabs\Lib\Apps::app_decode($match[1]); if ($app) - return app_render($app); + return Zotlab\Lib\Apps::app_render($app); } function bb_parse_element($match) { -- cgit v1.2.3 From 1aa3051e977dceb04fbe656763d8ef8a9803a571 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 22 May 2016 20:54:52 -0700 Subject: move chatroom stuff to zlib --- include/chat.php | 262 ----------------------------------------------- include/conversation.php | 3 +- include/widgets.php | 3 +- 3 files changed, 2 insertions(+), 266 deletions(-) delete mode 100644 include/chat.php (limited to 'include') diff --git a/include/chat.php b/include/chat.php deleted file mode 100644 index 604402045..000000000 --- a/include/chat.php +++ /dev/null @@ -1,262 +0,0 @@ - false); - - $name = trim($arr['name']); - if(! $name) { - $ret['message'] = t('Missing room name'); - return $ret; - } - - $r = q("select cr_id from chatroom where cr_uid = %d and cr_name = '%s' limit 1", - intval($channel['channel_id']), - dbesc($name) - ); - if($r) { - $ret['message'] = t('Duplicate room name'); - return $ret; - } - - $r = q("select count(cr_id) as total from chatroom where cr_aid = %d", - intval($channel['channel_account_id']) - ); - if($r) - $limit = service_class_fetch($channel['channel_id'], 'chatrooms'); - - if(($r) && ($limit !== false) && ($r[0]['total'] >= $limit)) { - $ret['message'] = upgrade_message(); - return $ret; - } - - if(! array_key_exists('expire', $arr)) - $arr['expire'] = 120; // minutes, e.g. 2 hours - - $created = datetime_convert(); - - $x = q("insert into chatroom ( cr_aid, cr_uid, cr_name, cr_created, cr_edited, cr_expire, allow_cid, allow_gid, deny_cid, deny_gid ) - values ( %d, %d , '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s' ) ", - intval($channel['channel_account_id']), - intval($channel['channel_id']), - dbesc($name), - dbesc($created), - dbesc($created), - intval($arr['expire']), - dbesc($arr['allow_cid']), - dbesc($arr['allow_gid']), - dbesc($arr['deny_cid']), - dbesc($arr['deny_gid']) - ); - - if($x) - $ret['success'] = true; - - return $ret; -} - - -function chatroom_destroy($channel,$arr) { - - $ret = array('success' => false); - - if(intval($arr['cr_id'])) - $sql_extra = " and cr_id = " . intval($arr['cr_id']) . " "; - elseif(trim($arr['cr_name'])) - $sql_extra = " and cr_name = '" . protect_sprintf(dbesc(trim($arr['cr_name']))) . "' "; - else { - $ret['message'] = t('Invalid room specifier.'); - return $ret; - } - - $r = q("select * from chatroom where cr_uid = %d $sql_extra limit 1", - intval($channel['channel_id']) - ); - if(! $r) { - $ret['message'] = t('Invalid room specifier.'); - return $ret; - } - - build_sync_packet($channel['channel_id'],array('chatroom' => $r)); - - q("delete from chatroom where cr_id = %d", - intval($r[0]['cr_id']) - ); - if($r[0]['cr_id']) { - q("delete from chatpresence where cp_room = %d", - intval($r[0]['cr_id']) - ); - q("delete from chat where chat_room = %d", - intval($r[0]['cr_id']) - ); - } - - $ret['success'] = true; - return $ret; -} - - -function chatroom_enter($observer_xchan, $room_id, $status, $client) { - - if(! $room_id || ! $observer_xchan) - return; - - $r = q("select * from chatroom where cr_id = %d limit 1", - intval($room_id) - ); - if(! $r) { - notice( t('Room not found.') . EOL); - return false; - } - require_once('include/security.php'); - $sql_extra = permissions_sql($r[0]['cr_uid']); - - $x = q("select * from chatroom where cr_id = %d and cr_uid = %d $sql_extra limit 1", - intval($room_id), - intval($r[0]['cr_uid']) - ); - if(! $x) { - notice( t('Permission denied.') . EOL); - return false; - } - - $limit = service_class_fetch($r[0]['cr_uid'], 'chatters_inroom'); - if($limit !== false) { - $y = q("select count(*) as total from chatpresence where cp_room = %d", - intval($room_id) - ); - if($y && $y[0]['total'] > $limit) { - notice( t('Room is full') . EOL); - return false; - } - } - - if(intval($x[0]['cr_expire'])) { - $r = q("delete from chat where created < %s - INTERVAL %s and chat_room = %d", - db_utcnow(), - db_quoteinterval( intval($x[0]['cr_expire']) . ' MINUTE' ), - intval($x[0]['cr_id']) - ); - } - - $r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d limit 1", - dbesc($observer_xchan), - intval($room_id) - ); - if($r) { - q("update chatpresence set cp_last = '%s' where cp_id = %d and cp_client = '%s'", - dbesc(datetime_convert()), - intval($r[0]['cp_id']), - dbesc($client) - ); - return true; - } - - $r = q("insert into chatpresence ( cp_room, cp_xchan, cp_last, cp_status, cp_client ) - values ( %d, '%s', '%s', '%s', '%s' )", - intval($room_id), - dbesc($observer_xchan), - dbesc(datetime_convert()), - dbesc($status), - dbesc($client) - ); - - return $r; -} - - -function chatroom_leave($observer_xchan, $room_id, $client) { - if(! $room_id || ! $observer_xchan) - return; - - $r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d and cp_client = '%s' limit 1", - dbesc($observer_xchan), - intval($room_id), - dbesc($client) - ); - if($r) { - q("delete from chatpresence where cp_id = %d", - intval($r[0]['cp_id']) - ); - } - - return true; -} - - -function chatroom_list($uid) { - require_once('include/security.php'); - $sql_extra = permissions_sql($uid); - - $r = q("select allow_cid, allow_gid, deny_cid, deny_gid, cr_name, cr_expire, cr_id, count(cp_id) as cr_inroom from chatroom left join chatpresence on cr_id = cp_room where cr_uid = %d $sql_extra group by cr_name, cr_id order by cr_name", - intval($uid) - ); - - return $r; -} - -function chatroom_list_count($uid) { - require_once('include/security.php'); - $sql_extra = permissions_sql($uid); - - $r = q("select count(*) as total from chatroom where cr_uid = %d $sql_extra", - intval($uid) - ); - - return $r[0]['total']; -} - -/** - * create a chat message via API. - * It is the caller's responsibility to enter the room. - */ - -function chat_message($uid, $room_id, $xchan, $text) { - - $ret = array('success' => false); - - if(! $text) - return; - - $sql_extra = permissions_sql($uid); - - $r = q("select * from chatroom where cr_uid = %d and cr_id = %d $sql_extra", - intval($uid), - intval($room_id) - ); - if(! $r) - return $ret; - - $arr = array( - 'chat_room' => $room_id, - 'chat_xchan' => $xchan, - 'chat_text' => $text - ); - - call_hooks('chat_message', $arr); - - $x = q("insert into chat ( chat_room, chat_xchan, created, chat_text ) - values( %d, '%s', '%s', '%s' )", - intval($room_id), - dbesc($xchan), - dbesc(datetime_convert()), - dbesc($arr['chat_text']) - ); - - $ret['success'] = true; - return $ret; -} diff --git a/include/conversation.php b/include/conversation.php index ca73a7a07..f405bc9d5 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -1658,8 +1658,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null){ if ($p['chat'] && feature_enabled($uid,'ajaxchat')) { - require_once('include/chat.php'); - $has_chats = chatroom_list_count($uid); + $has_chats = Zotlabs\Lib\Chatroom::list_count($uid); if ($has_chats) { $tabs[] = array( 'label' => t('Chatrooms'), diff --git a/include/widgets.php b/include/widgets.php index 27f50e9be..e6d162ccd 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -834,8 +834,7 @@ function widget_menu_preview($arr) { function widget_chatroom_list($arr) { - require_once("include/chat.php"); - $r = chatroom_list(App::$profile['profile_uid']); + $r = Zotlabs\Lib\Chatroom::roomlist(App::$profile['profile_uid']); if($r) { return replace_macros(get_markup_template('chatroomlist.tpl'), array( -- cgit v1.2.3 From bbc71343bdfc724425927ebab404b035c65f569c Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 22 May 2016 22:44:13 -0700 Subject: change the signed token format. We don't folks to be able to submit random text for signing by us, as they could then use these to generate known signatures. --- include/zot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/zot.php b/include/zot.php index 4b780db2a..8ba03ff5c 100644 --- a/include/zot.php +++ b/include/zot.php @@ -3818,7 +3818,7 @@ function zotinfo($arr) { // Communication details if($token) - $ret['signed_token'] = base64url_encode(rsa_sign($token,$e['channel_prvkey'])); + $ret['signed_token'] = base64url_encode(rsa_sign('token.' . $token,$e['channel_prvkey'])); $ret['guid'] = $e['xchan_guid']; -- cgit v1.2.3 From 29ba8918093166ac32ef9a727a9b71ba8e01a402 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 24 May 2016 01:25:13 -0700 Subject: moved enotify --- include/dir_fns.php | 3 + include/enotify.php | 652 ---------------------------------------------------- include/items.php | 15 +- include/network.php | 4 +- include/notify.php | 37 --- include/zot.php | 3 +- 6 files changed, 12 insertions(+), 702 deletions(-) delete mode 100644 include/enotify.php delete mode 100644 include/notify.php (limited to 'include') diff --git a/include/dir_fns.php b/include/dir_fns.php index 4e300663c..9f1be1a42 100644 --- a/include/dir_fns.php +++ b/include/dir_fns.php @@ -94,6 +94,9 @@ function get_directory_setting($observer, $setting) { if($ret === false) $ret = get_config('directory', $setting); + + // 'safemode' is the default if there is no observer or no established preference. + if($setting == 'safemode' && $ret === false) $ret = 1; diff --git a/include/enotify.php b/include/enotify.php deleted file mode 100644 index bd8698606..000000000 --- a/include/enotify.php +++ /dev/null @@ -1,652 +0,0 @@ -'); - - if ($params['type'] == NOTIFY_MAIL) { - logger('notification: mail'); - $subject = sprintf( t('[Hubzilla:Notify] New mail received at %s'),$sitename); - - $preamble = sprintf( t('%1$s, %2$s sent you a new private message at %3$s.'),$recip['channel_name'], $sender['xchan_name'],$sitename); - $epreamble = sprintf( t('%1$s sent you %2$s.'),'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]'); - $sitelink = t('Please visit %s to view and/or reply to your private messages.'); - $tsitelink = sprintf( $sitelink, $siteurl . '/mail/' . $params['item']['id'] ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - $itemlink = $siteurl . '/mail/' . $params['item']['id']; - } - - if ($params['type'] == NOTIFY_COMMENT) { -// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG); - - $itemlink = $params['link']; - - // ignore like/unlike activity on posts - they probably require a sepearate notification preference - - if (array_key_exists('item',$params) && (! visible_activity($params['item']))) - return; - - $parent_mid = $params['parent_mid']; - - // Check to see if there was already a notify for this post. - // If so don't create a second notification - - $p = null; - $p = q("select id from notify where link = '%s' and uid = %d limit 1", - dbesc($params['link']), - intval($recip['channel_id']) - ); - if ($p) { - logger('notification: comment already notified'); - pop_lang(); - return; - } - - - // if it's a post figure out who's post it is. - - $p = null; - - if($params['otype'] === 'item' && $parent_mid) { - $p = q("select * from item where mid = '%s' and uid = %d limit 1", - dbesc($parent_mid), - intval($recip['channel_id']) - ); - } - - xchan_query($p); - - - $item_post_type = item_post_type($p[0]); -// $private = $p[0]['item_private']; - $parent_id = $p[0]['id']; - - $parent_item = $p[0]; - - //$possess_desc = str_replace('',$possess_desc); - - // "a post" - $dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]a %4$s[/zrl]'), - $recip['channel_name'], - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $itemlink, - $item_post_type); - - // "George Bull's post" - if($p) - $dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]%4$s\'s %5$s[/zrl]'), - $recip['channel_name'], - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $itemlink, - $p[0]['author']['xchan_name'], - $item_post_type); - - // "your post" - if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall'])) - $dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]your %4$s[/zrl]'), - $recip['channel_name'], - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $itemlink, - $item_post_type); - - // Some mail softwares relies on subject field for threading. - // So, we cannot have different subjects for notifications of the same thread. - // Before this we have the name of the replier on the subject rendering - // differents subjects for messages on the same thread. - - $subject = sprintf( t('[Hubzilla:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']); - $preamble = sprintf( t('%1$s, %2$s commented on an item/conversation you have been following.'), $recip['channel_name'], $sender['xchan_name']); - $epreamble = $dest_str; - - $sitelink = t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf( $sitelink, $siteurl ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - } - - if($params['type'] == NOTIFY_WALL) { - $subject = sprintf( t('[Hubzilla:Notify] %s posted to your profile wall') , $sender['xchan_name']); - - $preamble = sprintf( t('%1$s, %2$s posted to your profile wall at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename); - - $epreamble = sprintf( t('%1$s, %2$s posted to [zrl=%3$s]your wall[/zrl]') , - $recip['channel_name'], - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $params['link']); - - $sitelink = t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf( $sitelink, $siteurl ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - $itemlink = $params['link']; - } - - if ($params['type'] == NOTIFY_TAGSELF) { - - $p = null; - $p = q("select id from notify where link = '%s' and uid = %d limit 1", - dbesc($params['link']), - intval($recip['channel_id']) - ); - if ($p) { - logger('enotify: tag: already notified about this post'); - pop_lang(); - return; - } - - $subject = sprintf( t('[Hubzilla:Notify] %s tagged you') , $sender['xchan_name']); - $preamble = sprintf( t('%1$s, %2$s tagged you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s, %2$s [zrl=%3$s]tagged you[/zrl].') , - $recip['channel_name'], - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $params['link']); - - $sitelink = t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf( $sitelink, $siteurl ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - $itemlink = $params['link']; - } - - if ($params['type'] == NOTIFY_POKE) { - $subject = sprintf( t('[Hubzilla:Notify] %1$s poked you') , $sender['xchan_name']); - $preamble = sprintf( t('%1$s, %2$s poked you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s, %2$s [zrl=%2$s]poked you[/zrl].') , - $recip['channel_name'], - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $params['link']); - - $subject = str_replace('poked', t($params['activity']), $subject); - $preamble = str_replace('poked', t($params['activity']), $preamble); - $epreamble = str_replace('poked', t($params['activity']), $epreamble); - - $sitelink = t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf( $sitelink, $siteurl ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - $itemlink = $params['link']; - } - - if ($params['type'] == NOTIFY_TAGSHARE) { - $subject = sprintf( t('[Hubzilla:Notify] %s tagged your post') , $sender['xchan_name']); - $preamble = sprintf( t('%1$s, %2$s tagged your post at %3$s') , $recip['channel_name'],$sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s, %2$s tagged [zrl=%3$s]your post[/zrl]') , - $recip['channel_name'], - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', - $itemlink); - - $sitelink = t('Please visit %s to view and/or reply to the conversation.'); - $tsitelink = sprintf( $sitelink, $siteurl ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - $itemlink = $params['link']; - } - - if ($params['type'] == NOTIFY_INTRO) { - $subject = sprintf( t('[Hubzilla:Notify] Introduction received')); - $preamble = sprintf( t('%1$s, you\'ve received an new connection request from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a new connection request[/zrl] from %3$s.'), - $recip['channel_name'], - $siteurl . '/connections/ifpending', - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]'); - $body = sprintf( t('You may visit their profile at %s'),$sender['xchan_url']); - - $sitelink = t('Please visit %s to approve or reject the connection request.'); - $tsitelink = sprintf( $sitelink, $siteurl . '/connections/ifpending'); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - $itemlink = $params['link']; - } - - if ($params['type'] == NOTIFY_SUGGEST) { - $subject = sprintf( t('[Hubzilla:Notify] Friend suggestion received')); - $preamble = sprintf( t('%1$s, you\'ve received a friend suggestion from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a friend suggestion[/zrl] for %3$s from %4$s.'), - $recip['channel_name'], - $itemlink, - '[zrl=' . $params['item']['url'] . ']' . $params['item']['name'] . '[/zrl]', - '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]'); - - $body = t('Name:') . ' ' . $params['item']['name'] . "\n"; - $body .= t('Photo:') . ' ' . $params['item']['photo'] . "\n"; - $body .= sprintf( t('You may visit their profile at %s'),$params['item']['url']); - - $sitelink = t('Please visit %s to approve or reject the suggestion.'); - $tsitelink = sprintf( $sitelink, $siteurl ); - $hsitelink = sprintf( $sitelink, '' . $sitename . ''); - $itemlink = $params['link']; - } - - if ($params['type'] == NOTIFY_CONFIRM) { - // ? - } - - if ($params['type'] == NOTIFY_SYSTEM) { - // ? - } - - $h = array( - 'params' => $params, - 'subject' => $subject, - 'preamble' => $preamble, - 'epreamble' => $epreamble, - 'body' => $body, - 'sitelink' => $sitelink, - 'sitename' => $sitename, - 'tsitelink' => $tsitelink, - 'hsitelink' => $hsitelink, - 'itemlink' => $itemlink, - 'sender' => $sender, - 'recipient' => $recip - ); - - call_hooks('enotify', $h); - - $subject = $h['subject']; - $preamble = $h['preamble']; - $epreamble = $h['epreamble']; - $body = $h['body']; - $sitelink = $h['sitelink']; - $tsitelink = $h['tsitelink']; - $hsitelink = $h['hsitelink']; - $itemlink = $h['itemlink']; - - - require_once('include/html2bbcode.php'); - - do { - $dups = false; - $hash = random_string(); - $r = q("SELECT `id` FROM `notify` WHERE `hash` = '%s' LIMIT 1", - dbesc($hash)); - if (count($r)) - $dups = true; - } while ($dups === true); - - - $datarray = array(); - $datarray['hash'] = $hash; - $datarray['sender_hash'] = $sender['xchan_hash']; - $datarray['name'] = $sender['xchan_name']; - $datarray['url'] = $sender['xchan_url']; - $datarray['photo'] = $sender['xchan_photo_s']; - $datarray['date'] = datetime_convert(); - $datarray['aid'] = $recip['channel_account_id']; - $datarray['uid'] = $recip['channel_id']; - $datarray['link'] = $itemlink; - $datarray['parent'] = $parent_mid; - $datarray['parent_item'] = $parent_item; - $datarray['type'] = $params['type']; - $datarray['verb'] = $params['verb']; - $datarray['otype'] = $params['otype']; - $datarray['abort'] = false; - - $datarray['item'] = $params['item']; - - call_hooks('enotify_store', $datarray); - - if ($datarray['abort']) { - pop_lang(); - return; - } - - - // create notification entry in DB - $seen = 0; - - // Mark some notifications as seen right away - // Note! The notification have to be created, because they are used to send emails - // So easiest solution to hide them from Notices is to mark them as seen right away. - // Another option would be to not add them to the DB, and change how emails are handled (probably would be better that way) - $always_show_in_notices = get_pconfig($recip['channel_id'],'system','always_show_in_notices'); - if (!$always_show_in_notices) { - if (($params['type'] == NOTIFY_WALL) || ($params['type'] == NOTIFY_MAIL) || ($params['type'] == NOTIFY_INTRO)) { - $seen = 1; - } - } - - $r = q("insert into notify (hash,name,url,photo,date,aid,uid,link,parent,seen,type,verb,otype) - values('%s','%s','%s','%s','%s',%d,%d,'%s','%s',%d,%d,'%s','%s')", - dbesc($datarray['hash']), - dbesc($datarray['name']), - dbesc($datarray['url']), - dbesc($datarray['photo']), - dbesc($datarray['date']), - intval($datarray['aid']), - intval($datarray['uid']), - dbesc($datarray['link']), - dbesc($datarray['parent']), - intval($seen), - intval($datarray['type']), - dbesc($datarray['verb']), - dbesc($datarray['otype']) - ); - - $r = q("select id from notify where hash = '%s' and uid = %d limit 1", - dbesc($hash), - intval($recip['channel_id']) - ); - if ($r) { - $notify_id = $r[0]['id']; - } else { - logger('notification not found.'); - pop_lang(); - return; - } - - $itemlink = z_root() . '/notify/view/' . $notify_id; - $msg = str_replace('$itemlink',$itemlink,$epreamble); - - // wretched hack, but we don't want to duplicate all the preamble variations and we also don't want to screw up a translation - - if ((App::$language === 'en' || (! App::$language)) && strpos($msg,', ')) - $msg = substr($msg,strpos($msg,', ')+1); - - $r = q("update notify set msg = '%s' where id = %d and uid = %d", - dbesc($msg), - intval($notify_id), - intval($datarray['uid']) - ); - - // send email notification if notification preferences permit - - require_once('bbcode.php'); - if ((intval($recip['channel_notifyflags']) & intval($params['type'])) || $params['type'] == NOTIFY_SYSTEM) { - - logger('notification: sending notification email'); - - $hn = get_pconfig($recip['channel_id'],'system','email_notify_host'); - if($hn && (! stristr(App::get_hostname(),$hn))) { - // this isn't the email notification host - pop_lang(); - return; - } - - $textversion = strip_tags(html_entity_decode(bbcode(stripslashes(str_replace(array("\\r", "\\n"), array( "", "\n"), $body))),ENT_QUOTES,'UTF-8')); - - $htmlversion = bbcode(stripslashes(str_replace(array("\\r","\\n"), array("","
\n"),$body))); - - - // use $_SESSION['zid_override'] to force zid() to use - // the recipient address instead of the current observer - - $_SESSION['zid_override'] = $recip['channel_address'] . '@' . App::get_hostname(); - $_SESSION['zrl_override'] = z_root() . '/channel/' . $recip['channel_address']; - - $textversion = zidify_links($textversion); - $htmlversion = zidify_links($htmlversion); - - // unset when done to revert to normal behaviour - - unset($_SESSION['zid_override']); - unset($_SESSION['zrl_override']); - - $datarray = array(); - $datarray['banner'] = $banner; - $datarray['product'] = $product; - $datarray['preamble'] = $preamble; - $datarray['sitename'] = $sitename; - $datarray['siteurl'] = $siteurl; - $datarray['type'] = $params['type']; - $datarray['parent'] = $params['parent_mid']; - $datarray['source_name'] = $sender['xchan_name']; - $datarray['source_link'] = $sender['xchan_url']; - $datarray['source_photo'] = $sender['xchan_photo_s']; - $datarray['uid'] = $recip['channel_id']; - $datarray['username'] = $recip['channel_name']; - $datarray['hsitelink'] = $hsitelink; - $datarray['tsitelink'] = $tsitelink; - $datarray['hitemlink'] = '' . $itemlink . ''; - $datarray['titemlink'] = $itemlink; - $datarray['thanks'] = $thanks; - $datarray['site_admin'] = $site_admin; - $datarray['title'] = stripslashes($title); - $datarray['htmlversion'] = $htmlversion; - $datarray['textversion'] = $textversion; - $datarray['subject'] = $subject; - $datarray['headers'] = $additional_mail_header; - $datarray['email_secure'] = false; - - call_hooks('enotify_mail', $datarray); - - // Default to private - don't disclose message contents over insecure channels (such as email) - // Might be interesting to use GPG,PGP,S/MIME encryption instead - // but we'll save that for a clever plugin developer to implement - - $private_activity = false; - - if (! $datarray['email_secure']) { - switch ($params['type']) { - case NOTIFY_WALL: - case NOTIFY_TAGSELF: - case NOTIFY_POKE: - case NOTIFY_COMMENT: - if (! $private) - break; - $private_activity = true; - case NOTIFY_MAIL: - $datarray['textversion'] = $datarray['htmlversion'] = $datarray['title'] = ''; - $datarray['subject'] = preg_replace('/' . preg_quote(t('[Hubzilla:Notify]')) . '/','$0*',$datarray['subject']); - break; - default: - break; - } - } - - if ($private_activity - && intval(get_pconfig($datarray['uid'], 'system', 'ignore_private_notifications'))) { - - pop_lang(); - return; - } - - // load the template for private message notifications - $tpl = get_markup_template('email_notify_html.tpl'); - $email_html_body = replace_macros($tpl,array( - '$banner' => $datarray['banner'], - '$notify_icon' => Zotlabs\Lib\System::get_notify_icon(), - '$product' => $datarray['product'], - '$preamble' => $datarray['preamble'], - '$sitename' => $datarray['sitename'], - '$siteurl' => $datarray['siteurl'], - '$source_name' => $datarray['source_name'], - '$source_link' => $datarray['source_link'], - '$source_photo' => $datarray['source_photo'], - '$username' => $datarray['to_name'], - '$hsitelink' => $datarray['hsitelink'], - '$hitemlink' => $datarray['hitemlink'], - '$thanks' => $datarray['thanks'], - '$site_admin' => $datarray['site_admin'], - '$title' => $datarray['title'], - '$htmlversion' => $datarray['htmlversion'], - )); - - // load the template for private message notifications - $tpl = get_markup_template('email_notify_text.tpl'); - $email_text_body = replace_macros($tpl, array( - '$banner' => $datarray['banner'], - '$product' => $datarray['product'], - '$preamble' => $datarray['preamble'], - '$sitename' => $datarray['sitename'], - '$siteurl' => $datarray['siteurl'], - '$source_name' => $datarray['source_name'], - '$source_link' => $datarray['source_link'], - '$source_photo' => $datarray['source_photo'], - '$username' => $datarray['to_name'], - '$tsitelink' => $datarray['tsitelink'], - '$titemlink' => $datarray['titemlink'], - '$thanks' => $datarray['thanks'], - '$site_admin' => $datarray['site_admin'], - '$title' => $datarray['title'], - '$textversion' => $datarray['textversion'], - )); - -// logger('text: ' . $email_text_body); - - // use the EmailNotification library to send the message - - enotify::send(array( - 'fromName' => $sender_name, - 'fromEmail' => $sender_email, - 'replyTo' => $sender_email, - 'toEmail' => $recip['account_email'], - 'messageSubject' => $datarray['subject'], - 'htmlVersion' => $email_html_body, - 'textVersion' => $email_text_body, - 'additionalMailHeader' => $datarray['headers'], - )); - } - - pop_lang(); - -} - - -/** - * @brief A class for sending email notifications. - * - * @fixme Class names start mostly with capital letter to distinguish them easier. - */ -class enotify { - /** - * @brief Send a multipart/alternative message with Text and HTML versions. - * - * @param array $params an assoziative array with: - * * \e string \b fromName name of the sender - * * \e string \b fromEmail email of the sender - * * \e string \b replyTo replyTo address to direct responses - * * \e string \b toEmail destination email address - * * \e string \b messageSubject subject of the message - * * \e string \b htmlVersion html version of the message - * * \e string \b textVersion text only version of the message - * * \e string \b additionalMailHeader additions to the smtp mail header - */ - static public function send($params) { - - $fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8'); - $messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8'); - - // generate a mime boundary - $mimeBoundary = rand(0, 9) . "-" - .rand(10000000000, 9999999999) . "-" - .rand(10000000000, 9999999999) . "=:" - .rand(10000, 99999); - - // generate a multipart/alternative message header - $messageHeader = - $params['additionalMailHeader'] . - "From: $fromName <{$params['fromEmail']}>\n" . - "Reply-To: $fromName <{$params['replyTo']}>\n" . - "MIME-Version: 1.0\n" . - "Content-Type: multipart/alternative; boundary=\"{$mimeBoundary}\""; - - // assemble the final multipart message body with the text and html types included - $textBody = chunk_split(base64_encode($params['textVersion'])); - $htmlBody = chunk_split(base64_encode($params['htmlVersion'])); - - $multipartMessageBody = - "--" . $mimeBoundary . "\n" . // plain text section - "Content-Type: text/plain; charset=UTF-8\n" . - "Content-Transfer-Encoding: base64\n\n" . - $textBody . "\n" . - "--" . $mimeBoundary . "\n" . // text/html section - "Content-Type: text/html; charset=UTF-8\n" . - "Content-Transfer-Encoding: base64\n\n" . - $htmlBody . "\n" . - "--" . $mimeBoundary . "--\n"; // message ending - - // send the message - $res = mail( - $params['toEmail'], // send to address - $messageSubject, // subject - $multipartMessageBody, // message body - $messageHeader // message headers - ); - logger("notification: enotify::send returns " . $res, LOGGER_DEBUG); - } -} diff --git a/include/items.php b/include/items.php index de0941c3c..a60c10bdd 100755 --- a/include/items.php +++ b/include/items.php @@ -6,6 +6,8 @@ // uncertain if this line is needed and why use Sabre\HTTP\URLUtil; +use Zotlabs\Lib as Zlib; + require_once('include/bbcode.php'); require_once('include/oembed.php'); require_once('include/crypto.php'); @@ -2284,8 +2286,8 @@ function send_status_notifications($post_id,$item) { if(! $notify) return; - require_once('include/enotify.php'); - notification(array( + + Zlib\Enotify::submit(array( 'type' => NOTIFY_COMMENT, 'from_xchan' => $item['author_xchan'], 'to_xchan' => $r[0]['channel_hash'], @@ -2378,8 +2380,7 @@ function tag_deliver($uid, $item_id) { $verb = urldecode(substr($item['verb'],strpos($item['verb'],'#')+1)); if($poke_notify) { - require_once('include/enotify.php'); - notification(array( + Zlib\Enotify::submit(array( 'to_xchan' => $u[0]['channel_hash'], 'from_xchan' => $item['author_xchan'], 'type' => NOTIFY_POKE, @@ -2544,8 +2545,7 @@ function tag_deliver($uid, $item_id) { * Kill two birds with one stone. As long as we're here, send a mention notification. */ - require_once('include/enotify.php'); - notification(array( + Zlib\Enotify::submit(array( 'to_xchan' => $u[0]['channel_hash'], 'from_xchan' => $item['author_xchan'], 'type' => NOTIFY_TAGSELF, @@ -3046,7 +3046,6 @@ function mail_store($arr) { ); } else { - require_once('include/enotify.php'); $notif_params = array( 'from_xchan' => $arr['from_xchan'], @@ -3057,7 +3056,7 @@ function mail_store($arr) { 'otype' => 'mail' ); - notification($notif_params); + Zlib\Enotify::submit($notif_params); } call_hooks('post_mail_end',$arr); diff --git a/include/network.php b/include/network.php index 3e5263d3e..9fe0fd9cf 100644 --- a/include/network.php +++ b/include/network.php @@ -1819,8 +1819,6 @@ function service_plink($contact, $guid) { function format_and_send_email($sender,$xchan,$item) { - require_once('include/enotify.php'); - $title = $item['title']; $body = $item['body']; @@ -1885,7 +1883,7 @@ function format_and_send_email($sender,$xchan,$item) { // use the EmailNotification library to send the message - enotify::send(array( + Zotlabs\Lib\Enotify::send(array( 'fromName' => $product, 'fromEmail' => $sender_email, 'replyTo' => $sender_email, diff --git a/include/notify.php b/include/notify.php deleted file mode 100644 index 2b032b56b..000000000 --- a/include/notify.php +++ /dev/null @@ -1,37 +0,0 @@ - $item['llink'], - 'name' => $item['author']['xchan_name'], - 'url' => $item['author']['xchan_url'], - 'photo' => $item['author']['xchan_photo_s'], - 'when' => relative_date($item['created']), - 'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'), - 'message' => strip_tags(bbcode($itemem_text)) - ); - -} - diff --git a/include/zot.php b/include/zot.php index 8ba03ff5c..64f1c0c0e 100644 --- a/include/zot.php +++ b/include/zot.php @@ -505,8 +505,7 @@ function zot_refresh($them, $channel = null, $force = false) { if($new_connection) { if($new_perms != $previous_perms) Zotlabs\Daemon\Master::Summon(array('Notifier','permission_create',$new_connection[0]['abook_id'])); - require_once('include/enotify.php'); - notification(array( + Zotlabs\Lib\Enotify::submit(array( 'type' => NOTIFY_INTRO, 'from_xchan' => $x['hash'], 'to_xchan' => $channel['channel_hash'], -- cgit v1.2.3 From e00b8a70829213a4333a53a097c2c498d529f5d6 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Tue, 24 May 2016 06:15:42 -0400 Subject: Delete wiki (in progress) --- include/wiki.php | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/include/wiki.php b/include/wiki.php index 7cd838f95..0f00cd122 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -7,14 +7,6 @@ use \Zotlabs\Storage\GitRepo as GitRepo; define ( 'WIKI_ITEM_RESOURCE_TYPE', 'wiki' ); -function wiki_create() { - -} - -function wiki_delete() { - -} - function wiki_list($nick, $observer_hash) { if (local_channel() || remote_channel()) { $sql_extra = item_permissions_sql(get_channel_by_nick($nick)['channel_id'], $observer_hash); @@ -36,7 +28,7 @@ function wiki_pages() { function wiki_init_wiki($channel, $name) { // Store the path as a relative path, but pass absolute path to mkdir $path = 'store/[data]/git/'.$channel['channel_address'].'/wiki/'.$name; - if (!mkdir(__DIR__ . '/../' . $path, 0770, true)) { + if (!os_mkdir(__DIR__ . '/../' . $path, 0770, true)) { logger('Error creating wiki path: ' . $name); return null; } @@ -109,3 +101,22 @@ function wiki_create_wiki($channel, $observer_hash, $name, $acl) { return array('item' => null, 'success' => false); } } + +function wiki_delete_wiki($resource_id) { + $item = q("SELECT id FROM item WHERE resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0 limit 1", + dbesc(WIKI_ITEM_RESOURCE_TYPE), + dbesc($resource_id) + ); + if (!$item) { + return array('items' => null, 'success' => false); + } else { + $drop = drop_item($item[0]['id'],false,DROPITEM_NORMAL,true); + $object = json_decode($item[0]['object'], true); + $abs_path = __DIR__ . '/../' . $object['path']; + logger('path to delete: ' . $abs_path); + $pathdel = true; + //$pathdel = rrmdir($abs_path); + + return array('item' => $item, 'success' => (($drop === 1 && $pathdel) ? true : false)); + } +} -- cgit v1.2.3 From 84ba6393ad32406a9875044aef2d031c7d0d7a46 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 24 May 2016 16:36:55 -0700 Subject: relocate index and db --- include/cli_startup.php | 4 +-- include/dba/dba_driver.php | 69 ++++++++++++++++++++++++++-------------------- include/network.php | 2 +- include/text.php | 4 +-- 4 files changed, 44 insertions(+), 35 deletions(-) (limited to 'include') diff --git a/include/cli_startup.php b/include/cli_startup.php index a33f7acb0..b89d5f1bb 100644 --- a/include/cli_startup.php +++ b/include/cli_startup.php @@ -14,7 +14,7 @@ function cli_startup() { App::init(); - if(is_null($db)) { + if(! DBA::$connected) { @include(".htconfig.php"); $a->convert(); @@ -26,7 +26,7 @@ function cli_startup() { date_default_timezone_set(App::$timezone); require_once('include/dba/dba_driver.php'); - $db = dba_factory($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type); + $db = DBA::dba_factory($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type); unset($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type); }; diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php index e15e107a8..52613a45e 100755 --- a/include/dba/dba_driver.php +++ b/include/dba/dba_driver.php @@ -1,4 +1,6 @@ connected) { - $dns = (($dbtype == DBTYPE_POSTGRES) ? 'postgres' : 'mysql') + if(is_object(self::$dba) && self::$dba->connected) { + $dns = ((self::$dbtype == DBTYPE_POSTGRES) ? 'postgres' : 'mysql') . ':host=' . $server . (is_null($port) ? '' : ';port=' . $port) . ';dbname=' . $db; - $dba->pdo_set(array($dns,$user,$pass)); + self::$dba->pdo_set(array($dns,$user,$pass)); } - define('NULL_DATE', $dba->get_null_date()); - define('ACTIVE_DBTYPE', $dbtype); - return $dba; + define('NULL_DATE', self::$dba->get_null_date()); + define('ACTIVE_DBTYPE', self::$dbtype); + return self::$dba; +} + } /** @@ -232,8 +241,8 @@ function printable($s) { function dbg($state) { global $db; - if($db) - $db->dbg($state); + if(\DBA::$dba) + \DBA::$dba->dbg($state); } /** @@ -249,19 +258,19 @@ function dbg($state) { function dbesc($str) { global $db; - if($db && $db->connected) - return($db->escape($str)); + if(\DBA::$dba && \DBA::$dba->connected) + return(\DBA::$dba->escape($str)); else return(str_replace("'", "\\'", $str)); } function dbescbin($str) { global $db; - return $db->escapebin($str); + return \DBA::$dba->escapebin($str); } function dbunescbin($str) { global $db; - return $db->unescapebin($str); + return \DBA::$dba->unescapebin($str); } function dbescdate($date) { @@ -275,27 +284,27 @@ function dbescdate($date) { function db_quoteinterval($txt) { global $db; - return $db->quote_interval($txt); + return \DBA::$dba->quote_interval($txt); } function dbesc_identifier($str) { global $db; - return $db->escape_identifier($str); + return \DBA::$dba->escape_identifier($str); } function db_utcnow() { global $db; - return $db->utcnow(); + return \DBA::$dba->utcnow(); } function db_optimizetable($table) { global $db; - $db->optimize_table($table); + \DBA::$dba->optimize_table($table); } function db_concat($fld, $sep) { global $db; - return $db->concat($fld, $sep); + return \DBA::$dba->concat($fld, $sep); } // Function: q($sql,$args); @@ -325,7 +334,7 @@ function q($sql) { $args = func_get_args(); unset($args[0]); - if($db && $db->connected) { + if(\DBA::$dba && \DBA::$dba->connected) { $stmt = vsprintf($sql, $args); if($stmt === false) { if(version_compare(PHP_VERSION, '5.4.0') >= 0) @@ -356,8 +365,8 @@ function q($sql) { function dbq($sql) { global $db; - if($db && $db->connected) - $ret = $db->q($sql); + if(\DBA::$dba && \DBA::$dba->connected) + $ret = \DBA::$dba->q($sql); else $ret = false; @@ -423,8 +432,8 @@ function db_getfunc($f) { function db_logger($s,$level = LOGGER_NORMAL,$syslog = LOG_INFO) { global $db; - $saved = $db->debug; - $db->debug = false; + $saved = \DBA::$dba->debug; + \DBA::$dba->debug = false; logger($s,$level,$syslog); - $db->debug = $saved; + \DBA::$dba->debug = $saved; } \ No newline at end of file diff --git a/include/network.php b/include/network.php index 9fe0fd9cf..35f4d113f 100644 --- a/include/network.php +++ b/include/network.php @@ -2040,7 +2040,7 @@ function get_site_info() { 'admin' => $admin, 'site_name' => (($site_name) ? $site_name : ''), 'platform' => Zotlabs\Lib\System::get_platform_name(), - 'dbdriver' => $db->getdriver(), + 'dbdriver' => DBA::$dba->getdriver(), 'lastpoll' => get_config('system','lastpoll'), 'info' => (($site_info) ? $site_info : ''), 'channels_total' => $channels_total_stat, diff --git a/include/text.php b/include/text.php index 91aeae989..21692e74f 100644 --- a/include/text.php +++ b/include/text.php @@ -571,7 +571,7 @@ function logger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) { global $a; global $db; - if((App::$module == 'install') || (! ($db && $db->connected))) + if((App::$module == 'install') || (! (DBA::$dba && DBA::$dba->connected))) return; $debugging = get_config('system', 'debugging'); @@ -652,7 +652,7 @@ function dlogger($msg, $level = 0) { global $a; global $db; - if((App::$module == 'install') || (! ($db && $db->connected))) + if((App::$module == 'install') || (! (DBA::$dba && DBA::$dba->connected))) return; $debugging = get_config('system','debugging'); -- cgit v1.2.3 From 516c43ba154dc43ec0ef6135fb0a9732d0185a6f Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 24 May 2016 17:54:45 -0700 Subject: more work associated with DBA and index.php shuffle --- include/cli_startup.php | 22 ++++--- include/dba/dba_driver.php | 139 +++++++++++++++++++++------------------------ include/text.php | 25 ++++---- 3 files changed, 89 insertions(+), 97 deletions(-) (limited to 'include') diff --git a/include/cli_startup.php b/include/cli_startup.php index b89d5f1bb..1436fe1ef 100644 --- a/include/cli_startup.php +++ b/include/cli_startup.php @@ -6,7 +6,7 @@ require_once('boot.php'); function cli_startup() { - global $a, $db, $default_timezone; + global $default_timezone; if(is_null($a)) { $a = new miniApp; @@ -14,21 +14,19 @@ function cli_startup() { App::init(); - if(! DBA::$connected) { - @include(".htconfig.php"); + @include(".htconfig.php"); - $a->convert(); + $a->convert(); - if(! defined('UNO')) - define('UNO', 0); + if(! defined('UNO')) + define('UNO', 0); - App::$timezone = ((x($default_timezone)) ? $default_timezone : 'UTC'); - date_default_timezone_set(App::$timezone); + App::$timezone = ((x($default_timezone)) ? $default_timezone : 'UTC'); + date_default_timezone_set(App::$timezone); - require_once('include/dba/dba_driver.php'); - $db = DBA::dba_factory($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type); - unset($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type); - }; + require_once('include/dba/dba_driver.php'); + DBA::dba_factory($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type); + unset($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type); App::$session = new Zotlabs\Web\Session(); App::$session->init(); diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php index 52613a45e..0ab5830ed 100755 --- a/include/dba/dba_driver.php +++ b/include/dba/dba_driver.php @@ -1,74 +1,77 @@ connected) { - $dns = ((self::$dbtype == DBTYPE_POSTGRES) ? 'postgres' : 'mysql') - . ':host=' . $server . (is_null($port) ? '' : ';port=' . $port) - . ';dbname=' . $db; - self::$dba->pdo_set(array($dns,$user,$pass)); - } + if(is_object(self::$dba) && self::$dba->connected) { + $dns = ((self::$dbtype == DBTYPE_POSTGRES) ? 'postgres' : 'mysql') + . ':host=' . $server . (is_null($port) ? '' : ';port=' . $port) + . ';dbname=' . $db; + self::$dba->pdo_set(array($dns,$user,$pass)); + } - define('NULL_DATE', self::$dba->get_null_date()); - define('ACTIVE_DBTYPE', self::$dbtype); - return self::$dba; -} + define('NULL_DATE', self::$dba->get_null_date()); + define('ACTIVE_DBTYPE', self::$dbtype); + return self::$dba; + } } @@ -256,7 +259,6 @@ function dbg($state) { * @return Return an escaped string of the value to pass to a DB query. */ function dbesc($str) { - global $db; if(\DBA::$dba && \DBA::$dba->connected) return(\DBA::$dba->escape($str)); @@ -264,12 +266,10 @@ function dbesc($str) { return(str_replace("'", "\\'", $str)); } function dbescbin($str) { - global $db; return \DBA::$dba->escapebin($str); } function dbunescbin($str) { - global $db; return \DBA::$dba->unescapebin($str); } @@ -283,36 +283,25 @@ function dbescdate($date) { } function db_quoteinterval($txt) { - global $db; return \DBA::$dba->quote_interval($txt); } function dbesc_identifier($str) { - global $db; return \DBA::$dba->escape_identifier($str); } function db_utcnow() { - global $db; return \DBA::$dba->utcnow(); } function db_optimizetable($table) { - global $db; \DBA::$dba->optimize_table($table); } function db_concat($fld, $sep) { - global $db; return \DBA::$dba->concat($fld, $sep); } -// Function: q($sql,$args); -// Description: execute SQL query with printf style args. -// Example: $r = q("SELECT * FROM `%s` WHERE `uid` = %d", -// 'user', 1); - - /** * @brief Execute a SQL query with printf style args. * @@ -328,8 +317,8 @@ function db_concat($fld, $sep) { * @param string $sql The SQL query to execute * @return bool|array */ + function q($sql) { - global $db; $args = func_get_args(); unset($args[0]); @@ -343,13 +332,14 @@ function q($sql) { else db_logger('dba: vsprintf error: ' . print_r(debug_backtrace(), true),LOGGER_NORMAL,LOG_CRIT); } - return $db->q($stmt); + return \DBA::$dba->q($stmt); } /* * This will happen occasionally trying to store the * session data after abnormal program termination */ + db_logger('dba: no database: ' . print_r($args,true),LOGGER_NORMAL,LOG_CRIT); return false; @@ -363,7 +353,6 @@ function q($sql) { * @param string $sql The SQL query to execute */ function dbq($sql) { - global $db; if(\DBA::$dba && \DBA::$dba->connected) $ret = \DBA::$dba->q($sql); @@ -427,11 +416,11 @@ function db_getfunc($f) { // The logger function may make DB calls internally to query the system logging parameters. // This can cause a recursion if database debugging is enabled. -// So this function preserves the current database debugging state and then turns it off while -// doing the logger() call +// So this function preserves the current database debugging state and then turns it off +// temporarily while doing the logger() call function db_logger($s,$level = LOGGER_NORMAL,$syslog = LOG_INFO) { - global $db; + $saved = \DBA::$dba->debug; \DBA::$dba->debug = false; logger($s,$level,$syslog); diff --git a/include/text.php b/include/text.php index 21692e74f..caaef664f 100644 --- a/include/text.php +++ b/include/text.php @@ -567,21 +567,25 @@ function attribute_contains($attr, $s) { */ function logger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) { - // turn off logger in install mode - global $a; - global $db; - - if((App::$module == 'install') || (! (DBA::$dba && DBA::$dba->connected))) - return; - $debugging = get_config('system', 'debugging'); - $loglevel = intval(get_config('system', 'loglevel')); - $logfile = get_config('system', 'logfile'); + if(App::$module == 'setup' && is_writable('install.log')) { + $debugging = true; + $logfile = 'install.log'; + $loglevel = LOGGER_ALL; + } + else { + $debugging = get_config('system', 'debugging'); + $loglevel = intval(get_config('system', 'loglevel')); + $logfile = get_config('system', 'logfile'); + } if((! $debugging) || (! $logfile) || ($level > $loglevel)) return; $where = ''; + + // We require > 5.4 but leave the version check so that install issues (including version) can be logged + if(version_compare(PHP_VERSION, '5.4.0') >= 0) { $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); $where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': '; @@ -590,7 +594,8 @@ function logger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) { $s = datetime_convert() . ':' . log_priority_str($priority) . ':' . session_id() . ':' . $where . $msg . PHP_EOL; $pluginfo = array('filename' => $logfile, 'loglevel' => $level, 'message' => $s,'priority' => $priority, 'logged' => false); - call_hooks('logger',$pluginfo); + if(! (App::$module == 'setup')) + call_hooks('logger',$pluginfo); if(! $pluginfo['logged']) @file_put_contents($pluginfo['filename'], $pluginfo['message'], FILE_APPEND); -- cgit v1.2.3 From f9a295a23627cf272e14559b8a11e3780de43ea1 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 24 May 2016 19:25:10 -0700 Subject: Add space between project name and server type --- include/config.php | 2 +- include/zot.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/config.php b/include/config.php index 12768f4da..29ea10b5a 100644 --- a/include/config.php +++ b/include/config.php @@ -44,7 +44,6 @@ * The category of the configuration value */ function load_config($family) { - global $a; if(! array_key_exists($family, App::$config)) App::$config[$family] = array(); @@ -110,6 +109,7 @@ function get_config($family, $key) { * The configuration key to query * @return mixed */ + function get_config_from_storage($family, $key) { $ret = q("SELECT * FROM config WHERE cat = '%s' AND k = '%s' LIMIT 1", dbesc($family), diff --git a/include/zot.php b/include/zot.php index 64f1c0c0e..cfe524135 100644 --- a/include/zot.php +++ b/include/zot.php @@ -3948,7 +3948,7 @@ function zotinfo($arr) { $ret['site']['sellpage'] = get_config('system','sellpage'); $ret['site']['location'] = get_config('system','site_location'); $ret['site']['realm'] = get_directory_realm(); - $ret['site']['project'] = Zotlabs\Lib\System::get_platform_name() . Zotlabs\Lib\System::get_server_role(); + $ret['site']['project'] = Zotlabs\Lib\System::get_platform_name() . ' ' . Zotlabs\Lib\System::get_server_role(); } -- cgit v1.2.3 From 80f2ba640ec528bd43db243122a69e765703b7c0 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 24 May 2016 20:49:23 -0700 Subject: code cleanup --- include/Import/import_diaspora.php | 1 - include/account.php | 3 ++- include/acl_selectors.php | 4 ---- include/activities.php | 1 - include/api.php | 3 --- include/bb2diaspora.php | 2 -- include/bbcode.php | 3 --- include/config.php | 14 +++----------- include/connections.php | 4 +--- include/conversation.php | 8 +++----- include/datetime.php | 1 - include/follow.php | 1 - include/help.php | 2 -- include/language.php | 6 ------ include/network.php | 9 --------- include/oembed.php | 2 +- include/photo/photo_driver.php | 6 +----- include/photos.php | 2 -- include/plugin.php | 11 +++++------ include/text.php | 28 ++++++++-------------------- include/widgets.php | 1 - include/zot.php | 4 ---- 22 files changed, 24 insertions(+), 92 deletions(-) (limited to 'include') diff --git a/include/Import/import_diaspora.php b/include/Import/import_diaspora.php index a94e73395..b664badf1 100644 --- a/include/Import/import_diaspora.php +++ b/include/Import/import_diaspora.php @@ -6,7 +6,6 @@ require_once('include/follow.php'); require_once('include/photo/photo_driver.php'); function import_diaspora($data) { - $a = get_app(); $account = App::get_account(); if(! $account) diff --git a/include/account.php b/include/account.php index e367e002d..a442f3073 100644 --- a/include/account.php +++ b/include/account.php @@ -656,7 +656,8 @@ function account_service_class_allows($aid, $property, $usage = false) { * @todo Should we merge this with account_service_class_fetch()? */ function service_class_fetch($uid, $property) { - $a = get_app(); + + if($uid == local_channel()) { $service_class = App::$account['account_service_class']; } diff --git a/include/acl_selectors.php b/include/acl_selectors.php index 886574714..1f97a7a7b 100644 --- a/include/acl_selectors.php +++ b/include/acl_selectors.php @@ -11,8 +11,6 @@ require_once("include/PermissionDescription.php"); function group_select($selname,$selclass,$preselected = false,$size = 4) { - $a = get_app(); - $o = ''; $o .= "\r\n"; - $r = q("SELECT * FROM `groups` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `name` ASC", + $r = q("SELECT * FROM `groups` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `gname` ASC", intval(local_channel()) ); @@ -32,7 +32,7 @@ function group_select($selname,$selclass,$preselected = false,$size = 4) { $selected = " selected=\"selected\" "; else $selected = ''; - $trimmed = mb_substr($rr['name'],0,12); + $trimmed = mb_substr($rr['gname'],0,12); $o .= "\r\n"; } diff --git a/include/channel.php b/include/channel.php index 35084741f..0e5490c86 100644 --- a/include/channel.php +++ b/include/channel.php @@ -337,7 +337,7 @@ function create_identity($arr) { // Not checking return value. // It's ok for this to fail if it's an imported channel, and therefore the hash is a duplicate - $r = q("INSERT INTO profile ( aid, uid, profile_guid, profile_name, is_default, publish, name, photo, thumb) + $r = q("INSERT INTO profile ( aid, uid, profile_guid, profile_name, is_default, publish, fullname, photo, thumb) VALUES ( %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s') ", intval($ret['channel']['channel_account_id']), intval($newuid), @@ -392,7 +392,7 @@ function create_identity($arr) { // if our role_permissions indicate that we're using a default collection ACL, add it. if(is_array($role_permissions) && $role_permissions['default_collection']) { - $r = q("select hash from groups where uid = %d and name = '%s' limit 1", + $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval($newuid), dbesc( t('Friends') ) ); @@ -561,7 +561,7 @@ function identity_basic_export($channel_id, $items = false) { // All other term types will be included in items, if requested. - $r = q("select * from term where type in (%d,%d) and uid = %d", + $r = q("select * from term where ttype in (%d,%d) and uid = %d", intval(TERM_SAVEDSEARCH), intval(TERM_THING), intval($channel_id) @@ -1257,7 +1257,7 @@ function advanced_profile(&$a) { if(! perm_is_allowed(App::$profile['profile_uid'],get_observer_hash(),'view_profile')) return ''; - if(App::$profile['name']) { + if(App::$profile['fullname']) { $profile_fields_basic = get_profile_fields_basic(); $profile_fields_advanced = get_profile_fields_advanced(); @@ -1281,7 +1281,7 @@ function advanced_profile(&$a) { $profile = array(); - $profile['fullname'] = array( t('Full Name:'), App::$profile['name'] ) ; + $profile['fullname'] = array( t('Full Name:'), App::$profile['fullname'] ) ; if(App::$profile['gender']) $profile['gender'] = array( t('Gender:'), App::$profile['gender'] ); @@ -1329,8 +1329,8 @@ function advanced_profile(&$a) { if(App::$profile['marital']) $profile['marital'] = array( t('Status:'), App::$profile['marital']); - if(App::$profile['with']) - $profile['marital']['with'] = bbcode(App::$profile['with']); + if(App::$profile['partner']) + $profile['marital']['partner'] = bbcode(App::$profile['partner']); if(strlen(App::$profile['howlong']) && App::$profile['howlong'] !== NULL_DATE) { $profile['howlong'] = relative_date(App::$profile['howlong'], t('for %1$d %2$s')); @@ -1370,7 +1370,7 @@ function advanced_profile(&$a) { if($txt = prepare_text(App::$profile['romance'])) $profile['romance'] = array( t('Love/Romance:'), $txt); - if($txt = prepare_text(App::$profile['work'])) $profile['work'] = array( t('Work/employment:'), $txt); + if($txt = prepare_text(App::$profile['employment'])) $profile['employment'] = array( t('Work/employment:'), $txt); if($txt = prepare_text(App::$profile['education'])) $profile['education'] = array( t('School/education:'), $txt ); @@ -1658,7 +1658,7 @@ function get_profile_fields_basic($filter = 0) { $profile_fields_basic = (($filter == 0) ? get_config('system','profile_fields_basic') : null); if(! $profile_fields_basic) - $profile_fields_basic = array('name','pdesc','chandesc','gender','dob','dob_tz','address','locality','region','postal_code','country_name','marital','sexual','homepage','hometown','keywords','about','contact'); + $profile_fields_basic = array('fullname','pdesc','chandesc','gender','dob','dob_tz','address','locality','region','postal_code','country_name','marital','sexual','homepage','hometown','keywords','about','contact'); $x = array(); if($profile_fields_basic) @@ -1673,7 +1673,7 @@ function get_profile_fields_advanced($filter = 0) { $basic = get_profile_fields_basic($filter); $profile_fields_advanced = (($filter == 0) ? get_config('system','profile_fields_advanced') : null); if(! $profile_fields_advanced) - $profile_fields_advanced = array('with','howlong','politic','religion','likes','dislikes','interest','channels','music','book','film','tv','romance','work','education'); + $profile_fields_advanced = array('partner','howlong','politic','religion','likes','dislikes','interest','channels','music','book','film','tv','romance','employment','education'); $x = array(); if($basic) diff --git a/include/contact_widgets.php b/include/contact_widgets.php index 14d26e257..85c46b0d1 100644 --- a/include/contact_widgets.php +++ b/include/contact_widgets.php @@ -39,7 +39,7 @@ function fileas_widget($baseurl,$selected = '') { return ''; $terms = array(); - $r = q("select distinct(term) from term where uid = %d and type = %d order by term asc", + $r = q("select distinct(term) from term where uid = %d and ttype = %d order by term asc", intval(local_channel()), intval(TERM_FILE) ); @@ -72,7 +72,7 @@ function categories_widget($baseurl,$selected = '') { from term join item on term.oid = item.id where item.uid = %d and term.uid = item.uid - and term.type = %d + and term.ttype = %d and term.otype = %d and item.owner_xchan = '%s' and item.item_wall = 1 diff --git a/include/event.php b/include/event.php index db67dac64..81e403d37 100644 --- a/include/event.php +++ b/include/event.php @@ -854,12 +854,12 @@ function event_store_item($arr, $event) { if(($arr['term']) && (is_array($arr['term']))) { foreach($arr['term'] as $t) { - q("insert into term (uid,oid,otype,type,term,url) + q("insert into term (uid,oid,otype,ttype,term,url) values(%d,%d,%d,%d,'%s','%s') ", intval($arr['uid']), intval($r[0]['id']), intval(TERM_OBJ_POST), - intval($t['type']), + intval($t['ttype']), dbesc($t['term']), dbesc($t['url']) ); diff --git a/include/feedutils.php b/include/feedutils.php index f370c540a..fb938cfdd 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -515,7 +515,7 @@ function get_atom_elements($feed, $item, &$author) { if($termterm) { $terms[] = array( 'otype' => TERM_OBJ_POST, - 'type' => $termtype, + 'ttype' => $termtype, 'url' => $termurl, 'term' => $termterm, ); diff --git a/include/group.php b/include/group.php index 748ec0c13..a4938b848 100644 --- a/include/group.php +++ b/include/group.php @@ -18,7 +18,7 @@ function group_add($uid,$name,$public = 0) { intval($r) ); if(count($z) && $z[0]['deleted']) { - /*$r = q("UPDATE `groups` SET `deleted` = 0 WHERE `uid` = %d AND `name` = '%s' LIMIT 1", + /*$r = q("UPDATE `groups` SET `deleted` = 0 WHERE `uid` = %d AND `gname` = '%s' LIMIT 1", intval($uid), dbesc($name) );*/ @@ -38,7 +38,7 @@ function group_add($uid,$name,$public = 0) { } while($dups == true); - $r = q("INSERT INTO `groups` ( hash, uid, visible, name ) + $r = q("INSERT INTO `groups` ( hash, uid, visible, gname ) VALUES( '%s', %d, %d, '%s' ) ", dbesc($hash), intval($uid), @@ -57,7 +57,7 @@ function group_add($uid,$name,$public = 0) { function group_rmv($uid,$name) { $ret = false; if(x($uid) && x($name)) { - $r = q("SELECT id, hash FROM `groups` WHERE `uid` = %d AND `name` = '%s' LIMIT 1", + $r = q("SELECT id, hash FROM `groups` WHERE `uid` = %d AND `gname` = '%s' LIMIT 1", intval($uid), dbesc($name) ); @@ -108,7 +108,7 @@ function group_rmv($uid,$name) { ); // remove group - $r = q("UPDATE `groups` SET `deleted` = 1 WHERE `uid` = %d AND `name` = '%s'", + $r = q("UPDATE `groups` SET `deleted` = 1 WHERE `uid` = %d AND `gname` = '%s'", intval($uid), dbesc($name) ); @@ -125,7 +125,7 @@ function group_rmv($uid,$name) { function group_byname($uid,$name) { if((! $uid) || (! strlen($name))) return false; - $r = q("SELECT * FROM `groups` WHERE `uid` = %d AND `name` = '%s' LIMIT 1", + $r = q("SELECT * FROM `groups` WHERE `uid` = %d AND `gname` = '%s' LIMIT 1", intval($uid), dbesc($name) ); @@ -232,13 +232,13 @@ function mini_group_select($uid,$group = '') { $grps = array(); $o = ''; - $r = q("SELECT * FROM `groups` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `name` ASC", + $r = q("SELECT * FROM `groups` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `gname` ASC", intval($uid) ); $grps[] = array('name' => '', 'hash' => '0', 'selected' => ''); if(count($r)) { foreach($r as $rr) { - $grps[] = array('name' => $rr['name'], 'id' => $rr['hash'], 'selected' => (($group == $rr['hash']) ? 'true' : '')); + $grps[] = array('name' => $rr['gname'], 'id' => $rr['hash'], 'selected' => (($group == $rr['hash']) ? 'true' : '')); } } @@ -271,7 +271,7 @@ function group_side($every="connections",$each="group",$edit = false, $group_id ); - $r = q("SELECT * FROM `groups` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `name` ASC", + $r = q("SELECT * FROM `groups` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `gname` ASC", intval($_SESSION['uid']) ); $member_of = array(); @@ -296,7 +296,7 @@ function group_side($every="connections",$each="group",$edit = false, $group_id 'id' => $rr['id'], 'enc_cid' => base64url_encode($cid), 'cid' => $cid, - 'text' => $rr['name'], + 'text' => $rr['gname'], 'selected' => $selected, 'href' => (($mode == 0) ? $each.'?f=&gid='.$rr['id'] : $each."/".$rr['id']) . ((x($_GET,'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET,'order')) ? '&order=' . $_GET['order'] : ''), 'edit' => $groupedit, @@ -340,7 +340,7 @@ function expand_groups($a) { function member_of($c) { - $r = q("SELECT `groups`.`name`, `groups`.`id` FROM `groups` LEFT JOIN `group_member` ON `group_member`.`gid` = `groups`.`id` WHERE `group_member`.`xchan` = '%s' AND `groups`.`deleted` = 0 ORDER BY `groups`.`name` ASC ", + $r = q("SELECT `groups`.`gname`, `groups`.`id` FROM `groups` LEFT JOIN `group_member` ON `group_member`.`gid` = `groups`.`id` WHERE `group_member`.`xchan` = '%s' AND `groups`.`deleted` = 0 ORDER BY `groups`.`gname` ASC ", dbesc($c) ); diff --git a/include/import.php b/include/import.php index 132306621..d094fb582 100644 --- a/include/import.php +++ b/include/import.php @@ -332,7 +332,9 @@ function import_apps($channel,$apps) { ); if($x) { foreach($term as $t) { - store_item_tag($channel['channel_id'],$x[0]['id'],TERM_OBJ_APP,$t['type'],escape_tags($t['term']),escape_tags($t['url'])); + if(array_key_exists('type',$t)) + $t['ttype'] = $t['type']; + store_item_tag($channel['channel_id'],$x[0]['id'],TERM_OBJ_APP,$t['ttype'],escape_tags($t['term']),escape_tags($t['url'])); } } } @@ -400,7 +402,9 @@ function sync_apps($channel,$apps) { if($exists && $term) { foreach($term as $t) { - store_item_tag($channel['channel_id'],$exists['id'],TERM_OBJ_APP,$t['type'],escape_tags($t['term']),escape_tags($t['url'])); + if(array_key_exists('type',$t)) + $t['ttype'] = $t['type']; + store_item_tag($channel['channel_id'],$exists['id'],TERM_OBJ_APP,$t['ttype'],escape_tags($t['term']),escape_tags($t['url'])); } } @@ -436,7 +440,9 @@ function sync_apps($channel,$apps) { ); if($x) { foreach($term as $t) { - store_item_tag($channel['channel_id'],$x[0]['id'],TERM_OBJ_APP,$t['type'],escape_tags($t['term']),escape_tags($t['url'])); + if(array_key_exists('type',$t)) + $t['ttype'] = $t['type']; + store_item_tag($channel['channel_id'],$x[0]['id'],TERM_OBJ_APP,$t['ttype'],escape_tags($t['term']),escape_tags($t['url'])); } } } diff --git a/include/items.php b/include/items.php index a60c10bdd..b283ed3ab 100755 --- a/include/items.php +++ b/include/items.php @@ -1182,8 +1182,8 @@ function encode_item_terms($terms,$mirror = false) { if($terms) { foreach($terms as $term) { - if(in_array($term['type'],$allowed_export_terms)) - $ret[] = array('tag' => $term['term'], 'url' => $term['url'], 'type' => termtype($term['type'])); + if(in_array($term['ttype'],$allowed_export_terms)) + $ret[] = array('tag' => $term['term'], 'url' => $term['url'], 'ttype' => termtype($term['type'])); } } @@ -1240,39 +1240,41 @@ function decode_tags($t) { $ret = array(); foreach($t as $x) { $tag = array(); + if(array_key_exists('type',$x)) + $x['ttype'] = $x['type']; $tag['term'] = htmlspecialchars($x['tag'], ENT_COMPAT, 'UTF-8', false); $tag['url'] = htmlspecialchars($x['url'], ENT_COMPAT, 'UTF-8', false); - switch($x['type']) { + switch($x['ttype']) { case 'hashtag': - $tag['type'] = TERM_HASHTAG; + $tag['ttype'] = TERM_HASHTAG; break; case 'mention': - $tag['type'] = TERM_MENTION; + $tag['ttype'] = TERM_MENTION; break; case 'category': - $tag['type'] = TERM_CATEGORY; + $tag['ttype'] = TERM_CATEGORY; break; case 'private_category': - $tag['type'] = TERM_PCATEGORY; + $tag['ttype'] = TERM_PCATEGORY; break; case 'file': - $tag['type'] = TERM_FILE; + $tag['ttype'] = TERM_FILE; break; case 'search': - $tag['type'] = TERM_SEARCH; + $tag['ttype'] = TERM_SEARCH; break; case 'thing': - $tag['type'] = TERM_THING; + $tag['ttype'] = TERM_THING; break; case 'bookmark': - $tag['type'] = TERM_BOOKMARK; + $tag['ttype'] = TERM_BOOKMARK; break; case 'communitytag': - $tag['type'] = TERM_COMMUNITYTAG; + $tag['ttype'] = TERM_COMMUNITYTAG; break; default: case 'unknown': - $tag['type'] = TERM_UNKNOWN; + $tag['ttype'] = TERM_UNKNOWN; break; } $ret[] = $tag; @@ -1855,12 +1857,12 @@ function item_store($arr, $allow_exec = false, $deliver = true) { if(($terms) && (is_array($terms))) { foreach($terms as $t) { - q("insert into term (uid,oid,otype,type,term,url) + q("insert into term (uid,oid,otype,ttype,term,url) values(%d,%d,%d,%d,'%s','%s') ", intval($arr['uid']), intval($current_post), intval(TERM_OBJ_POST), - intval($t['type']), + intval($t['ttype']), dbesc($t['term']), dbesc($t['url']) ); @@ -2134,12 +2136,12 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) { if(is_array($terms)) { foreach($terms as $t) { - q("insert into term (uid,oid,otype,type,term,url) + q("insert into term (uid,oid,otype,ttype,term,url) values(%d,%d,%d,%d,'%s','%s') ", intval($uid), intval($orig_post_id), intval(TERM_OBJ_POST), - intval($t['type']), + intval($t['ttype']), dbesc($t['term']), dbesc($t['url']) ); @@ -2720,7 +2722,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent) { foreach($tags as $tt) { $tt = trim($tt); if($tt) { - q("insert into term (uid,oid,otype,type,term,url) + q("insert into term (uid,oid,otype,ttype,term,url) values(%d,%d,%d,%d,'%s','%s') ", intval($channel['channel_id']), intval($item_id), @@ -2863,7 +2865,7 @@ function check_item_source($uid, $item) { foreach($words as $word) { if(substr($word,0,1) === '#' && $tags) { foreach($tags as $t) - if((($t['type'] == TERM_HASHTAG) || ($t['type'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*'))) + if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*'))) return true; } elseif((strpos($word,'/') === 0) && preg_match($word,$text)) @@ -2916,7 +2918,7 @@ function post_is_importable($item,$abook) { continue; if(substr($word,0,1) === '#' && $tags) { foreach($tags as $t) - if((($t['type'] == TERM_HASHTAG) || ($t['type'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*'))) + if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*'))) return false; } elseif((strpos($word,'/') === 0) && preg_match($word,$text)) @@ -2937,7 +2939,7 @@ function post_is_importable($item,$abook) { continue; if(substr($word,0,1) === '#' && $tags) { foreach($tags as $t) - if((($t['type'] == TERM_HASHTAG) || ($t['type'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*'))) + if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*'))) return true; } elseif((strpos($word,'/') === 0) && preg_match($word,$text)) @@ -3214,7 +3216,7 @@ function item_getfeedtags($item) { if(count($terms)) { foreach($terms as $term) { - if(($term['type'] == TERM_HASHTAG) || ($term['type'] == TERM_COMMUNITYTAG)) + if(($term['ttype'] == TERM_HASHTAG) || ($term['ttype'] == TERM_COMMUNITYTAG)) $ret[] = array('#',$term['url'],$term['term']); else $ret[] = array('@',$term['url'],$term['term']); @@ -3685,7 +3687,7 @@ function fetch_post_tags($items,$link = false) { for($x = 0; $x < count($items); $x ++) { if($tags) { foreach($tags as $t) { - if(($link) && ($t['type'] == TERM_MENTION)) + if(($link) && ($t['ttype'] == TERM_MENTION)) $t['url'] = chanlink_url($t['url']); if(array_key_exists('item_id',$items[$x])) { if($t['oid'] == $items[$x]['item_id']) { @@ -3895,8 +3897,8 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C } $contact_str = ''; - /** @FIXME $group is undefined */ - $contacts = group_get_members($group); + + $contacts = group_get_members($r[0]['id']); if ($contacts) { foreach($contacts as $c) { if($contact_str) @@ -3913,7 +3915,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str)) or allow_gid like '" . protect_sprintf('%<' . dbesc($r[0]['hash']) . '>%') . "' ) and id = parent $item_normal ) "; $x = group_rec_byhash($uid,$r[0]['hash']); - $result['headline'] = sprintf( t('Privacy group: %s'),$x['name']); + $result['headline'] = sprintf( t('Privacy group: %s'),$x['gname']); } elseif($arr['cid'] && $uid) { diff --git a/include/taxonomy.php b/include/taxonomy.php index e43f5e5d0..177215fe8 100644 --- a/include/taxonomy.php +++ b/include/taxonomy.php @@ -20,7 +20,7 @@ function file_tag_file_query($table,$s,$type = 'file') { else $termtype = TERM_CATEGORY; - return sprintf(" AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.type = %d and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ", + return sprintf(" AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.ttype = %d and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ", intval($termtype), protect_sprintf(dbesc($s)) ); @@ -29,14 +29,14 @@ function file_tag_file_query($table,$s,$type = 'file') { function term_query($table,$s,$type = TERM_UNKNOWN, $type2 = '') { if($type2) { - return sprintf(" AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.type in (%d, %d) and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ", + return sprintf(" AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.ttype in (%d, %d) and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ", intval($type), intval($type2), protect_sprintf(dbesc($s)) ); } else { - return sprintf(" AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.type = %d and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ", + return sprintf(" AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.ttype = %d and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ", intval($type), protect_sprintf(dbesc($s)) ); @@ -49,7 +49,7 @@ function store_item_tag($uid,$iid,$otype,$type,$term,$url = '') { return false; $r = q("select * from term - where uid = %d and oid = %d and otype = %d and type = %d + where uid = %d and oid = %d and otype = %d and ttype = %d and term = '%s' and url = '%s' ", intval($uid), intval($iid), @@ -61,7 +61,7 @@ function store_item_tag($uid,$iid,$otype,$type,$term,$url = '') { if($r) return false; - $r = q("insert into term (uid, oid, otype, type, term, url) + $r = q("insert into term (uid, oid, otype, ttype, term, url) values( %d, %d, %d, %d, '%s', '%s') ", intval($uid), intval($iid), @@ -85,7 +85,7 @@ function get_terms_oftype($arr,$type) { foreach($type as $t) foreach($arr as $x) - if($x['type'] == $t) + if($x['ttype'] == $t) $ret[] = $x; return $ret; @@ -93,9 +93,9 @@ function get_terms_oftype($arr,$type) { function format_term_for_display($term) { $s = ''; - if(($term['type'] == TERM_HASHTAG) || ($term['type'] == TERM_COMMUNITYTAG)) + if(($term['ttype'] == TERM_HASHTAG) || ($term['ttype'] == TERM_COMMUNITYTAG)) $s .= '#'; - elseif($term['type'] == TERM_MENTION) + elseif($term['ttype'] == TERM_MENTION) $s .= '@'; else return $s; @@ -142,7 +142,7 @@ function tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $re // Fetch tags $r = q("select term, count(term) as total from term left join item on term.oid = item.id - where term.uid = %d and term.type = %d + where term.uid = %d and term.ttype = %d and otype = %d and item_type = %d and item_private = 0 $sql_options $item_normal group by term order by total desc %s", diff --git a/include/text.php b/include/text.php index 375a89d3f..c57f5fce4 100644 --- a/include/text.php +++ b/include/text.php @@ -810,7 +810,7 @@ function get_mentions($item,$tags) { return $o; foreach($tags as $x) { - if($x['type'] == TERM_MENTION) { + if($x['ttype'] == TERM_MENTION) { $o .= "\t\t" . '' . "\r\n"; $o .= "\t\t" . '' . "\r\n"; } diff --git a/include/widgets.php b/include/widgets.php index b9cb8e50d..17a76c0f4 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -212,13 +212,13 @@ function widget_savedsearch($arr) { $search = ((x($_GET,'search')) ? $_GET['search'] : ''); if(x($_GET,'searchsave') && $search) { - $r = q("select * from `term` where `uid` = %d and `type` = %d and `term` = '%s' limit 1", + $r = q("select * from `term` where `uid` = %d and `ttype` = %d and `term` = '%s' limit 1", intval(local_channel()), intval(TERM_SAVEDSEARCH), dbesc($search) ); if(! $r) { - q("insert into `term` ( `uid`,`type`,`term` ) values ( %d, %d, '%s') ", + q("insert into `term` ( `uid`,`ttype`,`term` ) values ( %d, %d, '%s') ", intval(local_channel()), intval(TERM_SAVEDSEARCH), dbesc($search) @@ -227,7 +227,7 @@ function widget_savedsearch($arr) { } if(x($_GET,'searchremove') && $search) { - q("delete from `term` where `uid` = %d and `type` = %d and `term` = '%s'", + q("delete from `term` where `uid` = %d and `ttype` = %d and `term` = '%s'", intval(local_channel()), intval(TERM_SAVEDSEARCH), dbesc($search) @@ -254,7 +254,7 @@ function widget_savedsearch($arr) { $o = ''; - $r = q("select `tid`,`term` from `term` WHERE `uid` = %d and `type` = %d ", + $r = q("select `tid`,`term` from `term` WHERE `uid` = %d and `ttype` = %d ", intval(local_channel()), intval(TERM_SAVEDSEARCH) ); @@ -296,7 +296,7 @@ function widget_filer($arr) { $selected = ((x($_REQUEST,'file')) ? $_REQUEST['file'] : ''); $terms = array(); - $r = q("select distinct(term) from term where uid = %d and type = %d order by term asc", + $r = q("select distinct(term) from term where uid = %d and ttype = %d order by term asc", intval(local_channel()), intval(TERM_FILE) ); diff --git a/include/zot.php b/include/zot.php index 45c9238b2..af79b5723 100644 --- a/include/zot.php +++ b/include/zot.php @@ -1953,7 +1953,7 @@ function remove_community_tag($sender, $arr, $uid) { return; } - q("delete from term where uid = %d and oid = %d and otype = %d and type in ( %d, %d ) and term = '%s' and url = '%s'", + q("delete from term where uid = %d and oid = %d and otype = %d and ttype in ( %d, %d ) and term = '%s' and url = '%s'", intval($uid), intval($r[0]['id']), intval(TERM_OBJ_POST), @@ -3051,7 +3051,7 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) { } if($groups_changed) { - $r = q("select hash as collection, visible, deleted, name from groups where uid = %d", + $r = q("select hash as collection, visible, deleted, gname as name from groups where uid = %d", intval($uid) ); if($r) @@ -3344,10 +3344,10 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { } } if($found) { - if(($y['name'] != $cl['name']) + if(($y['gname'] != $cl['name']) || ($y['visible'] != $cl['visible']) || ($y['deleted'] != $cl['deleted'])) { - q("update groups set name = '%s', visible = %d, deleted = %d where hash = '%s' and uid = %d", + q("update groups set gname = '%s', visible = %d, deleted = %d where hash = '%s' and uid = %d", dbesc($cl['name']), intval($cl['visible']), intval($cl['deleted']), @@ -3363,7 +3363,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { } } if(! $found) { - $r = q("INSERT INTO `groups` ( hash, uid, visible, deleted, name ) + $r = q("INSERT INTO `groups` ( hash, uid, visible, deleted, gname ) VALUES( '%s', %d, %d, %d, '%s' ) ", dbesc($cl['collection']), intval($channel['channel_id']), @@ -3470,7 +3470,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { if(array_key_exists('profile',$arr) && is_array($arr['profile']) && count($arr['profile'])) { - $disallowed = array('id','aid','uid'); + $disallowed = array('id','aid','uid','guid'); foreach($arr['profile'] as $profile) { $x = q("select * from profile where profile_guid = '%s' and uid = %d limit 1", @@ -3494,13 +3494,22 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { foreach($profile as $k => $v) { if(in_array($k,$disallowed)) continue; + + if($k === 'name') + $clean['fullname'] = $v; + elseif($k === 'with') + $clean['partner'] = $v; + elseif($k === 'work') + $clean['employment'] = $v; + elseif(array_key_exists($k,$x[0])) + $clean[$k] = $v; - $clean[$k] = $v; /** - * @TODO check if these are allowed, otherwise we'll error + * @TODO * We also need to import local photos if a custom photo is selected */ } + if(count($clean)) { foreach($clean as $k => $v) { $r = dbq("UPDATE profile set `" . dbesc($k) . "` = '" . dbesc($v) -- cgit v1.2.3 From a9d7acda279ebb7f2b3cd61a91a5e1d8b590dcf2 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 1 Jun 2016 21:48:54 -0700 Subject: the rest of the schema updates - WARNING: some third party plugins may fail; e.g. embedphotos and chess. $item['object'] is now $item['obj'] and $photo['type'] is $photo['mimetype'], $photo['scale'] is $photo['imgscale'] and $photo['data'] is now $photo['content']. There are a number of other changes, but these are the ones noted to cause issues with third-party plugins. The project plugins have been updated. Please note any new issues as this effort touched a lot of code in a lot of files. --- include/api.php | 24 +++--- include/attach.php | 26 +++--- include/channel.php | 174 ++++------------------------------------- include/conversation.php | 16 ++-- include/event.php | 169 ++++++++++++++++++++++----------------- include/feedutils.php | 12 +-- include/import.php | 26 ++++-- include/items.php | 34 ++++---- include/photo/photo_driver.php | 50 ++++++------ include/photos.php | 28 +++---- include/sharedwithme.php | 4 +- include/text.php | 33 +------- include/widgets.php | 12 +-- 13 files changed, 236 insertions(+), 372 deletions(-) (limited to 'include') diff --git a/include/api.php b/include/api.php index 0833ae7b9..f0d886d9b 100644 --- a/include/api.php +++ b/include/api.php @@ -554,7 +554,7 @@ require_once('include/api_auth.php'); dbesc($_REQUEST['file_id']) ); if($r) { - unset($r[0]['data']); + unset($r[0]['content']); $ret = array('attach' => $r[0]); json_return_and_die($ret); } @@ -580,21 +580,21 @@ require_once('include/api_auth.php'); $length = intval($ptr['filesize']); if($ptr['is_dir']) - $ptr['data'] = ''; + $ptr['content'] = ''; elseif(! intval($r[0]['os_storage'])) { $ptr['start'] = $start; - $x = substr(dbunescbin($ptr['data'],$start,$length)); + $x = substr(dbunescbin($ptr['content'],$start,$length)); $ptr['length'] = strlen($x); - $ptr['data'] = base64_encode($x); + $ptr['content'] = base64_encode($x); } else { - $fp = fopen(dbunescbin($ptr['data']),'r'); + $fp = fopen(dbunescbin($ptr['content']),'r'); if($fp) { $seek = fseek($fp,$start,SEEK_SET); $x = fread($fp,$length); $ptr['start'] = $start; $ptr['length'] = strlen($x); - $ptr['data'] = base64_encode($x); + $ptr['content'] = base64_encode($x); } } @@ -617,11 +617,11 @@ require_once('include/api_auth.php'); ); if($r) { if($r[0]['is_dir']) - $r[0]['data'] = ''; + $r[0]['content'] = ''; elseif(intval($r[0]['os_storage'])) - $r[0]['data'] = base64_encode(file_get_contents(dbunescbin($r[0]['data']))); + $r[0]['content'] = base64_encode(file_get_contents(dbunescbin($r[0]['content']))); else - $r[0]['data'] = base64_encode(dbunescbin($r[0]['data'])); + $r[0]['content'] = base64_encode(dbunescbin($r[0]['content'])); $ret = array('attach' => $r[0]); json_return_and_die($ret); @@ -647,16 +647,16 @@ require_once('include/api_auth.php'); if (api_user()===false) return false; if(! $_REQUEST['photo_id']) return false; $scale = ((array_key_exists('scale',$_REQUEST)) ? intval($_REQUEST['scale']) : 0); - $r = q("select * from photo where uid = %d and resource_id = '%s' and scale = %d limit 1", + $r = q("select * from photo where uid = %d and resource_id = '%s' and imgscale = %d limit 1", intval(local_channel()), dbesc($_REQUEST['photo_id']), intval($scale) ); if($r) { - $data = dbunescbin($r[0]['data']); + $data = dbunescbin($r[0]['content']); if(array_key_exists('os_storage',$r[0]) && intval($r[0]['os_storage'])) $data = file_get_contents($data); - $r[0]['data'] = base64_encode($data); + $r[0]['content'] = base64_encode($data); $ret = array('photo' => $r[0]); $i = q("select id from item where uid = %d and resource_type = 'photo' and resource_id = '%s' limit 1", intval(local_channel()), diff --git a/include/attach.php b/include/attach.php index d9cd30f6d..78efde51f 100644 --- a/include/attach.php +++ b/include/attach.php @@ -720,7 +720,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { $edited = $created; if($options === 'replace') { - $r = q("update attach set filename = '%s', filetype = '%s', folder = '%s', filesize = %d, os_storage = %d, is_photo = %d, data = '%s', edited = '%s' where id = %d and uid = %d", + $r = q("update attach set filename = '%s', filetype = '%s', folder = '%s', filesize = %d, os_storage = %d, is_photo = %d, content = '%s', edited = '%s' where id = %d and uid = %d", dbesc($filename), dbesc($mimetype), dbesc($folder_hash), @@ -734,7 +734,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { ); } elseif($options === 'revise') { - $r = q("insert into attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, data, created, edited, allow_cid, allow_gid, deny_cid, deny_gid ) + $r = q("insert into attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, content, created, edited, allow_cid, allow_gid, deny_cid, deny_gid ) VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", intval($x[0]['aid']), intval($channel_id), @@ -775,7 +775,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { } else { - $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, data, created, edited, allow_cid, allow_gid,deny_cid, deny_gid ) + $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, content, created, edited, allow_cid, allow_gid,deny_cid, deny_gid ) VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", intval($channel['channel_account_id']), intval($channel_id), @@ -1032,7 +1032,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) { $created = datetime_convert(); - $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_dir, data, created, edited, allow_cid, allow_gid, deny_cid, deny_gid ) + $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_dir, content, created, edited, allow_cid, allow_gid, deny_cid, deny_gid ) VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", intval($channel['channel_account_id']), intval($channel_id), @@ -1275,16 +1275,16 @@ function attach_delete($channel_id, $resource, $is_photo = 0) { // delete a file from filesystem if(intval($r[0]['os_storage'])) { - $y = q("SELECT data FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1", + $y = q("SELECT content FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1", dbesc($resource), intval($channel_id) ); if($y) { - if(strpos($y[0]['data'],'store') === false) - $f = 'store/' . $channel_address . '/' . $y[0]['data']; + if(strpos($y[0]['content'],'store') === false) + $f = 'store/' . $channel_address . '/' . $y[0]['content']; else - $f = $y[0]['data']; + $f = $y[0]['content']; if(is_dir($f)) @rmdir($f); @@ -1585,7 +1585,7 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid, $arr['deny_gid'] = perms2str($u_arr_deny_gid); $arr['item_private'] = $private; $arr['verb'] = ACTIVITY_UPDATE; - $arr['object'] = $u_jsonobject; + $arr['obj'] = $u_jsonobject; $arr['body'] = ''; $post = item_store($arr); @@ -1620,7 +1620,7 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid, $arr['deny_gid'] = perms2str($arr_deny_gid); $arr['item_private'] = $private; $arr['verb'] = (($update) ? ACTIVITY_UPDATE : ACTIVITY_POST); - $arr['object'] = (($update) ? $u_jsonobject : $jsonobject); + $arr['obj'] = (($update) ? $u_jsonobject : $jsonobject); $arr['body'] = ''; $post = item_store($arr); @@ -1854,21 +1854,19 @@ function attach_export_data($channel, $resource_id, $deleted = false) { } while($hash_ptr); - - $paths = array_reverse($paths); $ret['attach'] = $paths; if($attach_ptr['is_photo']) { - $r = q("select * from photo where resource_id = '%s' and uid = %d order by scale asc", + $r = q("select * from photo where resource_id = '%s' and uid = %d order by imgscale asc", dbesc($resource_id), intval($channel['channel_id']) ); if($r) { for($x = 0; $x < count($r); $x ++) { - $r[$x]['data'] = base64_encode($r[$x]['data']); + $r[$x]['content'] = base64_encode($r[$x]['content']); } $ret['photo'] = $r; } diff --git a/include/channel.php b/include/channel.php index 0e5490c86..087bd4162 100644 --- a/include/channel.php +++ b/include/channel.php @@ -550,13 +550,13 @@ function identity_basic_export($channel_id, $items = false) { if($r) $ret['config'] = $r; - $r = q("select type, data, os_storage from photo where scale = 4 and photo_usage = %d and uid = %d limit 1", + $r = q("select mimetype, content, os_storage from photo where imgscale = 4 and photo_usage = %d and uid = %d limit 1", intval(PHOTO_PROFILE), intval($channel_id) ); if($r) { - $ret['photo'] = array('type' => $r[0]['type'], 'data' => (($r[0]['os_storage']) ? base64url_encode(file_get_contents($r[0]['data'])) : base64url_encode($r[0]['data']))); + $ret['photo'] = array('type' => $r[0]['mimetype'], 'data' => (($r[0]['os_storage']) ? base64url_encode(file_get_contents($r[0]['content'])) : base64url_encode($r[0]['content']))); } // All other term types will be included in items, if requested. @@ -1108,150 +1108,6 @@ function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = fa } -/** - * @FIXME or remove - */ - function get_birthdays() { - - $o = ''; - - if(! local_channel()) - return $o; - - $bd_format = t('g A l F d') ; // 8 AM Friday January 18 - $bd_short = t('F d'); - - $r = q("SELECT `event`.*, `event`.`id` AS `eid`, `contact`.* FROM `event` - LEFT JOIN `contact` ON `contact`.`id` = `event`.`cid` - WHERE `event`.`uid` = %d AND `type` = 'birthday' AND `start` < '%s' AND `finish` > '%s' - ORDER BY `start` ASC ", - intval(local_channel()), - dbesc(datetime_convert('UTC','UTC','now + 6 days')), - dbesc(datetime_convert('UTC','UTC','now')) - ); - - if($r && count($r)) { - $total = 0; - $now = strtotime('now'); - $cids = array(); - - $istoday = false; - foreach($r as $rr) { - if(strlen($rr['name'])) - $total ++; - if((strtotime($rr['start'] . ' +00:00') < $now) && (strtotime($rr['finish'] . ' +00:00') > $now)) - $istoday = true; - } - $classtoday = $istoday ? ' birthday-today ' : ''; - if($total) { - foreach($r as &$rr) { - if(! strlen($rr['name'])) - continue; - - // avoid duplicates - - if(in_array($rr['cid'],$cids)) - continue; - $cids[] = $rr['cid']; - - $today = (((strtotime($rr['start'] . ' +00:00') < $now) && (strtotime($rr['finish'] . ' +00:00') > $now)) ? true : false); - $sparkle = ''; - $url = $rr['url']; - if($rr['network'] === NETWORK_DFRN) { - $sparkle = " sparkle"; - $url = z_root() . '/redir/' . $rr['cid']; - } - - $rr['link'] = $url; - $rr['title'] = $rr['name']; - $rr['date'] = day_translate(datetime_convert('UTC', App::$timezone, $rr['start'], $rr['adjust'] ? $bd_format : $bd_short)) . (($today) ? ' ' . t('[today]') : ''); - $rr['startime'] = Null; - $rr['today'] = $today; - } - } - } - $tpl = get_markup_template("birthdays_reminder.tpl"); - return replace_macros($tpl, array( - '$baseurl' => z_root(), - '$classtoday' => $classtoday, - '$count' => $total, - '$event_reminders' => t('Birthday Reminders'), - '$event_title' => t('Birthdays this week:'), - '$events' => $r, - '$lbr' => '{', // raw brackets mess up if/endif macro processing - '$rbr' => '}' - )); - } - - -/** - * @FIXME - */ - function get_events() { - - require_once('include/bbcode.php'); - - if(! local_channel()) - return $o; - - $bd_format = t('g A l F d') ; // 8 AM Friday January 18 - $bd_short = t('F d'); - - $r = q("SELECT `event`.* FROM `event` - WHERE `event`.`uid` = %d AND `type` != 'birthday' AND `start` < '%s' AND `start` > '%s' - ORDER BY `start` ASC ", - intval(local_channel()), - dbesc(datetime_convert('UTC','UTC','now + 6 days')), - dbesc(datetime_convert('UTC','UTC','now - 1 days')) - ); - - if($r && count($r)) { - $now = strtotime('now'); - $istoday = false; - foreach($r as $rr) { - if(strlen($rr['name'])) - $total ++; - - $strt = datetime_convert('UTC',$rr['convert'] ? App::$timezone : 'UTC',$rr['start'],'Y-m-d'); - if($strt === datetime_convert('UTC',App::$timezone,'now','Y-m-d')) - $istoday = true; - } - $classtoday = (($istoday) ? 'event-today' : ''); - - foreach($r as &$rr) { - if($rr['adjust']) - $md = datetime_convert('UTC',App::$timezone,$rr['start'],'Y/m'); - else - $md = datetime_convert('UTC','UTC',$rr['start'],'Y/m'); - $md .= "/#link-".$rr['id']; - - $title = substr(strip_tags(bbcode($rr['desc'])),0,32) . '... '; - if(! $title) - $title = t('[No description]'); - - $strt = datetime_convert('UTC',$rr['convert'] ? App::$timezone : 'UTC',$rr['start']); - $today = ((substr($strt,0,10) === datetime_convert('UTC',App::$timezone,'now','Y-m-d')) ? true : false); - - $rr['link'] = $md; - $rr['title'] = $title; - $rr['date'] = day_translate(datetime_convert('UTC', $rr['adjust'] ? App::$timezone : 'UTC', $rr['start'], $bd_format)) . (($today) ? ' ' . t('[today]') : ''); - $rr['startime'] = $strt; - $rr['today'] = $today; - } - } - - $tpl = get_markup_template("events_reminder.tpl"); - return replace_macros($tpl, array( - '$baseurl' => z_root(), - '$classtoday' => $classtoday, - '$count' => count($r), - '$event_reminders' => t('Event Reminders'), - '$event_title' => t('Events this week:'), - '$events' => $r, - )); - } - - function advanced_profile(&$a) { require_once('include/text.php'); if(! perm_is_allowed(App::$profile['profile_uid'],get_observer_hash(),'view_profile')) @@ -1785,7 +1641,7 @@ function auto_channel_create($account_id) { function get_cover_photo($channel_id,$format = 'bbcode', $res = PHOTO_RES_COVER_1200) { - $r = q("select height, width, resource_id, type from photo where uid = %d and scale = %d and photo_usage = %d", + $r = q("select height, width, resource_id, mimetype from photo where uid = %d and imgscale = %d and photo_usage = %d", intval($channel_id), intval($res), intval(PHOTO_COVER) @@ -1808,8 +1664,8 @@ function get_cover_photo($channel_id,$format = 'bbcode', $res = PHOTO_RES_COVER_ default: $output = array( 'width' => $r[0]['width'], - 'height' => $r[0]['type'], - 'type' => $r[0]['type'], + 'height' => $r[0]['height'], + 'type' => $r[0]['mimetype'], 'url' => $url ); break; @@ -1834,19 +1690,19 @@ function get_zcard($channel,$observer_hash = '',$args = array()) { $width = 425; $size = 'hz_small'; $cover_size = PHOTO_RES_COVER_425; - $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']); + $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']); } elseif($maxwidth <= 900) { $width = 900; $size = 'hz_medium'; $cover_size = PHOTO_RES_COVER_850; - $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']); + $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']); } elseif($maxwidth <= 1200) { $width = 1200; $size = 'hz_large'; $cover_size = PHOTO_RES_COVER_1200; - $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']); + $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']); } // $scale = (float) $maxwidth / $width; @@ -1856,7 +1712,7 @@ function get_zcard($channel,$observer_hash = '',$args = array()) { $channel['channel_addr'] = $channel['channel_address'] . '@' . App::get_hostname(); $zcard = array('chan' => $channel); - $r = q("select height, width, resource_id, scale, type from photo where uid = %d and scale = %d and photo_usage = %d", + $r = q("select height, width, resource_id, imgscale, mimetype from photo where uid = %d and imgscale = %d and photo_usage = %d", intval($channel['channel_id']), intval($cover_size), intval(PHOTO_COVER) @@ -1864,7 +1720,7 @@ function get_zcard($channel,$observer_hash = '',$args = array()) { if($r) { $cover = $r[0]; - $cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['scale']; + $cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['imgscale']; } else { $cover = $pphoto; @@ -1900,25 +1756,25 @@ function get_zcard_embed($channel,$observer_hash = '',$args = array()) { $width = 425; $size = 'hz_small'; $cover_size = PHOTO_RES_COVER_425; - $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']); + $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']); } elseif($maxwidth <= 900) { $width = 900; $size = 'hz_medium'; $cover_size = PHOTO_RES_COVER_850; - $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']); + $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']); } elseif($maxwidth <= 1200) { $width = 1200; $size = 'hz_large'; $cover_size = PHOTO_RES_COVER_1200; - $pphoto = array('type' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']); + $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']); } $channel['channel_addr'] = $channel['channel_address'] . '@' . App::get_hostname(); $zcard = array('chan' => $channel); - $r = q("select height, width, resource_id, scale, type from photo where uid = %d and scale = %d and photo_usage = %d", + $r = q("select height, width, resource_id, imgscale, mimetype from photo where uid = %d and imgscale = %d and photo_usage = %d", intval($channel['channel_id']), intval($cover_size), intval(PHOTO_COVER) @@ -1926,7 +1782,7 @@ function get_zcard_embed($channel,$observer_hash = '',$args = array()) { if($r) { $cover = $r[0]; - $cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['scale']; + $cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['imgscale']; } else { $cover = $pphoto; diff --git a/include/conversation.php b/include/conversation.php index dabe2ca93..518193b08 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -93,15 +93,15 @@ function localize_item(&$item){ if (activity_match($item['verb'],ACTIVITY_LIKE) || activity_match($item['verb'],ACTIVITY_DISLIKE)){ - if(! $item['object']) + if(! $item['obj']) return; if(intval($item['item_thread_top'])) return; - $obj = json_decode_plus($item['object']); - if((! $obj) && ($item['object'])) { - logger('localize_item: failed to decode object: ' . print_r($item['object'],true)); + $obj = json_decode_plus($item['obj']); + if((! $obj) && ($item['obj'])) { + logger('localize_item: failed to decode object: ' . print_r($item['obj'],true)); } if($obj['author'] && $obj['author']['link']) @@ -186,7 +186,7 @@ function localize_item(&$item){ $Alink = $item['author']['xchan_url']; - $obj= json_decode_plus($item['object']); + $obj= json_decode_plus($item['obj']); $Blink = $Bphoto = ''; @@ -219,7 +219,7 @@ function localize_item(&$item){ $Aname = $item['author']['xchan_name']; $Alink = $item['author']['xchan_url']; - $obj= json_decode_plus($item['object']); + $obj= json_decode_plus($item['obj']); $Blink = $Bphoto = ''; @@ -299,7 +299,7 @@ function localize_item(&$item){ } $plink = '[zrl=' . $obj['plink'] . ']' . $post_type . '[/zrl]'; - $parsedobj = parse_xml_string($xmlhead.$item['object']); + $parsedobj = parse_xml_string($xmlhead.$item['obj']); $tag = sprintf('#[zrl=%s]%s[/zrl]', $parsedobj->id, $parsedobj->content); $item['body'] = sprintf( t('%1$s tagged %2$s\'s %3$s with %4$s'), $author, $objauthor, $plink, $tag ); @@ -316,7 +316,7 @@ function localize_item(&$item){ $xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">"; - $obj = parse_xml_string($xmlhead.$item['object']); + $obj = parse_xml_string($xmlhead.$item['obj']); if(strlen($obj->id)) { $r = q("select * from item where mid = '%s' and uid = %d limit 1", dbesc($obj->id), diff --git a/include/event.php b/include/event.php index 81e403d37..a4118ec78 100644 --- a/include/event.php +++ b/include/event.php @@ -28,22 +28,22 @@ function format_event_html($ev) { $o .= '

 ' . bbcode($ev['summary']) . '

' . "\r\n"; $o .= '
' . t('Starts:') . ' ' . (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), - $ev['start'] , $bd_format )) + $ev['dtstart'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', - $ev['start'] , $bd_format))) + $ev['dtstart'] , $bd_format))) . '
' . "\r\n"; if(! $ev['nofinish']) $o .= '
' . t('Finishes:') . ' ' . (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), - $ev['finish'] , $bd_format )) + $ev['dtend'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', - $ev['finish'] , $bd_format ))) + $ev['dtend'] , $bd_format ))) . '
' . "\r\n"; $o .= '
' . bbcode($ev['description']) . '
' . "\r\n"; @@ -58,6 +58,37 @@ function format_event_html($ev) { return $o; } +function format_event_obj($jobject) { + $event = array(); + + $object = json_decode($jobject,true); + + //ensure compatibility with older items - this check can be removed at a later point + if(array_key_exists('description', $object)) { + + $bd_format = t('l F d, Y \@ g:i A'); // Friday January 18, 2011 @ 8:01 AM + + $event['header'] = replace_macros(get_markup_template('event_item_header.tpl'),array( + '$title' => bbcode($object['title']), + '$dtstart_label' => t('Starts:'), + '$dtstart_title' => datetime_convert('UTC', 'UTC', $object['dtstart'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), + '$dtstart_dt' => (($object['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['dtstart'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['dtstart'] , $bd_format))), + '$finish' => (($object['nofinish']) ? false : true), + '$dtend_label' => t('Finishes:'), + '$dtend_title' => datetime_convert('UTC','UTC',$object['dtend'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), + '$dtend_dt' => (($object['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['dtend'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['dtend'] , $bd_format ))) + )); + + $event['content'] = replace_macros(get_markup_template('event_item_content.tpl'),array( + '$description' => bbcode($object['description']), + '$location_label' => t('Location:'), + '$location' => bbcode($object['location']) + )); + + } + + return $event; +} function ical_wrapper($ev) { @@ -68,7 +99,7 @@ function ical_wrapper($ev) { $o .= "\r\nVERSION:2.0"; $o .= "\r\nMETHOD:PUBLISH"; $o .= "\r\nPRODID:-//" . get_config('system','sitename') . "//" . Zotlabs\Lib\System::get_platform_name() . "//" . strtoupper(App::$language). "\r\n"; - if(array_key_exists('start', $ev)) + if(array_key_exists('dtstart', $ev)) $o .= format_event_ical($ev); else { foreach($ev as $e) { @@ -82,7 +113,7 @@ function ical_wrapper($ev) { function format_event_ical($ev) { - if($ev['type'] === 'task') + if($ev['etype'] === 'task') return format_todo_ical($ev); $o = ''; @@ -92,10 +123,10 @@ function format_event_ical($ev) { $o .= "\r\nCREATED:" . datetime_convert('UTC','UTC', $ev['created'],'Ymd\\THis\\Z'); $o .= "\r\nLAST-MODIFIED:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z'); $o .= "\r\nDTSTAMP:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z'); - if($ev['start']) - $o .= "\r\nDTSTART:" . datetime_convert('UTC','UTC', $ev['start'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); - if($ev['finish'] && ! $ev['nofinish']) - $o .= "\r\nDTEND:" . datetime_convert('UTC','UTC', $ev['finish'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); + if($ev['dtstart']) + $o .= "\r\nDTSTART:" . datetime_convert('UTC','UTC', $ev['dtstart'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); + if($ev['dtend'] && ! $ev['nofinish']) + $o .= "\r\nDTEND:" . datetime_convert('UTC','UTC', $ev['dtend'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); if($ev['summary']) $o .= "\r\nSUMMARY:" . format_ical_text($ev['summary']); if($ev['location']) @@ -119,10 +150,10 @@ function format_todo_ical($ev) { $o .= "\r\nCREATED:" . datetime_convert('UTC','UTC', $ev['created'],'Ymd\\THis\\Z'); $o .= "\r\nLAST-MODIFIED:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z'); $o .= "\r\nDTSTAMP:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z'); - if($ev['start']) - $o .= "\r\nDTSTART:" . datetime_convert('UTC','UTC', $ev['start'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); - if($ev['finish'] && ! $ev['nofinish']) - $o .= "\r\nDUE:" . datetime_convert('UTC','UTC', $ev['finish'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); + if($ev['dtstart']) + $o .= "\r\nDTSTART:" . datetime_convert('UTC','UTC', $ev['dtstart'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); + if($ev['dtend'] && ! $ev['nofinish']) + $o .= "\r\nDUE:" . datetime_convert('UTC','UTC', $ev['dtend'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); if($ev['summary']) $o .= "\r\nSUMMARY:" . format_ical_text($ev['summary']); if($ev['event_status']) { @@ -166,11 +197,11 @@ function format_event_bbcode($ev) { if($ev['description']) $o .= '[event-description]' . $ev['description'] . '[/event-description]'; - if($ev['start']) - $o .= '[event-start]' . $ev['start'] . '[/event-start]'; + if($ev['dtstart']) + $o .= '[event-start]' . $ev['dtstart'] . '[/event-start]'; - if(($ev['finish']) && (! $ev['nofinish'])) - $o .= '[event-finish]' . $ev['finish'] . '[/event-finish]'; + if(($ev['dtend']) && (! $ev['nofinish'])) + $o .= '[event-finish]' . $ev['dtend'] . '[/event-finish]'; if($ev['location']) $o .= '[event-location]' . $ev['location'] . '[/event-location]'; @@ -207,10 +238,10 @@ function bbtoevent($s) { $ev['description'] = $match[1]; $match = ''; if(preg_match("/\[event\-start\](.*?)\[\/event\-start\]/is",$s,$match)) - $ev['start'] = $match[1]; + $ev['dtstart'] = $match[1]; $match = ''; if(preg_match("/\[event\-finish\](.*?)\[\/event\-finish\]/is",$s,$match)) - $ev['finish'] = $match[1]; + $ev['dtend'] = $match[1]; $match = ''; if(preg_match("/\[event\-location\](.*?)\[\/event\-location\]/is",$s,$match)) $ev['location'] = $match[1]; @@ -220,11 +251,11 @@ function bbtoevent($s) { $match = ''; if(preg_match("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is",$s,$match)) $ev['adjust'] = $match[1]; - if(array_key_exists('start',$ev)) { - if(array_key_exists('finish',$ev)) { - if($ev['finish'] === $ev['start']) + if(array_key_exists('dtstart',$ev)) { + if(array_key_exists('dtend',$ev)) { + if($ev['dtend'] === $ev['dtstart']) $ev['nofinish'] = 1; - elseif($ev['finish']) + elseif($ev['dtend']) $ev['nofinish'] = 0; else $ev['nofinish'] = 1; @@ -260,8 +291,8 @@ function sort_by_date($arr) { */ function ev_compare($a, $b) { - $date_a = (($a['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$a['start']) : $a['start']); - $date_b = (($b['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$b['start']) : $b['start']); + $date_a = (($a['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$a['dtstart']) : $a['dtstart']); + $date_b = (($b['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$b['dtstart']) : $b['dtstart']); if ($date_a === $date_b) return strcasecmp($a['description'], $b['description']); @@ -274,7 +305,7 @@ function event_store_event($arr) { $arr['created'] = (($arr['created']) ? $arr['created'] : datetime_convert()); $arr['edited'] = (($arr['edited']) ? $arr['edited'] : datetime_convert()); - $arr['type'] = (($arr['type']) ? $arr['type'] : 'event' ); + $arr['etype'] = (($arr['etype']) ? $arr['etype'] : 'event' ); $arr['event_xchan'] = (($arr['event_xchan']) ? $arr['event_xchan'] : ''); $arr['event_priority'] = (($arr['event_priority']) ? $arr['event_priority'] : 0); @@ -324,12 +355,12 @@ function event_store_event($arr) { $r = q("UPDATE `event` SET `edited` = '%s', - `start` = '%s', - `finish` = '%s', + `dtstart` = '%s', + `dtend` = '%s', `summary` = '%s', `description` = '%s', `location` = '%s', - `type` = '%s', + `etype` = '%s', `adjust` = %d, `nofinish` = %d, `event_status` = '%s', @@ -345,12 +376,12 @@ function event_store_event($arr) { WHERE `id` = %d AND `uid` = %d", dbesc($arr['edited']), - dbesc($arr['start']), - dbesc($arr['finish']), + dbesc($arr['dtstart']), + dbesc($arr['dtend']), dbesc($arr['summary']), dbesc($arr['description']), dbesc($arr['location']), - dbesc($arr['type']), + dbesc($arr['etype']), intval($arr['adjust']), intval($arr['nofinish']), dbesc($arr['event_status']), @@ -378,7 +409,7 @@ function event_store_event($arr) { else $hash = random_string() . '@' . App::get_hostname(); - $r = q("INSERT INTO event ( uid,aid,event_xchan,event_hash,created,edited,start,finish,summary,description,location,type, + $r = q("INSERT INTO event ( uid,aid,event_xchan,event_hash,created,edited,dtstart,dtend,summary,description,location,etype, adjust,nofinish, event_status, event_status_date, event_percent, event_repeat, event_sequence, event_priority, 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', %d, '%s', %d, %d, '%s', '%s', '%s', '%s' ) ", intval($arr['uid']), @@ -387,12 +418,12 @@ function event_store_event($arr) { dbesc($hash), dbesc($arr['created']), dbesc($arr['edited']), - dbesc($arr['start']), - dbesc($arr['finish']), + dbesc($arr['dtstart']), + dbesc($arr['dtend']), dbesc($arr['summary']), dbesc($arr['description']), dbesc($arr['location']), - dbesc($arr['type']), + dbesc($arr['etype']), intval($arr['adjust']), intval($arr['nofinish']), dbesc($arr['event_status']), @@ -441,7 +472,7 @@ function event_addtocal($item_id, $uid) { $ev = bbtoevent($r[0]['body']); - if(x($ev,'summary') && x($ev,'start')) { + if(x($ev,'summary') && x($ev,'dtstart')) { $ev['event_xchan'] = $item['author_xchan']; $ev['uid'] = $channel['channel_id']; $ev['account'] = $channel['channel_account_id']; @@ -554,20 +585,20 @@ function event_import_ical($ical, $uid) { // logger('dtstart: ' . var_export($dtstart,true)); - $ev['start'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', + $ev['dtstart'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', $dtstart->format(\DateTime::W3C)); if(isset($ical->DTEND)) { $dtend = $ical->DTEND->getDateTime(); - $ev['finish'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', + $ev['dtend'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', $dtend->format(\DateTime::W3C)); } else $ev['nofinish'] = 1; - if($ev['start'] === $ev['finish']) + if($ev['dtstart'] === $ev['dtend']) $ev['nofinish'] = 1; if(isset($ical->CREATED)) { @@ -601,7 +632,7 @@ function event_import_ical($ical, $uid) { $ev['external_id'] = $evuid; } - if($ev['summary'] && $ev['start']) { + if($ev['summary'] && $ev['dtstart']) { $ev['event_xchan'] = $channel['channel_hash']; $ev['uid'] = $channel['channel_id']; $ev['account'] = $channel['channel_account_id']; @@ -640,29 +671,24 @@ function event_import_ical_task($ical, $uid) { $dtstart = $ical->DTSTART->getDateTime(); + $ev['adjust'] = (($ical->DTSTART->isFloating()) ? 1 : 0); + // logger('dtstart: ' . var_export($dtstart,true)); - if(($dtstart->timezone_type == 2) || (($dtstart->timezone_type == 3) && ($dtstart->timezone === 'UTC'))) { - $ev['adjust'] = 1; - } - else { - $ev['adjust'] = 0; - } - - $ev['start'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', + $ev['dtstart'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', $dtstart->format(\DateTime::W3C)); if(isset($ical->DUE)) { $dtend = $ical->DUE->getDateTime(); - $ev['finish'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', + $ev['dtend'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', $dtend->format(\DateTime::W3C)); } else $ev['nofinish'] = 1; - if($ev['start'] === $ev['finish']) + if($ev['dtstart'] === $ev['dtend']) $ev['nofinish'] = 1; if(isset($ical->CREATED)) { @@ -727,9 +753,9 @@ function event_import_ical_task($ical, $uid) { $ev['event_percent'] = (string) $ical->{'PERCENT-COMPLETE'} ; } - $ev['type'] = 'task'; + $ev['etype'] = 'task'; - if($ev['summary'] && $ev['start']) { + if($ev['summary'] && $ev['dtstart']) { $ev['event_xchan'] = $channel['channel_hash']; $ev['uid'] = $channel['channel_id']; $ev['account'] = $channel['channel_account_id']; @@ -781,7 +807,7 @@ function event_store_item($arr, $event) { if(($event) && array_key_exists('event_hash',$event) && (! array_key_exists('event_hash',$arr))) $arr['event_hash'] = $event['event_hash']; - if($event['type'] === 'birthday') { + if($event['etype'] === 'birthday') { if(! is_sys_channel($arr['uid'])) $prefix = t('This event has been added to your calendar.'); // $birthday = true; @@ -805,21 +831,22 @@ function event_store_item($arr, $event) { 'type' => ACTIVITY_OBJ_EVENT, 'id' => z_root() . '/event/' . $r[0]['resource_id'], 'title' => $arr['summary'], - 'start' => $arr['start'], - 'finish' => $arr['finish'], + 'dtstart' => $arr['dtstart'], + 'dtend' => $arr['dtend'], 'nofinish' => $arr['nofinish'], 'description' => $arr['description'], 'location' => $arr['location'], 'adjust' => $arr['adjust'], 'content' => format_event_bbcode($arr), 'author' => array( - 'name' => $r[0]['xchan_name'], - 'address' => $r[0]['xchan_addr'], - 'guid' => $r[0]['xchan_guid'], - 'guid_sig' => $r[0]['xchan_guid_sig'], - 'link' => array( - array('rel' => 'alternate', 'type' => 'text/html', 'href' => $r[0]['xchan_url']), - array('rel' => 'photo', 'type' => $r[0]['xchan_photo_mimetype'], 'href' => $r[0]['xchan_photo_m'])), + 'name' => $r[0]['xchan_name'], + 'address' => $r[0]['xchan_addr'], + 'guid' => $r[0]['xchan_guid'], + 'guid_sig' => $r[0]['xchan_guid_sig'], + 'link' => array( + array('rel' => 'alternate', 'type' => 'text/html', 'href' => $r[0]['xchan_url']), + array('rel' => 'photo', 'type' => $r[0]['xchan_photo_mimetype'], 'href' => $r[0]['xchan_photo_m']) + ), ), )); @@ -830,7 +857,7 @@ function event_store_item($arr, $event) { $sig = ''; - q("UPDATE item SET title = '%s', body = '%s', object = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', edited = '%s', sig = '%s', item_flags = %d, item_private = %d, obj_type = '%s' WHERE id = %d AND uid = %d", + q("UPDATE item SET title = '%s', body = '%s', obj = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', edited = '%s', sig = '%s', item_flags = %d, item_private = %d, obj_type = '%s' WHERE id = %d AND uid = %d", dbesc($arr['summary']), dbesc($prefix . format_event_bbcode($arr)), dbesc($object), @@ -946,12 +973,12 @@ function event_store_item($arr, $event) { dbesc($arr['event_xchan']) ); if($x) { - $item_arr['object'] = json_encode(array( + $item_arr['obj'] = json_encode(array( 'type' => ACTIVITY_OBJ_EVENT, 'id' => z_root() . '/event/' . $event['event_hash'], 'title' => $arr['summary'], - 'start' => $arr['start'], - 'finish' => $arr['finish'], + 'dtstart' => $arr['dtstart'], + 'dtend' => $arr['dtend'], 'nofinish' => $arr['nofinish'], 'description' => $arr['description'], 'location' => $arr['location'], @@ -1001,7 +1028,7 @@ function tasks_fetch($arr) { if($arr && $arr['all'] == 1) $sql_extra = ''; - $r = q("select * from event where type = 'task' and uid = %d $sql_extra order by created desc", + $r = q("select * from event where etype = 'task' and uid = %d $sql_extra order by created desc", intval(local_channel()) ); diff --git a/include/feedutils.php b/include/feedutils.php index fb938cfdd..685b2f982 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -144,9 +144,9 @@ function construct_verb($item) { function construct_activity_object($item) { - if($item['object']) { + if($item['obj']) { $o = '' . "\r\n"; - $r = json_decode($item['object'],false); + $r = json_decode($item['obj'],false); if(! $r) return ''; @@ -582,7 +582,7 @@ function get_atom_elements($feed, $item, &$author) { $obj['content'] = $body; } - $res['object'] = $obj; + $res['obj'] = $obj; } $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'target'); @@ -1163,12 +1163,12 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { } if(activity_match($item['obj_type'],ACTIVITY_OBJ_EVENT) && activity_match($item['verb'],ACTIVITY_POST)) { - $obj = ((is_array($item['obj'])) ? $item['object'] : json_decode($item['object'],true)); + $obj = ((is_array($item['obj'])) ? $item['obj'] : json_decode($item['obj'],true)); $o .= '' . xmlify($item['title']) . '' . "\r\n"; $o .= '' . xmlify(bbcode($obj['title'])) . '' . "\r\n"; - $o .= '' . datetime_convert('UTC','UTC', $obj['start'],'Ymd\\THis' . (($obj['adjust']) ? '\\Z' : '')) . '' . "\r\n"; - $o .= '' . datetime_convert('UTC','UTC', $obj['finish'],'Ymd\\THis' . (($obj['adjust']) ? '\\Z' : '')) . '' . "\r\n"; + $o .= '' . datetime_convert('UTC','UTC', $obj['dtstart'],'Ymd\\THis' . (($obj['adjust']) ? '\\Z' : '')) . '' . "\r\n"; + $o .= '' . datetime_convert('UTC','UTC', $obj['dtend'],'Ymd\\THis' . (($obj['adjust']) ? '\\Z' : '')) . '' . "\r\n"; $o .= '' . xmlify(bbcode($obj['location'])) . '' . "\r\n"; $o .= '' . xmlify(bbcode($obj['description'])) . '' . "\r\n"; } diff --git a/include/import.php b/include/import.php index d094fb582..6fcb08416 100644 --- a/include/import.php +++ b/include/import.php @@ -974,6 +974,11 @@ function sync_files($channel,$files) { $attachment_stored = false; foreach($f['attach'] as $att) { + if(array_key_exists('data',$att)) { + $att['content'] = $att['data']; + unset($att['data']); + } + if($att['deleted']) { attach_delete($channel,$att['hash']); continue; @@ -1043,7 +1048,7 @@ function sync_files($channel,$files) { // @fixme - update attachment structures if they are modified rather than created - $att['data'] = $newfname; + $att['content'] = $newfname; // Note: we use $att['hash'] below after it has been escaped to // fetch the file contents. @@ -1125,6 +1130,15 @@ function sync_files($channel,$files) { $p['aid'] = $channel['channel_account_id']; $p['uid'] = $channel['channel_id']; + if(array_key_exists('data',$p)) { + $p['content'] = $p['data']; + unset($p['data']); + } + if(array_key_exists('scale',$p)) { + $p['imgscale'] = $p['scale']; + unset($p['scale']); + } + // if this is a profile photo, undo the profile photo bit // for any other photo which previously held it. @@ -1150,15 +1164,15 @@ function sync_files($channel,$files) { ); } - if($p['scale'] === 0 && $p['os_storage']) - $p['data'] = $store_path; + if($p['imgscale'] === 0 && $p['os_storage']) + $p['content'] = $store_path; else - $p['data'] = base64_decode($p['data']); + $p['content'] = base64_decode($p['content']); - $exists = q("select * from photo where resource_id = '%s' and scale = %d and uid = %d limit 1", + $exists = q("select * from photo where resource_id = '%s' and imgscale = %d and uid = %d limit 1", dbesc($p['resource_id']), - intval($p['scale']), + intval($p['imgscale']), intval($channel['channel_id']) ); diff --git a/include/items.php b/include/items.php index b283ed3ab..f473b2bac 100755 --- a/include/items.php +++ b/include/items.php @@ -666,7 +666,7 @@ function get_item_elements($x,$allow_code = false) { $arr['diaspora_meta'] = (($x['diaspora_signature']) ? $x['diaspora_signature'] : ''); - $arr['object'] = activity_sanitise($x['object']); + $arr['obj'] = activity_sanitise($x['object']); $arr['target'] = activity_sanitise($x['target']); $arr['attach'] = activity_sanitise($x['attach']); @@ -1055,8 +1055,8 @@ function encode_item($item,$mirror = false) { $x['owner'] = encode_item_xchan($item['owner']); $x['author'] = encode_item_xchan($item['author']); - if($item['object']) - $x['object'] = json_decode_plus($item['object']); + if($item['obj']) + $x['object'] = json_decode_plus($item['obj']); if($item['target']) $x['target'] = json_decode_plus($item['target']); if($item['attach']) @@ -1595,9 +1595,9 @@ function item_store($arr, $allow_exec = false, $deliver = true) { } } - if((x($arr,'object')) && is_array($arr['object'])) { - activity_sanitise($arr['object']); - $arr['object'] = json_encode($arr['object']); + if((x($arr,'obj')) && is_array($arr['obj'])) { + activity_sanitise($arr['obj']); + $arr['obj'] = json_encode($arr['obj']); } if((x($arr,'target')) && is_array($arr['target'])) { @@ -1628,7 +1628,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) { $arr['thr_parent'] = ((x($arr,'thr_parent')) ? notags(trim($arr['thr_parent'])) : $arr['parent_mid']); $arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : ACTIVITY_POST); $arr['obj_type'] = ((x($arr,'obj_type')) ? notags(trim($arr['obj_type'])) : ACTIVITY_OBJ_NOTE); - $arr['object'] = ((x($arr,'object')) ? trim($arr['object']) : ''); + $arr['obj'] = ((x($arr,'obj')) ? trim($arr['obj']) : ''); $arr['tgt_type'] = ((x($arr,'tgt_type')) ? notags(trim($arr['tgt_type'])) : ''); $arr['target'] = ((x($arr,'target')) ? trim($arr['target']) : ''); $arr['plink'] = ((x($arr,'plink')) ? notags(trim($arr['plink'])) : ''); @@ -1697,7 +1697,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) { return $ret; } - if(($arr['obj_type'] == ACTIVITY_OBJ_NOTE) && (! $arr['object'])) + if(($arr['obj_type'] == ACTIVITY_OBJ_NOTE) && (! $arr['obj'])) $arr['obj_type'] = ACTIVITY_OBJ_COMMENT; // is the new message multi-level threaded? @@ -1991,9 +1991,9 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) { } } - if((x($arr,'object')) && is_array($arr['object'])) { - activity_sanitise($arr['object']); - $arr['object'] = json_encode($arr['object']); + if((x($arr,'obj')) && is_array($arr['obj'])) { + activity_sanitise($arr['obj']); + $arr['obj'] = json_encode($arr['obj']); } if((x($arr,'target')) && is_array($arr['target'])) { @@ -2035,7 +2035,7 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) { $arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : $orig[0]['coord']); $arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : $orig[0]['verb']); $arr['obj_type'] = ((x($arr,'obj_type')) ? notags(trim($arr['obj_type'])) : $orig[0]['obj_type']); - $arr['object'] = ((x($arr,'object')) ? trim($arr['object']) : $orig[0]['object']); + $arr['obj'] = ((x($arr,'obj')) ? trim($arr['obj']) : $orig[0]['obj']); $arr['tgt_type'] = ((x($arr,'tgt_type')) ? notags(trim($arr['tgt_type'])) : $orig[0]['tgt_type']); $arr['target'] = ((x($arr,'target')) ? trim($arr['target']) : $orig[0]['target']); $arr['plink'] = ((x($arr,'plink')) ? notags(trim($arr['plink'])) : $orig[0]['plink']); @@ -2369,10 +2369,10 @@ function tag_deliver($uid, $item_id) { if (stristr($item['verb'],ACTIVITY_POKE)) { $poke_notify = true; - if(($item['obj_type'] == "") || ($item['obj_type'] !== ACTIVITY_OBJ_PERSON) || (! $item['object'])) + if(($item['obj_type'] == "") || ($item['obj_type'] !== ACTIVITY_OBJ_PERSON) || (! $item['obj'])) $poke_notify = false; - $obj = json_decode_plus($item['object']); + $obj = json_decode_plus($item['obj']); if($obj) { if($obj['id'] !== $u[0]['channel_hash']) $poke_notify = false; @@ -2416,7 +2416,7 @@ function tag_deliver($uid, $item_id) { intval($u[0]['channel_id']) ); if($p) { - $j_obj = json_decode_plus($item['object']); + $j_obj = json_decode_plus($item['obj']); logger('tag_deliver: tag object: ' . print_r($j_obj,true), LOGGER_DATA); if($j_obj && $j_obj['id'] && $j_obj['title']) { if(is_array($j_obj['link'])) @@ -3093,7 +3093,7 @@ function fix_private_photos($s, $uid, $item = null, $cid = 0) { if($x) { $res = substr($i,$x+1); $i = substr($i,0,$x); - $r = q("SELECT * FROM `photo` WHERE `resource_id` = '%s' AND `scale` = %d AND `uid` = %d", + $r = q("SELECT * FROM `photo` WHERE `resource_id` = '%s' AND `imgscale` = %d AND `uid` = %d", dbesc($i), intval($res), intval($uid) @@ -4263,7 +4263,7 @@ function send_profile_photo_activity($channel,$photo,$profile) { $arr['obj_type'] = ACTIVITY_OBJ_PHOTO; $arr['verb'] = ACTIVITY_UPDATE; - $arr['object'] = json_encode(array( + $arr['obj'] = json_encode(array( 'type' => $arr['obj_type'], 'id' => z_root() . '/photo/profile/l/' . $channel['channel_id'], 'link' => array('rel' => 'photo', 'type' => $photo['type'], 'href' => z_root() . '/photo/profile/l/' . $channel['channel_id']) diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php index e57a9165a..6de75d497 100644 --- a/include/photo/photo_driver.php +++ b/include/photo/photo_driver.php @@ -316,7 +316,7 @@ abstract class photo_driver { $p['resource_id'] = (($arr['resource_id']) ? $arr['resource_id'] : ''); $p['filename'] = (($arr['filename']) ? $arr['filename'] : ''); $p['album'] = (($arr['album']) ? $arr['album'] : ''); - $p['scale'] = ((intval($arr['scale'])) ? intval($arr['scale']) : 0); + $p['imgscale'] = ((intval($arr['imgscale'])) ? intval($arr['imgscale']) : 0); $p['allow_cid'] = (($arr['allow_cid']) ? $arr['allow_cid'] : ''); $p['allow_gid'] = (($arr['allow_gid']) ? $arr['allow_gid'] : ''); $p['deny_cid'] = (($arr['deny_cid']) ? $arr['deny_cid'] : ''); @@ -329,14 +329,14 @@ abstract class photo_driver { $p['os_storage'] = intval($arr['os_storage']); $p['os_path'] = $arr['os_path']; - if(! intval($p['scale'])) - logger('save: ' . print_r($arr,true)); + if(! intval($p['imgscale'])) + logger('save: ' . print_r($arr,true), LOGGER_DATA); - $x = q("select id from photo where resource_id = '%s' and uid = %d and xchan = '%s' and `scale` = %d limit 1", + $x = q("select id from photo where resource_id = '%s' and uid = %d and xchan = '%s' and imgscale = %d limit 1", dbesc($p['resource_id']), intval($p['uid']), dbesc($p['xchan']), - intval($p['scale']) + intval($p['imgscale']) ); if($x) { $r = q("UPDATE `photo` set @@ -347,14 +347,14 @@ abstract class photo_driver { `created` = '%s', `edited` = '%s', `filename` = '%s', - `type` = '%s', + `mimetype` = '%s', `album` = '%s', `height` = %d, `width` = %d, - `data` = '%s', + `content` = '%s', `os_storage` = %d, - `size` = %d, - `scale` = %d, + `filesize` = %d, + `imgscale` = %d, `photo_usage` = %d, `title` = '%s', `description` = '%s', @@ -378,7 +378,7 @@ abstract class photo_driver { (intval($p['os_storage']) ? dbesc($p['os_path']) : dbescbin($this->imageString())), intval($p['os_storage']), intval(strlen($this->imageString())), - intval($p['scale']), + intval($p['imgscale']), intval($p['photo_usage']), dbesc($p['title']), dbesc($p['description']), @@ -391,7 +391,7 @@ abstract class photo_driver { } else { $r = q("INSERT INTO `photo` - ( `aid`, `uid`, `xchan`, `resource_id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `data`, `os_storage`, `size`, `scale`, `photo_usage`, `title`, `description`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` ) + ( `aid`, `uid`, `xchan`, `resource_id`, `created`, `edited`, `filename`, mimetype, `album`, `height`, `width`, `content`, `os_storage`, `filesize`, `imgscale`, `photo_usage`, `title`, `description`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` ) VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s' )", intval($p['aid']), intval($p['uid']), @@ -407,7 +407,7 @@ abstract class photo_driver { (intval($p['os_storage']) ? dbesc($p['os_path']) : dbescbin($this->imageString())), intval($p['os_storage']), intval(strlen($this->imageString())), - intval($p['scale']), + intval($p['imgscale']), intval($p['photo_usage']), dbesc($p['title']), dbesc($p['description']), @@ -422,7 +422,7 @@ abstract class photo_driver { public function store($aid, $uid, $xchan, $rid, $filename, $album, $scale, $usage = PHOTO_NORMAL, $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", + $x = q("select id from photo where `resource_id` = '%s' and uid = %d and `xchan` = '%s' and `imgscale` = %d limit 1", dbesc($rid), intval($uid), dbesc($xchan), @@ -437,13 +437,13 @@ abstract class photo_driver { `created` = '%s', `edited` = '%s', `filename` = '%s', - `type` = '%s', + `mimetype` = '%s', `album` = '%s', `height` = %d, `width` = %d, - `data` = '%s', - `size` = %d, - `scale` = %d, + `content` = '%s', + `filesize` = %d, + `imgscale` = %d, `photo_usage` = %d, `allow_cid` = '%s', `allow_gid` = '%s', @@ -475,7 +475,7 @@ abstract class photo_driver { } else { $r = q("INSERT INTO `photo` - ( `aid`, `uid`, `xchan`, `resource_id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `data`, `size`, `scale`, `photo_usage`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` ) + ( `aid`, `uid`, `xchan`, `resource_id`, `created`, `edited`, `filename`, mimetype, `album`, `height`, `width`, `content`, `filesize`, `imgscale`, `photo_usage`, `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), @@ -588,7 +588,7 @@ function import_xchan_photo($photo,$xchan,$thing = false) { if($thing) $hash = photo_new_resource(); else { - $r = q("select resource_id from photo where xchan = '%s' and photo_usage = %d and scale = 4 limit 1", + $r = q("select resource_id from photo where xchan = '%s' and photo_usage = %d and imgscale = 4 limit 1", dbesc($xchan), intval(PHOTO_XCHAN) ); @@ -654,7 +654,7 @@ function import_xchan_photo($photo,$xchan,$thing = false) { else $photo_failure = true; - $p = array('xchan' => $xchan,'resource_id' => $hash, 'filename' => basename($photo), 'album' => $album, 'photo_usage' => $flags, 'scale' => 4); + $p = array('xchan' => $xchan,'resource_id' => $hash, 'filename' => basename($photo), 'album' => $album, 'photo_usage' => $flags, 'imgscale' => 4); $r = $img->save($p); @@ -662,7 +662,7 @@ function import_xchan_photo($photo,$xchan,$thing = false) { $photo_failure = true; $img->scaleImage(80); - $p['scale'] = 5; + $p['imgscale'] = 5; $r = $img->save($p); @@ -670,7 +670,7 @@ function import_xchan_photo($photo,$xchan,$thing = false) { $photo_failure = true; $img->scaleImage(48); - $p['scale'] = 6; + $p['imgscale'] = 6; $r = $img->save($p); @@ -715,7 +715,7 @@ function import_channel_photo($photo,$type,$aid,$uid) { $img->scaleImageSquare(300); - $p = array('aid' => $aid, 'uid' => $uid, 'resource_id' => $hash, 'filename' => $filename, 'album' => t('Profile Photos'), 'photo_usage' => PHOTO_PROFILE, 'scale' => 4); + $p = array('aid' => $aid, 'uid' => $uid, 'resource_id' => $hash, 'filename' => $filename, 'album' => t('Profile Photos'), 'photo_usage' => PHOTO_PROFILE, 'imgscale' => 4); $r = $img->save($p); @@ -723,7 +723,7 @@ function import_channel_photo($photo,$type,$aid,$uid) { $photo_failure = true; $img->scaleImage(80); - $p['scale'] = 5; + $p['imgscale'] = 5; $r = $img->save($p); @@ -731,7 +731,7 @@ function import_channel_photo($photo,$type,$aid,$uid) { $photo_failure = true; $img->scaleImage(48); - $p['scale'] = 6; + $p['imgscale'] = 6; $r = $img->save($p); diff --git a/include/photos.php b/include/photos.php index c333a4d04..1cc64f6fa 100644 --- a/include/photos.php +++ b/include/photos.php @@ -71,17 +71,17 @@ function photo_upload($channel, $observer, $args) { $type = $args['getimagesize']['mime']; $os_storage = 1; } - elseif ($args['data']) { + elseif ($args['data'] || $args['content']) { // allow an import from a binary string representing the image. // This bypasses the upload step and max size limit checking - $imagedata = $args['data']; + $imagedata = (($args['content']) ? $args['content'] : $args['data']); $filename = $args['filename']; $filesize = strlen($imagedata); // this is going to be deleted if it exists $src = '/tmp/deletemenow'; - $type = $args['type']; + $type = (($args['mimetype']) ? $args['mimetype'] : $args['type']); } else { $f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => ''); @@ -125,7 +125,7 @@ function photo_upload($channel, $observer, $args) { $imagedata = @file_get_contents($src); } - $r = q("select sum(size) as total from photo where aid = %d and scale = 0 ", + $r = q("select sum(filesize) as total from photo where aid = %d and imgscale = 0 ", intval($account_id) ); @@ -172,7 +172,7 @@ function photo_upload($channel, $observer, $args) { $errors = false; $p = array('aid' => $account_id, 'uid' => $channel_id, 'xchan' => $visitor, 'resource_id' => $photo_hash, - 'filename' => $filename, 'album' => $album, 'scale' => 0, 'photo_usage' => PHOTO_NORMAL, + 'filename' => $filename, 'album' => $album, 'imgscale' => 0, 'photo_usage' => PHOTO_NORMAL, 'allow_cid' => $ac['allow_cid'], 'allow_gid' => $ac['allow_gid'], 'deny_cid' => $ac['deny_cid'], 'deny_gid' => $ac['deny_gid'], 'os_storage' => $os_storage, 'os_path' => $args['os_path'] @@ -205,7 +205,7 @@ function photo_upload($channel, $observer, $args) { if(($width > 1024 || $height > 1024) && (! $errors)) $ph->scaleImage(1024); - $p['scale'] = 1; + $p['imgscale'] = 1; $r1 = $ph->save($p); $link[1] = array( 'rel' => 'alternate', @@ -220,7 +220,7 @@ function photo_upload($channel, $observer, $args) { if(($width > 640 || $height > 640) && (! $errors)) $ph->scaleImage(640); - $p['scale'] = 2; + $p['imgscale'] = 2; $r2 = $ph->save($p); $link[2] = array( 'rel' => 'alternate', @@ -235,7 +235,7 @@ function photo_upload($channel, $observer, $args) { if(($width > 320 || $height > 320) && (! $errors)) $ph->scaleImage(320); - $p['scale'] = 3; + $p['imgscale'] = 3; $r3 = $ph->save($p); $link[3] = array( 'rel' => 'alternate', @@ -332,7 +332,7 @@ function photo_upload($channel, $observer, $args) { $item['body'] = $args['body']; $item['obj_type'] = ACTIVITY_OBJ_PHOTO; - $item['object'] = json_encode($object); + $item['obj'] = json_encode($object); $item['tgt_type'] = ACTIVITY_OBJ_ALBUM; $item['target'] = json_encode($target); @@ -389,8 +389,8 @@ function photo_upload($channel, $observer, $args) { $arr['deny_cid'] = $ac['deny_cid']; $arr['deny_gid'] = $ac['deny_gid']; $arr['verb'] = ACTIVITY_POST; - $arr['obj_type'] = ACTIVITY_OBJ_PHOTO; - $arr['object'] = json_encode($object); + $arr['obj_type'] = ACTIVITY_OBJ_PHOTO; + $arr['obj'] = json_encode($object); $arr['tgt_type'] = ACTIVITY_OBJ_ALBUM; $arr['target'] = json_encode($target); $arr['item_wall'] = 1; @@ -535,7 +535,7 @@ function photos_list_photos($channel, $observer, $album = '') { $ret = array('success' => false); - $r = q("select resource_id, created, edited, title, description, album, filename, type, height, width, size, scale, photo_usage, allow_cid, allow_gid, deny_cid, deny_gid from photo where uid = %d and photo_usage in ( %d, %d ) $sql_extra ", + $r = q("select resource_id, created, edited, title, description, album, filename, mimetype, height, width, filesize, imgscale, photo_usage, allow_cid, allow_gid, deny_cid, deny_gid from photo where uid = %d and photo_usage in ( %d, %d ) $sql_extra ", intval($channel_id), intval(PHOTO_NORMAL), intval(PHOTO_PROFILE) @@ -543,7 +543,7 @@ function photos_list_photos($channel, $observer, $album = '') { if($r) { for($x = 0; $x < count($r); $x ++) { - $r[$x]['src'] = z_root() . '/photo/' . $r[$x]['resource_id'] . '-' . $r[$x]['scale']; + $r[$x]['src'] = z_root() . '/photo/' . $r[$x]['resource_id'] . '-' . $r[$x]['imgscale']; } $ret['success'] = true; $ret['photos'] = $r; @@ -661,7 +661,7 @@ function photos_create_item($channel, $creator_hash, $photo, $visible = false) { $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid']; $arr['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']' - . '[zmg]' . z_root() . '/photo/' . $photo['resource_id'] . '-' . $photo['scale'] . '[/zmg]' + . '[zmg]' . z_root() . '/photo/' . $photo['resource_id'] . '-' . $photo['imgscale'] . '[/zmg]' . '[/zrl]'; $result = item_store($arr); diff --git a/include/sharedwithme.php b/include/sharedwithme.php index b01764ad3..b342f51d5 100644 --- a/include/sharedwithme.php +++ b/include/sharedwithme.php @@ -3,7 +3,7 @@ function apply_updates() { //check for updated items and remove them - $x = q("SELECT mid, max(object) AS object FROM item WHERE verb = '%s' AND obj_type = '%s' GROUP BY mid", + $x = q("SELECT mid, max(obj) AS obj FROM item WHERE verb = '%s' AND obj_type = '%s' GROUP BY mid", dbesc(ACTIVITY_UPDATE), dbesc(ACTIVITY_OBJ_FILE) ); @@ -12,7 +12,7 @@ function apply_updates() { foreach($x as $xx) { - $object = json_decode($xx['object'],true); + $object = json_decode($xx['obj'],true); $d_mid = $object['d_mid']; $u_mid = $xx['mid']; diff --git a/include/text.php b/include/text.php index c57f5fce4..551cb72bc 100644 --- a/include/text.php +++ b/include/text.php @@ -1458,37 +1458,6 @@ function generate_named_map($location) { return (($arr['html']) ? $arr['html'] : $location); } -function format_event($jobject) { - $event = array(); - - $object = json_decode($jobject,true); - - //ensure compatibility with older items - this check can be removed at a later point - if(array_key_exists('description', $object)) { - - $bd_format = t('l F d, Y \@ g:i A'); // Friday January 18, 2011 @ 8:01 AM - - $event['header'] = replace_macros(get_markup_template('event_item_header.tpl'),array( - '$title' => bbcode($object['title']), - '$dtstart_label' => t('Starts:'), - '$dtstart_title' => datetime_convert('UTC', 'UTC', $object['start'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), - '$dtstart_dt' => (($object['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['start'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['start'] , $bd_format))), - '$finish' => (($object['nofinish']) ? false : true), - '$dtend_label' => t('Finishes:'), - '$dtend_title' => datetime_convert('UTC','UTC',$object['finish'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), - '$dtend_dt' => (($object['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['finish'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['finish'] , $bd_format ))) - )); - - $event['content'] = replace_macros(get_markup_template('event_item_content.tpl'),array( - '$description' => bbcode($object['description']), - '$location_label' => t('Location:'), - '$location' => bbcode($object['location']) - )); - - } - - return $event; -} function prepare_body(&$item,$attach = false) { @@ -1516,7 +1485,7 @@ function prepare_body(&$item,$attach = false) { $s .= prepare_text($item['body'],$item['mimetype'], false); - $event = (($item['obj_type'] === ACTIVITY_OBJ_EVENT) ? format_event($item['object']) : false); + $event = (($item['obj_type'] === ACTIVITY_OBJ_EVENT) ? format_event_obj($item['obj']) : false); $prep_arr = array( 'item' => $item, diff --git a/include/widgets.php b/include/widgets.php index 17a76c0f4..3448aeb5e 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -1126,7 +1126,7 @@ function widget_photo_rand($arr) { $filtered = array(); if($ret['success'] && $ret['photos']) foreach($ret['photos'] as $p) - if($p['scale'] == $scale) + if($p['imgscale'] == $scale) $filtered[] = $p['src']; if($filtered) { @@ -1459,9 +1459,9 @@ function widget_album($args) { $order = 'DESC'; - $r = q("SELECT p.resource_id, p.id, p.filename, p.type, p.scale, p.description, p.created FROM photo p INNER JOIN - (SELECT resource_id, max(scale) scale FROM photo WHERE uid = %d AND album = '%s' AND scale <= 4 AND photo_usage IN ( %d, %d ) $sql_extra GROUP BY resource_id) ph - ON (p.resource_id = ph.resource_id AND p.scale = ph.scale) + $r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN + (SELECT resource_id, max(imgscale) imgscale FROM photo WHERE uid = %d AND album = '%s' AND imgscale <= 4 AND photo_usage IN ( %d, %d ) $sql_extra GROUP BY resource_id) ph + ON (p.resource_id = ph.resource_id AND p.imgscale = ph.imgscale) ORDER BY created $order ", intval($owner_uid), dbesc($album), @@ -1482,7 +1482,7 @@ function widget_album($args) { else $twist = 'rotright'; - $ext = $phototypes[$rr['type']]; + $ext = $phototypes[$rr['mimetype']]; $imgalt_e = $rr['filename']; $desc_e = $rr['description']; @@ -1495,7 +1495,7 @@ function widget_album($args) { 'twist' => ' ' . $twist . rand(2,4), 'link' => $imagelink, 'title' => t('View Photo'), - 'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['scale'] . '.' .$ext, + 'src' => z_root() . '/photo/' . $rr['resource_id'] . '-' . $rr['imgscale'] . '.' .$ext, 'alt' => $imgalt_e, 'desc'=> $desc_e, 'ext' => $ext, -- cgit v1.2.3 From f9075e2a2feca0f37fdf568be6e6e53460aa9034 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 2 Jun 2016 18:42:51 -0700 Subject: some initial emoji reaction work --- include/text.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/text.php b/include/text.php index 551cb72bc..834eec920 100644 --- a/include/text.php +++ b/include/text.php @@ -734,6 +734,10 @@ function get_tags($s) { // '=' needs to be avoided because when the replacement is made (in handle_tag()) it has to be ignored there // Feel free to allow '=' if the issue with '=' is solved in handle_tag() // added / ? and [ to avoid issues with hashchars in url paths + + // added ; to single word tags to allow emojis and other unicode character constructs in bbcode + // (this would actually be &#xnnnnn; but the ampersand will have been escaped to & by the time we see it.) + if(preg_match_all('/(? Date: Thu, 2 Jun 2016 22:27:26 -0400 Subject: Major corrections to access control and page construction. --- include/widgets.php | 24 ++++++++++++------------ include/wiki.php | 13 +++++++------ 2 files changed, 19 insertions(+), 18 deletions(-) (limited to 'include') diff --git a/include/widgets.php b/include/widgets.php index 536af8818..d9dac1afa 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -857,27 +857,27 @@ function widget_chatroom_members() { function widget_wiki_list($arr) { require_once("include/wiki.php"); - if (argc() > 1) { - $nick = argv(1); - $channel = get_channel_by_nick($nick); - } else { + $channel = null; + if (argc() < 2 && local_channel()) { + // This should not occur because /wiki should redirect to /wiki/channel ... $channel = \App::get_channel(); - $nick = $channel['channel_address']; - } - $wikis = wiki_list($channel, get_observer_hash()); - if (local_channel() === intval($channel['channel_id'])) { - $showControls = true; } else { - $showControls = false; + $channel = get_channel_by_nick(argv(1)); // Channel being viewed by observer } + if (!$channel) { + return ''; + } + $wikis = wiki_list($channel, get_observer_hash()); if ($wikis) { return replace_macros(get_markup_template('wikilist.tpl'), array( '$header' => t('Wiki List'), - '$channel' => $nick, + '$channel' => $channel['channel_address'], '$wikis' => $wikis['wikis'], - '$showControls' => $showControls + // If the observer is the local channel owner, show the wiki controls + '$showControls' => ((local_channel() === intval($channel['channel_id'])) ? true : false) )); } + return ''; } function widget_wiki_pages($arr) { diff --git a/include/wiki.php b/include/wiki.php index 14e8cc53a..84e7d8dfa 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -9,8 +9,9 @@ define ( 'WIKI_ITEM_RESOURCE_TYPE', 'wiki' ); function wiki_list($channel, $observer_hash) { $sql_extra = item_permissions_sql($channel['channel_id'], $observer_hash); - $wikis = q("SELECT * FROM item WHERE resource_type = '%s' AND mid = parent_mid AND item_deleted = 0 $sql_extra", - dbesc(WIKI_ITEM_RESOURCE_TYPE) + $wikis = q("SELECT * FROM item WHERE resource_type = '%s' AND mid = parent_mid AND uid = %d AND item_deleted = 0 $sql_extra", + dbesc(WIKI_ITEM_RESOURCE_TYPE), + intval($channel['channel_id']) ); // TODO: query db for wikis the observer can access. Return with two lists, for read and write access return array('wikis' => $wikis); @@ -195,8 +196,8 @@ function wiki_create_page($name, $resource_id) { function wiki_get_page_content($arr) { $page = ((array_key_exists('page',$arr)) ? $arr['page'] : ''); // TODO: look for page resource_id and retrieve that way alternatively - $wiki_resource_id = ((array_key_exists('wiki_resource_id',$arr)) ? $arr['wiki_resource_id'] : ''); - $w = wiki_get_wiki($wiki_resource_id); + $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : ''); + $w = wiki_get_wiki($resource_id); if (!$w['path']) { return array('content' => null, 'message' => 'Error reading wiki', 'success' => false); } @@ -230,7 +231,7 @@ function wiki_page_history($arr) { if($reponame === '') { $reponame = 'repo'; } - $git = new GitRepo('sys', null, false, $w['wiki']['title'], $w['path']); + $git = new GitRepo('', null, false, $w['wiki']['title'], $w['path']); try { $gitlog = $git->git->log('', $page_path , array('limit' => 50)); logger('gitlog: ' . json_encode($gitlog)); @@ -272,7 +273,7 @@ function wiki_git_commit($arr) { if($reponame === '') { $reponame = 'repo'; } - $git = new GitRepo('sys', null, false, $w['wiki']['title'], $w['path']); + $git = new GitRepo($observer['xchan_addr'], null, false, $w['wiki']['title'], $w['path']); try { $git->setIdentity($observer['xchan_name'], $observer['xchan_addr']); if ($files === null) { -- cgit v1.2.3 From 624f4641e2a8af91f519ac47ba1c72138734b17c Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 3 Jun 2016 15:09:58 -0700 Subject: missed an object -> obj conversion in prepare_body --- include/text.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/text.php b/include/text.php index 834eec920..72db9c5ea 100644 --- a/include/text.php +++ b/include/text.php @@ -1473,7 +1473,7 @@ function prepare_body(&$item,$attach = false) { if($is_photo) { - $object = json_decode($item['object'],true); + $object = json_decode($item['obj'],true); // if original photo width is <= 640px prepend it to item body if($object['link'][0]['width'] && $object['link'][0]['width'] <= 640) { -- cgit v1.2.3 From e81ac9e0637c4533aeb144511b8f68ec8a99e257 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 3 Jun 2016 16:04:54 -0700 Subject: turn emoji ability into a feature so that either a member or the site admin can disable it. Default is enabled. --- include/features.php | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/features.php b/include/features.php index 38700f9f5..6d38bcfb4 100644 --- a/include/features.php +++ b/include/features.php @@ -94,6 +94,7 @@ function get_features($filtered = true) { t('Post/Comment Tools'), array('commtag', t('Community Tagging'), t('Ability to tag existing posts'),false,get_config('feature_lock','commtag')), array('categories', t('Post Categories'), t('Add categories to your posts'),false,get_config('feature_lock','categories')), + array('emojis', t('Emoji Reactions'), t('Add emoji reaction ability to posts'),true,get_config('feature_lock','emojis')), array('filing', t('Saved Folders'), t('Ability to file posts under folders'),false,get_config('feature_lock','filing')), array('dislike', t('Dislike Posts'), t('Ability to dislike posts/comments'),false,get_config('feature_lock','dislike')), array('star_posts', t('Star Posts'), t('Ability to mark special posts with a star indicator'),false,get_config('feature_lock','star_posts')), -- cgit v1.2.3 From 20a79c7acf1850f431f4fd52972ea0b6acf8ce0c Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 3 Jun 2016 22:00:53 -0700 Subject: allow bbcode emojis (at least the single unicode character forms) --- include/bbcode.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include') diff --git a/include/bbcode.php b/include/bbcode.php index 42741b392..ed332146f 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -66,6 +66,19 @@ function bb_unspacefy_and_trim($st) { } +function bb_emoji($mtch) { + $s = strtolower($mtch[1]); + if(strpos($s,'x')) { + $e = substr($s,strpos($s,'x')+1); + if(file_exists('images/emoji/' . $e . '.png')) { + return 'emoji'; + } + else { + return $mtch[0]; + } + } +} + function bb_extract_images($body) { $saved_image = array(); @@ -1001,6 +1014,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false) $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim', $Text); } + $Text = preg_replace_callback('/\[\&\;([#a-z0-9]+)\;\]/', 'bb_emoji', $Text); $Text = preg_replace('/\[\&\;([#a-z0-9]+)\;\]/', '&$1;', $Text); // fix any escaped ampersands that may have been converted into links -- cgit v1.2.3 From b5d8443f59d96cece2357b6a791fe8ffe854dd95 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 4 Jun 2016 06:26:41 -0400 Subject: Created three distinct names for wiki and page that are suitable for URL, HTML, and raw display. Implemented in new wiki POST activity only so far. --- include/wiki.php | 56 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/include/wiki.php b/include/wiki.php index 84e7d8dfa..822cb1b88 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -33,11 +33,11 @@ function wiki_page_list($resource_id) { return array('pages' => $pages); } -function wiki_init_wiki($channel, $name) { +function wiki_init_wiki($channel, $wiki) { // Store the path as a relative path, but pass absolute path to mkdir - $path = 'store/[data]/git/'.$channel['channel_address'].'/wiki/'.$name; + $path = 'store/[data]/git/'.$channel['channel_address'].'/wiki/'.$wiki['urlName']; if (!os_mkdir(__DIR__ . '/../' . $path, 0770, true)) { - logger('Error creating wiki path: ' . $name); + logger('Error creating wiki path: ' . $path); return null; } // Create GitRepo object @@ -50,8 +50,8 @@ function wiki_init_wiki($channel, $name) { return array('path' => $path); } -function wiki_create_wiki($channel, $observer_hash, $name, $acl) { - $wikiinit = wiki_init_wiki($channel, $name); +function wiki_create_wiki($channel, $observer_hash, $wiki, $acl) { + $wikiinit = wiki_init_wiki($channel, $wiki); if (!$wikiinit['path']) { notice('Error creating wiki'); return array('item' => null, 'success' => false); @@ -73,7 +73,7 @@ function wiki_create_wiki($channel, $observer_hash, $name, $acl) { $mid = item_message_id(); $arr = array(); // Initialize the array of parameters for the post $item_hidden = 0; // TODO: Allow form creator to send post to ACL about new game automatically - $wiki_url = z_root() . '/wiki/' . $channel['channel_address'] . '/' . $name; + $wiki_url = z_root() . '/wiki/' . $channel['channel_address'] . '/' . $wiki['urlName']; $arr['aid'] = $channel['channel_account_id']; $arr['uid'] = $channel['channel_id']; $arr['mid'] = $mid; @@ -85,7 +85,7 @@ function wiki_create_wiki($channel, $observer_hash, $name, $acl) { $arr['author_xchan'] = $observer_hash; $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid']; $arr['llink'] = $arr['plink']; - $arr['title'] = $name; // name of new wiki; + $arr['title'] = $wiki['htmlName']; // name of new wiki; $arr['allow_cid'] = $ac['allow_cid']; $arr['allow_gid'] = $ac['allow_gid']; $arr['deny_cid'] = $ac['deny_cid']; @@ -96,11 +96,21 @@ function wiki_create_wiki($channel, $observer_hash, $name, $acl) { $arr['item_private'] = intval($acl->is_private()); $arr['verb'] = ACTIVITY_CREATE; $arr['obj_type'] = ACTIVITY_OBJ_WIKI; - $arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $name . '[/zrl][/td][/tr][/table]'; + $arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $wiki['htmlName'] . '[/zrl][/td][/tr][/table]'; // Save the path using iconfig. The file path should not be shared with other hubs if (!set_iconfig($arr, 'wiki', 'path', $path, false)) { return array('item' => null, 'success' => false); } + // Save the wiki name information using iconfig. This is shareable. + if (!set_iconfig($arr, 'wiki', 'rawName', $wiki['rawName'], true)) { + return array('item' => null, 'success' => false); + } + if (!set_iconfig($arr, 'wiki', 'htmlName', $wiki['htmlName'], true)) { + return array('item' => null, 'success' => false); + } + if (!set_iconfig($arr, 'wiki', 'urlName', $wiki['urlName'], true)) { + return array('item' => null, 'success' => false); + } $post = item_store($arr); $item_id = $post['item_id']; @@ -136,15 +146,23 @@ function wiki_get_wiki($resource_id) { if (!$item) { return array('wiki' => null, 'path' => null); } else { - $w = $item[0]; - //$object = json_decode($w['object'], true); + $w = $item[0]; // wiki item table record + // Get wiki metadata + $rawName = get_iconfig($w, 'wiki', 'rawName'); + $htmlName = get_iconfig($w, 'wiki', 'htmlName'); + $urlName = get_iconfig($w, 'wiki', 'urlName'); $path = get_iconfig($w, 'wiki', 'path'); if (!realpath(__DIR__ . '/../' . $path)) { return array('wiki' => null, 'path' => null); } // Path to wiki exists $abs_path = realpath(__DIR__ . '/../' . $path); - return array('wiki' => $w, 'path' => $abs_path); + return array( 'wiki' => $w, + 'path' => $abs_path, + 'rawName' => $rawName, + 'htmlName' => $htmlName, + 'urlName' => $urlName + ); } } @@ -180,15 +198,16 @@ function wiki_create_page($name, $resource_id) { if (!$w['path']) { return array('page' => null, 'message' => 'Wiki not found.', 'success' => false); } - $page_path = $w['path'] . '/' . $name; + $page = array('rawName' => $name, 'htmlName' => escape_tags($name), 'urlName' => urlencode(escape_tags($name)), 'fileName' => wiki_generate_page_filename($name)); + $page_path = $w['path'] . '/' . $page['urlName']; if (is_file($page_path)) { return array('page' => null, 'message' => 'Page already exists.', 'success' => false); } - // Create file called $name in the path + // Create the page file in the wiki repo if(!touch($page_path)) { return array('page' => null, 'message' => 'Page file cannot be created.', 'success' => false); } else { - return array('wiki' => $wikiname, 'message' => '', 'success' => true); + return array('page' => $page, 'message' => '', 'success' => true); } } @@ -298,3 +317,12 @@ function wiki_git_commit($arr) { json_return_and_die(array('message' => 'GitRepo error thrown', 'success' => false)); } } + +function wiki_generate_page_filename($name) { + $file = urlencode(escape_tags($name)); + if( $file === '') { + return null; + } else { + return $file . '.md'; + } +} \ No newline at end of file -- cgit v1.2.3 From 344c293424716cc53eed2fea9eb3a7512e725516 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 4 Jun 2016 15:12:04 -0400 Subject: Wiki and page filenames are abstracted from their displayed names. Special characters do not seem to break things. --- include/widgets.php | 10 ++++++---- include/wiki.php | 50 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 36 insertions(+), 24 deletions(-) (limited to 'include') diff --git a/include/widgets.php b/include/widgets.php index b5c3b425a..9ea517a2d 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -897,13 +897,15 @@ function widget_wiki_pages($arr) { $p = wiki_page_list($arr['resource_id']); if ($p['pages']) { $pages = $p['pages']; - $w = wiki_get_wiki($arr['resource_id']); - $wikiname = $w['wiki']['title']; + $w = $p['wiki']; + // Wiki item record is $w['wiki'] + $wikiname = $w['urlName']; if (!$wikiname) { $wikiname = ''; } } } + logger('pages: ' . json_encode($pages)); return replace_macros(get_markup_template('wiki_page_list.tpl'), array( '$hide' => $hide, '$not_refresh' => $not_refresh, @@ -916,9 +918,9 @@ function widget_wiki_pages($arr) { function widget_wiki_page_history($arr) { require_once("include/wiki.php"); - $pagename = ((array_key_exists('page', $arr)) ? $arr['page'] : ''); + $pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : ''); $resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : ''); - $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'page' => $pagename)); + $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); return replace_macros(get_markup_template('wiki_page_history.tpl'), array( '$pageHistory' => $pageHistory['history'] diff --git a/include/wiki.php b/include/wiki.php index 822cb1b88..ccf47ef9a 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -13,6 +13,12 @@ function wiki_list($channel, $observer_hash) { dbesc(WIKI_ITEM_RESOURCE_TYPE), intval($channel['channel_id']) ); + foreach($wikis as &$w) { + $w['rawName'] = get_iconfig($w, 'wiki', 'rawName'); + $w['htmlName'] = get_iconfig($w, 'wiki', 'htmlName'); + $w['urlName'] = get_iconfig($w, 'wiki', 'urlName'); + $w['path'] = get_iconfig($w, 'wiki', 'path'); + } // TODO: query db for wikis the observer can access. Return with two lists, for read and write access return array('wikis' => $wikis); } @@ -21,16 +27,20 @@ function wiki_page_list($resource_id) { // TODO: Create item table records for pages so that metadata like title can be applied $w = wiki_get_wiki($resource_id); if (!$w['path']) { - return array('pages' => null); + return array('pages' => null, 'wiki' => null); } $pages = array(); if (is_dir($w['path']) === true) { $files = array_diff(scandir($w['path']), array('.', '..', '.git')); // TODO: Check that the files are all text files - $pages = $files; + + foreach($files as $file) { + // strip the .md file extension and unwrap URL encoding to leave HTML encoded name + $pages[] = array('title' => urldecode(substr($file, 0, -3)), 'url' => urlencode(substr($file, 0, -3))); + } } - return array('pages' => $pages); + return array('pages' => $pages, 'wiki' => $w); } function wiki_init_wiki($channel, $wiki) { @@ -166,10 +176,10 @@ function wiki_get_wiki($resource_id) { } } -function wiki_exists_by_name($uid, $name) { +function wiki_exists_by_name($uid, $urlName) { $item = q("SELECT id,resource_id FROM item WHERE resource_type = '%s' AND title = '%s' AND uid = '%s' AND item_deleted = 0 limit 1", dbesc(WIKI_ITEM_RESOURCE_TYPE), - dbesc($name), + dbesc(escape_tags(urldecode($urlName))), dbesc($uid) ); if (!$item) { @@ -196,31 +206,31 @@ function wiki_get_permissions($resource_id, $owner_id, $observer_hash) { function wiki_create_page($name, $resource_id) { $w = wiki_get_wiki($resource_id); if (!$w['path']) { - return array('page' => null, 'message' => 'Wiki not found.', 'success' => false); + return array('page' => null, 'wiki' => null, 'message' => 'Wiki not found.', 'success' => false); } - $page = array('rawName' => $name, 'htmlName' => escape_tags($name), 'urlName' => urlencode(escape_tags($name)), 'fileName' => wiki_generate_page_filename($name)); - $page_path = $w['path'] . '/' . $page['urlName']; + $page = array('rawName' => $name, 'htmlName' => escape_tags($name), 'urlName' => urlencode(escape_tags($name)), 'fileName' => urlencode(escape_tags($name)).'.md'); + $page_path = $w['path'] . '/' . $page['fileName']; if (is_file($page_path)) { - return array('page' => null, 'message' => 'Page already exists.', 'success' => false); + return array('page' => null, 'wiki' => null, 'message' => 'Page already exists.', 'success' => false); } // Create the page file in the wiki repo if(!touch($page_path)) { - return array('page' => null, 'message' => 'Page file cannot be created.', 'success' => false); + return array('page' => null, 'wiki' => null, 'message' => 'Page file cannot be created.', 'success' => false); } else { - return array('page' => $page, 'message' => '', 'success' => true); + return array('page' => $page, 'wiki' => $w, 'message' => '', 'success' => true); } } function wiki_get_page_content($arr) { - $page = ((array_key_exists('page',$arr)) ? $arr['page'] : ''); - // TODO: look for page resource_id and retrieve that way alternatively + $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : ''); $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : ''); $w = wiki_get_wiki($resource_id); if (!$w['path']) { return array('content' => null, 'message' => 'Error reading wiki', 'success' => false); } - $page_path = $w['path'].'/'.escape_tags(urlencode($page)); + $page_path = $w['path'].'/'.$pageUrlName.'.md'; + logger('$page_path: ' . $page_path); if (is_readable($page_path) === true) { if(filesize($page_path) === 0) { $content = ''; @@ -236,13 +246,13 @@ function wiki_get_page_content($arr) { } function wiki_page_history($arr) { - $pagename = ((array_key_exists('page',$arr)) ? $arr['page'] : ''); + $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : ''); $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : ''); $w = wiki_get_wiki($resource_id); if (!$w['path']) { return array('history' => null, 'message' => 'Error reading wiki', 'success' => false); } - $page_path = $w['path'].'/'.$pagename; + $page_path = $w['path'].'/'.$pageUrlName.'.md'; if (!is_readable($page_path) === true) { return array('history' => null, 'message' => 'Cannot read wiki page: ' . $page_path, 'success' => false); } @@ -252,7 +262,7 @@ function wiki_page_history($arr) { } $git = new GitRepo('', null, false, $w['wiki']['title'], $w['path']); try { - $gitlog = $git->git->log('', $page_path , array('limit' => 50)); + $gitlog = $git->git->log('', $page_path , array('limit' => 500)); logger('gitlog: ' . json_encode($gitlog)); return array('history' => $gitlog, 'message' => '', 'success' => true); } catch (\PHPGit\Exception\GitException $e) { @@ -261,14 +271,14 @@ function wiki_page_history($arr) { } function wiki_save_page($arr) { - $pagename = ((array_key_exists('name',$arr)) ? $arr['name'] : ''); + $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : ''); $content = ((array_key_exists('content',$arr)) ? $arr['content'] : ''); $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : ''); $w = wiki_get_wiki($resource_id); if (!$w['path']) { return array('message' => 'Error reading wiki', 'success' => false); } - $page_path = $w['path'].'/'.$pagename; + $page_path = $w['path'].'/'.$pageUrlName.'.md'; if (is_writable($page_path) === true) { if(!file_put_contents($page_path, $content)) { return array('message' => 'Error writing to page file', 'success' => false); @@ -288,7 +298,7 @@ function wiki_git_commit($arr) { if (!$w['path']) { return array('message' => 'Error reading wiki', 'success' => false); } - $reponame = ((array_key_exists('title', $w['wiki'])) ? $w['wiki']['title'] : 'repo'); + $reponame = ((array_key_exists('title', $w['wiki'])) ? urlencode($w['wiki']['title']) : 'repo'); if($reponame === '') { $reponame = 'repo'; } -- cgit v1.2.3 From 4bc4fd5b7ebd7c5f25cfc9acfbda5b14a38dedb8 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 4 Jun 2016 18:00:32 -0400 Subject: Page deletion implemented. Hide the delete button and disallow for Home page. --- include/wiki.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include') diff --git a/include/wiki.php b/include/wiki.php index ccf47ef9a..1f90fae1e 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -289,6 +289,24 @@ function wiki_save_page($arr) { } } +function wiki_delete_page($arr) { + $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : ''); + $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : ''); + $w = wiki_get_wiki($resource_id); + if (!$w['path']) { + return array('message' => 'Error reading wiki', 'success' => false); + } + $page_path = $w['path'].'/'.$pageUrlName.'.md'; + if (is_writable($page_path) === true) { + if(!unlink($page_path)) { + return array('message' => 'Error deleting page file', 'success' => false); + } + return array('message' => '', 'success' => true); + } else { + return array('message' => 'Page file not writable', 'success' => false); + } +} + function wiki_git_commit($arr) { $files = ((array_key_exists('files', $arr)) ? $arr['files'] : null); $commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : 'Repo updated'); -- cgit v1.2.3 From 2c7ce20ccf9bb71a67ba24d238fd6a7361320b3e Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 4 Jun 2016 15:04:14 -0700 Subject: cross-site encoding issue with tags --- include/items.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/items.php b/include/items.php index f473b2bac..3b73310fe 100755 --- a/include/items.php +++ b/include/items.php @@ -1183,7 +1183,7 @@ function encode_item_terms($terms,$mirror = false) { if($terms) { foreach($terms as $term) { if(in_array($term['ttype'],$allowed_export_terms)) - $ret[] = array('tag' => $term['term'], 'url' => $term['url'], 'ttype' => termtype($term['type'])); + $ret[] = array('tag' => $term['term'], 'url' => $term['url'], 'type' => termtype($term['type'])); } } @@ -1240,11 +1240,9 @@ function decode_tags($t) { $ret = array(); foreach($t as $x) { $tag = array(); - if(array_key_exists('type',$x)) - $x['ttype'] = $x['type']; $tag['term'] = htmlspecialchars($x['tag'], ENT_COMPAT, 'UTF-8', false); $tag['url'] = htmlspecialchars($x['url'], ENT_COMPAT, 'UTF-8', false); - switch($x['ttype']) { + switch($x['type']) { case 'hashtag': $tag['ttype'] = TERM_HASHTAG; break; -- cgit v1.2.3 From a6012af00d13bdab1806b7ae172d271d4ad9ebe5 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 4 Jun 2016 17:06:12 -0700 Subject: For emojis in posts, extend smilies and save a lot of duplication of effort --- include/bbcode.php | 14 -------------- include/text.php | 12 ++++++++++++ 2 files changed, 12 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/include/bbcode.php b/include/bbcode.php index ed332146f..42741b392 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -66,19 +66,6 @@ function bb_unspacefy_and_trim($st) { } -function bb_emoji($mtch) { - $s = strtolower($mtch[1]); - if(strpos($s,'x')) { - $e = substr($s,strpos($s,'x')+1); - if(file_exists('images/emoji/' . $e . '.png')) { - return 'emoji'; - } - else { - return $mtch[0]; - } - } -} - function bb_extract_images($body) { $saved_image = array(); @@ -1014,7 +1001,6 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false) $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim', $Text); } - $Text = preg_replace_callback('/\[\&\;([#a-z0-9]+)\;\]/', 'bb_emoji', $Text); $Text = preg_replace('/\[\&\;([#a-z0-9]+)\;\]/', '&$1;', $Text); // fix any escaped ampersands that may have been converted into links diff --git a/include/text.php b/include/text.php index 72db9c5ea..5d0010bd5 100644 --- a/include/text.php +++ b/include/text.php @@ -1155,6 +1155,18 @@ function list_smilies() { ); + $x = get_config('feature','emoji'); + if($x === false) + $x = 1; + if($x) { + if(! App::$emojitab) + App::$emojitab = json_decode(file_get_contents('library/emoji.json'),true); + foreach(App::$emojitab as $e) { + $texts[] = $e['shortname']; + $icons[] = '' . $e['name'] . ''; + } + } + $params = array('texts' => $texts, 'icons' => $icons); call_hooks('smilie', $params); -- cgit v1.2.3 From 81f6511d340ce986e9a8ff06bbc27070818f690a Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 4 Jun 2016 17:09:37 -0700 Subject: return of the project smilie --- include/text.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/text.php b/include/text.php index 5d0010bd5..7495f01bd 100644 --- a/include/text.php +++ b/include/text.php @@ -1115,8 +1115,8 @@ function list_smilies() { ':coffee', ':facepalm', ':like', - ':dislike' - + ':dislike', + ':hubzilla' ); $icons = array( @@ -1152,6 +1152,7 @@ function list_smilies() { ':facepalm', ':like', ':dislike', + ':hubzilla', ); -- cgit v1.2.3 From bf438f67e15853488a0b2209194ce3365b918ca8 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 4 Jun 2016 17:13:55 -0700 Subject: the :tone variants are messed up, remove them --- include/text.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/text.php b/include/text.php index 7495f01bd..7d1e22170 100644 --- a/include/text.php +++ b/include/text.php @@ -1163,6 +1163,8 @@ function list_smilies() { if(! App::$emojitab) App::$emojitab = json_decode(file_get_contents('library/emoji.json'),true); foreach(App::$emojitab as $e) { + if(strpos($e['shortname'],':tone') === 0) + continue; $texts[] = $e['shortname']; $icons[] = '' . $e['name'] . ''; } -- cgit v1.2.3 From c1a24d44a35feca7539df6aa6909b00062072d28 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 4 Jun 2016 17:17:48 -0700 Subject: another switch of type and ttype --- include/items.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/items.php b/include/items.php index 3b73310fe..93385c6e6 100755 --- a/include/items.php +++ b/include/items.php @@ -1183,7 +1183,7 @@ function encode_item_terms($terms,$mirror = false) { if($terms) { foreach($terms as $term) { if(in_array($term['ttype'],$allowed_export_terms)) - $ret[] = array('tag' => $term['term'], 'url' => $term['url'], 'type' => termtype($term['type'])); + $ret[] = array('tag' => $term['term'], 'url' => $term['url'], 'type' => termtype($term['ttype'])); } } -- cgit v1.2.3 From dd6718c2cdf2cadaf7478b848eb892dcda1dc7e9 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 4 Jun 2016 18:10:42 -0700 Subject: provide a hover class for smiley emojis which renders them slightly larger on compatible devices when you single them out for inspection --- include/text.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/text.php b/include/text.php index 7d1e22170..1bc19da34 100644 --- a/include/text.php +++ b/include/text.php @@ -1166,7 +1166,7 @@ function list_smilies() { if(strpos($e['shortname'],':tone') === 0) continue; $texts[] = $e['shortname']; - $icons[] = '' . $e['name'] . ''; + $icons[] = '' . $e['name'] . ''; } } -- cgit v1.2.3 From 0a3fbdd128dd3b80868c93cb93901b501edf576c Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 5 Jun 2016 16:32:03 -0400 Subject: Basic page reversion implemented. The revert button on the history view replaces the editor text but does not save the page. --- include/wiki.php | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/wiki.php b/include/wiki.php index 1f90fae1e..cc948dee2 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -263,7 +263,6 @@ function wiki_page_history($arr) { $git = new GitRepo('', null, false, $w['wiki']['title'], $w['path']); try { $gitlog = $git->git->log('', $page_path , array('limit' => 500)); - logger('gitlog: ' . json_encode($gitlog)); return array('history' => $gitlog, 'message' => '', 'success' => true); } catch (\PHPGit\Exception\GitException $e) { return array('history' => null, 'message' => 'GitRepo error thrown', 'success' => false); @@ -307,6 +306,44 @@ function wiki_delete_page($arr) { } } +function wiki_revert_page($arr) { + $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : ''); + $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : ''); + $commitHash = ((array_key_exists('commitHash',$arr)) ? $arr['commitHash'] : null); + if (! $commitHash) { + return array('content' => $content, 'message' => 'No commit has provided', 'success' => false); + } + $w = wiki_get_wiki($resource_id); + if (!$w['path']) { + return array('content' => $content, 'message' => 'Error reading wiki', 'success' => false); + } + $page_path = $w['path'].'/'.$pageUrlName.'.md'; + if (is_writable($page_path) === true) { + + $reponame = ((array_key_exists('title', $w['wiki'])) ? urlencode($w['wiki']['title']) : 'repo'); + if($reponame === '') { + $reponame = 'repo'; + } + $git = new GitRepo($observer['xchan_addr'], null, false, $w['wiki']['title'], $w['path']); + $content = null; + try { + $git->setIdentity($observer['xchan_name'], $observer['xchan_addr']); + foreach ($git->git->tree($commitHash) as $object) { + logger('tree object: ' . json_encode($object)); + if ($object['type'] == 'blob' && $object['file'] === $pageUrlName.'.md' ) { + $content = $git->git->cat->blob($object['hash']); + logger('content: ' . json_encode($content)); + } + } + } catch (\PHPGit\Exception\GitException $e) { + json_return_and_die(array('content' => $content, 'message' => 'GitRepo error thrown', 'success' => false)); + } + return array('content' => $content, 'message' => '', 'success' => true); + } else { + return array('content' => $content, 'message' => 'Page file not writable', 'success' => false); + } +} + function wiki_git_commit($arr) { $files = ((array_key_exists('files', $arr)) ? $arr['files'] : null); $commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : 'Repo updated'); -- cgit v1.2.3 From 4528becf4ccbeea3d63f729ed643b5fc7d67f1bb Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 5 Jun 2016 20:52:40 -0400 Subject: Remove debugging logger statements --- include/widgets.php | 1 - include/wiki.php | 3 --- 2 files changed, 4 deletions(-) (limited to 'include') diff --git a/include/widgets.php b/include/widgets.php index 9ea517a2d..5237b1a30 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -905,7 +905,6 @@ function widget_wiki_pages($arr) { } } } - logger('pages: ' . json_encode($pages)); return replace_macros(get_markup_template('wiki_page_list.tpl'), array( '$hide' => $hide, '$not_refresh' => $not_refresh, diff --git a/include/wiki.php b/include/wiki.php index cc948dee2..23a22007f 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -230,7 +230,6 @@ function wiki_get_page_content($arr) { return array('content' => null, 'message' => 'Error reading wiki', 'success' => false); } $page_path = $w['path'].'/'.$pageUrlName.'.md'; - logger('$page_path: ' . $page_path); if (is_readable($page_path) === true) { if(filesize($page_path) === 0) { $content = ''; @@ -329,10 +328,8 @@ function wiki_revert_page($arr) { try { $git->setIdentity($observer['xchan_name'], $observer['xchan_addr']); foreach ($git->git->tree($commitHash) as $object) { - logger('tree object: ' . json_encode($object)); if ($object['type'] == 'blob' && $object['file'] === $pageUrlName.'.md' ) { $content = $git->git->cat->blob($object['hash']); - logger('content: ' . json_encode($content)); } } } catch (\PHPGit\Exception\GitException $e) { -- cgit v1.2.3 From adecd2960e2b7cdca8a23e5c4e8d80645407b513 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 5 Jun 2016 22:18:17 -0700 Subject: move pconfig to static class --- include/config.php | 180 ++--------------------------------------------------- 1 file changed, 6 insertions(+), 174 deletions(-) (limited to 'include') diff --git a/include/config.php b/include/config.php index fe7cbead6..d0ae4af39 100644 --- a/include/config.php +++ b/include/config.php @@ -60,201 +60,33 @@ function del_config($family, $key) { } - - - -/** - * @brief Loads all configuration values of a channel into a cached storage. - * - * All configuration values of the given channel are stored in global cache - * which is available under the global variable App::$config[$uid]. - * - * @param string $uid - * The channel_id - * @return void|false Nothing or false if $uid is false - */ - function load_pconfig($uid) { - if($uid === false) - return false; - - if(! array_key_exists($uid, App::$config)) - App::$config[$uid] = array(); + Zlib\PConfig::Load($uid); - $r = q("SELECT * FROM pconfig WHERE uid = %d", - intval($uid) - ); - - if($r) { - foreach($r as $rr) { - $k = $rr['k']; - $c = $rr['cat']; - if(! array_key_exists($c, App::$config[$uid])) { - App::$config[$uid][$c] = array(); - App::$config[$uid][$c]['config_loaded'] = true; - } - App::$config[$uid][$c][$k] = $rr['v']; - } - } } -/** - * @brief Get a particular channel's config variable given the category name - * ($family) and a key. - * - * Get a particular channel's config value from the given category ($family) - * and the $key from a cached storage in App::$config[$uid]. - * - * Returns false if not set. - * - * @param string $uid - * The channel_id - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to query - * @param boolean $instore (deprecated, without function) - * @return mixed Stored value or false if it does not exist - */ function get_pconfig($uid, $family, $key, $instore = false) { -// logger('include/config.php: get_pconfig() deprecated instore param used', LOGGER_DEBUG); - - if($uid === false) - return false; - if(! array_key_exists($uid, App::$config)) - load_pconfig($uid); + return Zlib\PConfig::Get($uid,$family,$key,$instore = false); - if((! array_key_exists($family, App::$config[$uid])) || (! array_key_exists($key, App::$config[$uid][$family]))) - return false; - - return ((! is_array(App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', App::$config[$uid][$family][$key])) - ? unserialize(App::$config[$uid][$family][$key]) - : App::$config[$uid][$family][$key] - ); } -/** - * @brief Sets a configuration value for a channel. - * - * Stores a config value ($value) in the category ($family) under the key ($key) - * for the channel_id $uid. - * - * @note Please do not store booleans - convert to 0/1 integer values! - * - * @param string $uid - * The channel_id - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to set - * @param string $value - * The value to store - * @return mixed Stored $value or false - */ -function set_pconfig($uid, $family, $key, $value) { - - // this catches subtle errors where this function has been called - // with local_channel() when not logged in (which returns false) - // and throws an error in array_key_exists below. - // we provide a function backtrace in the logs so that we can find - // and fix the calling function. - - if($uid === false) { - btlogger('UID is FALSE!', LOGGER_NORMAL, LOG_ERR); - return; - } - - // manage array value - $dbvalue = ((is_array($value)) ? serialize($value) : $value); - $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); - if(get_pconfig($uid, $family, $key) === false) { - if(! array_key_exists($uid, App::$config)) - App::$config[$uid] = array(); - if(! array_key_exists($family, App::$config[$uid])) - App::$config[$uid][$family] = array(); - - // keep a separate copy for all variables which were - // set in the life of this page. We need this to - // synchronise channel clones. - - if(! array_key_exists('transient', App::$config[$uid])) - App::$config[$uid]['transient'] = array(); - if(! array_key_exists($family, App::$config[$uid]['transient'])) - App::$config[$uid]['transient'][$family] = array(); - - App::$config[$uid][$family][$key] = $value; - App::$config[$uid]['transient'][$family][$key] = $value; - - $ret = q("INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ", - intval($uid), - dbesc($family), - dbesc($key), - dbesc($dbvalue) - ); - if($ret) - return $value; - - return $ret; - } - - $ret = q("UPDATE pconfig SET v = '%s' WHERE uid = %d and cat = '%s' AND k = '%s'", - dbesc($dbvalue), - intval($uid), - dbesc($family), - dbesc($key) - ); - - // keep a separate copy for all variables which were - // set in the life of this page. We need this to - // synchronise channel clones. - - if(! array_key_exists('transient', App::$config[$uid])) - App::$config[$uid]['transient'] = array(); - if(! array_key_exists($family, App::$config[$uid]['transient'])) - App::$config[$uid]['transient'][$family] = array(); - - App::$config[$uid][$family][$key] = $value; - App::$config[$uid]['transient'][$family][$key] = $value; +function set_pconfig($uid, $family, $key, $value) { - if($ret) - return $value; + return Zlib\PConfig::Set($uid,$family,$key,$value); - return $ret; } -/** - * @brief Deletes the given key from the channel's configuration. - * - * Removes the configured value from the stored cache in App::$config[$uid] - * and removes it from the database. - * - * @param string $uid - * The channel_id - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to delete - * @return mixed - */ function del_pconfig($uid, $family, $key) { - $ret = false; - - if (x(App::$config[$uid][$family], $key)) - unset(App::$config[$uid][$family][$key]); - $ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'", - intval($uid), - dbesc($family), - dbesc($key) - ); + return Zlib\PConfig::Delete($uid,$family,$key); - return $ret; } + /** * @brief Loads a full xchan's configuration into a cached storage. * -- cgit v1.2.3 From 037cd74e8e02f048892208bedef0d16faef16af4 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 6 Jun 2016 19:44:22 -0700 Subject: rename admin/users to admin/accounts, provide sortable columns in account and channel summaries - issue #255 --- include/widgets.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/widgets.php b/include/widgets.php index 3448aeb5e..a1b9f1956 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -1378,7 +1378,7 @@ function widget_admin($arr) { $aside = array( 'site' => array(z_root() . '/admin/site/', t('Site'), 'site'), - 'users' => array(z_root() . '/admin/users/', t('Accounts'), 'users', 'pending-update', t('Member registrations waiting for confirmation')), + 'accounts' => array(z_root() . '/admin/accounts/', t('Accounts'), 'accounts', 'pending-update', t('Member registrations waiting for confirmation')), 'channels' => array(z_root() . '/admin/channels/', t('Channels'), 'channels'), 'security' => array(z_root() . '/admin/security/', t('Security'), 'security'), 'features' => array(z_root() . '/admin/features/', t('Features'), 'features'), -- cgit v1.2.3 From a50e555515f9635610c28a5756875ae8629f4eb9 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 7 Jun 2016 16:23:14 -0700 Subject: 'recent photos' query was buggered, also fix issue #163 by adding configurable sort order to the album widget - default is album name ascending --- include/photos.php | 28 +++++++++++++--------------- include/widgets.php | 4 +++- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/include/photos.php b/include/photos.php index 1cc64f6fa..c64d662ea 100644 --- a/include/photos.php +++ b/include/photos.php @@ -443,7 +443,7 @@ function photo_upload($channel, $observer, $args) { * * success (bool) * * albums (array) */ -function photos_albums_list($channel, $observer) { +function photos_albums_list($channel, $observer, $sort_key = 'album', $direction = 'asc') { $channel_id = $channel['channel_id']; $observer_xchan = (($observer) ? $observer['xchan_hash'] : ''); @@ -451,11 +451,15 @@ function photos_albums_list($channel, $observer) { if(! perm_is_allowed($channel_id, $observer_xchan, 'view_storage')) return false; - /** @FIXME create a permissions SQL which works on arbitrary observers and channels, regardless of login or web status */ - $sql_extra = permissions_sql($channel_id); + $sql_extra = permissions_sql($channel_id,$observer_xchan); + + $sort_key = dbesc($sort_key); + $direction = dbesc($direction); + + - $albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and photo_usage IN ( %d, %d ) $sql_extra group by album order by max(created) desc", + $albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and photo_usage IN ( %d, %d ) $sql_extra group by album order by $sort_key $direction", intval($channel_id), intval(PHOTO_NORMAL), intval(PHOTO_PROFILE) @@ -483,20 +487,14 @@ function photos_albums_list($channel, $observer) { return $ret; } -function photos_album_widget($channelx,$observer,$albums = null) { +function photos_album_widget($channelx,$observer,$sortkey = 'album',$direction = 'asc') { $o = ''; - // If we weren't passed an album list, see if the photos module - // dropped one for us to find in App::$data['albums']. - // If all else fails, load it. - - if(! $albums) { - if(array_key_exists('albums', App::$data)) - $albums = App::$data['albums']; - else - $albums = photos_albums_list($channelx,$observer); - } + if(array_key_exists('albums', App::$data)) + $albums = App::$data['albums']; + else + $albums = photos_albums_list($channelx,$observer,$sortkey,$direction); if($albums['success']) { $o = replace_macros(get_markup_template('photo_albums.tpl'),array( diff --git a/include/widgets.php b/include/widgets.php index a1b9f1956..312b63729 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -799,8 +799,10 @@ function widget_photo_albums($arr) { if((! $channelx) || (! perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_storage'))) return ''; require_once('include/photos.php'); + $sortkey = ((array_key_exists('sortkey',$arr)) ? $arr['sortkey'] : 'album'); + $direction = ((array_key_exists('direction',$arr)) ? $arr['direction'] : 'asc'); - return photos_album_widget($channelx, App::get_observer()); + return photos_album_widget($channelx, App::get_observer(),$sortkey,$direction); } -- cgit v1.2.3 From 5ef8199dae8f49cf04888799f1257beef0d2a0e0 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 7 Jun 2016 18:17:39 -0700 Subject: Finish the config family --- include/config.php | 386 +++-------------------------------------------------- 1 file changed, 18 insertions(+), 368 deletions(-) (limited to 'include') diff --git a/include/config.php b/include/config.php index d0ae4af39..209d22d42 100644 --- a/include/config.php +++ b/include/config.php @@ -33,449 +33,99 @@ use Zotlabs\Lib as Zlib; - - function load_config($family) { - Zlib\Config::Load($family); - } function get_config($family, $key) { - return Zlib\Config::Get($family,$key); - } function set_config($family, $key, $value) { - return Zlib\Config::Set($family,$key,$value); - } function del_config($family, $key) { - return Zlib\Config::Delete($family,$key); - } - function load_pconfig($uid) { - Zlib\PConfig::Load($uid); - } function get_pconfig($uid, $family, $key, $instore = false) { - return Zlib\PConfig::Get($uid,$family,$key,$instore = false); - } - function set_pconfig($uid, $family, $key, $value) { - return Zlib\PConfig::Set($uid,$family,$key,$value); - } function del_pconfig($uid, $family, $key) { - return Zlib\PConfig::Delete($uid,$family,$key); - } - - -/** - * @brief Loads a full xchan's configuration into a cached storage. - * - * All configuration values of the given observer hash are stored in global - * cache which is available under the global variable App::$config[$xchan]. - * - * @param string $xchan - * The observer's hash - * @return void|false Returns false if xchan is not set - */ function load_xconfig($xchan) { - - if(! $xchan) - return false; - - if(! array_key_exists($xchan, App::$config)) - App::$config[$xchan] = array(); - - $r = q("SELECT * FROM xconfig WHERE xchan = '%s'", - dbesc($xchan) - ); - - if($r) { - foreach($r as $rr) { - $k = $rr['k']; - $c = $rr['cat']; - if(! array_key_exists($c, App::$config[$xchan])) { - App::$config[$xchan][$c] = array(); - App::$config[$xchan][$c]['config_loaded'] = true; - } - App::$config[$xchan][$c][$k] = $rr['v']; - } - } + Zlib\XConfig::Load($xchan); } -/** - * @brief Get a particular observer's config variable given the category - * name ($family) and a key. - * - * Get a particular observer's config value from the given category ($family) - * and the $key from a cached storage in App::$config[$xchan]. - * - * Returns false if not set. - * - * @param string $xchan - * The observer's hash - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to query - * @return mixed Stored $value or false if it does not exist - */ function get_xconfig($xchan, $family, $key) { - - if(! $xchan) - return false; - - if(! array_key_exists($xchan, App::$config)) - load_xconfig($xchan); - - if((! array_key_exists($family, App::$config[$xchan])) || (! array_key_exists($key, App::$config[$xchan][$family]))) - return false; - - return ((! is_array(App::$config[$xchan][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', App::$config[$xchan][$family][$key])) - ? unserialize(App::$config[$xchan][$family][$key]) - : App::$config[$xchan][$family][$key] - ); + return Zlib\XConfig::Get($xchan,$family,$key); } -/** - * @brief Sets a configuration value for an observer. - * - * Stores a config value ($value) in the category ($family) under the key ($key) - * for the observer's $xchan hash. - * - * @note Please do not store booleans - convert to 0/1 integer values! - * - * @param string $xchan - * The observer's hash - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to set - * @param string $value - * The value to store - * @return mixed Stored $value or false - */ function set_xconfig($xchan, $family, $key, $value) { - - // manage array value - $dbvalue = ((is_array($value)) ? serialize($value) : $value); - $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); - - if(get_xconfig($xchan, $family, $key) === false) { - if(! array_key_exists($xchan, App::$config)) - App::$config[$xchan] = array(); - if(! array_key_exists($family, App::$config[$xchan])) - App::$config[$xchan][$family] = array(); - - App::$config[$xchan][$family][$key] = $value; - $ret = q("INSERT INTO xconfig ( xchan, cat, k, v ) VALUES ( '%s', '%s', '%s', '%s' ) ", - dbesc($xchan), - dbesc($family), - dbesc($key), - dbesc($dbvalue) - ); - if($ret) - return $value; - return $ret; - } - - $ret = q("UPDATE xconfig SET v = '%s' WHERE xchan = '%s' and cat = '%s' AND k = '%s'", - dbesc($dbvalue), - dbesc($xchan), - dbesc($family), - dbesc($key) - ); - - App::$config[$xchan][$family][$key] = $value; - - if($ret) - return $value; - return $ret; + return Zlib\XConfig::Set($xchan,$family,$key,$value); } -/** - * @brief Deletes the given key from the observer's config. - * - * Removes the configured value from the stored cache in App::$config[$xchan] - * and removes it from the database. - * - * @param string $xchan - * The observer's hash - * @param string $family - * The category of the configuration value - * @param string $key - * The configuration key to delete - * @return mixed - */ function del_xconfig($xchan, $family, $key) { - - $ret = false; - - if(x(App::$config[$xchan][$family], $key)) - unset(App::$config[$xchan][$family][$key]); - $ret = q("DELETE FROM xconfig WHERE xchan = '%s' AND cat = '%s' AND k = '%s'", - dbesc($xchan), - dbesc($family), - dbesc($key) - ); - return $ret; + return Zlib\XConfig::Delete($xchan,$family,$key); } - -// account configuration storage is built on top of the under-utilised xconfig - function load_aconfig($account_id) { - load_xconfig('a_' . $account_id); + Zlib\AConfig::Load($account_id); } function get_aconfig($account_id, $family, $key) { - return get_xconfig('a_' . $account_id, $family, $key); + return Zlib\AConfig::Get($account_id, $family, $key); } function set_aconfig($account_id, $family, $key, $value) { - return set_xconfig('a_' . $account_id, $family, $key, $value); + return Zlib\AConfig::Set($account_id, $family, $key, $value); } function del_aconfig($account_id, $family, $key) { - return del_xconfig('a_' . $account_id, $family, $key); + return Zlib\AConfig::Delete($account_id, $family, $key); } function load_abconfig($chash,$xhash) { - $r = q("select * from abconfig where chan = '%s' and xchan = '%s'", - dbesc($chash), - dbesc($xhash) - ); - return $r; + Zlib\AbConfig::Load($chash,$xhash); } function get_abconfig($chash,$xhash,$family,$key) { - $r = q("select * from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' limit 1", - dbesc($chash), - dbesc($xhash), - dbesc($family), - dbesc($key) - ); - if($r) { - return ((preg_match('|^a:[0-9]+:{.*}$|s', $r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']); - } - return false; + return Zlib\AbConfig::Get($chash,$xhash,$family,$key); } - function set_abconfig($chash,$xhash,$family,$key,$value) { - - $dbvalue = ((is_array($value)) ? serialize($value) : $value); - $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); - - if(get_abconfig($chash,$xhash,$family,$key) === false) { - $r = q("insert into abconfig ( chan, xchan, cat, k, v ) values ( '%s', '%s', '%s', '%s', '%s' ) ", - dbesc($chash), - dbesc($xhash), - dbesc($family), - dbesc($key), - dbesc($dbvalue) - ); - } - else { - $r = q("update abconfig set v = '%s' where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ", - dbesc($dbvalue), - dbesc($chash), - dbesc($xhash), - dbesc($family), - dbesc($key) - ); - } - if($r) - return $value; - return false; + return Zlib\AbConfig::Set($chash,$xhash,$family,$key,$value); } - function del_abconfig($chash,$xhash,$family,$key) { - - $r = q("delete from abconfig where chan = '%s' and xchan = '%s' and cat = '%s' and k = '%s' ", - dbesc($chash), - dbesc($xhash), - dbesc($family), - dbesc($key) - ); - - return $r; + return Zlib\AbConfig::Delete($chash,$xhash,$family,$key); } - - - - +function load_iconfig(&$item) { + Zlib\IConfig::Load($item); +} function get_iconfig(&$item, $family, $key) { - - $is_item = false; - if(is_array($item)) { - $is_item = true; - if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig']))) - $item['iconfig'] = array(); - - if(array_key_exists('item_id',$item)) - $iid = $item['item_id']; - else - $iid = $item['id']; - } - elseif(intval($item)) - $iid = $item; - - if(! $iid) - return false; - - if(is_array($item) && array_key_exists('iconfig',$item) && is_array($item['iconfig'])) { - foreach($item['iconfig'] as $c) { - if($c['iid'] == $iid && $c['cat'] == $family && $c['k'] == $key) - return $c['v']; - } - } - - $r = q("select * from iconfig where iid = %d and cat = '%s' and k = '%s' limit 1", - intval($iid), - dbesc($family), - dbesc($key) - ); - if($r) { - $r[0]['v'] = ((preg_match('|^a:[0-9]+:{.*}$|s',$r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']); - if($is_item) - $item['iconfig'][] = $r[0]; - return $r[0]['v']; - } - return false; - + return Zlib\IConfig::Get($item, $family, $key); } -/** - * set_iconfig(&$item, $family, $key, $value, $sharing = false); - * - * $item - item array or item id. If passed an array the iconfig meta information is - * added to the item structure (which will need to be saved with item_store eventually). - * If passed an id, the DB is updated, but may not be federated and/or cloned. - * $family - namespace of meta variable - * $key - key of meta variable - * $value - value of meta variable - * $sharing - boolean (default false); if true the meta information is propagated with the item - * to other sites/channels, mostly useful when $item is an array and has not yet been stored/delivered. - * If the meta information is added after delivery and you wish it to be shared, it may be necessary to - * alter the item edited timestamp and invoke the delivery process on the updated item. The edited - * timestamp needs to be altered in order to trigger an item_store_update() at the receiving end. - */ - - function set_iconfig(&$item, $family, $key, $value, $sharing = false) { - - $dbvalue = ((is_array($value)) ? serialize($value) : $value); - $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); - - $is_item = false; - $idx = null; - - if(is_array($item)) { - $is_item = true; - if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig']))) - $item['iconfig'] = array(); - elseif($item['iconfig']) { - for($x = 0; $x < count($item['iconfig']); $x ++) { - if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) { - $idx = $x; - } - } - } - $entry = array('cat' => $family, 'k' => $key, 'v' => $value, 'sharing' => $sharing); - - if(is_null($idx)) - $item['iconfig'][] = $entry; - else - $item['iconfig'][$idx] = $entry; - return $value; - } - - if(intval($item)) - $iid = intval($item); - - if(! $iid) - return false; - - if(get_iconfig($item, $family, $key) === false) { - $r = q("insert into iconfig( iid, cat, k, v, sharing ) values ( %d, '%s', '%s', '%s', %d ) ", - intval($iid), - dbesc($family), - dbesc($key), - dbesc($dbvalue), - intval($sharing) - ); - } - else { - $r = q("update iconfig set v = '%s', sharing = %d where iid = %d and cat = '%s' and k = '%s' ", - dbesc($dbvalue), - intval($sharing), - intval($iid), - dbesc($family), - dbesc($key) - ); - } - - if(! $r) - return false; - - return $value; + return Zlib\IConfig::Set($item, $family, $key, $value, $sharing = false); } - - function del_iconfig(&$item, $family, $key) { - - - $is_item = false; - $idx = null; - - if(is_array($item)) { - $is_item = true; - if(is_array($item['iconfig'])) { - for($x = 0; $x < count($item['iconfig']); $x ++) { - if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) { - unset($item['iconfig'][$x]); - } - } - } - return true; - } - - if(intval($item)) - $iid = intval($item); - - if(! $iid) - return false; - - return q("delete from iconfig where iid = %d and cat = '%s' and k = '%s' ", - intval($iid), - dbesc($family), - dbesc($key) - ); - + return Zlib\IConfig::Delete($item, $family, $key); } - -- cgit v1.2.3 From e46e7002a8945f3156b4c4dcfdedb57316d94ba9 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 7 Jun 2016 22:55:24 -0700 Subject: block random_profile from accessing sys channels --- include/connections.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/connections.php b/include/connections.php index d18383fad..2d10b8354 100644 --- a/include/connections.php +++ b/include/connections.php @@ -590,7 +590,8 @@ function random_profile() { for($i = 0; $i < $retryrandom; $i++) { - $r = q("select xchan_url from xchan left join hubloc on hubloc_hash = xchan_hash where hubloc_connected > %s - interval %s order by $randfunc limit 1", + $r = q("select xchan_url from xchan left join hubloc on hubloc_hash = xchan_hash where xchan_addr not like '%s' and hubloc_connected > %s - interval %s order by $randfunc limit 1", + dbesc('sys@%'), db_utcnow(), db_quoteinterval('30 day') ); -- cgit v1.2.3 From 9410b63bbc819955964706c876bc2f7ecea10adf Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Wed, 8 Jun 2016 06:26:27 -0400 Subject: Revised permissions checks across API and enabled collaborative editing using the write_pages per-channel permission. --- include/wiki.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/wiki.php b/include/wiki.php index 23a22007f..f0785d549 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -196,10 +196,19 @@ function wiki_get_permissions($resource_id, $owner_id, $observer_hash) { dbesc(WIKI_ITEM_RESOURCE_TYPE), dbesc($resource_id) ); - if(!$r) { + + if (!$r) { return array('read' => false, 'write' => false, 'success' => true); } else { - return array('read' => true, 'write' => false, 'success' => true); + $perms = get_all_perms($owner_id, $observer_hash); + // TODO: Create a new permission setting for wiki analogous to webpages. Until + // then, use webpage permissions + if (!$perms['write_pages']) { + $write = false; + } else { + $write = true; + } + return array('read' => true, 'write' => $write, 'success' => true); } } -- cgit v1.2.3 From 40bba93a310fab27fb14a9b6a55bcaab1530eba2 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 8 Jun 2016 19:34:11 -0700 Subject: potential fix to hubzilla-addons issue 16 --- include/api.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/api.php b/include/api.php index f0d886d9b..be525f7e9 100644 --- a/include/api.php +++ b/include/api.php @@ -1904,10 +1904,15 @@ require_once('include/api_auth.php'); $ret = array(); + $x = array('items' => $r,'api_user' => api_user(),'user_info' => $user_info); + call_hooks('api_format_items',$x); + $r = $x['items']; + if(! $r) return $ret; foreach($r as $item) { + localize_item($item); $status_user = (($item['author_xchan']==$user_info['guid'])?$user_info: api_item_get_user($a,$item)); -- cgit v1.2.3 From 96cd63cf1a569c03575c0a04a6b29509f886e981 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 10 Jun 2016 22:41:58 -0700 Subject: iconfig sharing not set correctly --- include/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/config.php b/include/config.php index 209d22d42..65199283d 100644 --- a/include/config.php +++ b/include/config.php @@ -123,7 +123,7 @@ function get_iconfig(&$item, $family, $key) { } function set_iconfig(&$item, $family, $key, $value, $sharing = false) { - return Zlib\IConfig::Set($item, $family, $key, $value, $sharing = false); + return Zlib\IConfig::Set($item, $family, $key, $value, $sharing); } function del_iconfig(&$item, $family, $key) { -- cgit v1.2.3 From e109abbef7fed77898da7adb9d43e686dc96c29a Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 12 Jun 2016 07:17:23 -0400 Subject: Apply purify_html to page content before preview and save to prevent JavaScript code injection. --- include/wiki.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/wiki.php b/include/wiki.php index f0785d549..4aa3fc1b4 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -279,7 +279,7 @@ function wiki_page_history($arr) { function wiki_save_page($arr) { $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : ''); - $content = ((array_key_exists('content',$arr)) ? $arr['content'] : ''); + $content = ((array_key_exists('content',$arr)) ? purify_html($arr['content']) : ''); $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : ''); $w = wiki_get_wiki($resource_id); if (!$w['path']) { -- cgit v1.2.3 From 7abfe716b47cd6f0171f0304ec07370c16dd595b Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 12 Jun 2016 16:34:27 -0700 Subject: DB schema issue with import --- include/import.php | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/import.php b/include/import.php index 6fcb08416..be456bfa9 100644 --- a/include/import.php +++ b/include/import.php @@ -122,6 +122,11 @@ function import_profiles($channel,$profiles) { $profile['aid'] = get_account_id(); $profile['uid'] = $channel['channel_id']; + convert_oldfields($profile,'name','fullname'); + convert_oldfields($profile,'with','partner'); + convert_oldfields($profile,'work','employment'); + + // we are going to reset all profile photos to the original // somebody will have to fix this later and put all the applicable photos into the export @@ -644,6 +649,10 @@ function import_events($channel,$events) { unset($event['id']); $event['aid'] = $channel['channel_account_id']; $event['uid'] = $channel['channel_id']; + convert_oldfields($event,'start','dtstart'); + convert_oldfields($event,'finish','dtend'); + convert_oldfields($event,'type','etype'); + convert_oldfields($event,'ignore','dismissed'); dbesc_array($event); $r = dbq("INSERT INTO event (`" @@ -677,6 +686,12 @@ function sync_events($channel,$events) { $event['aid'] = $channel['channel_account_id']; $event['uid'] = $channel['channel_id']; + convert_oldfields($event,'start','dtstart'); + convert_oldfields($event,'finish','dtend'); + convert_oldfields($event,'type','etype'); + convert_oldfields($event,'ignore','dismissed'); + + $exists = false; $x = q("select * from event where event_hash = '%s' and uid = %d limit 1", @@ -974,10 +989,7 @@ function sync_files($channel,$files) { $attachment_stored = false; foreach($f['attach'] as $att) { - if(array_key_exists('data',$att)) { - $att['content'] = $att['data']; - unset($att['data']); - } + convert_oldfields($att,'data','content'); if($att['deleted']) { attach_delete($channel,$att['hash']); @@ -1130,14 +1142,10 @@ function sync_files($channel,$files) { $p['aid'] = $channel['channel_account_id']; $p['uid'] = $channel['channel_id']; - if(array_key_exists('data',$p)) { - $p['content'] = $p['data']; - unset($p['data']); - } - if(array_key_exists('scale',$p)) { - $p['imgscale'] = $p['scale']; - unset($p['scale']); - } + convert_oldfields($p,'data','content'); + convert_oldfields($p,'scale','imgscale'); + convert_oldfields($p,'size','filesize'); + convert_oldfields($p,'type','mimetype'); // if this is a profile photo, undo the profile photo bit // for any other photo which previously held it. @@ -1228,3 +1236,9 @@ function sync_files($channel,$files) { } +function convert_oldfields(&$arr,$old,$new) { + if(array_key_exists($old,$arr)) { + $arr[$new] = $arr[$old]; + unset($arr[$old]); + } +} -- cgit v1.2.3 From ef1c01d968edde6fc880fef6afbf1474bf44c068 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 15 Jun 2016 05:28:16 -0700 Subject: add new connection to default group when auto-accepted --- include/follow.php | 2 +- include/zot.php | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/follow.php b/include/follow.php index 0c3973175..e5a74f85e 100644 --- a/include/follow.php +++ b/include/follow.php @@ -275,7 +275,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) call_hooks('follow', $arr); - /** If there is a default group for this channel, add this member to it */ + /** If there is a default group for this channel, add this connection to it */ if($default_group) { require_once('include/group.php'); diff --git a/include/zot.php b/include/zot.php index af79b5723..043139e2f 100644 --- a/include/zot.php +++ b/include/zot.php @@ -538,6 +538,16 @@ function zot_refresh($them, $channel = null, $force = false) { Zotlabs\Daemon\Master::Summon(array('Onepoll',$new_connection[0]['abook_id'])); } + + /** If there is a default group for this channel, add this connection to it */ + $default_group = $channel['channel_default_group']; + if($default_group) { + require_once('include/group.php'); + $g = group_rec_byhash($channel['channel_id'],$default_group); + if($g) + group_add_member($channel['channel_id'],'',$x['hash'],$g['id']); + } + unset($new_connection[0]['abook_id']); unset($new_connection[0]['abook_account']); unset($new_connection[0]['abook_channel']); -- cgit v1.2.3