diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/feedutils.php | 367 | ||||
-rw-r--r-- | include/network.php | 379 | ||||
-rw-r--r-- | include/photos.php | 1 |
3 files changed, 436 insertions, 311 deletions
diff --git a/include/feedutils.php b/include/feedutils.php index 477685f9a..a5161dc6e 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -2,20 +2,24 @@ /** - * @brief Generate an Atom feed. + * @brief Return an Atom feed for channel. + * + * @see get_feed_for() * * @param array $channel - * @param array $params + * @param array $params associative array which configures the feed + * @return string with an atom feed */ function get_public_feed($channel, $params) { - $type = 'xml'; +/* $type = 'xml'; $begin = NULL_DATE; $end = ''; $start = 0; $records = 40; $direction = 'desc'; $pages = 0; +*/ if(! $params) $params = array(); @@ -28,7 +32,7 @@ function get_public_feed($channel, $params) { $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'] : ''); + $params['cat'] = ((x($params,'cat')) ? $params['cat'] : ''); // put a sane lower limit on feed requests if not specified @@ -50,12 +54,12 @@ function get_public_feed($channel, $params) { } /** - * @brief + * @brief Create an atom feed for $channel from template. * * @param array $channel - * @param string $observer_hash + * @param string $observer_hash xchan_hash from observer * @param array $params - * @return string + * @return string with an atom feed */ function get_feed_for($channel, $observer_hash, $params) { @@ -74,14 +78,14 @@ function get_feed_for($channel, $observer_hash, $params) { 'datequery' => $params['end'], 'datequery2' => $params['begin'], 'start' => $params['start'], // FIXME - 'records' => $params['records'], // 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'); @@ -92,7 +96,7 @@ function get_feed_for($channel, $observer_hash, $params) { '$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)) , + '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)), '$hub' => '', // feed_hublinks(), '$salmon' => '', // feed_salmonlinks($channel['channel_address']), '$name' => xmlify($channel['channel_name']), @@ -129,10 +133,10 @@ function get_feed_for($channel, $observer_hash, $params) { } /** - * @brief + * @brief Return the verb for an item, or fall back to ACTIVITY_POST. * * @param array $item an associative array with - * * \b string \b verb + * * \e string \b verb * @return string item's verb if set, default ACTIVITY_POST see boot.php */ function construct_verb($item) { @@ -165,9 +169,11 @@ function construct_activity_object($item) { else $o .= '<link rel="alternate" type="text/html" href="' . xmlify($r->link) . '" />' . "\r\n"; } - if($r->content) + if($r->content) { $o .= '<content type="html" >' . xmlify(bbcode($r->content)) . '</content>' . "\r\n"; + } $o .= '</as:object>' . "\r\n"; + return $o; } @@ -210,14 +216,16 @@ function construct_activity_target($item) { } /** - * @param object $feed + * @brief Return an array with a parsed atom item. + * + * @param SimplePie $feed * @param array $item * @param[out] array $author - * @return multitype:multitype: string NULL number Ambigous <NULL, string, number> Ambigous <mixed, string> Ambigous <multitype:multitype:string Ambigous <NULL, string> , multitype:multitype:string unknown > multitype:NULL unknown + * @return array Associative array with the parsed item data */ function get_atom_elements($feed, $item, &$author) { - //$best_photo = array(); + require_once('include/html2bbcode.php'); $res = array(); @@ -246,7 +254,7 @@ function get_atom_elements($feed, $item, &$author) { // 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"])) + if (title_is_body($res['title'], $res['body'])) $res['title'] = ""; if($res['plink']) @@ -268,15 +276,14 @@ function get_atom_elements($feed, $item, &$author) { if((x($res,'verb')) && ($res['verb'] === 'http://ostatus.org/schema/1.0/unfollow')) $res['verb'] = ACTIVITY_UNFOLLOW; - - if(array_key_exists('verb',$res) && $res['verb'] === ACTIVITY_SHARE) { // For Mastodon shares ("boosts"), we need to parse the original author information - // from the activity:object -> author structure + // from the activity:object -> author structure $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'object'); if($rawobj) { - $rawauthor = $rawobj->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author'); + $rawauthor = $rawobj->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); + if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name']) { $author['author_name'] = unxmlify($rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name']); } @@ -313,7 +320,7 @@ function get_atom_elements($feed, $item, &$author) { $rawactor = $item->get_item_tags(NAMESPACE_ACTIVITY, 'actor'); - if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['obj_type'][0]['data'],ACTIVITY_OBJ_PERSON)) { + 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) { @@ -374,9 +381,9 @@ function get_atom_elements($feed, $item, &$author) { } } - $ostatus_protocol = (($item->get_item_tags(NAMESPACE_OSTATUS,'conversation')) ? true : false); + $ostatus_protocol = (($item->get_item_tags(NAMESPACE_OSTATUS, 'conversation')) ? true : false); - $apps = $item->get_item_tags(NAMESPACE_STATUSNET,'notice_info'); + $apps = $item->get_item_tags(NAMESPACE_STATUSNET, 'notice_info'); if($apps && $apps[0]['attribs']['']['source']) { $res['app'] = strip_tags(unxmlify($apps[0]['attribs']['']['source'])); } @@ -389,7 +396,7 @@ function get_atom_elements($feed, $item, &$author) { $rawenv = $item->get_item_tags(NAMESPACE_DFRN, 'env'); if(! $rawenv) - $rawenv = $item->get_item_tags(NAMESPACE_ZOT,'source'); + $rawenv = $item->get_item_tags(NAMESPACE_ZOT, 'source'); if($rawenv) { $have_real_body = true; $res['body'] = $rawenv[0]['data']; @@ -436,9 +443,9 @@ function get_atom_elements($feed, $item, &$author) { } - // strip title and don't apply "title-in-body" if the feed involved + // strip title and don't apply "title-in-body" if the feed involved // uses the OStatus stack. We need a more generalised way for the calling - // function to specify this behaviour or for plugins to alter it. + // function to specify this behaviour or for plugins to alter it. if($ostatus_protocol) { $res['title'] = ''; @@ -464,7 +471,7 @@ function get_atom_elements($feed, $item, &$author) { ); } - $private = $item->get_item_tags(NAMESPACE_DFRN,'private'); + $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 @@ -474,11 +481,11 @@ function get_atom_elements($feed, $item, &$author) { if($rawlocation) $res['location'] = unxmlify($rawlocation[0]['data']); - $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'published'); + $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'); + $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'); if($rawedited) $res['edited'] = unxmlify($rawedited[0]['data']); @@ -508,7 +515,7 @@ function get_atom_elements($feed, $item, &$author) { $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner'); if(! $rawowner) - $rawowner = $item->get_item_tags(NAMESPACE_ZOT,'owner'); + $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']); @@ -530,20 +537,21 @@ function get_atom_elements($feed, $item, &$author) { } } - $rawgeo = $item->get_item_tags(NAMESPACE_GEORSS,'point'); + $rawgeo = $item->get_item_tags(NAMESPACE_GEORSS, 'point'); if($rawgeo) $res['coord'] = unxmlify($rawgeo[0]['data']); - $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:')) { @@ -558,7 +566,7 @@ function get_atom_elements($feed, $item, &$author) { if($termterm) { $terms[] = array( 'otype' => TERM_OBJ_POST, - 'ttype' => $termtype, + 'ttype' => $termtype, 'url' => $termurl, 'term' => $termterm, ); @@ -615,6 +623,7 @@ function get_atom_elements($feed, $item, &$author) { $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)) { @@ -666,18 +675,28 @@ function get_atom_elements($feed, $item, &$author) { $res['target'] = $obj; } - - $arr = array('feed' => $feed, 'item' => $item, 'author' => $author, 'result' => $res); + // build array to pass to hook + $arr = [ + 'feed' => $feed, + 'item' => $item, + 'author' => $author, + 'result' => $res + ]; call_hooks('parse_atom', $arr); - logger('get_atom_elements: author: ' . print_r($arr['author'],true),LOGGER_DATA); - - logger('get_atom_elements: ' . print_r($arr['result'],true),LOGGER_DATA); + logger('author: ' .print_r($arr['author'], true), LOGGER_DATA); + logger('result: ' .print_r($arr['result'], true), LOGGER_DATA); return $arr['result']; } +/** + * @brief Encodes SimplePie_Item link arrays. + * + * @param array $links Array with SimplePie_Item link tags + * @return array + */ function encode_rel_links($links) { $o = array(); if(! ((is_array($links)) && (count($links)))) @@ -691,26 +710,27 @@ function encode_rel_links($links) { $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']) + 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']) + 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 + * @param string $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 + * @param array $contact[in,out] * 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. @@ -728,14 +748,12 @@ function encode_rel_links($links) { */ function consume_feed($xml, $importer, &$contact, $pass = 0) { - require_once('library/simplepie/simplepie.inc'); - if(! strlen($xml)) { - logger('consume_feed: empty input'); + logger('Empty input'); return; } - $sys_expire = intval(get_config('system','default_expire_days')); + $sys_expire = intval(get_config('system', 'default_expire_days')); $chn_expire = intval($importer['channel_expire_days']); $expire_days = $sys_expire; @@ -743,14 +761,19 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { 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); + + // We can preserve iframes because we will strip them in the purifier after + // checking for supported video sources. + $strip_htmltags = $feed->strip_htmltags; + array_splice($strip_htmltags, array_search('iframe', $strip_htmltags), 1); + $feed->strip_htmltags($strip_htmltags); + $feed->init(); if($feed->error()) - logger('consume_feed: Error parsing XML: ' . $feed->error()); + logger('Error parsing XML: ' . $feed->error()); $permalink = $feed->get_permalink(); @@ -784,7 +807,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $item = $r[0]; if(! intval($item['item_deleted'])) { - logger('consume_feed: deleting item ' . $item['id'] . ' mid=' . $item['mid'], LOGGER_DEBUG); + logger('deleting item ' . $item['id'] . ' mid=' . $item['mid'], LOGGER_DEBUG); drop_item($item['id'],false); } } @@ -796,7 +819,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { if($feed->get_item_quantity()) { - logger('consume_feed: feed item count = ' . $feed->get_item_quantity(), LOGGER_DEBUG); + logger('feed item count = ' . $feed->get_item_quantity(), LOGGER_DEBUG); $items = $feed->get_items(); @@ -805,7 +828,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $is_reply = false; $item_id = normalise_id($item->get_id()); - logger('consume_feed: processing ' . $raw_item_id, LOGGER_DEBUG); + logger('processing ' . $item->get_id(), LOGGER_DEBUG); $rawthread = $item->get_item_tags( NAMESPACE_THREAD,'in-reply-to'); if(isset($rawthread[0]['attribs']['']['ref'])) { @@ -827,7 +850,6 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { if($datarray['mid']) $datarray['mid'] = normalise_id($item->get_id()); - if($contact['xchan_network'] === 'rss') { $datarray['public_policy'] = 'specific'; $datarray['comment_policy'] = 'none'; @@ -882,11 +904,10 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $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); + logger('data: ' . print_r($datarray, true), LOGGER_DATA); $xx = item_store($datarray); $r = $xx['item_id']; @@ -908,7 +929,6 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { $datarray['comment_policy'] = 'none'; } - if(is_array($contact)) { if((! x($author,'author_name')) || ($author['author_is_feed'])) $author['author_name'] = $contact['xchan_name']; @@ -919,7 +939,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } if((! x($author,'author_name')) || (! x($author,'author_link'))) { - logger('consume_feed: no author information! ' . print_r($author,true)); + logger('No author information! ' . print_r($author,true)); continue; } @@ -931,6 +951,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { if($cb['caught']) { if($cb['return_code']) http_status_exit($cb['return_code']); + continue; } } @@ -955,7 +976,6 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { } - $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", dbesc($item_id), intval($importer['channel_id']) @@ -977,55 +997,58 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { 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); + if(! link_compare($author['owner_link'], $contact['xchan_url'])) { + logger('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)) + 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); + logger('author: ' . print_r($author, true), LOGGER_DEBUG); + logger('data: ' . print_r($datarray, true), LOGGER_DATA); $xx = item_store($datarray); $r = $xx['item_id']; + continue; } } } } - +/** + * @brief Normalise an id. + * + * Strip "X-ZOT:" from $id. + * + * @param string $id + * @return string + */ function normalise_id($id) { - return str_replace('X-ZOT:','',$id); + return str_replace('X-ZOT:', '', $id); } /** - * @brief Process atom feed and return the first post and structure + * @brief Process atom feed and return the first post and structure. * - * @param array $xml + * @param string $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; @@ -1033,6 +1056,13 @@ function process_salmon_feed($xml, $importer) { $feed = new SimplePie(); $feed->set_raw_data($xml); + + // We can preserve iframes because we will strip them in the purifier after + // checking for supported video sources. + $strip_htmltags = $feed->strip_htmltags; + array_splice($strip_htmltags, array_search('iframe', $strip_htmltags), 1); + $feed->strip_htmltags($strip_htmltags); + $feed->init(); if($feed->error()) @@ -1054,7 +1084,7 @@ function process_salmon_feed($xml, $importer) { logger('processing ' . $item_id, LOGGER_DEBUG); - $rawthread = $item->get_item_tags( NAMESPACE_THREAD,'in-reply-to'); + $rawthread = $item->get_item_tags( NAMESPACE_THREAD, 'in-reply-to'); if(isset($rawthread[0]['attribs']['']['ref'])) { $is_reply = true; $parent_mid = normalise_id($rawthread[0]['attribs']['']['ref']); @@ -1065,94 +1095,107 @@ function process_salmon_feed($xml, $importer) { $ret['author'] = array(); - $datarray = get_atom_elements($feed,$item,$ret['author']); + $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 + // This item is likely coming from GNU-social via salmon and allows public interaction $datarray['public_policy'] = ''; $datarray['comment_policy'] = ''; - $ret['item'] = $datarray; + $ret['item'] = $datarray; } } return $ret; } -/* - * Given an xml (atom) feed, find author and hub links - */ - +/** + * @brief Given an xml (atom) feed, find author and hub links. + * + * @param string $xml + * @return array + */ function feed_meta($xml) { - require_once('library/simplepie/simplepie.inc'); $ret = array(); - if(! strlen($xml)) { - logger('empty input'); - return $ret; - } + if(! strlen($xml)) { + logger('empty input'); + return $ret; + } - $feed = new SimplePie(); - $feed->set_raw_data($xml); - $feed->init(); + $feed = new SimplePie(); + $feed->set_raw_data($xml); + $feed->init(); - if($feed->error()) { - logger('Error parsing XML: ' . $feed->error()); + if($feed->error()) { + logger('Error parsing XML: ' . $feed->error()); return $ret; } - $ret['hubs'] = $feed->get_links('hub'); + $ret['hubs'] = $feed->get_links('hub'); + + //logger('hubs: ' . print_r($hubs,true), LOGGER_DATA); -// 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()); + $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)); + $rawauthor = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); + logger('rawauthor: ' . print_r($rawauthor, true)); - if($rawauthor) { + 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']); + $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); + if(substr($author['author_link'],-1,1) == '/') + $author['author_link'] = substr($author['author_link'],0,-1); - $ret['author'] = $author; + $ret['author'] = $author; return $ret; } - - -function update_feed_item($uid,$datarray) { - logger('update_feed_item: not implemented! ' . $uid . ' ' . print_r($datarray,true), LOGGER_DATA); +/** + * @brief Not yet implemented function to update feed item. + * + * @param int $uid + * @param array $datarray + */ +function update_feed_item($uid, $datarray) { + logger('Not implemented! ' . $uid . ' ' . print_r($datarray, true), LOGGER_DATA); } - -function handle_feed($uid,$abook_id,$url) { +/** + * @brief Fetch the content of a feed and further consume it. + * + * It will first process parent items and in a second run child items. + * @see consume_feed() + * + * @param int $uid + * @param int $abook_id + * @param string $url URL of the feed + */ +function handle_feed($uid, $abook_id, $url) { $channel = channelx_by_n($uid); if(! $channel) @@ -1164,18 +1207,29 @@ function handle_feed($uid,$abook_id,$url) { ); $recurse = 0; - $z = z_fetch_url($url,false,$recurse,array('novalidate' => true)); + $z = z_fetch_url($url, false, $recurse, array('novalidate' => true)); -//logger('handle_feed:' . print_r($z,true)); + //logger('data:' . print_r($z, true), LOGGER_DATA); if($z['success']) { - consume_feed($z['body'],$channel,$x[0],1); - consume_feed($z['body'],$channel,$x[0],2); + 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) { +/** + * @brief Return a XML tag with author information. + * + * @param string $tag The XML tag to create + * @param string $name Name of the author + * @param string $uri + * @param int $h image height + * @param int $w image width + * @param string $type profile photo mime type + * @param string $photo Fully qualified URL to a profile/avator photo + * @return string + */ +function atom_author($tag, $name, $uri, $h, $w, $type, $photo) { $o = ''; if(! $tag) return $o; @@ -1199,7 +1253,20 @@ function atom_author($tag,$name,$uri,$h,$w,$type,$photo) { return $o; } -function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { +/** + * @brief Create an item for the Atom feed. + * + * @see get_feed_for() + * + * @param array $item + * @param string $type + * @param array $author + * @param array $owner + * @param string $comment default false + * @param number $cid default 0 + * @return void|string + */ +function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0) { if(! $item['parent']) return; @@ -1207,7 +1274,6 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { if($item['deleted']) return '<at:deleted-entry ref="' . xmlify($item['mid']) . '" when="' . xmlify(datetime_convert('UTC','UTC',$item['edited'] . '+00:00',ATOM_TIME)) . '" />' . "\r\n"; - create_export_photo_body($item); if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid']) @@ -1227,12 +1293,11 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { 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 .= '<thr:in-reply-to ref="' . 'X-ZOT:' . xmlify($parent_item) . '" type="text/html" href="' . xmlify($item['plink']) . '" />' . "\r\n"; - } if(activity_match($item['obj_type'],ACTIVITY_OBJ_EVENT) && activity_match($item['verb'],ACTIVITY_POST)) { $obj = ((is_array($item['obj'])) ? $item['obj'] : json_decode($item['obj'],true)); - + $o .= '<title>' . xmlify($item['title']) . '</title>' . "\r\n"; $o .= '<summary xmlns="urn:ietf:params:xml:ns:xcal">' . xmlify(bbcode($obj['title'])) . '</summary>' . "\r\n"; $o .= '<dtstart xmlns="urn:ietf:params:xml:ns:xcal">' . datetime_convert('UTC','UTC', $obj['dtstart'],'Ymd\\THis' . (($obj['adjust']) ? '\\Z' : '')) . '</dtstart>' . "\r\n"; @@ -1270,13 +1335,13 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { $actobj = construct_activity_object($item); if(strlen($actobj)) $o .= $actobj; + $actarg = construct_activity_target($item); if(strlen($actarg)) $o .= $actarg; - if($item['attach']) { - $enclosures = json_decode($item['attach'],true); + $enclosures = json_decode($item['attach'], true); if($enclosures) { foreach($enclosures as $enc) { $o .= '<link rel="enclosure" ' @@ -1291,7 +1356,7 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { if($item['term']) { foreach($item['term'] as $term) { $scheme = ''; - $label = ''; + $label = ''; switch($term['ttype']) { case TERM_UNKNOWN: $scheme = NAMESPACE_ZOT . '/term/unknown'; @@ -1322,34 +1387,46 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { $o .= '</entry>' . "\r\n"; - $x = [ - 'item' => $item, - 'type' => $type, - 'author' => $author, - 'owner' => $owner, - 'comment' => $comment, - 'abook_id' => $cid, - 'entry' => $o + // build array to pass to hook + $x = [ + 'item' => $item, + 'type' => $type, + 'author' => $author, + 'owner' => $owner, + 'comment' => $comment, + 'abook_id' => $cid, + 'entry' => $o ]; - call_hooks('atom_entry', $x); return $x['entry']; } - +/** + * @brief + * + * @param array $items + * @return array + */ function gen_asld($items) { $ret = array(); if(! $items) return $ret; + foreach($items as $item) { $ret[] = i2asld($item); } + return $ret; } - +/** + * @brief + * + * @param array $i + * @return array + */ function i2asld($i) { if(! $i) @@ -1379,12 +1456,9 @@ function i2asld($i) { if($i['obj_type'] === ACTIVITY_OBJ_NOTE) $ret['object'] = asencode_note($i); - $ret['actor'] = asencode_person($i['author']); - return $ret; - } function asencode_note($i) { @@ -1395,6 +1469,7 @@ function asencode_note($i) { $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); diff --git a/include/network.php b/include/network.php index e6a6fc2b4..6cc53e8b5 100644 --- a/include/network.php +++ b/include/network.php @@ -75,7 +75,7 @@ function z_fetch_url($url, $binary = false, $redirects = 0, $opts = array()) { if(x($opts,'readfunc')) @curl_setopt($ch, CURLOPT_READFUNCTION, $opts['readfunc']); - // When using the session option and fetching from our own site, + // When using the session option and fetching from our own site, // append the PHPSESSID cookie to any existing headers. // Don't add to $opts['headers'] so that the cookie does not get // sent to other sites via redirects @@ -398,18 +398,22 @@ function json_return_and_die($x, $content_type = 'application/json') { } - -// Generic XML return -// Outputs a basic dfrn XML status structure to STDOUT, with a <status> variable -// of $st and an optional text <message> of $message and terminates the current process. - - +/** + * @brief Generic XML return. + * + * Outputs a basic dfrn XML status structure to STDOUT, with a <status> variable + * of $st and an optional text <message> of $message and terminates the current + * process. + * + * @param string $st + * @param string $message + */ function xml_status($st, $message = '') { $xml_message = ((strlen($message)) ? "\t<message>" . xmlify($message) . "</message>\r\n" : ''); if($st) - logger('xml_status returning non_zero: ' . $st . " message=" . $message); + logger('Returning non_zero: ' . $st . " message=" . $message); header( "Content-type: text/xml" ); echo '<?xml version="1.0" encoding="UTF-8"?>'."\r\n"; @@ -418,15 +422,13 @@ function xml_status($st, $message = '') { } - /** - * @brief Send HTTP status header + * @brief Send HTTP status header. * * @param int $val * integer HTTP status result value * @param string $msg * optional message - * @returns nil */ function http_status($val, $msg = '') { if ($val >= 400) @@ -434,12 +436,11 @@ function http_status($val, $msg = '') { if ($val >= 200 && $val < 300) $msg = (($msg) ? $msg : 'OK'); - logger('http_status_exit ' . $val . ' ' . $msg); + logger('' . $val . ' ' . $msg); header($_SERVER['SERVER_PROTOCOL'] . ' ' . $val . ' ' . $msg); } - /** * @brief Send HTTP status header and exit. * @@ -447,58 +448,57 @@ function http_status($val, $msg = '') { * integer HTTP status result value * @param string $msg * optional message - * @returns (does not return, process is terminated) + * @return does not return, process is terminated */ function http_status_exit($val, $msg = '') { http_status($val, $msg); killme(); } - - -// convert an XML document to a normalised, case-corrected array -// used by webfinger - - +/** + * @brief convert an XML document to a normalised, case-corrected array used by webfinger. + * + * @param string|array|SimpleXMLElement $xml_element + * @param int $recursion_depth[in,out] + * @return NULL|string|array + */ function convert_xml_element_to_array($xml_element, &$recursion_depth=0) { - // If we're getting too deep, bail out - if ($recursion_depth > 512) { - return(null); - } - - if (!is_string($xml_element) && - !is_array($xml_element) && - (get_class($xml_element) == 'SimpleXMLElement')) { - $xml_element_copy = $xml_element; - $xml_element = get_object_vars($xml_element); - } + // If we're getting too deep, bail out + if ($recursion_depth > 512) { + return(null); + } - if (is_array($xml_element)) { - $result_array = array(); - if (count($xml_element) <= 0) { - return (trim(strval($xml_element_copy))); - } + if (!is_string($xml_element) && + !is_array($xml_element) && + (get_class($xml_element) == 'SimpleXMLElement')) { + $xml_element_copy = $xml_element; + $xml_element = get_object_vars($xml_element); + } - foreach($xml_element as $key=>$value) { + if (is_array($xml_element)) { + $result_array = array(); + if (count($xml_element) <= 0) { + return (trim(strval($xml_element_copy))); + } - $recursion_depth++; - $result_array[strtolower($key)] = + foreach($xml_element as $key=>$value) { + $recursion_depth++; + $result_array[strtolower($key)] = convert_xml_element_to_array($value, $recursion_depth); - $recursion_depth--; - } - if ($recursion_depth == 0) { - $temp_array = $result_array; - $result_array = array( - strtolower($xml_element_copy->getName()) => $temp_array, - ); - } - - return ($result_array); - - } else { - return (trim(strval($xml_element))); + $recursion_depth--; } + if ($recursion_depth == 0) { + $temp_array = $result_array; + $result_array = array( + strtolower($xml_element_copy->getName()) => $temp_array, + ); + } + + return ($result_array); + } else { + return (trim(strval($xml_element))); + } } @@ -512,7 +512,7 @@ function z_dns_check($h,$check_mx = 0) { if(is_array(\App::$config) && array_key_exists('system',\App::$config) && is_array(\App::$config['system']) - && array_key_exists('do_not_check_dns',\App::$config['system']) + && array_key_exists('do_not_check_dns',\App::$config['system']) && \App::$config['system']['do_not_check_dns']) return true; @@ -520,56 +520,71 @@ function z_dns_check($h,$check_mx = 0) { //$opts = DNS_A + DNS_CNAME + DNS_PTR; //if($check_mx) // $opts += DNS_MX; - // Specific record type flags are unreliable on FreeBSD and Mac, - // so now we'll ignore these and just check for the existence of any DNS record. + // Specific record type flags are unreliable on FreeBSD and Mac, + // so now we'll ignore these and just check for the existence of any DNS record. return((@dns_get_record($h) || filter_var($h, FILTER_VALIDATE_IP)) ? true : false); - } -// Take a URL from the wild, prepend http:// if necessary -// and check DNS to see if it's real (or check if is a valid IP address) -// return true if it's OK, false if something is wrong with it - - +/** + * @brief Validates a given URL + * + * Take a URL from the wild, prepend http:// if necessary and check DNS to see + * if it's real (or check if is a valid IP address). + * + * @see z_dns_check() + * + * @param string $url[in,out] URL to check + * @return boolean Return true if it's OK, false if something is wrong with it + */ function validate_url(&$url) { // no naked subdomains (allow localhost for tests) - if(strpos($url,'.') === false && strpos($url,'/localhost/') === false) + if(strpos($url, '.') === false && strpos($url, '/localhost/') === false) return false; - if(substr($url,0,4) != 'http') + + if(substr($url, 0, 4) != 'http') $url = 'http://' . $url; + $h = @parse_url($url); if(($h) && z_dns_check($h['host'])) { return true; } + return false; } -// checks that email is an actual resolvable internet address - - +/** + * @brief Checks that email is an actual resolvable internet address. + * + * @param string $addr + * @return boolean + */ function validate_email($addr) { - if(get_config('system','disable_email_validation')) + if(get_config('system', 'disable_email_validation')) return true; - if(! strpos($addr,'@')) + if(! strpos($addr, '@')) return false; - $h = substr($addr,strpos($addr,'@') + 1); - if(($h) && z_dns_check($h,true)) { + $h = substr($addr, strpos($addr, '@') + 1); + + if(($h) && z_dns_check($h, true)) { return true; } + return false; } -// Check $url against our list of allowed sites, -// wildcards allowed. If allowed_sites is unset return true; -// If url is allowed, return true. -// otherwise, return false - - +/** + * @brief Check $url against our list of allowed sites. + * + * Wildcards allowed. If allowed_sites is unset return true. + * + * @param string $url + * @return boolean Return true if url is allowed, otherwise return false + */ function allowed_url($url) { $h = @parse_url($url); @@ -578,7 +593,7 @@ function allowed_url($url) { return false; } - $str_allowed = get_config('system','allowed_sites'); + $str_allowed = get_config('system', 'allowed_sites'); if(! $str_allowed) return true; @@ -606,21 +621,23 @@ function allowed_url($url) { return $found; } -// check if email address is allowed to register here. -// Compare against our list (wildcards allowed). -// Returns false if not allowed, true if allowed or if -// allowed list is not configured. - - +/** + * @brief Check if email address is allowed to register here. + * + * Compare against our list (wildcards allowed). + * + * @param string $email + * @return boolean Returns false if not allowed, true if allowed or if allowed list is + * not configured. + */ function allowed_email($email) { - - $domain = strtolower(substr($email,strpos($email,'@') + 1)); + $domain = strtolower(substr($email, strpos($email, '@') + 1)); if(! $domain) return false; - $str_allowed = get_config('system','allowed_email'); - $str_not_allowed = get_config('system','not_allowed_email'); + $str_allowed = get_config('system', 'allowed_email'); + $str_not_allowed = get_config('system', 'not_allowed_email'); if(! $str_allowed && ! $str_not_allowed) return true; @@ -631,7 +648,7 @@ function allowed_email($email) { $fnmatch = function_exists('fnmatch'); - $allowed = explode(',',$str_allowed); + $allowed = explode(',', $str_allowed); if(count($allowed)) { foreach($allowed as $a) { @@ -643,7 +660,7 @@ function allowed_email($email) { } } - $not_allowed = explode(',',$str_not_allowed); + $not_allowed = explode(',', $str_not_allowed); if(count($not_allowed)) { foreach($not_allowed as $na) { @@ -660,6 +677,7 @@ function allowed_email($email) { } elseif (!$str_allowed && !$found_not_allowed) { $return = true; } + return $return; } @@ -669,10 +687,12 @@ function parse_xml_string($s,$strict = true) { if($strict) { if(! strstr($s,'<?xml')) return false; + $s2 = substr($s,strpos($s,'<?xml')); } else $s2 = $s; + libxml_use_internal_errors(true); $x = @simplexml_load_string($s2); @@ -680,8 +700,10 @@ function parse_xml_string($s,$strict = true) { logger('libxml: parse: error: ' . $s2, LOGGER_DATA); foreach(libxml_get_errors() as $err) logger('libxml: parse: ' . $err->code." at ".$err->line.":".$err->column." : ".$err->message, LOGGER_DATA); + libxml_clear_errors(); } + return $x; } @@ -697,7 +719,7 @@ function scale_external_images($s, $include_link = true, $scale_replace = false) require_once('include/photo/photo_driver.php'); foreach($matches as $mtch) { - logger('scale_external_image: ' . $mtch[2] . ' ' . $mtch[3]); + logger('data: ' . $mtch[2] . ' ' . $mtch[3]); if(substr($mtch[1],0,1) == '=') { $owidth = intval(substr($mtch[2],1)); @@ -748,12 +770,12 @@ function scale_external_images($s, $include_link = true, $scale_replace = false) $ph->scaleImage(1024); $new_width = $ph->getWidth(); $new_height = $ph->getHeight(); - logger('scale_external_images: ' . $orig_width . '->' . $new_width . 'w ' . $orig_height . '->' . $new_height . 'h' . ' match: ' . $mtch[0], LOGGER_DEBUG); + logger('data: ' . $orig_width . '->' . $new_width . 'w ' . $orig_height . '->' . $new_height . 'h' . ' match: ' . $mtch[0], LOGGER_DEBUG); $s = str_replace($mtch[0],'[' . $tag . '=' . $new_width . 'x' . $new_height. ']' . $scaled . '[/' . $tag . ']' . "\n" . (($include_link) ? '[zrl=' . $mtch[2] . ']' . t('view full size') . '[/zrl]' . "\n" : ''),$s); - logger('scale_external_images: new string: ' . $s, LOGGER_DEBUG); + logger('new string: ' . $s, LOGGER_DEBUG); } } } @@ -768,27 +790,31 @@ function scale_external_images($s, $include_link = true, $scale_replace = false) } /** - * xml2array() will convert the given XML text to an array in the XML structure. + * @brief xml2array() will convert the given XML text to an array in the XML structure. + * * Link: http://www.bin-co.com/php/scripts/xml2array/ - * Portions significantly re-written by mike@macgirvin.com for Friendica (namespaces, lowercase tags, get_attribute default changed, more...) - * Arguments : $contents - The XML text - * $namespaces - true or false include namespace information in the returned array as array elements. - * $get_attributes - 1 or 0. If this is 1 the function will get the attributes as well as the tag values - this results in a different array structure in the return value. - * $priority - Can be 'tag' or 'attribute'. This will change the way the resulting array sturcture. For 'tag', the tags are given more importance. - * Return: The parsed XML in an array form. Use print_r() to see the resulting array structure. + * Portions significantly re-written by mike@macgirvin.com for Friendica + * (namespaces, lowercase tags, get_attribute default changed, more...) + * * Examples: $array = xml2array(file_get_contents('feed.xml')); - * $array = xml2array(file_get_contents('feed.xml', true, 1, 'attribute')); + * $array = xml2array(file_get_contents('feed.xml', true, 1, 'attribute')); + * + * @param string $contents The XML text + * @param boolean $namespaces true or false include namespace information in the returned array as array elements + * @param int $get_attributes 1 or 0. If this is 1 the function will get the attributes as well as the tag values - this results in a different array structure in the return value. + * @param string $priority Can be 'tag' or 'attribute'. This will change the way the resulting array sturcture. For 'tag', the tags are given more importance. + * + * @return array The parsed XML in an array form. Use print_r() to see the resulting array structure. */ - function xml2array($contents, $namespaces = true, $get_attributes=1, $priority = 'attribute') { - if(!$contents) return array(); + if(!$contents) + return array(); if(!function_exists('xml_parser_create')) { logger('xml2array: parser function missing'); return array(); } - libxml_use_internal_errors(true); libxml_clear_errors(); @@ -814,6 +840,7 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority = foreach(libxml_get_errors() as $err) logger('libxml: parse: ' . $err->code . " at " . $err->line . ":" . $err->column . " : " . $err->message, LOGGER_DATA); libxml_clear_errors(); + return; } @@ -880,7 +907,6 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority = $current[$tag]['0_attr'] = $current[$tag.'_attr']; unset($current[$tag.'_attr']); } - } $last_item_index = $repeated_tag_index[$tag.'_'.$level]-1; $current = &$current[$tag][$last_item_index]; @@ -891,7 +917,8 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority = if(!isset($current[$tag])) { //New Key $current[$tag] = $result; $repeated_tag_index[$tag.'_'.$level] = 1; - if($priority == 'tag' and $attributes_data) $current[$tag. '_attr'] = $attributes_data; + if($priority == 'tag' and $attributes_data) + $current[$tag. '_attr'] = $attributes_data; } else { // If taken, put all things inside a list(array) if(isset($current[$tag][0]) and is_array($current[$tag])) { // If it is already an array... @@ -903,13 +930,11 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority = $current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data; } $repeated_tag_index[$tag.'_'.$level]++; - } else { // If it is not an array... $current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value $repeated_tag_index[$tag.'_'.$level] = 1; if($priority == 'tag' and $get_attributes) { if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well - $current[$tag]['0_attr'] = $current[$tag.'_attr']; unset($current[$tag.'_attr']); } @@ -982,14 +1007,21 @@ function email_header_encode($in_str, $charset = 'UTF-8') { return $out_str; } - -function discover_by_url($url,$arr = null) { - require_once('library/HTML5/Parser.php'); +/** + * @brief Creates an xchan entry for URL. + * + * @param string $url URL to discover + * @param array $arr fallback values if scrape_feed() is empty + * + * @return boolean + */ +function discover_by_url($url, $arr = null) { $x = scrape_feed($url); if(! $x) { if(! $arr) return false; + $network = (($arr['network']) ? $arr['network'] : 'unknown'); $name = (($arr['name']) ? $arr['name'] : 'unknown'); $photo = (($arr['photo']) ? $arr['photo'] : ''); @@ -1012,24 +1044,23 @@ function discover_by_url($url,$arr = null) { // try and discover stuff from the feeed - require_once('library/simplepie/simplepie.inc'); $feed = new SimplePie(); $level = 0; - $x = z_fetch_url($guid,false,$level,array('novalidate' => true)); + $x = z_fetch_url($guid, false, $level, array('novalidate' => true)); if(! $x['success']) { - logger('probe_url: feed fetch failed for ' . $poll); + logger('Feed fetch failed for ' . $guid); return false; } $xml = $x['body']; - logger('probe_url: fetch feed: ' . $guid . ' returns: ' . $xml, LOGGER_DATA); - logger('probe_url: scrape_feed: headers: ' . $x['header'], LOGGER_DATA); + logger('Fetch feed: ' . $guid . ' returns: ' . $xml, LOGGER_DATA); + logger('scrape_feed: headers: ' . $x['header'], LOGGER_DATA); // Don't try and parse an empty string $feed->set_raw_data(($xml) ? $xml : '<?xml version="1.0" encoding="utf-8" ?><xml></xml>'); $feed->init(); if($feed->error()) - logger('probe_url: scrape_feed: Error parsing XML: ' . $feed->error()); + logger('scrape_feed: Error parsing XML: ' . $feed->error()); $name = unxmlify(trim($feed->get_title())); $photo = $feed->get_image_url(); @@ -1070,7 +1101,7 @@ function discover_by_url($url,$arr = null) { $profile = trim(unxmlify($author->get_link())); } if(! $photo) { - $rawmedia = $item->get_item_tags('http://search.yahoo.com/mrss/','thumbnail'); + $rawmedia = $item->get_item_tags('http://search.yahoo.com/mrss/', 'thumbnail'); if($rawmedia && $rawmedia[0]['attribs']['']['url']) $photo = unxmlify($rawmedia[0]['attribs']['']['url']); } @@ -1084,7 +1115,7 @@ function discover_by_url($url,$arr = null) { } } } - if($poll === $profile) + if($guid === $profile) $lnk = $feed->get_permalink(); if(isset($lnk) && strlen($lnk)) $profile = $lnk; @@ -1096,9 +1127,6 @@ function discover_by_url($url,$arr = null) { if(! $name) $name = notags($feed->get_description()); - if(! $guid) - return false; - $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($guid) ); @@ -1112,7 +1140,6 @@ function discover_by_url($url,$arr = null) { [ 'xchan_hash' => $guid, 'xchan_guid' => $guid, - 'xchan_pubkey' => $pubkey, 'xchan_addr' => $addr, 'xchan_url' => $profile, 'xchan_name' => $name, @@ -1130,11 +1157,10 @@ function discover_by_url($url,$arr = null) { dbesc($photos[3]), dbesc($guid) ); - return true; + return true; } - function discover_by_webbie($webbie) { $result = []; @@ -1183,7 +1209,6 @@ function discover_by_webbie($webbie) { function webfinger_rfc7033($webbie,$zot = false) { - if(strpos($webbie,'@')) { $lhs = substr($webbie,0,strpos($webbie,'@')); $rhs = substr($webbie,strpos($webbie,'@')+1); @@ -1268,14 +1293,14 @@ function fetch_lrdd_template($host) { } if(! strpos($tpl,'{uri}')) $tpl = ''; - return $tpl; + return $tpl; } function fetch_xrd_links($url) { - logger('fetch_xrd_links: ' . $url, LOGGER_DEBUG); + logger('url: ' . $url, LOGGER_DEBUG); $redirects = 0; $x = z_fetch_url($url,false,$redirects,array('timeout' => 20)); @@ -1284,7 +1309,7 @@ function fetch_xrd_links($url) { return array(); $xml = $x['body']; - logger('fetch_xrd_links: ' . $xml, LOGGER_DATA); + logger('data: ' . $xml, LOGGER_DATA); if ((! $xml) || (! stristr($xml,'<xrd'))) return array(); @@ -1322,13 +1347,21 @@ function fetch_xrd_links($url) { $links[]['@attributes'] = array('rel' => 'subject' , 'href' => $arr['xrd']['subject']); } - logger('fetch_xrd_links: ' . print_r($links,true), LOGGER_DATA); + logger('data: ' . print_r($links, true), LOGGER_DATA); return $links; } +/** + * @brief + * + * @param string $url The URL to scrape + * @return array + */ + function scrape_feed($url) { + require_once('library/HTML5/Parser.php'); $ret = array(); $level = 0; @@ -1341,15 +1374,14 @@ function scrape_feed($url) { $code = $x['return_code']; $s = $x['body']; - logger('scrape_feed: returns: ' . $code . ' headers=' . $headers, LOGGER_DEBUG); + logger('returns: ' . $code . ' headers=' . $headers, LOGGER_DEBUG); if(! $s) { - logger('scrape_feed: no data returned for ' . $url); + logger('No data returned for ' . $url); return $ret; } - - $lines = explode("\n",$headers); + $lines = explode("\n", $headers); if(count($lines)) { foreach($lines as $line) { if(stristr($line,'content-type:')) { @@ -1373,15 +1405,14 @@ function scrape_feed($url) { try { $dom = HTML5_Parser::parse($s); } catch (DOMException $e) { - logger('scrape_feed: parse error: ' . $e); + logger('Parse error: ' . $e); } if(! $dom) { - logger('scrape_feed: failed to parse.'); + logger('Failed to parse.'); return $ret; } - $head = $dom->getElementsByTagName('base'); if($head) { foreach($head as $head0) { @@ -1426,11 +1457,12 @@ function format_and_send_email($sender,$xchan,$item) { $title = $item['title']; $body = $item['body']; - $textversion = strip_tags(html_entity_decode(bbcode(str_replace(array("\\r", "\\n"), array( "", "\n"), $body)),ENT_QUOTES,'UTF-8')); + $textversion = strip_tags(html_entity_decode(bbcode(str_replace(array("\\r", "\\n"), array( "", "\n"), $body)),ENT_QUOTES,'UTF-8')); $htmlversion = bbcode(str_replace(array("\\r","\\n"), array("","<br />\n"),$body)); $banner = t('$Projectname Notification'); + $product = t('$projectname'); // PLATFORM_NAME; $siteurl = z_root(); $thanks = t('Thank You,'); @@ -1537,8 +1569,6 @@ function do_delivery($deliveries) { if($deliver) Zotlabs\Daemon\Master::Summon(array('Deliver',$deliver)); - - } @@ -1595,7 +1625,7 @@ function get_site_info() { $commit = ''; } else { - $version = $commit = ''; + $version = $commit = ''; } //Statistics @@ -1612,12 +1642,12 @@ function get_site_info() { foreach(App::$config['feature_lock'] as $k => $v) { if($k === 'config_loaded') continue; + $locked_features[$k] = intval($v); } } - $data = [ 'url' => z_root(), 'platform' => Zotlabs\Lib\System::get_platform_name(), @@ -1645,16 +1675,20 @@ function get_site_info() { 'local_posts' => $local_posts_stat, 'hide_in_statistics' => $hide_in_statistics ]; + return $data; } - - +/** + * @brief + * + * @param string $url + * @return boolean + */ function check_siteallowed($url) { $retvalue = true; - $arr = array('url' => $url); call_hooks('check_siteallowed',$arr); @@ -1680,9 +1714,16 @@ function check_siteallowed($url) { } } } + return $retvalue; } +/** + * @brief + * + * @param string $hash + * @return boolean + */ function check_channelallowed($hash) { $retvalue = true; @@ -1712,6 +1753,7 @@ function check_channelallowed($hash) { } } } + return $retvalue; } @@ -1742,9 +1784,14 @@ function get_repository_version($branch = 'master') { return $matches[3]; } return '?.?'; - } +/** + * @brief Get translated network name. + * + * @param string $s Network string, see boot.php + * @return string Translated name of the network + */ function network_to_name($s) { $nets = array( @@ -1767,27 +1814,24 @@ function network_to_name($s) { $search = array_keys($nets); $replace = array_values($nets); - return str_replace($search,$replace,$s); - + return str_replace($search, $replace, $s); } - +/** + * @brief Send a text email message. + * + * @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 + */ function z_mail($params) { - /** - * @brief Send a text email message - * - * @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 - */ - if(! $params['fromEmail']) { $params['fromEmail'] = get_config('system','from_email'); if(! $params['fromEmail']) @@ -1833,8 +1877,13 @@ function z_mail($params) { return $res; } -// discover the best API path available for redmatrix/hubzilla servers +/** + * @brief Discover the best API path available for redmatrix/hubzilla servers. + * + * @param string $host + * @return string + */ function probe_api_path($host) { $schemes = ['https', 'http' ]; @@ -1844,8 +1893,8 @@ function probe_api_path($host) { foreach($paths as $path) { $curpath = $scheme . '://' . $host . $path; $x = z_fetch_url($curpath); - if($x['success'] && ! strlen($x['body'],'not implemented')) - return str_replace('version','',$curpath); + if($x['success'] && ! strlen($x['body'], 'not implemented')) + return str_replace('version', '', $curpath); } } diff --git a/include/photos.php b/include/photos.php index 9b2515658..896f3e1f2 100644 --- a/include/photos.php +++ b/include/photos.php @@ -470,6 +470,7 @@ function photos_albums_list($channel, $observer, $sort_key = 'display_path', $di intval($channel_id) ); if($x) { + require_once('include/attach.php'); foreach($r as $rv) { foreach($x as $xv) { if($xv['folder'] === $rv['hash']) { |