get_feed_tags() public method

This method allows you to get access to ANY element/attribute that is a sub-element of the opening feed tag. The return value is an indexed array of elements matching the given namespace and tag name. Each element has attribs, data and child subkeys. For attribs and child, these contain namespace subkeys. attribs then has one level of associative name => value data (where value is a string) after the namespace. child has tag-indexed keys after the namespace, each member of which is an indexed array matching this same format. For example:
This is probably a bad example because we already support
 natively, but it shows you how to parse through
the nodes.
$group = $item->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group');
$content = $group[0]['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'];
$file = $content[0]['attribs']['']['url'];
echo $file;
See also: http://simplepie.org/wiki/faq/supported_xml_namespaces
Since: 1.0
public get_feed_tags ( string $namespace, string $tag ) : array
$namespace string The URL of the XML namespace of the elements you're trying to access
$tag string Tag name
return array
コード例 #1
0
ファイル: network.php プロジェクト: bashrc/hubzilla
function discover_by_url($url, $arr = null)
{
    require_once 'library/HTML5/Parser.php';
    $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'] : '';
        $addr = $arr['addr'] ? $arr['addr'] : '';
        $guid = $url;
    }
    $profile = $url;
    logger('scrape_feed results: ' . print_r($x, true));
    if ($x['feed_atom']) {
        $guid = $x['feed_atom'];
    }
    if ($x['feed_rss']) {
        $guid = $x['feed_rss'];
    }
    if (!$guid) {
        return false;
    }
    // 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));
    if (!$x['success']) {
        logger('probe_url: feed fetch failed for ' . $poll);
        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);
    // 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());
    }
    $name = unxmlify(trim($feed->get_title()));
    $photo = $feed->get_image_url();
    $author = $feed->get_author();
    if ($author) {
        if (!$name) {
            $name = unxmlify(trim($author->get_name()));
        }
        if (!$name) {
            $name = trim(unxmlify($author->get_email()));
            if (strpos($name, '@') !== false) {
                $name = substr($name, 0, strpos($name, '@'));
            }
        }
        if (!$profile && $author->get_link()) {
            $profile = trim(unxmlify($author->get_link()));
        }
        if (!$photo) {
            $rawtags = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
            if ($rawtags) {
                $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
                if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo') {
                    $photo = $elems['link'][0]['attribs']['']['href'];
                }
            }
        }
    } else {
        $item = $feed->get_item(0);
        if ($item) {
            $author = $item->get_author();
            if ($author) {
                if (!$name) {
                    $name = trim(unxmlify($author->get_name()));
                    if (!$name) {
                        $name = trim(unxmlify($author->get_email()));
                    }
                    if (strpos($name, '@') !== false) {
                        $name = substr($name, 0, strpos($name, '@'));
                    }
                }
                if (!$profile && $author->get_link()) {
                    $profile = trim(unxmlify($author->get_link()));
                }
            }
            if (!$photo) {
                $rawmedia = $item->get_item_tags('http://search.yahoo.com/mrss/', 'thumbnail');
                if ($rawmedia && $rawmedia[0]['attribs']['']['url']) {
                    $photo = unxmlify($rawmedia[0]['attribs']['']['url']);
                }
            }
            if (!$photo) {
                $rawtags = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
                if ($rawtags) {
                    $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
                    if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo') {
                        $photo = $elems['link'][0]['attribs']['']['href'];
                    }
                }
            }
        }
    }
    if ($poll === $profile) {
        $lnk = $feed->get_permalink();
    }
    if (isset($lnk) && strlen($lnk)) {
        $profile = $lnk;
    }
    if (!$network) {
        $network = 'rss';
    }
    if (!$name) {
        $name = notags($feed->get_description());
    }
    if (!$guid) {
        return false;
    }
    $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($guid));
    if ($r) {
        return true;
    }
    if (!$photo) {
        $photo = z_root() . '/images/rss_icon.png';
    }
    $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_instance_url, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ", dbesc($guid), dbesc($guid), dbesc($pubkey), dbesc($addr), dbesc($profile), dbesc($name), dbesc($network), dbesc(z_root()), dbesc(datetime_convert()));
    $photos = import_xchan_photo($photo, $guid);
    $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($guid));
    return true;
}
コード例 #2
0
ファイル: items.php プロジェクト: einervonvielen/redmatrix
/**
 * @brief Process atom feed and update anything/everything we might need to update.
 *
 * $hub = should we find a hub declation in the feed, pass it back to our calling process, who might (or
 *        might not) try and subscribe to it.
 * $datedir sorts in reverse order
 *
 * @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;
    }
    $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 (!($item['item_restrict'] & 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 (!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['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 (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 ($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'] = $item_id;
                $datarray['uid'] = $importer['channel_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'];
                }
                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;
            }
        }
    }
}
コード例 #3
0
ファイル: items.php プロジェクト: EmilienB/friendica
function local_delivery($importer, $data)
{
    $a = get_app();
    logger(__FUNCTION__, LOGGER_TRACE);
    if ($importer['readonly']) {
        // We aren't receiving stuff from this person. But we will quietly ignore them
        // rather than a blatant "go away" message.
        logger('local_delivery: ignoring');
        return 0;
        //NOTREACHED
    }
    // Consume notification feed. This may differ from consuming a public feed in several ways
    // - might contain email or friend suggestions
    // - might contain remote followup to our message
    //		- in which case we need to accept it and then notify other conversants
    // - we may need to send various email notifications
    $feed = new SimplePie();
    $feed->set_raw_data($data);
    $feed->enable_order_by_date(false);
    $feed->init();
    if ($feed->error()) {
        logger('local_delivery: Error parsing XML: ' . $feed->error());
    }
    // Check at the feed level for updated contact name and/or photo
    $name_updated = '';
    $new_name = '';
    $photo_timestamp = '';
    $photo_url = '';
    $contact_updated = '';
    $rawtags = $feed->get_feed_tags(NAMESPACE_DFRN, 'owner');
    // Fallback should not be needed here. If it isn't DFRN it won't have DFRN updated tags
    //	if(! $rawtags)
    //		$rawtags = $feed->get_feed_tags( SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
    if ($rawtags) {
        $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
        if ($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
            $name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated'];
            $new_name = $elems['name'][0]['data'];
            // Manually checking for changed contact names
            if ($new_name != $importer['name'] and $new_name != "" and $name_updated <= $importer['name-date']) {
                $name_updated = date("c");
                $photo_timestamp = date("c");
            }
        }
        if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo' && $elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
            if ($photo_timestamp == "") {
                $photo_timestamp = datetime_convert('UTC', 'UTC', $elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
            }
            $photo_url = $elems['link'][0]['attribs']['']['href'];
        }
    }
    if ($photo_timestamp && strlen($photo_url) && $photo_timestamp > $importer['avatar-date']) {
        $contact_updated = $photo_timestamp;
        logger('local_delivery: Updating photo for ' . $importer['name']);
        require_once "include/Photo.php";
        $photos = import_profile_photo($photo_url, $importer['importer_uid'], $importer['id']);
        q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'\n\t\t\tWHERE `uid` = %d AND `id` = %d AND NOT `self`", dbesc(datetime_convert()), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), intval($importer['importer_uid']), intval($importer['id']));
    }
    if ($name_updated && strlen($new_name) && $name_updated > $importer['name-date']) {
        if ($name_updated > $contact_updated) {
            $contact_updated = $name_updated;
        }
        $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `id` = %d LIMIT 1", intval($importer['importer_uid']), intval($importer['id']));
        $x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d AND `name` != '%s' AND NOT `self`", dbesc(notags(trim($new_name))), dbesc(datetime_convert()), intval($importer['importer_uid']), intval($importer['id']), dbesc(notags(trim($new_name))));
        // do our best to update the name on content items
        if (count($r) and notags(trim($new_name)) != $r[0]['name']) {
            q("UPDATE `item` SET `author-name` = '%s' WHERE `author-name` = '%s' AND `author-link` = '%s' AND `uid` = %d AND `author-name` != '%s'", dbesc(notags(trim($new_name))), dbesc($r[0]['name']), dbesc($r[0]['url']), intval($importer['importer_uid']), dbesc(notags(trim($new_name))));
        }
    }
    if ($contact_updated and $new_name and $photo_url) {
        poco_check($importer['url'], $new_name, NETWORK_DFRN, $photo_url, "", "", "", "", "", $contact_updated, 2, $importer['id'], $importer['importer_uid']);
    }
    // Currently unsupported - needs a lot of work
    $reloc = $feed->get_feed_tags(NAMESPACE_DFRN, 'relocate');
    if (isset($reloc[0]['child'][NAMESPACE_DFRN])) {
        $base = $reloc[0]['child'][NAMESPACE_DFRN];
        $newloc = array();
        $newloc['uid'] = $importer['importer_uid'];
        $newloc['cid'] = $importer['id'];
        $newloc['name'] = notags(unxmlify($base['name'][0]['data']));
        $newloc['photo'] = notags(unxmlify($base['photo'][0]['data']));
        $newloc['thumb'] = notags(unxmlify($base['thumb'][0]['data']));
        $newloc['micro'] = notags(unxmlify($base['micro'][0]['data']));
        $newloc['url'] = notags(unxmlify($base['url'][0]['data']));
        $newloc['request'] = notags(unxmlify($base['request'][0]['data']));
        $newloc['confirm'] = notags(unxmlify($base['confirm'][0]['data']));
        $newloc['notify'] = notags(unxmlify($base['notify'][0]['data']));
        $newloc['poll'] = notags(unxmlify($base['poll'][0]['data']));
        $newloc['sitepubkey'] = notags(unxmlify($base['sitepubkey'][0]['data']));
        /** relocated user must have original key pair */
        /*$newloc['pubkey'] = notags(unxmlify($base['pubkey'][0]['data']));
        		$newloc['prvkey'] = notags(unxmlify($base['prvkey'][0]['data']));*/
        logger("items:relocate contact " . print_r($newloc, true) . print_r($importer, true), LOGGER_DEBUG);
        // update contact
        $r = q("SELECT photo, url FROM contact WHERE id=%d AND uid=%d;", intval($importer['id']), intval($importer['importer_uid']));
        if ($r === false) {
            return 1;
        }
        $old = $r[0];
        $x = q("UPDATE contact SET\n\t\t\t\t\tname = '%s',\n\t\t\t\t\tphoto = '%s',\n\t\t\t\t\tthumb = '%s',\n\t\t\t\t\tmicro = '%s',\n\t\t\t\t\turl = '%s',\n\t\t\t\t\tnurl = '%s',\n\t\t\t\t\trequest = '%s',\n\t\t\t\t\tconfirm = '%s',\n\t\t\t\t\tnotify = '%s',\n\t\t\t\t\tpoll = '%s',\n\t\t\t\t\t`site-pubkey` = '%s'\n\t\t\tWHERE id=%d AND uid=%d;", dbesc($newloc['name']), dbesc($newloc['photo']), dbesc($newloc['thumb']), dbesc($newloc['micro']), dbesc($newloc['url']), dbesc(normalise_link($newloc['url'])), dbesc($newloc['request']), dbesc($newloc['confirm']), dbesc($newloc['notify']), dbesc($newloc['poll']), dbesc($newloc['sitepubkey']), intval($importer['id']), intval($importer['importer_uid']));
        if ($x === false) {
            return 1;
        }
        // update items
        $fields = array('owner-link' => array($old['url'], $newloc['url']), 'author-link' => array($old['url'], $newloc['url']), 'owner-avatar' => array($old['photo'], $newloc['photo']), 'author-avatar' => array($old['photo'], $newloc['photo']));
        foreach ($fields as $n => $f) {
            $x = q("UPDATE `item` SET `%s`='%s' WHERE `%s`='%s' AND uid=%d", $n, dbesc($f[1]), $n, dbesc($f[0]), intval($importer['importer_uid']));
            if ($x === false) {
                return 1;
            }
        }
        // TODO
        // merge with current record, current contents have priority
        // update record, set url-updated
        // update profile photos
        // schedule a scan?
        return 0;
    }
    // handle friend suggestion notification
    $sugg = $feed->get_feed_tags(NAMESPACE_DFRN, 'suggest');
    if (isset($sugg[0]['child'][NAMESPACE_DFRN])) {
        $base = $sugg[0]['child'][NAMESPACE_DFRN];
        $fsugg = array();
        $fsugg['uid'] = $importer['importer_uid'];
        $fsugg['cid'] = $importer['id'];
        $fsugg['name'] = notags(unxmlify($base['name'][0]['data']));
        $fsugg['photo'] = notags(unxmlify($base['photo'][0]['data']));
        $fsugg['url'] = notags(unxmlify($base['url'][0]['data']));
        $fsugg['request'] = notags(unxmlify($base['request'][0]['data']));
        $fsugg['body'] = escape_tags(unxmlify($base['note'][0]['data']));
        // Does our member already have a friend matching this description?
        $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `nurl` = '%s' AND `uid` = %d LIMIT 1", dbesc($fsugg['name']), dbesc(normalise_link($fsugg['url'])), intval($fsugg['uid']));
        if (count($r)) {
            return 0;
        }
        // Do we already have an fcontact record for this person?
        $fid = 0;
        $r = q("SELECT * FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1", dbesc($fsugg['url']), dbesc($fsugg['name']), dbesc($fsugg['request']));
        if (count($r)) {
            $fid = $r[0]['id'];
            // OK, we do. Do we already have an introduction for this person ?
            $r = q("select id from intro where uid = %d and fid = %d limit 1", intval($fsugg['uid']), intval($fid));
            if (count($r)) {
                return 0;
            }
        }
        if (!$fid) {
            $r = q("INSERT INTO `fcontact` ( `name`,`url`,`photo`,`request` ) VALUES ( '%s', '%s', '%s', '%s' ) ", dbesc($fsugg['name']), dbesc($fsugg['url']), dbesc($fsugg['photo']), dbesc($fsugg['request']));
        }
        $r = q("SELECT * FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1", dbesc($fsugg['url']), dbesc($fsugg['name']), dbesc($fsugg['request']));
        if (count($r)) {
            $fid = $r[0]['id'];
        } else {
            return 0;
        }
        $hash = random_string();
        $r = q("INSERT INTO `intro` ( `uid`, `fid`, `contact-id`, `note`, `hash`, `datetime`, `blocked` )\n\t\t\tVALUES( %d, %d, %d, '%s', '%s', '%s', %d )", intval($fsugg['uid']), intval($fid), intval($fsugg['cid']), dbesc($fsugg['body']), dbesc($hash), dbesc(datetime_convert()), intval(0));
        notification(array('type' => NOTIFY_SUGGEST, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $fsugg, 'link' => $a->get_baseurl() . '/notifications/intros', 'source_name' => $importer['name'], 'source_link' => $importer['url'], 'source_photo' => $importer['photo'], 'verb' => ACTIVITY_REQ_FRIEND, 'otype' => 'intro'));
        return 0;
    }
    $ismail = false;
    $rawmail = $feed->get_feed_tags(NAMESPACE_DFRN, 'mail');
    if (isset($rawmail[0]['child'][NAMESPACE_DFRN])) {
        logger('local_delivery: private message received');
        $ismail = true;
        $base = $rawmail[0]['child'][NAMESPACE_DFRN];
        $msg = array();
        $msg['uid'] = $importer['importer_uid'];
        $msg['from-name'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['name'][0]['data']));
        $msg['from-photo'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['avatar'][0]['data']));
        $msg['from-url'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['uri'][0]['data']));
        $msg['contact-id'] = $importer['id'];
        $msg['title'] = notags(unxmlify($base['subject'][0]['data']));
        $msg['body'] = escape_tags(unxmlify($base['content'][0]['data']));
        $msg['seen'] = 0;
        $msg['replied'] = 0;
        $msg['uri'] = notags(unxmlify($base['id'][0]['data']));
        $msg['parent-uri'] = notags(unxmlify($base['in-reply-to'][0]['data']));
        $msg['created'] = datetime_convert(notags(unxmlify('UTC', 'UTC', $base['sentdate'][0]['data'])));
        dbesc_array($msg);
        $r = dbq("INSERT INTO `mail` (`" . implode("`, `", array_keys($msg)) . "`) VALUES ('" . implode("', '", array_values($msg)) . "')");
        // send notifications.
        require_once 'include/enotify.php';
        $notif_params = array('type' => NOTIFY_MAIL, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $msg, 'source_name' => $msg['from-name'], 'source_link' => $importer['url'], 'source_photo' => $importer['thumb'], 'verb' => ACTIVITY_POST, 'otype' => 'mail');
        notification($notif_params);
        return 0;
        // NOTREACHED
    }
    $community_page = 0;
    $rawtags = $feed->get_feed_tags(NAMESPACE_DFRN, 'community');
    if ($rawtags) {
        $community_page = intval($rawtags[0]['data']);
    }
    if (intval($importer['forum']) != $community_page) {
        q("update contact set forum = %d where id = %d", intval($community_page), intval($importer['id']));
        $importer['forum'] = (string) $community_page;
    }
    logger('local_delivery: feed item count = ' . $feed->get_item_quantity());
    // process any deleted entries
    $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry');
    if (is_array($del_entries) && count($del_entries)) {
        foreach ($del_entries as $dentry) {
            $deleted = false;
            if (isset($dentry['attribs']['']['ref'])) {
                $uri = $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) {
                // check for relayed deletes to our conversation
                $is_reply = false;
                $r = q("select * from item where uri = '%s' and uid = %d limit 1", dbesc($uri), intval($importer['importer_uid']));
                if (count($r)) {
                    $parent_uri = $r[0]['parent-uri'];
                    if ($r[0]['id'] != $r[0]['parent']) {
                        $is_reply = true;
                    }
                }
                if ($is_reply) {
                    $community = false;
                    if ($importer['page-flags'] == PAGE_COMMUNITY || $importer['page-flags'] == PAGE_PRVGROUP) {
                        $sql_extra = '';
                        $community = true;
                        logger('local_delivery: possible community delete');
                    } else {
                        $sql_extra = " and contact.self = 1 and item.wall = 1 ";
                    }
                    // was the top-level post for this reply written by somebody on this site?
                    // Specifically, the recipient?
                    $is_a_remote_delete = false;
                    // POSSIBLE CLEANUP --> Why select so many fields when only forum_mode and wall are used?
                    $r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, `item`.`forum_mode`,`item`.`origin`,`item`.`wall`,\n\t\t\t\t\t\t`contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item`\n\t\t\t\t\t\tINNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\t\t\tWHERE `item`.`uri` = '%s' AND (`item`.`parent-uri` = '%s' or `item`.`thr-parent` = '%s')\n\t\t\t\t\t\tAND `item`.`uid` = %d\n\t\t\t\t\t\t{$sql_extra}\n\t\t\t\t\t\tLIMIT 1", dbesc($parent_uri), dbesc($parent_uri), dbesc($parent_uri), intval($importer['importer_uid']));
                    if ($r && count($r)) {
                        $is_a_remote_delete = true;
                    }
                    // Does this have the characteristics of a community or private group comment?
                    // If it's a reply to a wall post on a community/prvgroup page it's a
                    // valid community comment. Also forum_mode makes it valid for sure.
                    // If neither, it's not.
                    if ($is_a_remote_delete && $community) {
                        if (!$r[0]['forum_mode'] && !$r[0]['wall']) {
                            $is_a_remote_delete = false;
                            logger('local_delivery: not a community delete');
                        }
                    }
                    if ($is_a_remote_delete) {
                        logger('local_delivery: received remote delete');
                    }
                }
                $r = q("SELECT `item`.*, `contact`.`self` FROM `item` INNER JOIN contact on `item`.`contact-id` = `contact`.`id`\n\t\t\t\t\tWHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1", dbesc($uri), intval($importer['importer_uid']), intval($importer['id']));
                if (count($r)) {
                    $item = $r[0];
                    if ($item['deleted']) {
                        continue;
                    }
                    logger('local_delivery: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
                    if ($item['object-type'] === ACTIVITY_OBJ_EVENT) {
                        logger("Deleting event " . $item['event-id'], LOGGER_DEBUG);
                        event_delete($item['event-id']);
                    }
                    if ($item['verb'] === ACTIVITY_TAG && $item['object-type'] === ACTIVITY_OBJ_TAGTERM) {
                        $xo = parse_xml_string($item['object'], false);
                        $xt = parse_xml_string($item['target'], false);
                        if ($xt->type === ACTIVITY_OBJ_NOTE) {
                            $i = q("select * from `item` where uri = '%s' and uid = %d limit 1", dbesc($xt->id), intval($importer['importer_uid']));
                            if (count($i)) {
                                // For tags, the owner cannot remove the tag on the author's copy of the post.
                                $owner_remove = $item['contact-id'] == $i[0]['contact-id'] ? true : false;
                                $author_remove = $item['origin'] && $item['self'] ? true : false;
                                $author_copy = $item['origin'] ? true : false;
                                if ($owner_remove && $author_copy) {
                                    continue;
                                }
                                if ($author_remove || $owner_remove) {
                                    $tags = explode(',', $i[0]['tag']);
                                    $newtags = array();
                                    if (count($tags)) {
                                        foreach ($tags as $tag) {
                                            if (trim($tag) !== trim($xo->body)) {
                                                $newtags[] = trim($tag);
                                            }
                                        }
                                    }
                                    q("update item set tag = '%s' where id = %d", dbesc(implode(',', $newtags)), intval($i[0]['id']));
                                    create_tags_from_item($i[0]['id']);
                                }
                            }
                        }
                    }
                    if ($item['uri'] == $item['parent-uri']) {
                        $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',\n\t\t\t\t\t\t\t`body` = '', `title` = ''\n\t\t\t\t\t\t\tWHERE `parent-uri` = '%s' AND `uid` = %d", dbesc($when), dbesc(datetime_convert()), dbesc($item['uri']), intval($importer['importer_uid']));
                        create_tags_from_itemuri($item['uri'], $importer['importer_uid']);
                        create_files_from_itemuri($item['uri'], $importer['importer_uid']);
                        update_thread_uri($item['uri'], $importer['importer_uid']);
                    } else {
                        $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',\n\t\t\t\t\t\t\t`body` = '', `title` = ''\n\t\t\t\t\t\t\tWHERE `uri` = '%s' AND `uid` = %d", dbesc($when), dbesc(datetime_convert()), dbesc($uri), intval($importer['importer_uid']));
                        create_tags_from_itemuri($uri, $importer['importer_uid']);
                        create_files_from_itemuri($uri, $importer['importer_uid']);
                        update_thread_uri($uri, $importer['importer_uid']);
                        if ($item['last-child']) {
                            // ensure that last-child is set in case the comment that had it just got wiped.
                            q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ", dbesc(datetime_convert()), dbesc($item['parent-uri']), intval($item['uid']));
                            // who is the last child now?
                            $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `uid` = %d\n\t\t\t\t\t\t\t\tORDER BY `created` DESC LIMIT 1", dbesc($item['parent-uri']), intval($importer['importer_uid']));
                            if (count($r)) {
                                q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d", intval($r[0]['id']));
                            }
                        }
                        // if this is a relayed delete, propagate it to other recipients
                        if ($is_a_remote_delete) {
                            proc_run('php', "include/notifier.php", "drop", $item['id']);
                        }
                    }
                }
            }
        }
    }
    foreach ($feed->get_items() as $item) {
        $is_reply = false;
        $item_id = $item->get_id();
        $rawthread = $item->get_item_tags(NAMESPACE_THREAD, 'in-reply-to');
        if (isset($rawthread[0]['attribs']['']['ref'])) {
            $is_reply = true;
            $parent_uri = $rawthread[0]['attribs']['']['ref'];
        }
        if ($is_reply) {
            $community = false;
            if ($importer['page-flags'] == PAGE_COMMUNITY || $importer['page-flags'] == PAGE_PRVGROUP) {
                $sql_extra = '';
                $community = true;
                logger('local_delivery: possible community reply');
            } else {
                $sql_extra = " and contact.self = 1 and item.wall = 1 ";
            }
            // was the top-level post for this reply written by somebody on this site?
            // Specifically, the recipient?
            $is_a_remote_comment = false;
            $top_uri = $parent_uri;
            $r = q("select `item`.`parent-uri` from `item`\n\t\t\t\tWHERE `item`.`uri` = '%s'\n\t\t\t\tLIMIT 1", dbesc($parent_uri));
            if ($r && count($r)) {
                $top_uri = $r[0]['parent-uri'];
                // POSSIBLE CLEANUP --> Why select so many fields when only forum_mode and wall are used?
                $r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, `item`.`forum_mode`,`item`.`origin`,`item`.`wall`,\n\t\t\t\t\t`contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item`\n\t\t\t\t\tINNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\t\tWHERE `item`.`uri` = '%s' AND (`item`.`parent-uri` = '%s' or `item`.`thr-parent` = '%s')\n\t\t\t\t\tAND `item`.`uid` = %d\n\t\t\t\t\t{$sql_extra}\n\t\t\t\t\tLIMIT 1", dbesc($top_uri), dbesc($top_uri), dbesc($top_uri), intval($importer['importer_uid']));
                if ($r && count($r)) {
                    $is_a_remote_comment = true;
                }
            }
            // Does this have the characteristics of a community or private group comment?
            // If it's a reply to a wall post on a community/prvgroup page it's a
            // valid community comment. Also forum_mode makes it valid for sure.
            // If neither, it's not.
            if ($is_a_remote_comment && $community) {
                if (!$r[0]['forum_mode'] && !$r[0]['wall']) {
                    $is_a_remote_comment = false;
                    logger('local_delivery: not a community reply');
                }
            }
            if ($is_a_remote_comment) {
                logger('local_delivery: received remote comment');
                $is_like = false;
                // remote reply to our post. Import and then notify everybody else.
                $datarray = get_atom_elements($feed, $item);
                $r = q("SELECT `id`, `uid`, `last-child`, `edited`, `body`  FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid']));
                // Update content if 'updated' changes
                if (count($r)) {
                    $iid = $r[0]['id'];
                    if (edited_timestamp_is_newer($r[0], $datarray)) {
                        // do not accept (ignore) an earlier edit than one we currently have.
                        if (datetime_convert('UTC', 'UTC', $datarray['edited']) < $r[0]['edited']) {
                            continue;
                        }
                        logger('received updated comment', LOGGER_DEBUG);
                        $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s', `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc(datetime_convert()), dbesc($item_id), intval($importer['importer_uid']));
                        create_tags_from_itemuri($item_id, $importer['importer_uid']);
                        proc_run('php', "include/notifier.php", "comment-import", $iid);
                    }
                    continue;
                }
                $own = q("select name,url,thumb from contact where uid = %d and self = 1 limit 1", intval($importer['importer_uid']));
                $datarray['type'] = 'remote-comment';
                $datarray['wall'] = 1;
                $datarray['parent-uri'] = $parent_uri;
                $datarray['uid'] = $importer['importer_uid'];
                $datarray['owner-name'] = $own[0]['name'];
                $datarray['owner-link'] = $own[0]['url'];
                $datarray['owner-avatar'] = $own[0]['thumb'];
                $datarray['contact-id'] = $importer['id'];
                if ($datarray['verb'] === ACTIVITY_LIKE || $datarray['verb'] === ACTIVITY_DISLIKE || $datarray['verb'] === ACTIVITY_ATTEND || $datarray['verb'] === ACTIVITY_ATTENDNO || $datarray['verb'] === ACTIVITY_ATTENDMAYBE) {
                    $is_like = true;
                    $datarray['type'] = 'activity';
                    $datarray['gravity'] = GRAVITY_LIKE;
                    $datarray['last-child'] = 0;
                    // only one like or dislike per person
                    // splitted into two queries for performance issues
                    $r = q("select id from item where uid = %d and `contact-id` = %d and verb = '%s' and (`parent-uri` = '%s') and deleted = 0 limit 1", intval($datarray['uid']), intval($datarray['contact-id']), dbesc($datarray['verb']), dbesc($datarray['parent-uri']));
                    if ($r && count($r)) {
                        continue;
                    }
                    $r = q("select id from item where uid = %d and `contact-id` = %d and verb = '%s' and (`thr-parent` = '%s') and deleted = 0 limit 1", intval($datarray['uid']), intval($datarray['contact-id']), dbesc($datarray['verb']), dbesc($datarray['parent-uri']));
                    if ($r && count($r)) {
                        continue;
                    }
                }
                if ($datarray['verb'] === ACTIVITY_TAG && $datarray['object-type'] === ACTIVITY_OBJ_TAGTERM) {
                    $xo = parse_xml_string($datarray['object'], false);
                    $xt = parse_xml_string($datarray['target'], false);
                    if ($xt->type == ACTIVITY_OBJ_NOTE && $xt->id) {
                        // fetch the parent item
                        $tagp = q("select * from item where uri = '%s' and uid = %d limit 1", dbesc($xt->id), intval($importer['importer_uid']));
                        if (!count($tagp)) {
                            continue;
                        }
                        // extract tag, if not duplicate, and this user allows tags, add to parent item
                        if ($xo->id && $xo->content) {
                            $newtag = '#[url=' . $xo->id . ']' . $xo->content . '[/url]';
                            if (!stristr($tagp[0]['tag'], $newtag)) {
                                $i = q("SELECT `blocktags` FROM `user` where `uid` = %d LIMIT 1", intval($importer['importer_uid']));
                                if (count($i) && !intval($i[0]['blocktags'])) {
                                    q("UPDATE item SET tag = '%s', `edited` = '%s', `changed` = '%s' WHERE id = %d", dbesc($tagp[0]['tag'] . (strlen($tagp[0]['tag']) ? ',' : '') . $newtag), intval($tagp[0]['id']), dbesc(datetime_convert()), dbesc(datetime_convert()));
                                    create_tags_from_item($tagp[0]['id']);
                                }
                            }
                        }
                    }
                }
                $posted_id = item_store($datarray);
                $parent = 0;
                if ($posted_id) {
                    $datarray["id"] = $posted_id;
                    $r = q("SELECT `parent`, `parent-uri` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($posted_id), intval($importer['importer_uid']));
                    if (count($r)) {
                        $parent = $r[0]['parent'];
                        $parent_uri = $r[0]['parent-uri'];
                    }
                    if (!$is_like) {
                        $r1 = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `uid` = %d AND `parent` = %d", dbesc(datetime_convert()), intval($importer['importer_uid']), intval($r[0]['parent']));
                        $r2 = q("UPDATE `item` SET `last-child` = 1, `changed` = '%s' WHERE `uid` = %d AND `id` = %d", dbesc(datetime_convert()), intval($importer['importer_uid']), intval($posted_id));
                    }
                    if ($posted_id && $parent) {
                        proc_run('php', "include/notifier.php", "comment-import", "{$posted_id}");
                        if (!$is_like && !$importer['self']) {
                            require_once 'include/enotify.php';
                            notification(array('type' => NOTIFY_COMMENT, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . urlencode(get_item_guid($posted_id)), 'source_name' => stripslashes($datarray['author-name']), 'source_link' => $datarray['author-link'], 'source_photo' => link_compare($datarray['author-link'], $importer['url']) ? $importer['thumb'] : $datarray['author-avatar'], 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $parent, 'parent_uri' => $parent_uri));
                        }
                    }
                    return 0;
                    // NOTREACHED
                }
            } else {
                // regular comment that is part of this total conversation. Have we seen it? If not, import it.
                $item_id = $item->get_id();
                $datarray = get_atom_elements($feed, $item);
                if ($importer['rel'] == CONTACT_IS_FOLLOWER) {
                    continue;
                }
                $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid']));
                // Update content if 'updated' changes
                if (count($r)) {
                    if (edited_timestamp_is_newer($r[0], $datarray)) {
                        // do not accept (ignore) an earlier edit than one we currently have.
                        if (datetime_convert('UTC', 'UTC', $datarray['edited']) < $r[0]['edited']) {
                            continue;
                        }
                        $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s', `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc(datetime_convert()), dbesc($item_id), intval($importer['importer_uid']));
                        create_tags_from_itemuri($item_id, $importer['importer_uid']);
                    }
                    // update last-child if it changes
                    $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
                    if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
                        $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc($parent_uri), intval($importer['importer_uid']));
                        $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s'  WHERE `uri` = '%s' AND `uid` = %d", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['importer_uid']));
                    }
                    continue;
                }
                $datarray['parent-uri'] = $parent_uri;
                $datarray['uid'] = $importer['importer_uid'];
                $datarray['contact-id'] = $importer['id'];
                if ($datarray['verb'] === ACTIVITY_LIKE || $datarray['verb'] === ACTIVITY_DISLIKE || $datarray['verb'] === ACTIVITY_ATTEND || $datarray['verb'] === ACTIVITY_ATTENDNO || $datarray['verb'] === ACTIVITY_ATTENDMAYBE) {
                    $datarray['type'] = 'activity';
                    $datarray['gravity'] = GRAVITY_LIKE;
                    // only one like or dislike per person
                    // splitted into two queries for performance issues
                    $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 and (`parent-uri` = '%s') limit 1", intval($datarray['uid']), intval($datarray['contact-id']), dbesc($datarray['verb']), dbesc($parent_uri));
                    if ($r && count($r)) {
                        continue;
                    }
                    $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 and (`thr-parent` = '%s') limit 1", intval($datarray['uid']), intval($datarray['contact-id']), dbesc($datarray['verb']), dbesc($parent_uri));
                    if ($r && count($r)) {
                        continue;
                    }
                }
                if ($datarray['verb'] === ACTIVITY_TAG && $datarray['object-type'] === ACTIVITY_OBJ_TAGTERM) {
                    $xo = parse_xml_string($datarray['object'], false);
                    $xt = parse_xml_string($datarray['target'], false);
                    if ($xt->type == ACTIVITY_OBJ_NOTE) {
                        $r = q("select * from item where `uri` = '%s' AND `uid` = %d limit 1", dbesc($xt->id), intval($importer['importer_uid']));
                        if (!count($r)) {
                            continue;
                        }
                        // extract tag, if not duplicate, add to parent item
                        if ($xo->content) {
                            if (!stristr($r[0]['tag'], trim($xo->content))) {
                                q("UPDATE item SET tag = '%s' WHERE id = %d", dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . '#[url=' . $xo->id . ']' . $xo->content . '[/url]'), intval($r[0]['id']));
                                create_tags_from_item($r[0]['id']);
                            }
                        }
                    }
                }
                $posted_id = item_store($datarray);
                // find out if our user is involved in this conversation and wants to be notified.
                if (!x($datarray['type']) || $datarray['type'] != 'activity') {
                    $myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 AND `deleted` = 0", dbesc($top_uri), intval($importer['importer_uid']));
                    if (count($myconv)) {
                        $importer_url = $a->get_baseurl() . '/profile/' . $importer['nickname'];
                        // first make sure this isn't our own post coming back to us from a wall-to-wall event
                        if (!link_compare($datarray['author-link'], $importer_url)) {
                            foreach ($myconv as $conv) {
                                // now if we find a match, it means we're in this conversation
                                if (!link_compare($conv['author-link'], $importer_url)) {
                                    continue;
                                }
                                require_once 'include/enotify.php';
                                $conv_parent = $conv['parent'];
                                notification(array('type' => NOTIFY_COMMENT, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . urlencode(get_item_guid($posted_id)), 'source_name' => stripslashes($datarray['author-name']), 'source_link' => $datarray['author-link'], 'source_photo' => link_compare($datarray['author-link'], $importer['url']) ? $importer['thumb'] : $datarray['author-avatar'], 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $conv_parent, 'parent_uri' => $parent_uri));
                                // only send one notification
                                break;
                            }
                        }
                    }
                }
                continue;
            }
        } else {
            // Head post of a conversation. Have we seen it? If not, import it.
            $item_id = $item->get_id();
            $datarray = get_atom_elements($feed, $item);
            if (x($datarray, 'object-type') && $datarray['object-type'] === ACTIVITY_OBJ_EVENT) {
                $ev = bbtoevent($datarray['body']);
                if ((x($ev, 'desc') || x($ev, 'summary')) && x($ev, 'start')) {
                    $ev['cid'] = $importer['id'];
                    $ev['uid'] = $importer['uid'];
                    $ev['uri'] = $item_id;
                    $ev['edited'] = $datarray['edited'];
                    $ev['private'] = $datarray['private'];
                    $ev['guid'] = $datarray['guid'];
                    $r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['uid']));
                    if (count($r)) {
                        $ev['id'] = $r[0]['id'];
                    }
                    $xyz = event_store($ev);
                    continue;
                }
            }
            $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid']));
            // Update content if 'updated' changes
            if (count($r)) {
                if (edited_timestamp_is_newer($r[0], $datarray)) {
                    // do not accept (ignore) an earlier edit than one we currently have.
                    if (datetime_convert('UTC', 'UTC', $datarray['edited']) < $r[0]['edited']) {
                        continue;
                    }
                    $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s', `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc(datetime_convert()), dbesc($item_id), intval($importer['importer_uid']));
                    create_tags_from_itemuri($item_id, $importer['importer_uid']);
                    update_thread_uri($item_id, $importer['importer_uid']);
                }
                // update last-child if it changes
                $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
                if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
                    $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['importer_uid']));
                }
                continue;
            }
            $datarray['parent-uri'] = $item_id;
            $datarray['uid'] = $importer['importer_uid'];
            $datarray['contact-id'] = $importer['id'];
            if (!link_compare($datarray['owner-link'], $importer['url'])) {
                // The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery,
                // but otherwise there's a possible data mixup on the sender's system.
                // the tgroup delivery code called from item_store will correct it if it's a forum,
                // but we're going to unconditionally correct it here so that the post will always be owned by our contact.
                logger('local_delivery: Correcting item owner.', LOGGER_DEBUG);
                $datarray['owner-name'] = $importer['senderName'];
                $datarray['owner-link'] = $importer['url'];
                $datarray['owner-avatar'] = $importer['thumb'];
            }
            if ($importer['rel'] == CONTACT_IS_FOLLOWER && !tgroup_check($importer['importer_uid'], $datarray)) {
                continue;
            }
            // This is my contact on another system, but it's really me.
            // Turn this into a wall post.
            $notify = item_is_remote_self($importer, $datarray);
            $posted_id = item_store($datarray, false, $notify);
            if (stristr($datarray['verb'], ACTIVITY_POKE)) {
                $verb = urldecode(substr($datarray['verb'], strpos($datarray['verb'], '#') + 1));
                if (!$verb) {
                    continue;
                }
                $xo = parse_xml_string($datarray['object'], false);
                if ($xo->type == ACTIVITY_OBJ_PERSON && $xo->id) {
                    // somebody was poked/prodded. Was it me?
                    $links = parse_xml_string("<links>" . unxmlify($xo->link) . "</links>", false);
                    foreach ($links->link as $l) {
                        $atts = $l->attributes();
                        switch ($atts['rel']) {
                            case "alternate":
                                $Blink = $atts['href'];
                                break;
                            default:
                                break;
                        }
                    }
                    if ($Blink && link_compare($Blink, $a->get_baseurl() . '/profile/' . $importer['nickname'])) {
                        // send a notification
                        require_once 'include/enotify.php';
                        notification(array('type' => NOTIFY_POKE, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . urlencode(get_item_guid($posted_id)), 'source_name' => stripslashes($datarray['author-name']), 'source_link' => $datarray['author-link'], 'source_photo' => link_compare($datarray['author-link'], $importer['url']) ? $importer['thumb'] : $datarray['author-avatar'], 'verb' => $datarray['verb'], 'otype' => 'person', 'activity' => $verb, 'parent' => $datarray['parent']));
                    }
                }
            }
            continue;
        }
    }
    return 0;
    // NOTREACHED
}
コード例 #4
0
ファイル: Scrape.php プロジェクト: robhell/friendica
function probe_url($url, $mode = PROBE_NORMAL)
{
    require_once 'include/email.php';
    $result = array();
    if (!$url) {
        return $result;
    }
    $network = null;
    $diaspora = false;
    $diaspora_base = '';
    $diaspora_guid = '';
    $diaspora_key = '';
    $has_lrdd = false;
    $email_conversant = false;
    $twitter = strpos($url, 'twitter.com') !== false ? true : false;
    $at_addr = strpos($url, '@') !== false ? true : false;
    if (!$twitter) {
        if (strpos($url, 'mailto:') !== false && $at_addr) {
            $url = str_replace('mailto:', '', $url);
            $links = array();
        } else {
            $links = lrdd($url);
        }
        if (count($links)) {
            $has_lrdd = true;
            logger('probe_url: found lrdd links: ' . print_r($links, true), LOGGER_DATA);
            foreach ($links as $link) {
                if ($link['@attributes']['rel'] === NAMESPACE_ZOT) {
                    $zot = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === NAMESPACE_DFRN) {
                    $dfrn = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'salmon') {
                    $notify = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === NAMESPACE_FEED) {
                    $poll = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard') {
                    $hcard = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') {
                    $profile = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0') {
                    $poco = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
                    $diaspora_base = unamp($link['@attributes']['href']);
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
                    $diaspora_guid = unamp($link['@attributes']['href']);
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'diaspora-public-key') {
                    $diaspora_key = base64_decode(unamp($link['@attributes']['href']));
                    $pubkey = rsatopem($diaspora_key);
                    $diaspora = true;
                }
            }
            // Status.Net can have more than one profile URL. We need to match the profile URL
            // to a contact on incoming messages to prevent spam, and we won't know which one
            // to match. So in case of two, one of them is stored as an alias. Only store URL's
            // and not webfinger user@host aliases. If they've got more than two non-email style
            // aliases, let's hope we're lucky and get one that matches the feed author-uri because
            // otherwise we're screwed.
            foreach ($links as $link) {
                if ($link['@attributes']['rel'] === 'alias') {
                    if (strpos($link['@attributes']['href'], '@') === false) {
                        if (isset($profile)) {
                            if ($link['@attributes']['href'] !== $profile) {
                                $alias = unamp($link['@attributes']['href']);
                            }
                        } else {
                            $profile = unamp($link['@attributes']['href']);
                        }
                    }
                }
            }
        } elseif ($mode == PROBE_NORMAL) {
            // Check email
            $orig_url = $url;
            if (strpos($orig_url, '@') && validate_email($orig_url)) {
                $x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1", intval(local_user()));
                $r = q("SELECT * FROM `mailacct` WHERE `uid` = %d AND `server` != '' LIMIT 1", intval(local_user()));
                if (count($x) && count($r)) {
                    $mailbox = construct_mailbox_name($r[0]);
                    $password = '';
                    openssl_private_decrypt(hex2bin($r[0]['pass']), $password, $x[0]['prvkey']);
                    $mbox = email_connect($mailbox, $r[0]['user'], $password);
                    if (!$mbox) {
                        logger('probe_url: email_connect failed.');
                    }
                    unset($password);
                }
                if ($mbox) {
                    $msgs = email_poll($mbox, $orig_url);
                    logger('probe_url: searching ' . $orig_url . ', ' . count($msgs) . ' messages found.', LOGGER_DEBUG);
                    if (count($msgs)) {
                        $addr = $orig_url;
                        $network = NETWORK_MAIL;
                        $name = substr($url, 0, strpos($url, '@'));
                        $phost = substr($url, strpos($url, '@') + 1);
                        $profile = 'http://' . $phost;
                        // fix nick character range
                        $vcard = array('fn' => $name, 'nick' => $name, 'photo' => avatar_img($url));
                        $notify = 'smtp ' . random_string();
                        $poll = 'email ' . random_string();
                        $priority = 0;
                        $x = email_msg_meta($mbox, $msgs[0]);
                        if (stristr($x->from, $orig_url)) {
                            $adr = imap_rfc822_parse_adrlist($x->from, '');
                        } elseif (stristr($x->to, $orig_url)) {
                            $adr = imap_rfc822_parse_adrlist($x->to, '');
                        }
                        if (isset($adr)) {
                            foreach ($adr as $feadr) {
                                if (strcasecmp($feadr->mailbox, $name) == 0 && strcasecmp($feadr->host, $phost) == 0 && strlen($feadr->personal)) {
                                    $personal = imap_mime_header_decode($feadr->personal);
                                    $vcard['fn'] = "";
                                    foreach ($personal as $perspart) {
                                        if ($perspart->charset != "default") {
                                            $vcard['fn'] .= iconv($perspart->charset, 'UTF-8//IGNORE', $perspart->text);
                                        } else {
                                            $vcard['fn'] .= $perspart->text;
                                        }
                                    }
                                    $vcard['fn'] = notags($vcard['fn']);
                                }
                            }
                        }
                    }
                    imap_close($mbox);
                }
            }
        }
    }
    if ($mode == PROBE_NORMAL) {
        if (strlen($zot)) {
            $s = fetch_url($zot);
            if ($s) {
                $j = json_decode($s);
                if ($j) {
                    $network = NETWORK_ZOT;
                    $vcard = array('fn' => $j->fullname, 'nick' => $j->nickname, 'photo' => $j->photo);
                    $profile = $j->url;
                    $notify = $j->post;
                    $pubkey = $j->pubkey;
                    $poll = 'N/A';
                }
            }
        }
        if (strlen($dfrn)) {
            $ret = scrape_dfrn($hcard ? $hcard : $dfrn);
            if (is_array($ret) && x($ret, 'dfrn-request')) {
                $network = NETWORK_DFRN;
                $request = $ret['dfrn-request'];
                $confirm = $ret['dfrn-confirm'];
                $notify = $ret['dfrn-notify'];
                $poll = $ret['dfrn-poll'];
                $vcard = array();
                $vcard['fn'] = $ret['fn'];
                $vcard['nick'] = $ret['nick'];
                $vcard['photo'] = $ret['photo'];
            }
        }
    }
    if ($diaspora && $diaspora_base && $diaspora_guid) {
        if ($mode == PROBE_DIASPORA || !$notify) {
            $notify = $diaspora_base . 'receive/users/' . $diaspora_guid;
            $batch = $diaspora_base . 'receive/public';
        }
        if (strpos($url, '@')) {
            $addr = str_replace('acct:', '', $url);
        }
    }
    if ($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) {
        if ($diaspora) {
            $network = NETWORK_DIASPORA;
        } elseif ($has_lrdd) {
            $network = NETWORK_OSTATUS;
        }
        $priority = 0;
        if ($hcard && !$vcard) {
            $vcard = scrape_vcard($hcard);
            // Google doesn't use absolute url in profile photos
            if (x($vcard, 'photo') && substr($vcard['photo'], 0, 1) == '/') {
                $h = @parse_url($hcard);
                if ($h) {
                    $vcard['photo'] = $h['scheme'] . '://' . $h['host'] . $vcard['photo'];
                }
            }
            logger('probe_url: scrape_vcard: ' . print_r($vcard, true), LOGGER_DATA);
        }
        if ($twitter) {
            logger('twitter: setup');
            $tid = basename($url);
            $tapi = 'https://api.twitter.com/1/statuses/user_timeline.rss';
            if (intval($tid)) {
                $poll = $tapi . '?user_id=' . $tid;
            } else {
                $poll = $tapi . '?screen_name=' . $tid;
            }
            $profile = 'http://twitter.com/#!/' . $tid;
            $vcard['photo'] = 'https://api.twitter.com/1/users/profile_image/' . $tid;
            $vcard['nick'] = $tid;
            $vcard['fn'] = $tid . '@twitter';
        }
        if (!x($vcard, 'fn')) {
            if (x($vcard, 'nick')) {
                $vcard['fn'] = $vcard['nick'];
            }
        }
        $check_feed = false;
        if ($twitter || !$poll) {
            $check_feed = true;
        }
        if (!isset($vcard) || !x($vcard, 'fn') || !$profile) {
            $check_feed = true;
        }
        if ($at_addr && !count($links)) {
            $check_feed = false;
        }
        if ($check_feed) {
            $feedret = scrape_feed($poll ? $poll : $url);
            logger('probe_url: scrape_feed ' . ($poll ? $poll : $url) . ' returns: ' . print_r($feedret, true), LOGGER_DATA);
            if (count($feedret) && ($feedret['feed_atom'] || $feedret['feed_rss'])) {
                $poll = x($feedret, 'feed_atom') ? unamp($feedret['feed_atom']) : unamp($feedret['feed_rss']);
                if (!x($vcard)) {
                    $vcard = array();
                }
            }
            if (x($feedret, 'photo') && !x($vcard, 'photo')) {
                $vcard['photo'] = $feedret['photo'];
            }
            require_once 'library/simplepie/simplepie.inc';
            $feed = new SimplePie();
            $xml = fetch_url($poll);
            logger('probe_url: fetch feed: ' . $poll . ' returns: ' . $xml, LOGGER_DATA);
            $a = get_app();
            logger('probe_url: scrape_feed: headers: ' . $a->get_curl_headers(), LOGGER_DATA);
            $feed->set_raw_data($xml);
            $feed->init();
            if ($feed->error()) {
                logger('probe_url: scrape_feed: Error parsing XML: ' . $feed->error());
            }
            if (!x($vcard, 'photo')) {
                $vcard['photo'] = $feed->get_image_url();
            }
            $author = $feed->get_author();
            if ($author) {
                $vcard['fn'] = unxmlify(trim($author->get_name()));
                if (!$vcard['fn']) {
                    $vcard['fn'] = trim(unxmlify($author->get_email()));
                }
                if (strpos($vcard['fn'], '@') !== false) {
                    $vcard['fn'] = substr($vcard['fn'], 0, strpos($vcard['fn'], '@'));
                }
                $email = unxmlify($author->get_email());
                if (!$profile && $author->get_link()) {
                    $profile = trim(unxmlify($author->get_link()));
                }
                if (!$vcard['photo']) {
                    $rawtags = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
                    if ($rawtags) {
                        $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
                        if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo') {
                            $vcard['photo'] = $elems['link'][0]['attribs']['']['href'];
                        }
                    }
                }
            } else {
                $item = $feed->get_item(0);
                if ($item) {
                    $author = $item->get_author();
                    if ($author) {
                        $vcard['fn'] = trim(unxmlify($author->get_name()));
                        if (!$vcard['fn']) {
                            $vcard['fn'] = trim(unxmlify($author->get_email()));
                        }
                        if (strpos($vcard['fn'], '@') !== false) {
                            $vcard['fn'] = substr($vcard['fn'], 0, strpos($vcard['fn'], '@'));
                        }
                        $email = unxmlify($author->get_email());
                        if (!$profile && $author->get_link()) {
                            $profile = trim(unxmlify($author->get_link()));
                        }
                    }
                    if (!$vcard['photo']) {
                        $rawmedia = $item->get_item_tags('http://search.yahoo.com/mrss/', 'thumbnail');
                        if ($rawmedia && $rawmedia[0]['attribs']['']['url']) {
                            $vcard['photo'] = unxmlify($rawmedia[0]['attribs']['']['url']);
                        }
                    }
                    if (!$vcard['photo']) {
                        $rawtags = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
                        if ($rawtags) {
                            $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
                            if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo') {
                                $vcard['photo'] = $elems['link'][0]['attribs']['']['href'];
                            }
                        }
                    }
                }
            }
            if (!$vcard['photo'] && strlen($email)) {
                $vcard['photo'] = avatar_img($email);
            }
            if ($poll === $profile) {
                $lnk = $feed->get_permalink();
            }
            if (isset($lnk) && strlen($lnk)) {
                $profile = $lnk;
            }
            if (!x($vcard, 'fn')) {
                $vcard['fn'] = notags($feed->get_title());
            }
            if (!x($vcard, 'fn')) {
                $vcard['fn'] = notags($feed->get_description());
            }
            if (strpos($vcard['fn'], 'Twitter / ') !== false) {
                $vcard['fn'] = substr($vcard['fn'], strpos($vcard['fn'], '/') + 1);
                $vcard['fn'] = trim($vcard['fn']);
            }
            if (!x($vcard, 'nick')) {
                $vcard['nick'] = strtolower(notags(unxmlify($vcard['fn'])));
                if (strpos($vcard['nick'], ' ')) {
                    $vcard['nick'] = trim(substr($vcard['nick'], 0, strpos($vcard['nick'], ' ')));
                }
            }
            if (!$network) {
                $network = NETWORK_FEED;
            }
            if (!$priority) {
                $priority = 2;
            }
        }
    }
    if (!x($vcard, 'photo')) {
        $a = get_app();
        $vcard['photo'] = $a->get_baseurl() . '/images/person-175.jpg';
    }
    if (!$profile) {
        $profile = $url;
    }
    // No human could be associated with this link, use the URL as the contact name
    if ($network === NETWORK_FEED && $poll && !x($vcard, 'fn')) {
        $vcard['fn'] = $url;
    }
    $vcard['fn'] = notags($vcard['fn']);
    $vcard['nick'] = str_replace(' ', '', notags($vcard['nick']));
    $result['name'] = $vcard['fn'];
    $result['nick'] = $vcard['nick'];
    $result['url'] = $profile;
    $result['addr'] = $addr;
    $result['batch'] = $batch;
    $result['notify'] = $notify;
    $result['poll'] = $poll;
    $result['request'] = $request;
    $result['confirm'] = $confirm;
    $result['poco'] = $poco;
    $result['photo'] = $vcard['photo'];
    $result['priority'] = $priority;
    $result['network'] = $network;
    $result['alias'] = $alias;
    $result['pubkey'] = $pubkey;
    logger('probe_url: ' . print_r($result, true), LOGGER_DEBUG);
    return $result;
}
コード例 #5
0
function dfrn_notify_post(&$a)
{
    $dfrn_id = notags(trim($_POST['dfrn_id']));
    $challenge = notags(trim($_POST['challenge']));
    $data = $_POST['data'];
    $r = q("SELECT * FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1", dbesc($dfrn_id), dbesc($challenge));
    if (!count($r)) {
        xml_status(3);
    }
    $r = q("DELETE FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1", dbesc($dfrn_id), dbesc($challenge));
    // find the local user who owns this relationship.
    $r = q("SELECT `contact`.*, `user`.* FROM `contact` LEFT JOIN `user` on `user`.`uid` = 1 \n\t\tWHERE ( `issued-id` = '%s' OR ( `duplex` = 1 AND `dfrn-id` = '%s' )) LIMIT 1", dbesc($dfrn_id), dbesc($dfrn_id));
    if (!count($r)) {
        xml_status(3);
        return;
        //NOTREACHED
    }
    $importer = $r[0];
    $feed = new SimplePie();
    $feed->set_raw_data($data);
    $feed->enable_order_by_date(false);
    $feed->init();
    $ismail = false;
    $rawmail = $feed->get_feed_tags(NAMESPACE_DFRN, 'mail');
    if (isset($rawmail[0]['child'][NAMESPACE_DFRN])) {
        if ($importer['readonly']) {
            // We aren't receiving email from this person. But we will quietly ignore them
            // rather than a blatant "go away" message.
            xml_status(0);
            return;
            //NOTREACHED
        }
        $ismail = true;
        $base = $rawmail[0]['child'][NAMESPACE_DFRN];
        $msg = array();
        $msg['from-name'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['name'][0]['data']));
        $msg['from-photo'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['avatar'][0]['data']));
        $msg['from-url'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['uri'][0]['data']));
        $msg['contact-id'] = $importer['id'];
        $msg['title'] = notags(unxmlify($base['subject'][0]['data']));
        $msg['body'] = escape_tags(unxmlify($base['content'][0]['data']));
        $msg['delivered'] = 1;
        $msg['seen'] = 0;
        $msg['replied'] = 0;
        $msg['uri'] = notags(unxmlify($base['id'][0]['data']));
        $msg['parent-uri'] = notags(unxmlify($base['in-reply-to'][0]['data']));
        $msg['created'] = datetime_convert(notags(unxmlify('UTC', 'UTC', $base['sentdate'][0]['data'])));
        dbesc_array($msg);
        $r = q("INSERT INTO `mail` (`" . implode("`, `", array_keys($msg)) . "`) VALUES ('" . implode("', '", array_values($msg)) . "')");
        require_once 'bbcode.php';
        if ($importer['notify-flags'] & NOTIFY_MAIL) {
            $tpl = file_get_contents('view/mail_received_eml.tpl');
            $email_tpl = replace_macros($tpl, array('$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$username' => $importer['username'], '$email' => $importer['email'], '$from' => $msg['from-name'], '$title' => $msg['title'], '$body' => strip_tags(bbcode($msg['body']))));
            $res = mail($importer['email'], t("New mail received at ") . $a->config['sitename'], $email_tpl, t("From: Administrator@") . $a->get_hostname());
        }
        xml_status(0);
        return;
        // NOTREACHED
    }
    if ($importer['readonly'] && !x($a->config['rockstar'])) {
        // This contact is readonly and we're going to ignore him/her, except if we're in
        // RockStar configuration. Us rockstars wan't people to talk about us. We just don't
        // want to have to deal with them individually. So our "readonly" fans can post to
        // our wall and comment, but they can't send us email.
        xml_status(0);
        return;
        // NOTREACHED
    }
    foreach ($feed->get_items() as $item) {
        $deleted = false;
        $rawdelete = $item->get_item_tags("http://purl.org/atompub/tombstones/1.0", 'deleted-entry');
        if (isset($rawdelete[0]['attribs']['']['ref'])) {
            $uri = $rawthread[0]['attribs']['']['ref'];
            $deleted = true;
            if (isset($rawdelete[0]['attribs']['']['when'])) {
                $when = $rawthread[0]['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) {
            $r = q("SELECT * FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($uri));
            if (count($r)) {
                $item = $r[0];
                if ($item['uri'] == $item['parent-uri']) {
                    $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s' , `changed` = '%s'\n\t\t\t\t\t\tWHERE `parent-uri` = '%s'", dbesc($when), dbesc(datetime_convert()), dbesc($item['uri']));
                } else {
                    $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s' , `changed` = '%s' \n\t\t\t\t\t\tWHERE `uri` = '%s' LIMIT 1", dbesc($when), dbesc(datetime_convert()), dbesc($uri));
                }
                if ($item['last-child']) {
                    // ensure that last-child is set in case the comment that had it just got wiped.
                    $q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' ", dbesc(datetime_convert()), dbesc($item['parent-uri']));
                    // who is the last child now?
                    $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 \n\t\t\t\t\t\tORDER BY `edited` DESC LIMIT 1", dbesc($item['parent-uri']));
                    if (count($r)) {
                        q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($r[0]['id']));
                    }
                }
            }
            continue;
        }
        $is_reply = false;
        $item_id = $item->get_id();
        $rawthread = $item->get_item_tags("http://purl.org/syndication/thread/1.0", 'in-reply-to');
        if (isset($rawthread[0]['attribs']['']['ref'])) {
            $is_reply = true;
            $parent_uri = $rawthread[0]['attribs']['']['ref'];
        }
        if ($is_reply) {
            if ($feed->get_item_quantity() == 1) {
                // remote reply to our post. Import and then notify everybody else.
                $datarray = get_atom_elements($item);
                $datarray['wall'] = 1;
                $datarray['type'] = 'remote-comment';
                $datarray['parent-uri'] = $parent_uri;
                $datarray['contact-id'] = $importer['id'];
                $posted_id = post_remote($a, $datarray);
                if ($posted_id) {
                    $r = q("SELECT `parent` FROM `item` WHERE `id` = %d LIMIT 1", intval($posted_id));
                    if (count($r)) {
                        $r1 = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent` = %d", dbesc(datetime_convert()), intval($r[0]['parent']));
                    }
                    $r2 = q("UPDATE `item` SET `last-child` = 1, `changed` = '%s' WHERE `id` = %d LIMIT 1", dbesc(datetime_convert()), intval($posted_id));
                    $php_path = strlen($a->config['php_path']) ? $a->config['php_path'] : 'php';
                    proc_close(proc_open("\"{$php_path}\" \"include/notifier.php\" \"comment-import\" \"{$posted_id}\" &", array(), $foo));
                    if ($importer['notify-flags'] & NOTIFY_COMMENT && !$importer['self']) {
                        require_once 'bbcode.php';
                        $from = stripslashes($datarray['author-name']);
                        $tpl = file_get_contents('view/cmnt_received_eml.tpl');
                        $email_tpl = replace_macros($tpl, array('$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$username' => $importer['username'], '$email' => $importer['email'], '$from' => $from, '$body' => strip_tags(bbcode(stripslashes($datarray['body'])))));
                        $res = mail($importer['email'], $from . t(" commented on your item at ") . $a->config['sitename'], $email_tpl, t("From: Administrator@") . $a->get_hostname());
                    }
                }
                xml_status(0);
                return;
            } else {
                // regular comment that is part of this total conversation. Have we seen it? If not, import it.
                $item_id = $item->get_id();
                $r = q("SELECT `last-child`, `edited` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($item_id));
                // FIXME update content if 'updated' changes
                if (count($r)) {
                    $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
                    if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
                        $r = q("UPDATE `item` SET `last-child` = %d, `changed` = '%s' WHERE `uri` = '%s' LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id));
                    }
                    continue;
                }
                $datarray = get_atom_elements($item);
                $datarray['parent-uri'] = $parent_uri;
                $datarray['contact-id'] = $importer['id'];
                $r = post_remote($a, $datarray);
                // find out if our user is involved in this conversation and wants to be notified.
                if ($importer['notify-flags'] & NOTIFY_COMMENT) {
                    $myconv = q("SELECT `author-link` FROM `item` WHERE `parent-uri` = '%s'", dbesc($parent_uri));
                    if (count($myconv)) {
                        foreach ($myconv as $conv) {
                            if ($conv['author-link'] != $importer['url']) {
                                continue;
                            }
                            require_once 'bbcode.php';
                            $from = stripslashes($datarray['author-name']);
                            $tpl = file_get_contents('view/cmnt_received_eml.tpl');
                            $email_tpl = replace_macros($tpl, array('$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$username' => $importer['username'], '$email' => $importer['email'], '$from' => $from, '$body' => strip_tags(bbcode(stripslashes($datarray['body'])))));
                            $res = mail($importer['email'], $from . t(" commented on an item at ") . $a->config['sitename'], $email_tpl, t("From: Administrator@") . $a->get_hostname());
                            break;
                        }
                    }
                }
                continue;
            }
        } else {
            // Head post of a conversation. Have we seen it? If not, import it.
            $item_id = $item->get_id();
            $r = q("SELECT `last-child`, `edited` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($item_id));
            if (count($r)) {
                $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
                if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
                    $r = q("UPDATE `item` SET `last-child` = %d, `changed` = '%s' WHERE `uri` = '%s' LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id));
                }
                continue;
            }
            $datarray = get_atom_elements($item);
            $datarray['parent-uri'] = $item_id;
            $datarray['contact-id'] = $importer['id'];
            $r = post_remote($a, $datarray);
            continue;
        }
    }
    xml_status(0);
    killme();
}
コード例 #6
0
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;
}
コード例 #7
0
ファイル: items.php プロジェクト: robhell/friendica
function local_delivery($importer, $data)
{
    $a = get_app();
    if ($importer['readonly']) {
        // We aren't receiving stuff from this person. But we will quietly ignore them
        // rather than a blatant "go away" message.
        logger('local_delivery: ignoring');
        return 0;
        //NOTREACHED
    }
    // Consume notification feed. This may differ from consuming a public feed in several ways
    // - might contain email or friend suggestions
    // - might contain remote followup to our message
    //		- in which case we need to accept it and then notify other conversants
    // - we may need to send various email notifications
    $feed = new SimplePie();
    $feed->set_raw_data($data);
    $feed->enable_order_by_date(false);
    $feed->init();
    /*
    	// Currently unsupported - needs a lot of work
    	$reloc = $feed->get_feed_tags( NAMESPACE_DFRN, 'relocate' );
    	if(isset($reloc[0]['child'][NAMESPACE_DFRN])) {
    		$base = $reloc[0]['child'][NAMESPACE_DFRN];
    		$newloc = array();
    		$newloc['uid'] = $importer['importer_uid'];
    		$newloc['cid'] = $importer['id'];
    		$newloc['name'] = notags(unxmlify($base['name'][0]['data']));
    		$newloc['photo'] = notags(unxmlify($base['photo'][0]['data']));
    		$newloc['url'] = notags(unxmlify($base['url'][0]['data']));
    		$newloc['request'] = notags(unxmlify($base['request'][0]['data']));
    		$newloc['confirm'] = notags(unxmlify($base['confirm'][0]['data']));
    		$newloc['notify'] = notags(unxmlify($base['notify'][0]['data']));
    		$newloc['poll'] = notags(unxmlify($base['poll'][0]['data']));
    		$newloc['site-pubkey'] = notags(unxmlify($base['site-pubkey'][0]['data']));
    		$newloc['pubkey'] = notags(unxmlify($base['pubkey'][0]['data']));
    		$newloc['prvkey'] = notags(unxmlify($base['prvkey'][0]['data']));
    		
    		// TODO
    		// merge with current record, current contents have priority
    		// update record, set url-updated
    		// update profile photos
    		// schedule a scan?
    
    	}
    */
    // handle friend suggestion notification
    $sugg = $feed->get_feed_tags(NAMESPACE_DFRN, 'suggest');
    if (isset($sugg[0]['child'][NAMESPACE_DFRN])) {
        $base = $sugg[0]['child'][NAMESPACE_DFRN];
        $fsugg = array();
        $fsugg['uid'] = $importer['importer_uid'];
        $fsugg['cid'] = $importer['id'];
        $fsugg['name'] = notags(unxmlify($base['name'][0]['data']));
        $fsugg['photo'] = notags(unxmlify($base['photo'][0]['data']));
        $fsugg['url'] = notags(unxmlify($base['url'][0]['data']));
        $fsugg['request'] = notags(unxmlify($base['request'][0]['data']));
        $fsugg['body'] = escape_tags(unxmlify($base['note'][0]['data']));
        // Does our member already have a friend matching this description?
        $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `nurl` = '%s' AND `uid` = %d LIMIT 1", dbesc($fsugg['name']), dbesc(normalise_link($fsugg['url'])), intval($fsugg['uid']));
        if (count($r)) {
            return 0;
        }
        // Do we already have an fcontact record for this person?
        $fid = 0;
        $r = q("SELECT * FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1", dbesc($fsugg['url']), dbesc($fsugg['name']), dbesc($fsugg['request']));
        if (count($r)) {
            $fid = $r[0]['id'];
            // OK, we do. Do we already have an introduction for this person ?
            $r = q("select id from intro where uid = %d and fid = %d limit 1", intval($fsugg['uid']), intval($fid));
            if (count($r)) {
                return 0;
            }
        }
        if (!$fid) {
            $r = q("INSERT INTO `fcontact` ( `name`,`url`,`photo`,`request` ) VALUES ( '%s', '%s', '%s', '%s' ) ", dbesc($fsugg['name']), dbesc($fsugg['url']), dbesc($fsugg['photo']), dbesc($fsugg['request']));
        }
        $r = q("SELECT * FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1", dbesc($fsugg['url']), dbesc($fsugg['name']), dbesc($fsugg['request']));
        if (count($r)) {
            $fid = $r[0]['id'];
        } else {
            return 0;
        }
        $hash = random_string();
        $r = q("INSERT INTO `intro` ( `uid`, `fid`, `contact-id`, `note`, `hash`, `datetime`, `blocked` )\n\t\t\tVALUES( %d, %d, %d, '%s', '%s', '%s', %d )", intval($fsugg['uid']), intval($fid), intval($fsugg['cid']), dbesc($fsugg['body']), dbesc($hash), dbesc(datetime_convert()), intval(0));
        notification(array('type' => NOTIFY_SUGGEST, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $fsugg, 'link' => $a->get_baseurl() . '/notifications/intros', 'source_name' => $importer['name'], 'source_link' => $importer['url'], 'source_photo' => $importer['photo'], 'verb' => ACTIVITY_REQ_FRIEND, 'otype' => 'intro'));
        return 0;
    }
    $ismail = false;
    $rawmail = $feed->get_feed_tags(NAMESPACE_DFRN, 'mail');
    if (isset($rawmail[0]['child'][NAMESPACE_DFRN])) {
        logger('local_delivery: private message received');
        $ismail = true;
        $base = $rawmail[0]['child'][NAMESPACE_DFRN];
        $msg = array();
        $msg['uid'] = $importer['importer_uid'];
        $msg['from-name'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['name'][0]['data']));
        $msg['from-photo'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['avatar'][0]['data']));
        $msg['from-url'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['uri'][0]['data']));
        $msg['contact-id'] = $importer['id'];
        $msg['title'] = notags(unxmlify($base['subject'][0]['data']));
        $msg['body'] = escape_tags(unxmlify($base['content'][0]['data']));
        $msg['seen'] = 0;
        $msg['replied'] = 0;
        $msg['uri'] = notags(unxmlify($base['id'][0]['data']));
        $msg['parent-uri'] = notags(unxmlify($base['in-reply-to'][0]['data']));
        $msg['created'] = datetime_convert(notags(unxmlify('UTC', 'UTC', $base['sentdate'][0]['data'])));
        dbesc_array($msg);
        $r = dbq("INSERT INTO `mail` (`" . implode("`, `", array_keys($msg)) . "`) VALUES ('" . implode("', '", array_values($msg)) . "')");
        // send notifications.
        require_once 'include/enotify.php';
        $notif_params = array('type' => NOTIFY_MAIL, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $msg, 'source_name' => $msg['from-name'], 'source_link' => $importer['url'], 'source_photo' => $importer['thumb'], 'verb' => ACTIVITY_POST, 'otype' => 'mail');
        notification($notif_params);
        return 0;
        // NOTREACHED
    }
    $community_page = 0;
    $rawtags = $feed->get_feed_tags(NAMESPACE_DFRN, 'community');
    if ($rawtags) {
        $community_page = intval($rawtags[0]['data']);
    }
    if (intval($importer['forum']) != $community_page) {
        q("update contact set forum = %d where id = %d limit 1", intval($community_page), intval($importer['id']));
        $importer['forum'] = (string) $community_page;
    }
    logger('local_delivery: feed item count = ' . $feed->get_item_quantity());
    // process any deleted entries
    $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry');
    if (is_array($del_entries) && count($del_entries)) {
        foreach ($del_entries as $dentry) {
            $deleted = false;
            if (isset($dentry['attribs']['']['ref'])) {
                $uri = $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) {
                $r = q("SELECT `item`.*, `contact`.`self` FROM `item` left join contact on `item`.`contact-id` = `contact`.`id`\n\t\t\t\t\tWHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1", dbesc($uri), intval($importer['importer_uid']), intval($importer['id']));
                if (count($r)) {
                    $item = $r[0];
                    if ($item['deleted']) {
                        continue;
                    }
                    logger('local_delivery: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
                    if ($item['verb'] === ACTIVITY_TAG && $item['object-type'] === ACTIVITY_OBJ_TAGTERM) {
                        $xo = parse_xml_string($item['object'], false);
                        $xt = parse_xml_string($item['target'], false);
                        if ($xt->type === ACTIVITY_OBJ_NOTE) {
                            $i = q("select * from `item` where uri = '%s' and uid = %d limit 1", dbesc($xt->id), intval($importer['importer_uid']));
                            if (count($i)) {
                                // For tags, the owner cannot remove the tag on the author's copy of the post.
                                $owner_remove = $item['contact-id'] == $i[0]['contact-id'] ? true : false;
                                $author_remove = $item['origin'] && $item['self'] ? true : false;
                                $author_copy = $item['origin'] ? true : false;
                                if ($owner_remove && $author_copy) {
                                    continue;
                                }
                                if ($author_remove || $owner_remove) {
                                    $tags = explode(',', $i[0]['tag']);
                                    $newtags = array();
                                    if (count($tags)) {
                                        foreach ($tags as $tag) {
                                            if (trim($tag) !== trim($xo->body)) {
                                                $newtags[] = trim($tag);
                                            }
                                        }
                                    }
                                    q("update item set tag = '%s' where id = %d limit 1", dbesc(implode(',', $newtags)), intval($i[0]['id']));
                                }
                            }
                        }
                    }
                    if ($item['uri'] == $item['parent-uri']) {
                        $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s'\n\t\t\t\t\t\t\tWHERE `parent-uri` = '%s' AND `uid` = %d", dbesc($when), dbesc(datetime_convert()), dbesc($item['uri']), intval($importer['importer_uid']));
                    } else {
                        $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' \n\t\t\t\t\t\t\tWHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($when), dbesc(datetime_convert()), dbesc($uri), intval($importer['importer_uid']));
                        if ($item['last-child']) {
                            // ensure that last-child is set in case the comment that had it just got wiped.
                            q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ", dbesc(datetime_convert()), dbesc($item['parent-uri']), intval($item['uid']));
                            // who is the last child now?
                            $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `uid` = %d\n\t\t\t\t\t\t\t\tORDER BY `created` DESC LIMIT 1", dbesc($item['parent-uri']), intval($importer['importer_uid']));
                            if (count($r)) {
                                q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($r[0]['id']));
                            }
                        }
                    }
                }
            }
        }
    }
    foreach ($feed->get_items() as $item) {
        $is_reply = false;
        $item_id = $item->get_id();
        $rawthread = $item->get_item_tags(NAMESPACE_THREAD, 'in-reply-to');
        if (isset($rawthread[0]['attribs']['']['ref'])) {
            $is_reply = true;
            $parent_uri = $rawthread[0]['attribs']['']['ref'];
        }
        if ($is_reply) {
            $community = false;
            if ($importer['page-flags'] == PAGE_COMMUNITY || $importer['page-flags'] == PAGE_PRVGROUP) {
                $sql_extra = '';
                $community = true;
                logger('local_delivery: possible community reply');
            } else {
                $sql_extra = " and contact.self = 1 and item.wall = 1 ";
            }
            // was the top-level post for this reply written by somebody on this site?
            // Specifically, the recipient?
            $is_a_remote_comment = false;
            $r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, `item`.`forum_mode`,`item`.`origin`,`item`.`wall`, \n\t\t\t\t`contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item` \n\t\t\t\tLEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` \n\t\t\t\tWHERE `item`.`uri` = '%s' AND `item`.`parent-uri` = '%s'\n\t\t\t\tAND `item`.`uid` = %d \n\t\t\t\t{$sql_extra}\n\t\t\t\tLIMIT 1", dbesc($parent_uri), dbesc($parent_uri), intval($importer['importer_uid']));
            if ($r && count($r)) {
                $is_a_remote_comment = true;
            }
            // Does this have the characteristics of a community or private group comment?
            // If it's a reply to a wall post on a community/prvgroup page it's a
            // valid community comment. Also forum_mode makes it valid for sure.
            // If neither, it's not.
            if ($is_a_remote_comment && $community) {
                if (!$r[0]['forum_mode'] && !$r[0]['wall']) {
                    $is_a_remote_comment = false;
                    logger('local_delivery: not a community reply');
                }
            }
            if ($is_a_remote_comment) {
                logger('local_delivery: received remote comment');
                $is_like = false;
                // remote reply to our post. Import and then notify everybody else.
                $datarray = get_atom_elements($feed, $item);
                $r = q("SELECT `id`, `uid`, `last-child`, `edited`, `body`  FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid']));
                // Update content if 'updated' changes
                if (count($r)) {
                    $iid = $r[0]['id'];
                    if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) {
                        logger('received updated comment', LOGGER_DEBUG);
                        $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['importer_uid']));
                        proc_run('php', "include/notifier.php", "comment-import", $iid);
                    }
                    continue;
                }
                // TODO: make this next part work against both delivery threads of a community post
                //				if((! link_compare($datarray['author-link'],$importer['url'])) && (! $community)) {
                //					logger('local_delivery: received relay claiming to be from ' . $importer['url'] . ' however comment author url is ' . $datarray['author-link'] );
                // they won't know what to do so don't report an error. Just quietly die.
                //					return 0;
                //				}
                // our user with $importer['importer_uid'] is the owner
                $own = q("select name,url,thumb from contact where uid = %d and self = 1 limit 1", intval($importer['importer_uid']));
                $datarray['type'] = 'remote-comment';
                $datarray['wall'] = 1;
                $datarray['parent-uri'] = $parent_uri;
                $datarray['uid'] = $importer['importer_uid'];
                $datarray['owner-name'] = $own[0]['name'];
                $datarray['owner-link'] = $own[0]['url'];
                $datarray['owner-avatar'] = $own[0]['thumb'];
                $datarray['contact-id'] = $importer['id'];
                if ($datarray['verb'] === ACTIVITY_LIKE || $datarray['verb'] === ACTIVITY_DISLIKE) {
                    $is_like = true;
                    $datarray['type'] = 'activity';
                    $datarray['gravity'] = GRAVITY_LIKE;
                    $datarray['last-child'] = 0;
                    // only one like or dislike per person
                    $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 limit 1", intval($datarray['uid']), intval($datarray['contact-id']), dbesc($datarray['verb']));
                    if ($r && count($r)) {
                        continue;
                    }
                }
                if ($datarray['verb'] === ACTIVITY_TAG && $datarray['object-type'] === ACTIVITY_OBJ_TAGTERM) {
                    $xo = parse_xml_string($datarray['object'], false);
                    $xt = parse_xml_string($datarray['target'], false);
                    if ($xt->type == ACTIVITY_OBJ_NOTE && $xt->id) {
                        // fetch the parent item
                        $tagp = q("select * from item where uri = '%s' and uid = %d limit 1", dbesc($xt->id), intval($importer['importer_uid']));
                        if (!count($tagp)) {
                            continue;
                        }
                        // extract tag, if not duplicate, and this user allows tags, add to parent item
                        if ($xo->id && $xo->content) {
                            $newtag = '#[url=' . $xo->id . ']' . $xo->content . '[/url]';
                            if (!stristr($tagp[0]['tag'], $newtag)) {
                                $i = q("SELECT `blocktags` FROM `user` where `uid` = %d LIMIT 1", intval($importer['importer_uid']));
                                if (count($i) && !intval($i[0]['blocktags'])) {
                                    q("UPDATE item SET tag = '%s', `edited` = '%s' WHERE id = %d LIMIT 1", dbesc($tagp[0]['tag'] . (strlen($tagp[0]['tag']) ? ',' : '') . $newtag), intval($tagp[0]['id']), dbesc(datetime_convert()));
                                }
                            }
                        }
                    }
                }
                // 				if($community) {
                //					$newtag = '@[url=' . $a->get_baseurl() . '/profile/' . $importer['nickname'] . ']' . $importer['username'] . '[/url]';
                //					if(! stristr($datarray['tag'],$newtag)) {
                //						if(strlen($datarray['tag']))
                //							$datarray['tag'] .= ',';
                //						$datarray['tag'] .= $newtag;
                //					}
                //				}
                $posted_id = item_store($datarray);
                $parent = 0;
                if ($posted_id) {
                    $r = q("SELECT `parent` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($posted_id), intval($importer['importer_uid']));
                    if (count($r)) {
                        $parent = $r[0]['parent'];
                    }
                    if (!$is_like) {
                        $r1 = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `uid` = %d AND `parent` = %d", dbesc(datetime_convert()), intval($importer['importer_uid']), intval($r[0]['parent']));
                        $r2 = q("UPDATE `item` SET `last-child` = 1, `changed` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(datetime_convert()), intval($importer['importer_uid']), intval($posted_id));
                    }
                    if ($posted_id && $parent) {
                        proc_run('php', "include/notifier.php", "comment-import", "{$posted_id}");
                        if (!$is_like && !$importer['self']) {
                            require_once 'include/enotify.php';
                            notification(array('type' => NOTIFY_COMMENT, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, 'source_name' => stripslashes($datarray['author-name']), 'source_link' => $datarray['author-link'], 'source_photo' => link_compare($datarray['author-link'], $importer['url']) ? $importer['thumb'] : $datarray['author-avatar'], 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $parent));
                        }
                    }
                    return 0;
                    // NOTREACHED
                }
            } else {
                // regular comment that is part of this total conversation. Have we seen it? If not, import it.
                $item_id = $item->get_id();
                $datarray = get_atom_elements($feed, $item);
                $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid']));
                // Update content if 'updated' changes
                if (count($r)) {
                    if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) {
                        $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['importer_uid']));
                    }
                    // update last-child if it changes
                    $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
                    if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
                        $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc($parent_uri), intval($importer['importer_uid']));
                        $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s'  WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['importer_uid']));
                    }
                    continue;
                }
                $datarray['parent-uri'] = $parent_uri;
                $datarray['uid'] = $importer['importer_uid'];
                $datarray['contact-id'] = $importer['id'];
                if ($datarray['verb'] == ACTIVITY_LIKE || $datarray['verb'] == ACTIVITY_DISLIKE) {
                    $datarray['type'] = 'activity';
                    $datarray['gravity'] = GRAVITY_LIKE;
                    // only one like or dislike per person
                    $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 limit 1", intval($datarray['uid']), intval($datarray['contact-id']), dbesc($datarray['verb']));
                    if ($r && count($r)) {
                        continue;
                    }
                }
                if ($datarray['verb'] === ACTIVITY_TAG && $datarray['object-type'] === ACTIVITY_OBJ_TAGTERM) {
                    $xo = parse_xml_string($datarray['object'], false);
                    $xt = parse_xml_string($datarray['target'], false);
                    if ($xt->type == ACTIVITY_OBJ_NOTE) {
                        $r = q("select * from item where `uri` = '%s' AND `uid` = %d limit 1", dbesc($xt->id), intval($importer['importer_uid']));
                        if (!count($r)) {
                            continue;
                        }
                        // extract tag, if not duplicate, add to parent item
                        if ($xo->content) {
                            if (!stristr($r[0]['tag'], trim($xo->content))) {
                                q("UPDATE item SET tag = '%s' WHERE id = %d LIMIT 1", dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . '#[url=' . $xo->id . ']' . $xo->content . '[/url]'), intval($r[0]['id']));
                            }
                        }
                    }
                }
                $posted_id = item_store($datarray);
                // find out if our user is involved in this conversation and wants to be notified.
                if (!x($datarray['type']) || $datarray['type'] != 'activity') {
                    $myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 AND `deleted` = 0", dbesc($parent_uri), intval($importer['importer_uid']));
                    if (count($myconv)) {
                        $importer_url = $a->get_baseurl() . '/profile/' . $importer['nickname'];
                        // first make sure this isn't our own post coming back to us from a wall-to-wall event
                        if (!link_compare($datarray['author-link'], $importer_url)) {
                            foreach ($myconv as $conv) {
                                // now if we find a match, it means we're in this conversation
                                if (!link_compare($conv['author-link'], $importer_url)) {
                                    continue;
                                }
                                require_once 'include/enotify.php';
                                $conv_parent = $conv['parent'];
                                notification(array('type' => NOTIFY_COMMENT, 'notify_flags' => $importer['notify-flags'], 'language' => $importer['language'], 'to_name' => $importer['username'], 'to_email' => $importer['email'], 'uid' => $importer['importer_uid'], 'item' => $datarray, 'link' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, 'source_name' => stripslashes($datarray['author-name']), 'source_link' => $datarray['author-link'], 'source_photo' => link_compare($datarray['author-link'], $importer['url']) ? $importer['thumb'] : $datarray['author-avatar'], 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $conv_parent));
                                // only send one notification
                                break;
                            }
                        }
                    }
                }
                continue;
            }
        } else {
            // Head post of a conversation. Have we seen it? If not, import it.
            $item_id = $item->get_id();
            $datarray = get_atom_elements($feed, $item);
            if (x($datarray, 'object-type') && $datarray['object-type'] === ACTIVITY_OBJ_EVENT) {
                $ev = bbtoevent($datarray['body']);
                if (x($ev, 'desc') && x($ev, 'start')) {
                    $ev['cid'] = $importer['id'];
                    $ev['uid'] = $importer['uid'];
                    $ev['uri'] = $item_id;
                    $ev['edited'] = $datarray['edited'];
                    $ev['private'] = $datarray['private'];
                    $r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['uid']));
                    if (count($r)) {
                        $ev['id'] = $r[0]['id'];
                    }
                    $xyz = event_store($ev);
                    continue;
                }
            }
            $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid']));
            // Update content if 'updated' changes
            if (count($r)) {
                if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) {
                    $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['title']), dbesc($datarray['body']), dbesc($datarray['tag']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['importer_uid']));
                }
                // update last-child if it changes
                $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
                if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
                    $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['importer_uid']));
                }
                continue;
            }
            // This is my contact on another system, but it's really me.
            // Turn this into a wall post.
            if ($importer['remote_self']) {
                $datarray['wall'] = 1;
            }
            $datarray['parent-uri'] = $item_id;
            $datarray['uid'] = $importer['importer_uid'];
            $datarray['contact-id'] = $importer['id'];
            if (!link_compare($datarray['owner-link'], $contact['url'])) {
                // The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery,
                // but otherwise there's a possible data mixup on the sender's system.
                // the tgroup delivery code called from item_store will correct it if it's a forum,
                // but we're going to unconditionally correct it here so that the post will always be owned by our contact.
                logger('local_delivery: Correcting item owner.', LOGGER_DEBUG);
                $datarray['owner-name'] = $importer['senderName'];
                $datarray['owner-link'] = $importer['url'];
                $datarray['owner-avatar'] = $importer['thumb'];
            }
            $r = item_store($datarray);
            continue;
        }
    }
    return 0;
    // NOTREACHED
}
コード例 #8
0
ファイル: poller.php プロジェクト: vishalp/MistparkPE-Remix
 $xml = post_url($contact['poll'], $postvars);
 if (!strlen($xml)) {
     // an empty response may mean there's nothing new - record the fact that we checked
     $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1", dbesc(datetime_convert()), intval($contact['id']));
     continue;
 }
 $feed = new SimplePie();
 $feed->set_raw_data($xml);
 $feed->enable_order_by_date(false);
 $feed->init();
 // Check at the feed level for updated contact name and/or photo
 $name_updated = '';
 $new_name = '';
 $photo_timestamp = '';
 $photo_url = '';
 $rawtags = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, author);
 if ($rawtags) {
     $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
     if ($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
         $name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated'];
         $new_name = $elems['name'][0]['data'];
     }
     if ($elems['link'][0]['attribs']['']['rel'] == 'photo' && $elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
         $photo_timestamp = datetime_convert('UTC', 'UTC', $elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
         $photo_url = $elems['link'][0]['attribs']['']['href'];
     }
 }
 if (!$photo_timestamp) {
     $photo_rawupdate = $feed->get_feed_tags(NAMESPACE_DFRN, 'icon-updated');
     if ($photo_rawupdate) {
         $photo_timestamp = datetime_convert('UTC', 'UTC', $photo_rawupdate[0]['data']);
コード例 #9
0
ファイル: items.php プロジェクト: ryivhnn/friendica
function local_delivery($importer, $data)
{
    $a = get_app();
    if ($importer['readonly']) {
        // We aren't receiving stuff from this person. But we will quietly ignore them
        // rather than a blatant "go away" message.
        logger('local_delivery: ignoring');
        return 0;
        //NOTREACHED
    }
    // Consume notification feed. This may differ from consuming a public feed in several ways
    // - might contain email or friend suggestions
    // - might contain remote followup to our message
    //		- in which case we need to accept it and then notify other conversants
    // - we may need to send various email notifications
    $feed = new SimplePie();
    $feed->set_raw_data($data);
    $feed->enable_order_by_date(false);
    $feed->init();
    $reloc = $feed->get_feed_tags(NAMESPACE_DFRN, 'relocate');
    if (isset($reloc[0]['child'][NAMESPACE_DFRN])) {
        $base = $reloc[0]['child'][NAMESPACE_DFRN];
        $newloc = array();
        $newloc['uid'] = $importer['importer_uid'];
        $newloc['cid'] = $importer['id'];
        $newloc['name'] = notags(unxmlify($base['name'][0]['data']));
        $newloc['photo'] = notags(unxmlify($base['photo'][0]['data']));
        $newloc['url'] = notags(unxmlify($base['url'][0]['data']));
        $newloc['request'] = notags(unxmlify($base['request'][0]['data']));
        $newloc['confirm'] = notags(unxmlify($base['confirm'][0]['data']));
        $newloc['notify'] = notags(unxmlify($base['notify'][0]['data']));
        $newloc['poll'] = notags(unxmlify($base['poll'][0]['data']));
        $newloc['site-pubkey'] = notags(unxmlify($base['site-pubkey'][0]['data']));
        $newloc['pubkey'] = notags(unxmlify($base['pubkey'][0]['data']));
        $newloc['prvkey'] = notags(unxmlify($base['prvkey'][0]['data']));
        // TODO
        // merge with current record, current contents have priority
        // update record, set url-updated
        // update profile photos
        // schedule a scan?
    }
    // handle friend suggestion notification
    $sugg = $feed->get_feed_tags(NAMESPACE_DFRN, 'suggest');
    if (isset($sugg[0]['child'][NAMESPACE_DFRN])) {
        $base = $sugg[0]['child'][NAMESPACE_DFRN];
        $fsugg = array();
        $fsugg['uid'] = $importer['importer_uid'];
        $fsugg['cid'] = $importer['id'];
        $fsugg['name'] = notags(unxmlify($base['name'][0]['data']));
        $fsugg['photo'] = notags(unxmlify($base['photo'][0]['data']));
        $fsugg['url'] = notags(unxmlify($base['url'][0]['data']));
        $fsugg['request'] = notags(unxmlify($base['request'][0]['data']));
        $fsugg['body'] = escape_tags(unxmlify($base['note'][0]['data']));
        // Does our member already have a friend matching this description?
        $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `nurl` = '%s' AND `uid` = %d LIMIT 1", dbesc($fsugg['name']), dbesc(normalise_link($fsugg['url'])), intval($fsugg['uid']));
        if (count($r)) {
            return 0;
        }
        // Do we already have an fcontact record for this person?
        $fid = 0;
        $r = q("SELECT * FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1", dbesc($fsugg['url']), dbesc($fsugg['name']), dbesc($fsugg['request']));
        if (count($r)) {
            $fid = $r[0]['id'];
        }
        if (!$fid) {
            $r = q("INSERT INTO `fcontact` ( `name`,`url`,`photo`,`request` ) VALUES ( '%s', '%s', '%s', '%s' ) ", dbesc($fsugg['name']), dbesc($fsugg['url']), dbesc($fsugg['photo']), dbesc($fsugg['request']));
        }
        $r = q("SELECT * FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1", dbesc($fsugg['url']), dbesc($fsugg['name']), dbesc($fsugg['request']));
        if (count($r)) {
            $fid = $r[0]['id'];
        } else {
            return 0;
        }
        $hash = random_string();
        $r = q("INSERT INTO `intro` ( `uid`, `fid`, `contact-id`, `note`, `hash`, `datetime`, `blocked` )\n\t\t\tVALUES( %d, %d, %d, '%s', '%s', '%s', %d )", intval($fsugg['uid']), intval($fid), intval($fsugg['cid']), dbesc($fsugg['body']), dbesc($hash), dbesc(datetime_convert()), intval(0));
        // TODO - send email notify (which may require a new notification preference)
        return 0;
    }
    $ismail = false;
    $rawmail = $feed->get_feed_tags(NAMESPACE_DFRN, 'mail');
    if (isset($rawmail[0]['child'][NAMESPACE_DFRN])) {
        logger('local_delivery: private message received');
        $ismail = true;
        $base = $rawmail[0]['child'][NAMESPACE_DFRN];
        $msg = array();
        $msg['uid'] = $importer['importer_uid'];
        $msg['from-name'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['name'][0]['data']));
        $msg['from-photo'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['avatar'][0]['data']));
        $msg['from-url'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['uri'][0]['data']));
        $msg['contact-id'] = $importer['id'];
        $msg['title'] = notags(unxmlify($base['subject'][0]['data']));
        $msg['body'] = escape_tags(unxmlify($base['content'][0]['data']));
        $msg['seen'] = 0;
        $msg['replied'] = 0;
        $msg['uri'] = notags(unxmlify($base['id'][0]['data']));
        $msg['parent-uri'] = notags(unxmlify($base['in-reply-to'][0]['data']));
        $msg['created'] = datetime_convert(notags(unxmlify('UTC', 'UTC', $base['sentdate'][0]['data'])));
        dbesc_array($msg);
        $r = dbq("INSERT INTO `mail` (`" . implode("`, `", array_keys($msg)) . "`) VALUES ('" . implode("', '", array_values($msg)) . "')");
        // send email notification if requested.
        require_once 'bbcode.php';
        if ($importer['notify-flags'] & NOTIFY_MAIL) {
            push_lang($importer['language']);
            // name of the automated email sender
            $msg['notificationfromname'] = t('Administrator');
            // noreply address to send from
            $msg['notificationfromemail'] = t('noreply') . '@' . $a->get_hostname();
            // text version
            // process the message body to display properly in text mode
            // 		1) substitute a \n character for the "\" then "n", so it behaves properly (it doesn't come in as a \n character)
            //		2) remove escape slashes
            //		3) decode any bbcode from the message editor
            //		4) decode any encoded html tags
            //		5) remove html tags
            $msg['textversion'] = strip_tags(html_entity_decode(bbcode(stripslashes(str_replace(array("\\r\\n", "\\r", "\\n"), "\n", $msg['body']))), ENT_QUOTES, 'UTF-8'));
            // html version
            // process the message body to display properly in text mode
            // 		1) substitute a <br /> tag for the "\" then "n", so it behaves properly (it doesn't come in as a \n character)
            //		2) remove escape slashes
            //		3) decode any bbcode from the message editor
            //		4) decode any encoded html tags
            $msg['htmlversion'] = html_entity_decode(bbcode(stripslashes(str_replace(array("\\r\\n", "\\r", "\\n\\n", "\\n"), "<br />\n", $msg['body']))));
            // load the template for private message notifications
            $tpl = get_intltext_template('mail_received_html_body_eml.tpl');
            $email_html_body_tpl = replace_macros($tpl, array('$username' => $importer['username'], '$siteName' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$thumb' => $importer['thumb'], '$email' => $importer['email'], '$url' => $importer['url'], '$from' => $msg['from-name'], '$title' => stripslashes($msg['title']), '$htmlversion' => $msg['htmlversion'], '$mimeboundary' => $msg['mimeboundary'], '$hostname' => $a->get_hostname()));
            // load the template for private message notifications
            $tpl = get_intltext_template('mail_received_text_body_eml.tpl');
            $email_text_body_tpl = replace_macros($tpl, array('$username' => $importer['username'], '$siteName' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$thumb' => $importer['thumb'], '$email' => $importer['email'], '$url' => $importer['url'], '$from' => $msg['from-name'], '$title' => stripslashes($msg['title']), '$textversion' => $msg['textversion'], '$mimeboundary' => $msg['mimeboundary'], '$hostname' => $a->get_hostname()));
            // use the EmailNotification library to send the message
            require_once "include/EmailNotification.php";
            EmailNotification::sendTextHtmlEmail($msg['notificationfromname'], $msg['notificationfromemail'], $msg['notificationfromemail'], $importer['email'], t('New mail received at ') . $a->config['sitename'], $email_html_body_tpl, $email_text_body_tpl);
            pop_lang();
        }
        return 0;
        // NOTREACHED
    }
    logger('local_delivery: feed item count = ' . $feed->get_item_quantity());
    // process any deleted entries
    $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry');
    if (is_array($del_entries) && count($del_entries)) {
        foreach ($del_entries as $dentry) {
            $deleted = false;
            if (isset($dentry['attribs']['']['ref'])) {
                $uri = $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) {
                $r = q("SELECT `item`.*, `contact`.`self` FROM `item` left join contact on `item`.`contact-id` = `contact`.`id`\n\t\t\t\t\tWHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d LIMIT 1", dbesc($uri), intval($importer['importer_uid']), intval($importer['id']));
                if (count($r)) {
                    $item = $r[0];
                    if ($item['deleted']) {
                        continue;
                    }
                    logger('local_delivery: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
                    if ($item['verb'] === ACTIVITY_TAG && $item['object-type'] === ACTVITY_OBJ_TAGTERM) {
                        $xo = parse_xml_string($item['object'], false);
                        $xt = parse_xml_string($item['target'], false);
                        if ($xt->type === ACTIVITY_OBJ_NOTE) {
                            $i = q("select * from `item` where uri = '%s' and uid = %d limit 1", dbesc($xt->id), intval($importer['importer_uid']));
                            if (count($i)) {
                                // For tags, the owner cannot remove the tag on the author's copy of the post.
                                $owner_remove = $item['contact-id'] == $i[0]['contact-id'] ? true : false;
                                $author_remove = $item['origin'] && $item['self'] ? true : false;
                                $author_copy = $item['origin'] ? true : false;
                                if ($owner_remove && $author_copy) {
                                    continue;
                                }
                                if ($author_remove || $owner_remove) {
                                    $tags = explode(',', $i[0]['tag']);
                                    $newtags = array();
                                    if (count($tags)) {
                                        foreach ($tags as $tag) {
                                            if (trim($tag) !== trim($xo->body)) {
                                                $newtags[] = trim($tag);
                                            }
                                        }
                                    }
                                    q("update item set tag = '%s' where id = %d limit 1", dbesc(implode(',', $newtags)), intval($i[0]['id']));
                                }
                            }
                        }
                    }
                    if ($item['uri'] == $item['parent-uri']) {
                        $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s'\n\t\t\t\t\t\t\tWHERE `parent-uri` = '%s' AND `uid` = %d", dbesc($when), dbesc(datetime_convert()), dbesc($item['uri']), intval($importer['importer_uid']));
                    } else {
                        $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' \n\t\t\t\t\t\t\tWHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($when), dbesc(datetime_convert()), dbesc($uri), intval($importer['importer_uid']));
                        if ($item['last-child']) {
                            // ensure that last-child is set in case the comment that had it just got wiped.
                            q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ", dbesc(datetime_convert()), dbesc($item['parent-uri']), intval($item['uid']));
                            // who is the last child now?
                            $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `uid` = %d\n\t\t\t\t\t\t\t\tORDER BY `created` DESC LIMIT 1", dbesc($item['parent-uri']), intval($importer['importer_uid']));
                            if (count($r)) {
                                q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($r[0]['id']));
                            }
                        }
                    }
                }
            }
        }
    }
    foreach ($feed->get_items() as $item) {
        $is_reply = false;
        $item_id = $item->get_id();
        $rawthread = $item->get_item_tags(NAMESPACE_THREAD, 'in-reply-to');
        if (isset($rawthread[0]['attribs']['']['ref'])) {
            $is_reply = true;
            $parent_uri = $rawthread[0]['attribs']['']['ref'];
        }
        if ($is_reply) {
            $community = false;
            if ($importer['page-flags'] == PAGE_COMMUNITY) {
                $sql_extra = '';
                $community = true;
                logger('local_delivery: community reply');
            } else {
                $sql_extra = " and contact.self = 1 and item.wall = 1 ";
            }
            // was the top-level post for this reply written by somebody on this site?
            // Specifically, the recipient?
            $r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, \n\t\t\t\t`contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item` \n\t\t\t\tLEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` \n\t\t\t\tWHERE `item`.`uri` = '%s' AND `item`.`parent-uri` = '%s'\n\t\t\t\tAND `item`.`uid` = %d \n\t\t\t\t{$sql_extra}\n\t\t\t\tLIMIT 1", dbesc($parent_uri), dbesc($parent_uri), intval($importer['importer_uid']));
            if ($r && count($r)) {
                logger('local_delivery: received remote comment');
                $is_like = false;
                // remote reply to our post. Import and then notify everybody else.
                $datarray = get_atom_elements($feed, $item);
                // TODO: make this next part work against both delivery threads of a community post
                //				if((! link_compare($datarray['author-link'],$importer['url'])) && (! $community)) {
                //					logger('local_delivery: received relay claiming to be from ' . $importer['url'] . ' however comment author url is ' . $datarray['author-link'] );
                // they won't know what to do so don't report an error. Just quietly die.
                //					return 0;
                //				}
                $datarray['type'] = 'remote-comment';
                $datarray['wall'] = 1;
                $datarray['parent-uri'] = $parent_uri;
                $datarray['uid'] = $importer['importer_uid'];
                $datarray['owner-name'] = $r[0]['name'];
                $datarray['owner-link'] = $r[0]['url'];
                $datarray['owner-avatar'] = $r[0]['thumb'];
                $datarray['contact-id'] = $importer['id'];
                if ($datarray['verb'] === ACTIVITY_LIKE || $datarray['verb'] === ACTIVITY_DISLIKE) {
                    $is_like = true;
                    $datarray['type'] = 'activity';
                    $datarray['gravity'] = GRAVITY_LIKE;
                    $datarray['last-child'] = 0;
                }
                if ($datarray['verb'] === ACTIVITY_TAG && $datarray['object-type'] === ACTIVITY_OBJ_TAGTERM) {
                    $xo = parse_xml_string($datarray['object'], false);
                    $xt = parse_xml_string($datarray['target'], false);
                    if ($xt->type == ACTIVITY_OBJ_NOTE && $xt->id == $r[0]['uri']) {
                        // extract tag, if not duplicate, and this user allows tags, add to parent item
                        if ($xo->id && $xo->content) {
                            $newtag = '#[url=' . $xo->id . ']' . $xo->content . '[/url]';
                            if (!stristr($r[0]['tag'], $newtag)) {
                                $i = q("SELECT `blocktags` FROM `user` where `uid` = %d LIMIT 1", intval($importer['importer_uid']));
                                if (count($i) && !$i[0]['blocktags']) {
                                    q("UPDATE item SET tag = '%s' WHERE id = %d LIMIT 1", dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . $newtag), intval($r[0]['id']));
                                }
                            }
                        }
                    }
                }
                // 				if($community) {
                //					$newtag = '@[url=' . $a->get_baseurl() . '/profile/' . $importer['nickname'] . ']' . $importer['username'] . '[/url]';
                //					if(! stristr($datarray['tag'],$newtag)) {
                //						if(strlen($datarray['tag']))
                //							$datarray['tag'] .= ',';
                //						$datarray['tag'] .= $newtag;
                //					}
                //				}
                $posted_id = item_store($datarray);
                $parent = 0;
                if ($posted_id) {
                    $r = q("SELECT `parent` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($posted_id), intval($importer['importer_uid']));
                    if (count($r)) {
                        $parent = $r[0]['parent'];
                    }
                    if (!$is_like) {
                        $r1 = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `uid` = %d AND `parent` = %d", dbesc(datetime_convert()), intval($importer['importer_uid']), intval($r[0]['parent']));
                        $r2 = q("UPDATE `item` SET `last-child` = 1, `changed` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1", dbesc(datetime_convert()), intval($importer['importer_uid']), intval($posted_id));
                    }
                    if ($posted_id && $parent) {
                        proc_run('php', "include/notifier.php", "comment-import", "{$posted_id}");
                        if (!$is_like && $importer['notify-flags'] & NOTIFY_COMMENT && !$importer['self']) {
                            push_lang($importer['language']);
                            require_once 'bbcode.php';
                            $from = stripslashes($datarray['author-name']);
                            // name of the automated email sender
                            $msg['notificationfromname'] = stripslashes($datarray['author-name']);
                            // noreply address to send from
                            $msg['notificationfromemail'] = t('noreply') . '@' . $a->get_hostname();
                            // text version
                            // process the message body to display properly in text mode
                            $msg['textversion'] = html_entity_decode(strip_tags(bbcode(stripslashes($datarray['body']))), ENT_QUOTES, 'UTF-8');
                            // html version
                            // process the message body to display properly in text mode
                            $msg['htmlversion'] = html_entity_decode(bbcode(stripslashes(str_replace(array("\\r\\n", "\\r", "\\n\\n", "\\n"), "<br />\n", $datarray['body']))));
                            $imgtouse = link_compare($datarray['author-link'], $importer['url']) ? $importer['thumb'] : $datarray['author-avatar'];
                            // load the template for private message notifications
                            $tpl = get_intltext_template('cmnt_received_html_body_eml.tpl');
                            $email_html_body_tpl = replace_macros($tpl, array('$username' => $importer['username'], '$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$thumb' => $imgtouse, '$email' => $importer['email'], '$url' => $datarray['author-link'], '$from' => $from, '$body' => $msg['htmlversion'], '$display' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id));
                            // load the template for private message notifications
                            $tpl = get_intltext_template('cmnt_received_text_body_eml.tpl');
                            $email_text_body_tpl = replace_macros($tpl, array('$username' => $importer['username'], '$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$thumb' => $imgtouse, '$email' => $importer['email'], '$url' => $datarray['author-link'], '$from' => $from, '$body' => $msg['textversion'], '$display' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id));
                            // use the EmailNotification library to send the message
                            require_once "include/EmailNotification.php";
                            EmailNotification::sendTextHtmlEmail($msg['notificationfromname'], t("Administrator") . '@' . $a->get_hostname(), t("noreply") . '@' . $a->get_hostname(), $importer['email'], sprintf(t('%s commented on an item at %s'), $from, $a->config['sitename']), $email_html_body_tpl, $email_text_body_tpl);
                            pop_lang();
                        }
                    }
                    return 0;
                    // NOTREACHED
                }
            } else {
                // regular comment that is part of this total conversation. Have we seen it? If not, import it.
                $item_id = $item->get_id();
                $datarray = get_atom_elements($feed, $item);
                $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid']));
                // Update content if 'updated' changes
                if (count($r)) {
                    if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) {
                        $r = q("UPDATE `item` SET `body` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['body']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['importer_uid']));
                    }
                    // update last-child if it changes
                    $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
                    if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
                        $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc(datetime_convert()), dbesc($parent_uri), intval($importer['importer_uid']));
                        $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s'  WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['importer_uid']));
                    }
                    continue;
                }
                $datarray['parent-uri'] = $parent_uri;
                $datarray['uid'] = $importer['importer_uid'];
                $datarray['contact-id'] = $importer['id'];
                if ($datarray['verb'] == ACTIVITY_LIKE || $datarray['verb'] == ACTIVITY_DISLIKE) {
                    $datarray['type'] = 'activity';
                    $datarray['gravity'] = GRAVITY_LIKE;
                }
                if ($datarray['verb'] === ACTIVITY_TAG && $datarray['object-type'] === ACTIVITY_OBJ_TAGTERM) {
                    $xo = parse_xml_string($datarray['object'], false);
                    $xt = parse_xml_string($datarray['target'], false);
                    if ($xt->type == ACTIVITY_OBJ_NOTE) {
                        $r = q("select * from item where `uri` = '%s' AND `uid` = %d limit 1", dbesc($xt->id), intval($importer['importer_uid']));
                        if (!count($r)) {
                            continue;
                        }
                        // extract tag, if not duplicate, add to parent item
                        if ($xo->content) {
                            if (!stristr($r[0]['tag'], trim($xo->content))) {
                                q("UPDATE item SET tag = '%s' WHERE id = %d LIMIT 1", dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . '#[url=' . $xo->id . ']' . $xo->content . '[/url]'), intval($r[0]['id']));
                            }
                        }
                    }
                }
                $posted_id = item_store($datarray);
                // find out if our user is involved in this conversation and wants to be notified.
                if ($datarray['type'] != 'activity' && $importer['notify-flags'] & NOTIFY_COMMENT) {
                    $myconv = q("SELECT `author-link`, `author-avatar` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 ", dbesc($parent_uri), intval($importer['importer_uid']));
                    if (count($myconv)) {
                        $importer_url = $a->get_baseurl() . '/profile/' . $importer['nickname'];
                        foreach ($myconv as $conv) {
                            if (!link_compare($conv['author-link'], $importer_url)) {
                                continue;
                            }
                            push_lang($importer['language']);
                            require_once 'bbcode.php';
                            $from = stripslashes($datarray['author-name']);
                            // name of the automated email sender
                            $msg['notificationfromname'] = stripslashes($datarray['author-name']);
                            // noreply address to send from
                            $msg['notificationfromemail'] = t('noreply') . '@' . $a->get_hostname();
                            // text version
                            // process the message body to display properly in text mode
                            $msg['textversion'] = html_entity_decode(strip_tags(bbcode(stripslashes($datarray['body']))), ENT_QUOTES, 'UTF-8');
                            // html version
                            // process the message body to display properly in text mode
                            $msg['htmlversion'] = html_entity_decode(bbcode(stripslashes(str_replace(array("\\r\\n", "\\r", "\\n\\n", "\\n"), "<br />\n", $datarray['body']))));
                            $imgtouse = link_compare($datarray['author-link'], $importer['url']) ? $importer['thumb'] : $datarray['author-avatar'];
                            // load the template for private message notifications
                            $tpl = get_intltext_template('cmnt_received_html_body_eml.tpl');
                            $email_html_body_tpl = replace_macros($tpl, array('$username' => $importer['username'], '$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$thumb' => $imgtouse, '$url' => $datarray['author-link'], '$from' => $from, '$body' => $msg['htmlversion'], '$display' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id));
                            // load the template for private message notifications
                            $tpl = get_intltext_template('cmnt_received_text_body_eml.tpl');
                            $email_text_body_tpl = replace_macros($tpl, array('$username' => $importer['username'], '$sitename' => $a->config['sitename'], '$siteurl' => $a->get_baseurl(), '$thumb' => $imgtouse, '$url' => $datarray['author-link'], '$from' => $from, '$body' => $msg['textversion'], '$display' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id));
                            // use the EmailNotification library to send the message
                            require_once "include/EmailNotification.php";
                            EmailNotification::sendTextHtmlEmail($msg['notificationfromname'], t("Administrator@") . $a->get_hostname(), t("noreply") . '@' . $a->get_hostname(), $importer['email'], sprintf(t('%s commented on an item at %s'), $from, $a->config['sitename']), $email_html_body_tpl, $email_text_body_tpl);
                            pop_lang();
                            break;
                        }
                    }
                }
                continue;
            }
        } else {
            // Head post of a conversation. Have we seen it? If not, import it.
            $item_id = $item->get_id();
            $datarray = get_atom_elements($feed, $item);
            if (x($datarray, 'object-type') && $datarray['object-type'] === ACTIVITY_OBJ_EVENT) {
                $ev = bbtoevent($datarray['body']);
                if (x($ev, 'desc') && x($ev, 'start')) {
                    $ev['cid'] = $importer['id'];
                    $ev['uid'] = $importer['uid'];
                    $ev['uri'] = $item_id;
                    $ev['edited'] = $datarray['edited'];
                    $ev['private'] = $datarray['private'];
                    $r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['uid']));
                    if (count($r)) {
                        $ev['id'] = $r[0]['id'];
                    }
                    $xyz = event_store($ev);
                    continue;
                }
            }
            $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($item_id), intval($importer['importer_uid']));
            // Update content if 'updated' changes
            if (count($r)) {
                if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) {
                    $r = q("UPDATE `item` SET `body` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", dbesc($datarray['body']), dbesc(datetime_convert('UTC', 'UTC', $datarray['edited'])), dbesc($item_id), intval($importer['importer_uid']));
                }
                // update last-child if it changes
                $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow');
                if ($allow && $allow[0]['data'] != $r[0]['last-child']) {
                    $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", intval($allow[0]['data']), dbesc(datetime_convert()), dbesc($item_id), intval($importer['importer_uid']));
                }
                continue;
            }
            // This is my contact on another system, but it's really me.
            // Turn this into a wall post.
            if ($contact['remote_self']) {
                $datarray['wall'] = 1;
            }
            $datarray['parent-uri'] = $item_id;
            $datarray['uid'] = $importer['importer_uid'];
            $datarray['contact-id'] = $importer['id'];
            $r = item_store($datarray);
            continue;
        }
    }
    return 0;
    // NOTREACHED
}
コード例 #10
0
ファイル: Scrape.php プロジェクト: vinzv/friendica
function probe_url($url, $mode = PROBE_NORMAL, $level = 1)
{
    require_once 'include/email.php';
    $result = array();
    if (!$url) {
        return $result;
    }
    $result = Cache::get("probe_url:" . $mode . ":" . $url);
    if (!is_null($result)) {
        $result = unserialize($result);
        return $result;
    }
    $network = null;
    $diaspora = false;
    $diaspora_base = '';
    $diaspora_guid = '';
    $diaspora_key = '';
    $has_lrdd = false;
    $email_conversant = false;
    $connectornetworks = false;
    $appnet = false;
    if (strpos($url, 'twitter.com')) {
        $connectornetworks = true;
        $network = NETWORK_TWITTER;
    }
    // Twitter is deactivated since twitter closed its old API
    //$twitter = ((strpos($url,'twitter.com') !== false) ? true : false);
    $lastfm = strpos($url, 'last.fm/user') !== false ? true : false;
    $at_addr = strpos($url, '@') !== false ? true : false;
    if (!$appnet && !$lastfm && !$connectornetworks) {
        if (strpos($url, 'mailto:') !== false && $at_addr) {
            $url = str_replace('mailto:', '', $url);
            $links = array();
        } else {
            $links = lrdd($url);
        }
        if (count($links)) {
            $has_lrdd = true;
            logger('probe_url: found lrdd links: ' . print_r($links, true), LOGGER_DATA);
            foreach ($links as $link) {
                if ($link['@attributes']['rel'] === NAMESPACE_ZOT) {
                    $zot = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === NAMESPACE_DFRN) {
                    $dfrn = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'salmon') {
                    $notify = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === NAMESPACE_FEED) {
                    $poll = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard') {
                    $hcard = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') {
                    $profile = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0') {
                    $poco = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
                    $diaspora_base = unamp($link['@attributes']['href']);
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
                    $diaspora_guid = unamp($link['@attributes']['href']);
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'diaspora-public-key') {
                    $diaspora_key = base64_decode(unamp($link['@attributes']['href']));
                    if (strstr($diaspora_key, 'RSA ')) {
                        $pubkey = rsatopem($diaspora_key);
                    } else {
                        $pubkey = $diaspora_key;
                    }
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'http://ostatus.org/schema/1.0/subscribe' and $mode == PROBE_NORMAL) {
                    $diaspora = false;
                }
            }
            // Status.Net can have more than one profile URL. We need to match the profile URL
            // to a contact on incoming messages to prevent spam, and we won't know which one
            // to match. So in case of two, one of them is stored as an alias. Only store URL's
            // and not webfinger user@host aliases. If they've got more than two non-email style
            // aliases, let's hope we're lucky and get one that matches the feed author-uri because
            // otherwise we're screwed.
            foreach ($links as $link) {
                if ($link['@attributes']['rel'] === 'alias') {
                    if (strpos($link['@attributes']['href'], '@') === false) {
                        if (isset($profile)) {
                            if ($link['@attributes']['href'] !== $profile) {
                                $alias = unamp($link['@attributes']['href']);
                            }
                        } else {
                            $profile = unamp($link['@attributes']['href']);
                        }
                    }
                }
            }
            // If the profile is different from the url then the url is abviously an alias
            if ($alias == "" and $profile != "" and !$at_addr and normalise_link($profile) != normalise_link($url)) {
                $alias = $url;
            }
        } elseif ($mode == PROBE_NORMAL) {
            // Check email
            $orig_url = $url;
            if (strpos($orig_url, '@') && validate_email($orig_url)) {
                $x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1", intval(local_user()));
                $r = q("SELECT * FROM `mailacct` WHERE `uid` = %d AND `server` != '' LIMIT 1", intval(local_user()));
                if (count($x) && count($r)) {
                    $mailbox = construct_mailbox_name($r[0]);
                    $password = '';
                    openssl_private_decrypt(hex2bin($r[0]['pass']), $password, $x[0]['prvkey']);
                    $mbox = email_connect($mailbox, $r[0]['user'], $password);
                    if (!$mbox) {
                        logger('probe_url: email_connect failed.');
                    }
                    unset($password);
                }
                if ($mbox) {
                    $msgs = email_poll($mbox, $orig_url);
                    logger('probe_url: searching ' . $orig_url . ', ' . count($msgs) . ' messages found.', LOGGER_DEBUG);
                    if (count($msgs)) {
                        $addr = $orig_url;
                        $network = NETWORK_MAIL;
                        $name = substr($url, 0, strpos($url, '@'));
                        $phost = substr($url, strpos($url, '@') + 1);
                        $profile = 'http://' . $phost;
                        // fix nick character range
                        $vcard = array('fn' => $name, 'nick' => $name, 'photo' => avatar_img($url));
                        $notify = 'smtp ' . random_string();
                        $poll = 'email ' . random_string();
                        $priority = 0;
                        $x = email_msg_meta($mbox, $msgs[0]);
                        if (stristr($x[0]->from, $orig_url)) {
                            $adr = imap_rfc822_parse_adrlist($x[0]->from, '');
                        } elseif (stristr($x[0]->to, $orig_url)) {
                            $adr = imap_rfc822_parse_adrlist($x[0]->to, '');
                        }
                        if (isset($adr)) {
                            foreach ($adr as $feadr) {
                                if (strcasecmp($feadr->mailbox, $name) == 0 && strcasecmp($feadr->host, $phost) == 0 && strlen($feadr->personal)) {
                                    $personal = imap_mime_header_decode($feadr->personal);
                                    $vcard['fn'] = "";
                                    foreach ($personal as $perspart) {
                                        if ($perspart->charset != "default") {
                                            $vcard['fn'] .= iconv($perspart->charset, 'UTF-8//IGNORE', $perspart->text);
                                        } else {
                                            $vcard['fn'] .= $perspart->text;
                                        }
                                    }
                                    $vcard['fn'] = notags($vcard['fn']);
                                }
                            }
                        }
                    }
                    imap_close($mbox);
                }
            }
        }
    }
    if ($mode == PROBE_NORMAL) {
        if (strlen($zot)) {
            $s = fetch_url($zot);
            if ($s) {
                $j = json_decode($s);
                if ($j) {
                    $network = NETWORK_ZOT;
                    $vcard = array('fn' => $j->fullname, 'nick' => $j->nickname, 'photo' => $j->photo);
                    $profile = $j->url;
                    $notify = $j->post;
                    $pubkey = $j->pubkey;
                    $poll = 'N/A';
                }
            }
        }
        if (strlen($dfrn)) {
            $ret = scrape_dfrn($hcard ? $hcard : $dfrn, true);
            if (is_array($ret) && x($ret, 'dfrn-request')) {
                $network = NETWORK_DFRN;
                $request = $ret['dfrn-request'];
                $confirm = $ret['dfrn-confirm'];
                $notify = $ret['dfrn-notify'];
                $poll = $ret['dfrn-poll'];
                $vcard = array();
                $vcard['fn'] = $ret['fn'];
                $vcard['nick'] = $ret['nick'];
                $vcard['photo'] = $ret['photo'];
            }
        }
    }
    if ($diaspora && $diaspora_base && $diaspora_guid) {
        if ($mode == PROBE_DIASPORA || !$notify) {
            $notify = $diaspora_base . 'receive/users/' . $diaspora_guid;
            $batch = $diaspora_base . 'receive/public';
        }
        if (strpos($url, '@')) {
            $addr = str_replace('acct:', '', $url);
        }
    }
    if ($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) {
        if ($diaspora) {
            $network = NETWORK_DIASPORA;
        } elseif ($has_lrdd and $notify) {
            $network = NETWORK_OSTATUS;
        }
        if (strpos($url, '@')) {
            $addr = str_replace('acct:', '', $url);
        }
        $priority = 0;
        if ($hcard && !$vcard) {
            $vcard = scrape_vcard($hcard);
            // Google doesn't use absolute url in profile photos
            if (x($vcard, 'photo') && substr($vcard['photo'], 0, 1) == '/') {
                $h = @parse_url($hcard);
                if ($h) {
                    $vcard['photo'] = $h['scheme'] . '://' . $h['host'] . $vcard['photo'];
                }
            }
            logger('probe_url: scrape_vcard: ' . print_r($vcard, true), LOGGER_DATA);
        }
        if ($diaspora && $addr) {
            // Diaspora returns the name as the nick. As the nick will never be updated,
            // let's use the Diaspora nickname (the first part of the handle) as the nick instead
            $addr_parts = explode('@', $addr);
            $vcard['nick'] = $addr_parts[0];
        }
        /* if($twitter) {
        			logger('twitter: setup');
        			$tid = basename($url);
        			$tapi = 'https://api.twitter.com/1/statuses/user_timeline.rss';
        			if(intval($tid))
        				$poll = $tapi . '?user_id=' . $tid;
        			else
        				$poll = $tapi . '?screen_name=' . $tid;
        			$profile = 'http://twitter.com/#!/' . $tid;
        			//$vcard['photo'] = 'https://api.twitter.com/1/users/profile_image/' . $tid;
        			$vcard['photo'] = 'https://api.twitter.com/1/users/profile_image?screen_name=' . $tid . '&size=bigger';
        			$vcard['nick'] = $tid;
        			$vcard['fn'] = $tid;
        		} */
        if ($lastfm) {
            $profile = $url;
            $poll = str_replace(array('www.', 'last.fm/'), array('', 'ws.audioscrobbler.com/1.0/'), $url) . '/recenttracks.rss';
            $vcard['nick'] = basename($url);
            $vcard['fn'] = $vcard['nick'] . t(' on Last.fm');
            $network = NETWORK_FEED;
        }
        if (!x($vcard, 'fn')) {
            if (x($vcard, 'nick')) {
                $vcard['fn'] = $vcard['nick'];
            }
        }
        $check_feed = false;
        if (stristr($url, 'tumblr.com') && !stristr($url, '/rss')) {
            $poll = $url . '/rss';
            $check_feed = true;
            // Will leave it to others to figure out how to grab the avatar, which is on the $url page in the open graph meta links
        }
        if ($appnet || !$poll) {
            $check_feed = true;
        }
        if (!isset($vcard) || !x($vcard, 'fn') || !$profile) {
            $check_feed = true;
        }
        if ($at_addr && !count($links)) {
            $check_feed = false;
        }
        if ($connectornetworks) {
            $check_feed = false;
        }
        if ($check_feed) {
            $feedret = scrape_feed($poll ? $poll : $url);
            logger('probe_url: scrape_feed ' . ($poll ? $poll : $url) . ' returns: ' . print_r($feedret, true), LOGGER_DATA);
            if (count($feedret) && ($feedret['feed_atom'] || $feedret['feed_rss'])) {
                $poll = x($feedret, 'feed_atom') ? unamp($feedret['feed_atom']) : unamp($feedret['feed_rss']);
                if (!x($vcard)) {
                    $vcard = array();
                }
            }
            if (x($feedret, 'photo') && !x($vcard, 'photo')) {
                $vcard['photo'] = $feedret['photo'];
            }
            require_once 'library/simplepie/simplepie.inc';
            $feed = new SimplePie();
            $xml = fetch_url($poll);
            logger('probe_url: fetch feed: ' . $poll . ' returns: ' . $xml, LOGGER_DATA);
            $a = get_app();
            logger('probe_url: scrape_feed: headers: ' . $a->get_curl_headers(), 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());
                $network = NETWORK_PHANTOM;
            }
            if (!x($vcard, 'photo')) {
                $vcard['photo'] = $feed->get_image_url();
            }
            $author = $feed->get_author();
            if ($author) {
                $vcard['fn'] = unxmlify(trim($author->get_name()));
                if (!$vcard['fn']) {
                    $vcard['fn'] = trim(unxmlify($author->get_email()));
                }
                if (strpos($vcard['fn'], '@') !== false) {
                    $vcard['fn'] = substr($vcard['fn'], 0, strpos($vcard['fn'], '@'));
                }
                $email = unxmlify($author->get_email());
                if (!$profile && $author->get_link()) {
                    $profile = trim(unxmlify($author->get_link()));
                }
                if (!$vcard['photo']) {
                    $rawtags = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
                    if ($rawtags) {
                        $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
                        if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo') {
                            $vcard['photo'] = $elems['link'][0]['attribs']['']['href'];
                        }
                    }
                }
                // Fetch fullname via poco:displayName
                $pocotags = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
                if ($pocotags) {
                    $elems = $pocotags[0]['child']['http://portablecontacts.net/spec/1.0'];
                    if (isset($elems["displayName"])) {
                        $vcard['fn'] = $elems["displayName"][0]["data"];
                    }
                    if (isset($elems["preferredUsername"])) {
                        $vcard['nick'] = $elems["preferredUsername"][0]["data"];
                    }
                }
            } else {
                $item = $feed->get_item(0);
                if ($item) {
                    $author = $item->get_author();
                    if ($author) {
                        $vcard['fn'] = trim(unxmlify($author->get_name()));
                        if (!$vcard['fn']) {
                            $vcard['fn'] = trim(unxmlify($author->get_email()));
                        }
                        if (strpos($vcard['fn'], '@') !== false) {
                            $vcard['fn'] = substr($vcard['fn'], 0, strpos($vcard['fn'], '@'));
                        }
                        $email = unxmlify($author->get_email());
                        if (!$profile && $author->get_link()) {
                            $profile = trim(unxmlify($author->get_link()));
                        }
                    }
                    if (!$vcard['photo']) {
                        $rawmedia = $item->get_item_tags('http://search.yahoo.com/mrss/', 'thumbnail');
                        if ($rawmedia && $rawmedia[0]['attribs']['']['url']) {
                            $vcard['photo'] = unxmlify($rawmedia[0]['attribs']['']['url']);
                        }
                    }
                    if (!$vcard['photo']) {
                        $rawtags = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
                        if ($rawtags) {
                            $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
                            if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo') {
                                $vcard['photo'] = $elems['link'][0]['attribs']['']['href'];
                            }
                        }
                    }
                }
            }
            // Workaround for misconfigured Friendica servers
            if ($network == "" and strstr($url, "/profile/")) {
                $noscrape = str_replace("/profile/", "/noscrape/", $url);
                $noscrapejson = fetch_url($noscrape);
                if ($noscrapejson) {
                    $network = NETWORK_DFRN;
                    $poco = str_replace("/profile/", "/poco/", $url);
                    $noscrapedata = json_decode($noscrapejson, true);
                    if (isset($noscrapedata["addr"])) {
                        $addr = $noscrapedata["addr"];
                    }
                    if (isset($noscrapedata["fn"])) {
                        $vcard["fn"] = $noscrapedata["fn"];
                    }
                    if (isset($noscrapedata["key"])) {
                        $pubkey = $noscrapedata["key"];
                    }
                    if (isset($noscrapedata["photo"])) {
                        $vcard["photo"] = $noscrapedata["photo"];
                    }
                    if (isset($noscrapedata["dfrn-request"])) {
                        $request = $noscrapedata["dfrn-request"];
                    }
                    if (isset($noscrapedata["dfrn-confirm"])) {
                        $confirm = $noscrapedata["dfrn-confirm"];
                    }
                    if (isset($noscrapedata["dfrn-notify"])) {
                        $notify = $noscrapedata["dfrn-notify"];
                    }
                    if (isset($noscrapedata["dfrn-poll"])) {
                        $poll = $noscrapedata["dfrn-poll"];
                    }
                }
            }
            if (!$vcard['photo'] && strlen($email)) {
                $vcard['photo'] = avatar_img($email);
            }
            if ($poll === $profile) {
                $lnk = $feed->get_permalink();
            }
            if (isset($lnk) && strlen($lnk)) {
                $profile = $lnk;
            }
            if (!$network) {
                $network = NETWORK_FEED;
                // If it is a feed, don't take the author name as feed name
                unset($vcard['fn']);
            }
            if (!x($vcard, 'fn')) {
                $vcard['fn'] = notags($feed->get_title());
            }
            if (!x($vcard, 'fn')) {
                $vcard['fn'] = notags($feed->get_description());
            }
            if (strpos($vcard['fn'], 'Twitter / ') !== false) {
                $vcard['fn'] = substr($vcard['fn'], strpos($vcard['fn'], '/') + 1);
                $vcard['fn'] = trim($vcard['fn']);
            }
            if (!x($vcard, 'nick')) {
                $vcard['nick'] = strtolower(notags(unxmlify($vcard['fn'])));
                if (strpos($vcard['nick'], ' ')) {
                    $vcard['nick'] = trim(substr($vcard['nick'], 0, strpos($vcard['nick'], ' ')));
                }
            }
            if (!$priority) {
                $priority = 2;
            }
        }
    }
    if (!x($vcard, 'photo')) {
        $a = get_app();
        $vcard['photo'] = $a->get_baseurl() . '/images/person-175.jpg';
    }
    if (!$profile) {
        $profile = $url;
    }
    // No human could be associated with this link, use the URL as the contact name
    if ($network === NETWORK_FEED && $poll && !x($vcard, 'fn')) {
        $vcard['fn'] = $url;
    }
    if ($notify != "" and $poll != "") {
        $baseurl = matching(normalise_link($notify), normalise_link($poll));
        $baseurl2 = matching($baseurl, normalise_link($profile));
        if ($baseurl2 != "") {
            $baseurl = $baseurl2;
        }
    }
    if ($baseurl == "" and $notify != "") {
        $baseurl = matching(normalise_link($profile), normalise_link($notify));
    }
    if ($baseurl == "" and $poll != "") {
        $baseurl = matching(normalise_link($profile), normalise_link($poll));
    }
    $baseurl = rtrim($baseurl, "/");
    if (strpos($url, '@') and $addr == "" and $network == NETWORK_DFRN) {
        $addr = str_replace('acct:', '', $url);
    }
    $vcard['fn'] = notags($vcard['fn']);
    $vcard['nick'] = str_replace(' ', '', notags($vcard['nick']));
    $result['name'] = $vcard['fn'];
    $result['nick'] = $vcard['nick'];
    $result['url'] = $profile;
    $result['addr'] = $addr;
    $result['batch'] = $batch;
    $result['notify'] = $notify;
    $result['poll'] = $poll;
    $result['request'] = $request;
    $result['confirm'] = $confirm;
    $result['poco'] = $poco;
    $result['photo'] = $vcard['photo'];
    $result['priority'] = $priority;
    $result['network'] = $network;
    $result['alias'] = $alias;
    $result['pubkey'] = $pubkey;
    $result['baseurl'] = $baseurl;
    logger('probe_url: ' . print_r($result, true), LOGGER_DEBUG);
    if ($level == 1) {
        // Trying if it maybe a diaspora account
        if ($result['network'] == NETWORK_FEED or $result['addr'] == "") {
            require_once 'include/bbcode.php';
            $address = GetProfileUsername($url, "", true);
            $result2 = probe_url($address, $mode, ++$level);
            if ($result2['network'] != "") {
                $result = $result2;
            }
        }
        // Maybe it's some non standard GNU Social installation (Single user, subfolder or no uri rewrite)
        if ($result['network'] == NETWORK_FEED and $result['baseurl'] != "" and $result['nick'] != "") {
            $addr = $result['nick'] . '@' . str_replace("http://", "", $result['baseurl']);
            $result2 = probe_url($addr, $mode, ++$level);
            if ($result2['network'] != "" and $result2['network'] != NETWORK_FEED) {
                $result = $result2;
            }
        }
    }
    // Only store into the cache if the value seems to be valid
    if ($result['network'] != NETWORK_PHANTOM) {
        Cache::set("probe_url:" . $mode . ":" . $url, serialize($result), CACHE_DAY);
    }
    return $result;
}
コード例 #11
0
 function get_feed_tags($namespace, $tag)
 {
     $tags = parent::get_feed_tags($namespace, $tag);
     // Allow filters to filter SimplePie handling
     return apply_filters('feedwordpie_get_feed_tags', $tags, $namespace, $tag, $this);
 }
コード例 #12
0
ファイル: arxiv.php プロジェクト: kojino/scientists
# Construct the query with the search parameters
$query = "search_query=" . $search_query . "&start=" . $start . "&max_results=" . $max_results;
# SimplePie will automatically sort the entries by date
# unless we explicitly turn this off
$feed = new SimplePie($base_url . $query);
$feed->enable_order_by_date(false);
$feed->init();
$feed->handle_content_type();
# Use these namespaces to retrieve tags
$atom_ns = 'http://www.w3.org/2005/Atom';
$opensearch_ns = 'http://a9.com/-/spec/opensearch/1.1/';
$arxiv_ns = 'http://arxiv.org/schemas/atom';
# print out feed information
print "Feed information" . EOL;
print "Feed title: " . $feed->get_title() . EOL;
$last_updated = $feed->get_feed_tags($atom_ns, 'updated');
print "Last Updated: " . $last_updated[0]['data'] . EOL . EOL;
# opensearch metadata such as totalResults, startIndex,
# and itemsPerPage live in the opensearch namespase
print "<b>Opensearch metadata such as totalResults, startIndex, and itemsPerPage live in the opensearch namespase</b>" . EOL;
$totalResults = $feed->get_feed_tags($opensearch_ns, 'totalResults');
print "totalResults for this query: " . $totalResults[0]['data'] . EOL;
// $startIndex = $feed->get_feed_tags($opensearch_ns,'startIndex');
// print("startIndex for these results: ".$startIndex[0]['data'].EOL);
// $itemsPerPage = $feed->get_feed_tags($opensearch_ns,'itemsPerPage');
// print("itemsPerPage for these results: ".$itemsPerPage[0]['data'].EOL.EOL);
# Run through each entry, and print out information
# some entry metadata lives in the arXiv namespace
// print("<b>Run through each entry, and print out information some entry metadata lives in the arXiv namespace</b>".EOL);
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow(0, 1, 'id')->setCellValueByColumnAndRow(1, 1, 'title')->setCellValueByColumnAndRow(2, 1, 'published')->setCellValueByColumnAndRow(3, 1, 'author1')->setCellValueByColumnAndRow(4, 1, 'affil1')->setCellValueByColumnAndRow(5, 1, 'author2')->setCellValueByColumnAndRow(6, 1, 'affil2')->setCellValueByColumnAndRow(7, 1, 'author3')->setCellValueByColumnAndRow(8, 1, 'affil3')->setCellValueByColumnAndRow(9, 1, 'author4')->setCellValueByColumnAndRow(10, 1, 'affil4');
$i = 2;
コード例 #13
0
ファイル: poller.php プロジェクト: rabuzarus/dir
     continue;
 }
 $postvars['dfrn_id'] = $contact['dfrn-id'];
 $challenge = hex2bin($res->challenge);
 openssl_public_decrypt($challenge, $postvars['challenge'], $contact['pubkey']);
 $xml = post_url($contact['poll'], $postvars);
 if (!strlen($xml)) {
     // an empty response may mean there's nothing new - record the fact that we checked
     $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1", dbesc(datetime_convert()), intval($contact['id']));
     continue;
 }
 $feed = new SimplePie();
 $feed->set_raw_data($xml);
 $feed->enable_order_by_date(false);
 $feed->init();
 $photo_rawupdate = $feed->get_feed_tags(NAMESPACE_DFRN, 'icon-updated');
 if ($photo_rawupdate) {
     $photo_timestamp = datetime_convert('UTC', 'UTC', $photo_rawupdate[0]['data']);
     $photo_url = $feed->get_image_url();
     if (strlen($photo_url) && $photo_timestamp > $contact['avatar-date']) {
         require_once "Photo.php";
         $photo_failure = false;
         $r = q("SELECT `resource-id` FROM `photo` WHERE `contact-id` = %d LIMIT 1", intval($contact['id']));
         if (count($r)) {
             $resource_id = $r[0]['resource-id'];
             $img_str = fetch_url($photo_url, true);
             $img = new Photo($img_str);
             if ($img) {
                 q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND contact-id` = %d ", dbesc($resource_id), intval($contact['id']));
                 $img->scaleImageSquare(175);
                 $hash = $resource_id;