set_raw_data() public method

Allows you to use a string of RSS/Atom data instead of a remote feed. If you have a feed available as a string in PHP, you can tell SimplePie to parse that data string instead of a remote feed. Any set feed URL takes precedence.
See also: set_feed_url()
Since: 1.0 Beta 3
public set_raw_data ( string $data )
$data string RSS or Atom data as a string.
Esempio n. 1
0
 /**
  * Provided a URL, will return an array representing the feed item for that
  * URL.  A feed item contains the content, url, simplepie object, and failure
  * status for the URL passed.  Handles caching of content requests.
  *
  * @return array
  * @author Jared Lang
  **/
 protected static function __new_feed($url)
 {
     $timer = Timer::start();
     require_once THEME_DIR . '/third-party/simplepie.php';
     $simplepie = null;
     $failed = False;
     $cache_key = 'feedmanager-' . md5($url);
     $content = get_site_transient($cache_key);
     if ($content === False) {
         $content = @file_get_contents($url);
         if ($content === False) {
             $failed = True;
             $content = null;
             error_log('FeedManager failed to fetch data using url of ' . $url);
         } else {
             set_site_transient($cache_key, $content, self::$cache_length);
         }
     }
     if ($content) {
         $simplepie = new SimplePie();
         $simplepie->set_raw_data($content);
         $simplepie->init();
         $simplepie->handle_content_type();
         if ($simplepie->error) {
             error_log($simplepie->error);
             $simplepie = null;
             $failed = True;
         }
     } else {
         $failed = True;
     }
     $elapsed = round($timer->elapsed() * 1000);
     debug("__new_feed: {$elapsed} milliseconds");
     return array('content' => $content, 'url' => $url, 'simplepie' => $simplepie, 'failed' => $failed);
 }
Esempio n. 2
0
 public static function simplepie($feed_url = NULL)
 {
     if (!$feed_url) {
         return false;
     }
     $data = new SimplePie();
     //*******************************
     // Convert To GeoRSS feed
     // To Disable Uncomment these 3 lines
     //*******************************
     $geocoder = new Geocoder();
     $georss_feed = $geocoder->geocode_feed($feed_url);
     if ($georss_feed == false or empty($georss_feed)) {
         // Our RSS feed pull failed, so let's grab the original RSS feed
         $data->set_feed_url($feed_url);
     } else {
         // Converting our feed to GeoRSS was successful, use that data
         $data->set_raw_data($georss_feed);
     }
     // Uncomment Below to disable geocoding
     //$data->set_feed_url( $feed_url );
     //*******************************
     $data->enable_cache(false);
     $data->enable_order_by_date(true);
     $data->init();
     $data->handle_content_type();
     return $data;
 }
 function rss_to_activity_streams($data)
 {
     //
     $feed = new SimplePie();
     $feed->set_raw_data($data);
     //
     unset($data);
     //
     $feed->set_stupidly_fast(true);
     $feed->init();
     $feed->handle_content_type();
     //
     $id = md5($url);
     $title = 'submit';
     $link = 'http://' . $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
     $activityStream = new ActivityStreamsDoc($id, $title, $link);
     //
     foreach ($feed->get_items() as $item) {
         $author = $item->get_author();
         if (!$author) {
             $author = $feed->get_author();
         }
         //
         $activityStream->entry($item->get_id(), date("r", $item->get_date()), $author ? $author->get_name() : null, $author ? $author->get_link() : null, $item->get_title(), $item->get_permalink(), $item->get_description());
     }
     return $activityStream;
 }
Esempio n. 4
0
 /**
  * Provided a URL, will return an array representing the feed item for that
  * URL.  A feed item contains the content, url, simplepie object, and failure
  * status for the URL passed.  Handles caching of content requests.
  *
  * @return array
  * @author Jared Lang
  * */
 protected static function __new_feed($url)
 {
     require_once ABSPATH . '/wp-includes/class-simplepie.php';
     $simplepie = null;
     $failed = False;
     $cache_key = 'feedmanager-' . md5($url);
     $content = get_site_transient($cache_key);
     if ($content === False) {
         $content = @file_get_contents($url);
         if ($content === False) {
             $failed = True;
             $content = null;
             error_log('FeedManager failed to fetch data using url of ' . $url);
         } else {
             set_site_transient($cache_key, $content, self::$cache_length);
         }
     }
     if ($content) {
         $simplepie = new SimplePie();
         $simplepie->set_raw_data($content);
         $simplepie->init();
         $simplepie->handle_content_type();
         if ($simplepie->error) {
             error_log($simplepie->error);
             $simplepie = null;
             $failed = True;
         }
     } else {
         $failed = True;
     }
     return array('content' => $content, 'url' => $url, 'simplepie' => $simplepie, 'failed' => $failed);
 }
Esempio n. 5
0
 function feed()
 {
     $feed = new SimplePie();
     $feed->set_raw_data($this->data);
     $feed->enable_cache(false);
     $feed->init();
     return $feed;
 }
 public function setUp()
 {
     parent::setUp();
     $rss_sample = file_get_contents(dirname(__FILE__) . '/test-assets/rss');
     $sampleFeed = new SimplePie();
     $sampleFeed->set_raw_data($rss_sample);
     $sampleFeed->init();
     self::$sampleFeed = $sampleFeed;
     $this->testFeedUrl = 'http://www.theguardian.com/world/rss';
 }
 static function parseFeed($url, $omitDB = false)
 {
     global $wgOut;
     //reset array
     self::$data = array('feedTitle' => '', 'images' => array());
     if (!$omitDB) {
         //check DB for this URL - we might have it already (background task will refresh it)
         $data = self::getDataByUrl($url);
     }
     if ($omitDB || is_null($data)) {
         //no data in DB - fetch from feed
         $itemCount = 0;
         $rssContent = Http::get($url);
         $feed = new SimplePie();
         $feed->set_raw_data($rssContent);
         $feed->init();
         self::$data['feedTitle'] = $feed->get_title();
         foreach ($feed->get_items() as $item) {
             $enclosures = $item->get_enclosures();
             $enclosuresFound = false;
             //we have enclosures - use them instead of content of feed (usually there are bigger image while content uses thumbnails)
             if (!is_null($enclosures)) {
                 foreach ($enclosures as $enclosure) {
                     $type = $enclosure->get_type();
                     if (!empty($type) && substr($type, 0, 6) === 'image/') {
                         self::$data['images'][] = array('src' => $enclosure->get_link(), 'caption' => $item->get_title(), 'link' => $item->get_link());
                         $enclosuresFound = true;
                         break;
                         //one image per feed
                     }
                 }
             }
             //if enclosures has not been found or doesn't contain any images - use regular method
             if (!$enclosuresFound) {
                 //look for <img /> tags
                 $description = $item->get_description();
                 preg_match('/<img .*?src=([\'"])(.*?\\.(?:jpg|jpeg|gif|png))\\1/', $description, $matches);
                 if (!empty($matches[2])) {
                     self::$data['images'][] = array('src' => $matches[2], 'caption' => $item->get_title(), 'link' => $item->get_link());
                 }
             }
             if (count(self::$data['images']) >= 20 || ++$itemCount > 50) {
                 break;
                 //take up to 20 images, from up to 50 articles.
             }
         }
         //store data in DB only if valid rss (images found)
         if (count(self::$data['images'])) {
             self::setData($url, self::$data);
         }
     } else {
         self::$data = $data;
     }
     return self::$data;
 }
Esempio n. 8
0
 public function loadStringIntoSimplePieObject($xmldata)
 {
     // Create a new instance of the SimplePie object
     $feed = new SimplePie();
     $feed->enable_cache(false);
     // $feed->set_feed_url('http://simplepie.org/blog/feed/');
     $feed->set_raw_data($xmldata);
     $feed->init();
     $feed->handle_content_type();
     return $feed;
 }
Esempio n. 9
0
 /**
  * Run a test using a sprintf template and data
  *
  * @param string $template 
  */
 protected function checkFromTemplate($template, $data, $expected)
 {
     if (!is_array($data)) {
         $data = array($data);
     }
     $xml = vsprintf($template, $data);
     $feed = new SimplePie();
     $feed->set_raw_data($xml);
     $feed->enable_cache(false);
     $feed->init();
     return $feed;
 }
function powerpress_get_news($feed_url, $limit = 10)
{
    include_once ABSPATH . WPINC . '/feed.php';
    $rss = fetch_feed($feed_url);
    // If feed doesn't work...
    if (is_wp_error($rss)) {
        require_once ABSPATH . WPINC . '/class-feed.php';
        // Try fetching the feed using CURL directly...
        $content = powerpress_remote_fopen($feed_url, false, array(), 3, false, true);
        if (!$content) {
            return false;
        }
        // Load the content in a fetch_feed object...
        $rss = new SimplePie();
        $rss->set_sanitize_class('WP_SimplePie_Sanitize_KSES');
        // We must manually overwrite $feed->sanitize because SimplePie's
        // constructor sets it before we have a chance to set the sanitization class
        $rss->sanitize = new WP_SimplePie_Sanitize_KSES();
        $rss->set_cache_class('WP_Feed_Cache');
        $rss->set_file_class('WP_SimplePie_File');
        $rss->set_raw_data($content);
        $rss->set_cache_duration(apply_filters('wp_feed_cache_transient_lifetime', 12 * HOUR_IN_SECONDS, $feed_url));
        do_action_ref_array('wp_feed_options', array(&$rss, $feed_url));
        $rss->init();
        $rss->set_output_encoding(get_option('blog_charset'));
        $rss->handle_content_type();
        if ($rss->error()) {
            return false;
        }
    }
    $rss_items = $rss->get_items(0, $rss->get_item_quantity($limit));
    // If the feed was erroneously
    if (!$rss_items) {
        $md5 = md5($this->feed);
        delete_transient('feed_' . $md5);
        delete_transient('feed_mod_' . $md5);
        $rss->__destruct();
        unset($rss);
        $rss = fetch_feed($this->feed);
        $rss_items = $rss->get_items(0, $rss->get_item_quantity($num));
        $rss->__destruct();
        unset($rss);
    }
    return $rss_items;
}
Esempio n. 11
0
 /**
  * Fetch feed w/o caching.
  *
  * @param int    $limit Number of entries to fetch.
  * @param string $feed  URI of RSS feed to import.
  *
  * @return array List of feed entries.
  */
 public function fetch_feed($limit, $feed)
 {
     if (!class_exists('SimplePie_File')) {
         include_once ABSPATH . WPINC . DIRECTORY_SEPARATOR . 'SimplePie' . DIRECTORY_SEPARATOR . 'File.php';
     }
     $result = array();
     try {
         $file = new SimplePie_File($feed);
         $feed = new SimplePie();
         $feed->set_raw_data($file->body);
         $feed->init();
         if (!is_wp_error($feed)) {
             $result = $feed->get_items(0, $limit);
         }
     } catch (Exception $exception) {
     }
     // discard
     return $result;
 }
Esempio n. 12
0
 /**
  * Given the content of a page and its URL, returns an array of FeedItem objects (or false on failure)
  * @param $content
  * @param $url
  * @return array|bool
  */
 function parseFeed($content, $url)
 {
     // Check for microformats
     if ($html = @\DOMDocument::loadHTML($content)) {
         try {
             $parser = new \Mf2\Parser($html, $url);
             $parsed_content = $parser->parse();
             return $this->mf2FeedToFeedItems($parsed_content, $url);
         } catch (\Exception $e) {
             return false;
         }
     }
     // Try XML (RSS or Atom)
     $xml_parser = new \SimplePie();
     $xml_parser->set_raw_data($content);
     $xml_parser->init();
     if (!$xml_parser->error()) {
         return $this->xmlFeedToFeedItems($xml_parser->get_items(), $url);
     }
     return false;
 }
Esempio n. 13
0
 public static function simplepie($feed_url = NULL)
 {
     if (!$feed_url) {
         return false;
     }
     $data = new SimplePie();
     //*******************************
     // Convert To GeoRSS feed
     // To Disable Uncomment these 3 lines
     //*******************************
     $geocoder = new Geocoder();
     $georss_feed = $geocoder->geocode_feed($feed_url);
     $data->set_raw_data($georss_feed);
     // Uncomment Below to disable geocoding
     //$data->set_feed_url( $feed_url );
     //*******************************
     $data->enable_cache(false);
     $data->enable_order_by_date(true);
     $data->init();
     $data->handle_content_type();
     return $data;
 }
Esempio n. 14
0
 /**
  * Geonames Feeds GeoCoding (RSS to GEORSS)
  * Due to limitations, this returns only 20 items
  *
  * @param   string location / address
  * @return  string raw georss data
  */
 function geocode_feed($feed_url = NULL)
 {
     $base_url = "http://" . GEOCODER_GEONAMES . "/rssToGeoRSS?";
     // Only requests service if we have an user
     $geocode_username = Settings_Model::get_setting('feed_geolocation_user');
     if ($feed_url && !empty($geocode_username)) {
         // First check to make sure geonames webservice is running
         $geonames_status = @remote::status($base_url);
         if ($geonames_status == "200") {
             // Successful
             $request_url = $base_url . "&feedUrl=" . urlencode($feed_url) . "&username=" . $geocode_username;
         } else {
             // Down perhaps?? Use direct feed
             $request_url = $feed_url;
         }
         $request = new HttpClient($request_url);
         if (!($georss = $request->execute($request_url))) {
             // If the request failed, something may be wrong with the GEOCODER_GEONAMES service
             return false;
         }
         //$georss = utf8_encode($georss);
         // Lez verify this we got a good reply from the geocoder before proceeding
         $data = new SimplePie();
         $data->set_raw_data($georss);
         $data->init();
         $data->handle_content_type();
         // Feed no good - get outta here!
         if ($data->error()) {
             Kohana::log('error', $data->error() . $request_url);
             return false;
         }
         return trim($georss);
     } else {
         return false;
     }
 }
Esempio n. 15
0
/**
* Update the feeds
* 
*/
function UpdateFeeds()
{
    if (!is_dir('./tmp')) {
        mkdir('./tmp', 0777);
    }
    $feedData = array();
    $lock = Lock("Update Feeds", false);
    if (isset($lock)) {
        // load the list of feeds
        require_once './settings/feeds.inc';
        require_once './lib/simplepie.inc';
        // loop through and update each one
        foreach ($feeds as $category => &$feedList) {
            $feedData[$category] = array();
            foreach ($feedList as $feedSource => $feedUrl) {
                $feedUrl = trim($feedUrl);
                if (strlen($feedUrl)) {
                    $feed = new SimplePie();
                    if ($feed) {
                        $rawFeed = trim(http_fetch($feedUrl));
                        $feed->set_raw_data($rawFeed);
                        $feed->enable_cache(false);
                        $feed->init();
                        // try sanitizing the data if we have a problem parsing the feed
                        if (strlen($feed->error())) {
                            FixFeed($rawFeed);
                            $feed->set_raw_data($rawFeed);
                            $feed->enable_cache(false);
                            $feed->init();
                        }
                        foreach ($feed->get_items() as $item) {
                            $dateStr = $item->get_date(DATE_RSS);
                            if ($dateStr && strlen($dateStr)) {
                                $date = strtotime($dateStr);
                                if ($date) {
                                    // only include articles from the last 30 days
                                    $now = time();
                                    $elapsed = 0;
                                    if ($now > $date) {
                                        $elapsed = $now - $date;
                                    }
                                    $days = (int) ($elapsed / 86400);
                                    if ($days <= 30) {
                                        // make sure we don't have another article from the exact same time
                                        while (isset($feedData[$category][$date])) {
                                            $date++;
                                        }
                                        $feedData[$category][$date] = array('source' => $feedSource, 'title' => $item->get_title(), 'link' => urldecode($item->get_permalink()), 'date' => $dateStr);
                                    }
                                }
                            }
                            $item->__destruct();
                        }
                        $feed->__destruct();
                        unset($feed);
                    }
                }
            }
            if (count($feedData[$category])) {
                krsort($feedData[$category]);
            }
        }
        // save out the feed data
        file_put_contents('./tmp/feeds.dat', json_encode($feedData));
        Unlock($lock);
    }
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
 /**
  * Given the XML source of an export, imports each post into Known.
  * @param $xml
  */
 static function importFeedXML($xml)
 {
     // Blogger will be imported as blog posts, so make sure we can import those ...
     if (!($text = site()->plugins()->get('Text'))) {
         return false;
     }
     $xml_parser = new \SimplePie();
     $xml_parser->set_raw_data($xml);
     $xml_parser->init();
     if ($items = $xml_parser->get_items()) {
         foreach ($items as $item) {
             /* @var \SimplePie_Item $item */
             $post_type = 'post';
             if ($categories = $item->get_categories()) {
                 foreach ($categories as $category) {
                     if (!empty($category->term) && !empty($category->scheme)) {
                         if ($category->scheme == 'http://schemas.google.com/g/2005#kind') {
                             foreach (['settings', 'template', 'comment'] as $term) {
                                 if (substr_count($category->term, $term)) {
                                     $post_type = $term;
                                 }
                             }
                         }
                     }
                 }
             }
             if ($post_type == 'post') {
                 $body = $item->get_content();
                 $tags = [];
                 if ($categories = $item->get_categories()) {
                     foreach ($categories as $category) {
                         if (empty($category->scheme) || $category->scheme != 'http://schemas.google.com/g/2005#kind') {
                             $tags[] = '#' . preg_replace('/\\W+/', '', $category->term);
                         }
                     }
                 }
                 if (!empty($tags)) {
                     $body .= '<p>' . implode(' ', $tags) . '</p>';
                 }
                 self::importImagesFromBodyHTML($body, 'blogspot.com');
                 $object = new \IdnoPlugins\Text\Entry();
                 $object->setTitle(html_entity_decode($item->get_title()));
                 $object->created = strtotime($item->get_date("c"));
                 $object->body = $body;
                 $object->save(true);
             }
         }
     }
 }
Esempio n. 18
0
function salmon_post(&$a)
{
    $xml = file_get_contents('php://input');
    logger('mod-salmon: new salmon ' . $xml, LOGGER_DATA);
    $nick = $a->argc > 1 ? notags(trim($a->argv[1])) : '';
    $mentions = $a->argc > 2 && $a->argv[2] === 'mention' ? true : false;
    $r = q("SELECT * FROM `user` WHERE `nickname` = '%s' AND `account_expired` = 0 AND `account_removed` = 0 LIMIT 1", dbesc($nick));
    if (!count($r)) {
        http_status_exit(500);
    }
    $importer = $r[0];
    // parse the xml
    $dom = simplexml_load_string($xml, 'SimpleXMLElement', 0, NAMESPACE_SALMON_ME);
    // figure out where in the DOM tree our data is hiding
    if ($dom->provenance->data) {
        $base = $dom->provenance;
    } elseif ($dom->env->data) {
        $base = $dom->env;
    } elseif ($dom->data) {
        $base = $dom;
    }
    if (!$base) {
        logger('mod-salmon: unable to locate salmon data in xml ');
        http_status_exit(400);
    }
    // Stash the signature away for now. We have to find their key or it won't be good for anything.
    $signature = base64url_decode($base->sig);
    // unpack the  data
    // strip whitespace so our data element will return to one big base64 blob
    $data = str_replace(array(" ", "\t", "\r", "\n"), array("", "", "", ""), $base->data);
    // stash away some other stuff for later
    $type = $base->data[0]->attributes()->type[0];
    $keyhash = $base->sig[0]->attributes()->keyhash[0];
    $encoding = $base->encoding;
    $alg = $base->alg;
    // Salmon magic signatures have evolved and there is no way of knowing ahead of time which
    // flavour we have. We'll try and verify it regardless.
    $stnet_signed_data = $data;
    $signed_data = $data . '.' . base64url_encode($type) . '.' . base64url_encode($encoding) . '.' . base64url_encode($alg);
    $compliant_format = str_replace('=', '', $signed_data);
    // decode the data
    $data = base64url_decode($data);
    // Remove the xml declaration
    $data = preg_replace('/\\<\\?xml[^\\?].*\\?\\>/', '', $data);
    // Create a fake feed wrapper so simplepie doesn't choke
    $tpl = get_markup_template('fake_feed.tpl');
    $base = substr($data, strpos($data, '<entry'));
    $feedxml = $tpl . $base . '</feed>';
    logger('mod-salmon: Processed feed: ' . $feedxml);
    // Now parse it like a normal atom feed to scrape out the author URI
    $feed = new SimplePie();
    $feed->set_raw_data($feedxml);
    $feed->enable_order_by_date(false);
    $feed->init();
    logger('mod-salmon: Feed parsed.');
    if ($feed->get_item_quantity()) {
        foreach ($feed->get_items() as $item) {
            $author = $item->get_author();
            $author_link = unxmlify($author->get_link());
            break;
        }
    }
    if (!$author_link) {
        logger('mod-salmon: Could not retrieve author URI.');
        http_status_exit(400);
    }
    // Once we have the author URI, go to the web and try to find their public key
    logger('mod-salmon: Fetching key for ' . $author_link);
    $key = get_salmon_key($author_link, $keyhash);
    if (!$key) {
        logger('mod-salmon: Could not retrieve author key.');
        http_status_exit(400);
    }
    $key_info = explode('.', $key);
    $m = base64url_decode($key_info[1]);
    $e = base64url_decode($key_info[2]);
    logger('mod-salmon: key details: ' . print_r($key_info, true), LOGGER_DEBUG);
    $pubkey = metopem($m, $e);
    // We should have everything we need now. Let's see if it verifies.
    $verify = rsa_verify($compliant_format, $signature, $pubkey);
    if (!$verify) {
        logger('mod-salmon: message did not verify using protocol. Trying padding hack.');
        $verify = rsa_verify($signed_data, $signature, $pubkey);
    }
    if (!$verify) {
        logger('mod-salmon: message did not verify using padding. Trying old statusnet hack.');
        $verify = rsa_verify($stnet_signed_data, $signature, $pubkey);
    }
    if (!$verify) {
        logger('mod-salmon: Message did not verify. Discarding.');
        http_status_exit(400);
    }
    logger('mod-salmon: Message verified.');
    /*
     *
     * If we reached this point, the message is good. Now let's figure out if the author is allowed to send us stuff.
     *
     */
    $r = q("SELECT * FROM `contact` WHERE `network` = '%s' AND ( `url` = '%s' OR `alias` = '%s' ) \n\t\tAND `uid` = %d LIMIT 1", dbesc(NETWORK_OSTATUS), dbesc($author_link), dbesc($author_link), intval($importer['uid']));
    if (!count($r)) {
        logger('mod-salmon: Author unknown to us.');
        if (get_pconfig($importer['uid'], 'system', 'ostatus_autofriend')) {
            require_once 'include/follow.php';
            $result = new_contact($importer['uid'], $author_link);
            if ($result['success']) {
                $r = q("SELECT * FROM `contact` WHERE `network` = '%s' AND ( `url` = '%s' OR `alias` = '%s' ) \n\t\t\t\t\tAND `uid` = %d LIMIT 1", dbesc(NETWORK_OSTATUS), dbesc($author_link), dbesc($author_link), intval($importer['uid']));
            }
        }
    }
    // is this a follower? Or have we ignored the person?
    // If so we can not accept this post.
    if (count($r) && ($r[0]['readonly'] || $r[0]['rel'] == CONTACT_IS_FOLLOWER || $r[0]['blocked'])) {
        logger('mod-salmon: Ignoring this author.');
        http_status_exit(202);
        // NOTREACHED
    }
    require_once 'include/items.php';
    // Placeholder for hub discovery. We shouldn't find any hubs
    // since we supplied the fake feed header - and it doesn't have any.
    $hub = '';
    /**
     *
     * anti-spam measure: consume_feed will accept a follow activity from 
     * this person (and nothing else) if there is no existing contact record.
     *
     */
    $contact_rec = count($r) ? $r[0] : null;
    consume_feed($feedxml, $importer, $contact_rec, $hub);
    http_status_exit(200);
}
Esempio n. 19
0
        /**
         * Gets the list of blogs from blogger into an array $this->blogs[]
         */
        function get_blogs($iter = 0)
        {
            $xml = $this->connector->oauth_get('https://www.blogger.com/feeds/default/blogs');

            // Give it a few retries... apparently this step often flakes out the first time.
            if (empty($xml))
            {
                if ($iter < 3)
                {
                    return $this->get_blogs($iter + 1);
                } else
                {
                    return false;
                }
            }

            $feed = new SimplePie();
            $feed->set_raw_data($xml);
            $feed->init();
            
            $i = 0;
            foreach ($feed->get_items() as $item)
            {
                $blog = new Blogger_Importer_Blog(); 
                $blog->ID = $i++;
                //Perhaps these could be passed as parameters to the new blog object or the init defaults call?
                $blog->title = $item->get_title();
                $blog->summary = $item->get_description();

                //ID is of the form tag:blogger.com,1999:blog-417730729915399755
                //We need that number from the end
                $rawid = explode('-', $item->get_id());
                $blog->id = $rawid[count($rawid) - 1];

                $parts = parse_url($item->get_link(0, 'alternate'));
                $blog->host = $parts['host'];
                $blog->gateway = $item->get_link(0, 'edit');
                $blog->posts_url = $item->get_link(0, 'http://schemas.google.com/g/2005#post');
                //AGC:20/4/2012 Developers guide suggests that the correct feed is located as follows
                //See https://developers.google.com/blogger/docs/1.0/developers_guide_php
                $blog->comments_url = "http://www.blogger.com/feeds/{$blog->id}/comments/default";

                $blog->init_defaults($this->connector->get_total_results($blog->posts_url),$this->connector->get_total_results($blog->comments_url));

                $this->blogs[] = $blog;
            }
            
            return true;
        }
Esempio n. 20
0
 /**
  * setup simplepie
  */
 private function _setup_simplepie($feed_url)
 {
     $data = new SimplePie();
     // Convert To GeoRSS feed
     $geocoder = new Geocoder();
     $georss_feed = $geocoder->geocode_feed($feed_url);
     $data->set_raw_data($georss_feed);
     $data->enable_cache(false);
     $data->enable_order_by_date(true);
     $data->init();
     $data->handle_content_type();
     return $data;
 }
Esempio n. 21
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();
}
 /**
  * Get a specific data metrics
  *
  * @param metrics - the metrics to get
  * @param startDate - the start date to get
  * @param endDate - the end date to get
  * @param dimensions - the dimensions to grab
  * @param sort - the properties to sort on
  * @param filter - the property to filter on
  * @param limit - the number of items to get
  * @return the specific metrics in array form
  **/
 function getMetrics($metric, $startDate, $endDate, $dimensions = false, $sort = false, $filter = false, $limit = false)
 {
     # Ensure the start date is after Jan 1 2005
     $startDate = $this->verifyStartDate($startDate);
     # Build the query url
     $url = $this->baseFeed . "/data?ids={$this->accountId}&start-date={$startDate}&end-date={$endDate}&metrics={$metric}";
     # Add optional dimensions
     if ($dimensions) {
         $url .= "&dimensions={$dimensions}";
     }
     # Add optional sort
     if ($sort) {
         $url .= "&sort={$sort}";
     }
     # Add optional filter
     if ($filter) {
         $url .= "&filters={$filter}";
     }
     # Add optional limit
     if ($limit) {
         $url .= "&max-results={$limit}";
     }
     # Request the metric data
     $response = $this->http($url);
     # Check if the response received exists, else stop processing now
     if ($response == '' || $this->responseCode != '200') {
         return false;
     }
     # Parse the XML using SimplePie
     $simplePie = new SimplePie();
     $simplePie->set_raw_data($response);
     $simplePie->enable_order_by_date(false);
     $simplePie->init();
     $simplePie->handle_content_type();
     $datas = $simplePie->get_items();
     $ids = array();
     # Read out the data until the metric is found
     foreach ($datas as $data) {
         $metrics = $data->get_item_tags('http://schemas.google.com/analytics/2009', 'metric');
         $dimensions = $data->get_item_tags('http://schemas.google.com/analytics/2009', 'dimension');
         $id = array();
         $id['title'] = $data->get_title();
         # Loop through the dimensions
         if (is_array($dimensions)) {
             foreach ($dimensions as $property) {
                 # Get the property information
                 $name = $property['attribs']['']['name'];
                 $value = $property['attribs']['']['value'];
                 # Add the propery data to the id array
                 $id[$name] = $value;
             }
         }
         # Loop through the metrics
         if (is_array($metrics)) {
             foreach ($metrics as $property) {
                 # Get the property information
                 $name = $property['attribs']['']['name'];
                 $value = $property['attribs']['']['value'];
                 # Add the propery data to the id array
                 $id[$name] = $value;
             }
         }
         $ids[] = $id;
     }
     return $ids;
 }
Esempio n. 23
0
     openssl_public_decrypt($challenge, $postvars['challenge'], $contact['pubkey']);
 }
 $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
 if ($final_dfrn_id != $idtosend) {
     // did not decode properly - cannot trust this site
     continue;
 }
 $postvars['dfrn_id'] = $idtosend;
 $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']) {
Esempio n. 24
0
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;
}
Esempio n. 25
0
 /**
  * Main method to import the feed items
  *
  * @since	4.0
  * @access	public
  * @param	string
  * @return
  */
 public function import(EasyBlogTableFeed &$feed, $limit = 0)
 {
     // Load site language file
     EB::loadLanguages();
     // Import simplepie library
     jimport('simplepie.simplepie');
     // We need DomDocument to exist
     if (!class_exists('DomDocument')) {
         return false;
     }
     // Set the maximum execution time to a higher value
     @ini_set('max_execution_time', 720);
     // Get the feed params
     $params = EB::registry($feed->params);
     // Determines the limit of items to fetch
     $limit = $limit ? $limit : $params->get('feedamount', 0);
     // Setup the outgoing connection to the feed source
     $connector = EB::connector();
     $connector->addUrl($feed->url);
     $connector->execute();
     // Get the contents
     $contents = $connector->getResult($feed->url);
     // If contents is empty, we know something failed
     if (!$contents) {
         return EB::exception(JText::sprintf('COM_EASYBLOG_FEEDS_UNABLE_TO_REACH_TARGET_URL', $feed->url), EASYBLOG_MSG_ERROR);
     }
     // Get the cleaner to clean things up
     $cleaner = $this->getAdapter('Cleaner');
     $contents = $cleaner->cleanup($contents);
     // Load up the xml parser
     $parser = new SimplePie();
     $parser->strip_htmltags(false);
     $parser->set_raw_data($contents);
     @$parser->init();
     // Get a list of items
     // We need to supress errors here because simplepie will throw errors on STRICT mode.
     $items = @$parser->get_items();
     if (!$items) {
         // TODO: Language string
         return EB::exception('COM_EASYBLOG_FEEDS_NOTHING_TO_BE_IMPORTED_CURRENTLY', EASYBLOG_MSG_ERROR);
     }
     // Get the feeds model
     $model = EB::model('Feeds');
     // Determines the total number of items migrated
     $total = 0;
     foreach ($items as $item) {
         // If it reaches limit, skip processing
         if ($limit && $total == $limit) {
             break;
         }
         // Get the item's unique id
         $uid = @$item->get_id();
         // If item already exists, skip this
         if ($model->isFeedItemImported($feed->id, $uid)) {
             continue;
         }
         // Log down a new history record to avoid fetching of the same item again
         $history = EB::table('FeedHistory');
         $history->feed_id = $feed->id;
         $history->uid = $uid;
         $history->created = EB::date()->toSql();
         $history->store();
         // Get the item's link
         $link = @$item->get_link();
         // Load up the post library
         $post = EB::post();
         $createOption = array('overrideDoctType' => 'legacy', 'checkAcl' => false, 'overrideAuthorId' => $feed->item_creator);
         $post->create($createOption);
         // Pass this to the adapter to map the items
         $mapper = $this->getAdapter('Mapper');
         $mapper->map($post, $item, $feed, $params);
         // Now we need to get the content of the blog post
         $mapper->mapContent($post, $item, $feed, $params);
         $saveOptions = array('applyDateOffset' => false, 'validateData' => false, 'useAuthorAsRevisionOwner' => true, 'checkAcl' => false, 'overrideAuthorId' => $feed->item_creator);
         // Try to save the blog post now
         try {
             $post->save($saveOptions);
             // Update the history table
             $history->post_id = $post->id;
             $history->store();
             $total++;
         } catch (EasyBlogException $exception) {
             // do nothing.
         }
     }
     return EB::exception(JText::sprintf('COM_EASYBLOG_FEEDS_POSTS_MIGRATED_FROM_FEED', $total, $feed->url), EASYBLOG_MSG_SUCCESS);
 }
Esempio n. 26
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;
}
Esempio n. 27
0
/**
 * @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;
            }
        }
    }
}
Esempio n. 28
0
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
}
Esempio n. 29
0
 /**
  * Setup simplepie
  * @param string $raw_data
  */
 private function _setup_simplepie($raw_data)
 {
     $data = new SimplePie();
     $data->set_raw_data($raw_data);
     $data->enable_cache(false);
     $data->enable_order_by_date(true);
     $data->init();
     $data->handle_content_type();
     return $data;
 }
 /**
  * Factory method to create a SimplePie instance
  *
  * If a file URL is set as feedUrl on the channel, the raw data will be set
  * on SimplePie to enable functional testing.
  *
  * @param \Planetflow3\Domain\Model\Channel $channel
  * @return \SimplePie
  */
 protected function createSimplePie(Channel $channel)
 {
     $simplePie = new \SimplePie();
     if (strpos($channel->getFeedUrl(), 'file://') === 0) {
         $simplePie->set_raw_data(file_get_contents($channel->getFeedUrl()));
     } else {
         $simplePie->set_feed_url($channel->getFeedUrl());
     }
     $simplePie->enable_cache(FALSE);
     $simplePie->init();
     return $simplePie;
 }