Commit b6459e61 authored by Klaus Weidenbach's avatar Klaus Weidenbach

Update SimplePie library.

As a follow up to issue #699 update SimplePie from 1.2.1-dev (around
6years old) to current git master (1.4.4-dev). We use the master branch
until the next release because it contains our patch for enclosure
titles already. The other patches in the library from us can be done by
configuring the SimplePie object in our code instead.
Used composer to manage this library and use class autoloading.
Add some unit tests for include/feedutils.php, but the interesting parts
are unfortunately not testable with the current code.
parent b4f65840
......@@ -32,7 +32,8 @@
"michelf/php-markdown" : "^1.7",
"pixel418/markdownify": "^2.2",
"bshaffer/oauth2-server-php": "^1.9",
"ezyang/htmlpurifier": "^4.9"
"ezyang/htmlpurifier": "^4.9",
"simplepie/simplepie": ">=1.4.4 || dev-master"
},
"require-dev" : {
"php" : ">=7.0",
......@@ -56,5 +57,9 @@
"minimum-stability" : "stable",
"config" : {
"notify-on-install" : false
}
},
"repositories": [{
"type": "vcs",
"url": "https://github.com/simplepie/simplepie"
}]
}
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "f1d40dcfbbb2f5364ad55235efaeb5ab",
"content-hash": "62261cde663585403a8dd8fda5b85a95",
"packages": [
{
"name": "bshaffer/oauth2-server-php",
......@@ -668,6 +668,69 @@
"xml"
],
"time": "2016-10-09T22:57:52+00:00"
},
{
"name": "simplepie/simplepie",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/simplepie/simplepie.git",
"reference": "59e7204610d3a8989822eba1c0cbf1d1680bd10d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/simplepie/simplepie/zipball/59e7204610d3a8989822eba1c0cbf1d1680bd10d",
"reference": "59e7204610d3a8989822eba1c0cbf1d1680bd10d",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "~4 || ~5"
},
"suggest": {
"mf2/mf2": "Microformat module that allows for parsing HTML for microformats"
},
"type": "library",
"autoload": {
"psr-0": {
"SimplePie": "library"
}
},
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Ryan Parman",
"homepage": "http://ryanparman.com/",
"role": "Creator, alumnus developer"
},
{
"name": "Geoffrey Sneddon",
"homepage": "http://gsnedders.com/",
"role": "Alumnus developer"
},
{
"name": "Ryan McCue",
"email": "me@ryanmccue.info",
"homepage": "http://ryanmccue.info/",
"role": "Developer"
}
],
"description": "A simple Atom/RSS parsing library for PHP",
"homepage": "http://simplepie.org/",
"keywords": [
"atom",
"feeds",
"rss"
],
"support": {
"source": "https://github.com/simplepie/simplepie/tree/master",
"issues": "https://github.com/simplepie/simplepie/issues"
},
"time": "2017-04-06 03:36:48"
}
],
"packages-dev": [
......@@ -3612,6 +3675,7 @@
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"simplepie/simplepie": 20,
"behat/behat": 0,
"behat/mink-extension": 0,
"behat/mink-goutte-driver": 0
......
......@@ -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'])
......@@ -269,14 +277,13 @@ function get_atom_elements($feed, $item, &$author) {
$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']);
}
......@@ -299,7 +306,7 @@ function get_atom_elements($feed, $item, &$author) {
// 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');
$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'];
......@@ -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) {
......@@ -357,7 +364,7 @@ function get_atom_elements($feed, $item, &$author) {
$rawactor = $feed->get_feed_tags(NAMESPACE_ACTIVITY, 'subject');
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)) {
......@@ -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();