コード例 #1
0
ファイル: Scrape.php プロジェクト: robhell/friendica
function probe_url($url, $mode = PROBE_NORMAL)
{
    require_once 'include/email.php';
    $result = array();
    if (!$url) {
        return $result;
    }
    $network = null;
    $diaspora = false;
    $diaspora_base = '';
    $diaspora_guid = '';
    $diaspora_key = '';
    $has_lrdd = false;
    $email_conversant = false;
    $twitter = strpos($url, 'twitter.com') !== false ? true : false;
    $at_addr = strpos($url, '@') !== false ? true : false;
    if (!$twitter) {
        if (strpos($url, 'mailto:') !== false && $at_addr) {
            $url = str_replace('mailto:', '', $url);
            $links = array();
        } else {
            $links = lrdd($url);
        }
        if (count($links)) {
            $has_lrdd = true;
            logger('probe_url: found lrdd links: ' . print_r($links, true), LOGGER_DATA);
            foreach ($links as $link) {
                if ($link['@attributes']['rel'] === NAMESPACE_ZOT) {
                    $zot = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === NAMESPACE_DFRN) {
                    $dfrn = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'salmon') {
                    $notify = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === NAMESPACE_FEED) {
                    $poll = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard') {
                    $hcard = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') {
                    $profile = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0') {
                    $poco = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
                    $diaspora_base = unamp($link['@attributes']['href']);
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
                    $diaspora_guid = unamp($link['@attributes']['href']);
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'diaspora-public-key') {
                    $diaspora_key = base64_decode(unamp($link['@attributes']['href']));
                    $pubkey = rsatopem($diaspora_key);
                    $diaspora = true;
                }
            }
            // Status.Net can have more than one profile URL. We need to match the profile URL
            // to a contact on incoming messages to prevent spam, and we won't know which one
            // to match. So in case of two, one of them is stored as an alias. Only store URL's
            // and not webfinger user@host aliases. If they've got more than two non-email style
            // aliases, let's hope we're lucky and get one that matches the feed author-uri because
            // otherwise we're screwed.
            foreach ($links as $link) {
                if ($link['@attributes']['rel'] === 'alias') {
                    if (strpos($link['@attributes']['href'], '@') === false) {
                        if (isset($profile)) {
                            if ($link['@attributes']['href'] !== $profile) {
                                $alias = unamp($link['@attributes']['href']);
                            }
                        } else {
                            $profile = unamp($link['@attributes']['href']);
                        }
                    }
                }
            }
        } elseif ($mode == PROBE_NORMAL) {
            // Check email
            $orig_url = $url;
            if (strpos($orig_url, '@') && validate_email($orig_url)) {
                $x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1", intval(local_user()));
                $r = q("SELECT * FROM `mailacct` WHERE `uid` = %d AND `server` != '' LIMIT 1", intval(local_user()));
                if (count($x) && count($r)) {
                    $mailbox = construct_mailbox_name($r[0]);
                    $password = '';
                    openssl_private_decrypt(hex2bin($r[0]['pass']), $password, $x[0]['prvkey']);
                    $mbox = email_connect($mailbox, $r[0]['user'], $password);
                    if (!$mbox) {
                        logger('probe_url: email_connect failed.');
                    }
                    unset($password);
                }
                if ($mbox) {
                    $msgs = email_poll($mbox, $orig_url);
                    logger('probe_url: searching ' . $orig_url . ', ' . count($msgs) . ' messages found.', LOGGER_DEBUG);
                    if (count($msgs)) {
                        $addr = $orig_url;
                        $network = NETWORK_MAIL;
                        $name = substr($url, 0, strpos($url, '@'));
                        $phost = substr($url, strpos($url, '@') + 1);
                        $profile = 'http://' . $phost;
                        // fix nick character range
                        $vcard = array('fn' => $name, 'nick' => $name, 'photo' => avatar_img($url));
                        $notify = 'smtp ' . random_string();
                        $poll = 'email ' . random_string();
                        $priority = 0;
                        $x = email_msg_meta($mbox, $msgs[0]);
                        if (stristr($x->from, $orig_url)) {
                            $adr = imap_rfc822_parse_adrlist($x->from, '');
                        } elseif (stristr($x->to, $orig_url)) {
                            $adr = imap_rfc822_parse_adrlist($x->to, '');
                        }
                        if (isset($adr)) {
                            foreach ($adr as $feadr) {
                                if (strcasecmp($feadr->mailbox, $name) == 0 && strcasecmp($feadr->host, $phost) == 0 && strlen($feadr->personal)) {
                                    $personal = imap_mime_header_decode($feadr->personal);
                                    $vcard['fn'] = "";
                                    foreach ($personal as $perspart) {
                                        if ($perspart->charset != "default") {
                                            $vcard['fn'] .= iconv($perspart->charset, 'UTF-8//IGNORE', $perspart->text);
                                        } else {
                                            $vcard['fn'] .= $perspart->text;
                                        }
                                    }
                                    $vcard['fn'] = notags($vcard['fn']);
                                }
                            }
                        }
                    }
                    imap_close($mbox);
                }
            }
        }
    }
    if ($mode == PROBE_NORMAL) {
        if (strlen($zot)) {
            $s = fetch_url($zot);
            if ($s) {
                $j = json_decode($s);
                if ($j) {
                    $network = NETWORK_ZOT;
                    $vcard = array('fn' => $j->fullname, 'nick' => $j->nickname, 'photo' => $j->photo);
                    $profile = $j->url;
                    $notify = $j->post;
                    $pubkey = $j->pubkey;
                    $poll = 'N/A';
                }
            }
        }
        if (strlen($dfrn)) {
            $ret = scrape_dfrn($hcard ? $hcard : $dfrn);
            if (is_array($ret) && x($ret, 'dfrn-request')) {
                $network = NETWORK_DFRN;
                $request = $ret['dfrn-request'];
                $confirm = $ret['dfrn-confirm'];
                $notify = $ret['dfrn-notify'];
                $poll = $ret['dfrn-poll'];
                $vcard = array();
                $vcard['fn'] = $ret['fn'];
                $vcard['nick'] = $ret['nick'];
                $vcard['photo'] = $ret['photo'];
            }
        }
    }
    if ($diaspora && $diaspora_base && $diaspora_guid) {
        if ($mode == PROBE_DIASPORA || !$notify) {
            $notify = $diaspora_base . 'receive/users/' . $diaspora_guid;
            $batch = $diaspora_base . 'receive/public';
        }
        if (strpos($url, '@')) {
            $addr = str_replace('acct:', '', $url);
        }
    }
    if ($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) {
        if ($diaspora) {
            $network = NETWORK_DIASPORA;
        } elseif ($has_lrdd) {
            $network = NETWORK_OSTATUS;
        }
        $priority = 0;
        if ($hcard && !$vcard) {
            $vcard = scrape_vcard($hcard);
            // Google doesn't use absolute url in profile photos
            if (x($vcard, 'photo') && substr($vcard['photo'], 0, 1) == '/') {
                $h = @parse_url($hcard);
                if ($h) {
                    $vcard['photo'] = $h['scheme'] . '://' . $h['host'] . $vcard['photo'];
                }
            }
            logger('probe_url: scrape_vcard: ' . print_r($vcard, true), LOGGER_DATA);
        }
        if ($twitter) {
            logger('twitter: setup');
            $tid = basename($url);
            $tapi = 'https://api.twitter.com/1/statuses/user_timeline.rss';
            if (intval($tid)) {
                $poll = $tapi . '?user_id=' . $tid;
            } else {
                $poll = $tapi . '?screen_name=' . $tid;
            }
            $profile = 'http://twitter.com/#!/' . $tid;
            $vcard['photo'] = 'https://api.twitter.com/1/users/profile_image/' . $tid;
            $vcard['nick'] = $tid;
            $vcard['fn'] = $tid . '@twitter';
        }
        if (!x($vcard, 'fn')) {
            if (x($vcard, 'nick')) {
                $vcard['fn'] = $vcard['nick'];
            }
        }
        $check_feed = false;
        if ($twitter || !$poll) {
            $check_feed = true;
        }
        if (!isset($vcard) || !x($vcard, 'fn') || !$profile) {
            $check_feed = true;
        }
        if ($at_addr && !count($links)) {
            $check_feed = false;
        }
        if ($check_feed) {
            $feedret = scrape_feed($poll ? $poll : $url);
            logger('probe_url: scrape_feed ' . ($poll ? $poll : $url) . ' returns: ' . print_r($feedret, true), LOGGER_DATA);
            if (count($feedret) && ($feedret['feed_atom'] || $feedret['feed_rss'])) {
                $poll = x($feedret, 'feed_atom') ? unamp($feedret['feed_atom']) : unamp($feedret['feed_rss']);
                if (!x($vcard)) {
                    $vcard = array();
                }
            }
            if (x($feedret, 'photo') && !x($vcard, 'photo')) {
                $vcard['photo'] = $feedret['photo'];
            }
            require_once 'library/simplepie/simplepie.inc';
            $feed = new SimplePie();
            $xml = fetch_url($poll);
            logger('probe_url: fetch feed: ' . $poll . ' returns: ' . $xml, LOGGER_DATA);
            $a = get_app();
            logger('probe_url: scrape_feed: headers: ' . $a->get_curl_headers(), LOGGER_DATA);
            $feed->set_raw_data($xml);
            $feed->init();
            if ($feed->error()) {
                logger('probe_url: scrape_feed: Error parsing XML: ' . $feed->error());
            }
            if (!x($vcard, 'photo')) {
                $vcard['photo'] = $feed->get_image_url();
            }
            $author = $feed->get_author();
            if ($author) {
                $vcard['fn'] = unxmlify(trim($author->get_name()));
                if (!$vcard['fn']) {
                    $vcard['fn'] = trim(unxmlify($author->get_email()));
                }
                if (strpos($vcard['fn'], '@') !== false) {
                    $vcard['fn'] = substr($vcard['fn'], 0, strpos($vcard['fn'], '@'));
                }
                $email = unxmlify($author->get_email());
                if (!$profile && $author->get_link()) {
                    $profile = trim(unxmlify($author->get_link()));
                }
                if (!$vcard['photo']) {
                    $rawtags = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
                    if ($rawtags) {
                        $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
                        if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo') {
                            $vcard['photo'] = $elems['link'][0]['attribs']['']['href'];
                        }
                    }
                }
            } else {
                $item = $feed->get_item(0);
                if ($item) {
                    $author = $item->get_author();
                    if ($author) {
                        $vcard['fn'] = trim(unxmlify($author->get_name()));
                        if (!$vcard['fn']) {
                            $vcard['fn'] = trim(unxmlify($author->get_email()));
                        }
                        if (strpos($vcard['fn'], '@') !== false) {
                            $vcard['fn'] = substr($vcard['fn'], 0, strpos($vcard['fn'], '@'));
                        }
                        $email = unxmlify($author->get_email());
                        if (!$profile && $author->get_link()) {
                            $profile = trim(unxmlify($author->get_link()));
                        }
                    }
                    if (!$vcard['photo']) {
                        $rawmedia = $item->get_item_tags('http://search.yahoo.com/mrss/', 'thumbnail');
                        if ($rawmedia && $rawmedia[0]['attribs']['']['url']) {
                            $vcard['photo'] = unxmlify($rawmedia[0]['attribs']['']['url']);
                        }
                    }
                    if (!$vcard['photo']) {
                        $rawtags = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
                        if ($rawtags) {
                            $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
                            if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo') {
                                $vcard['photo'] = $elems['link'][0]['attribs']['']['href'];
                            }
                        }
                    }
                }
            }
            if (!$vcard['photo'] && strlen($email)) {
                $vcard['photo'] = avatar_img($email);
            }
            if ($poll === $profile) {
                $lnk = $feed->get_permalink();
            }
            if (isset($lnk) && strlen($lnk)) {
                $profile = $lnk;
            }
            if (!x($vcard, 'fn')) {
                $vcard['fn'] = notags($feed->get_title());
            }
            if (!x($vcard, 'fn')) {
                $vcard['fn'] = notags($feed->get_description());
            }
            if (strpos($vcard['fn'], 'Twitter / ') !== false) {
                $vcard['fn'] = substr($vcard['fn'], strpos($vcard['fn'], '/') + 1);
                $vcard['fn'] = trim($vcard['fn']);
            }
            if (!x($vcard, 'nick')) {
                $vcard['nick'] = strtolower(notags(unxmlify($vcard['fn'])));
                if (strpos($vcard['nick'], ' ')) {
                    $vcard['nick'] = trim(substr($vcard['nick'], 0, strpos($vcard['nick'], ' ')));
                }
            }
            if (!$network) {
                $network = NETWORK_FEED;
            }
            if (!$priority) {
                $priority = 2;
            }
        }
    }
    if (!x($vcard, 'photo')) {
        $a = get_app();
        $vcard['photo'] = $a->get_baseurl() . '/images/person-175.jpg';
    }
    if (!$profile) {
        $profile = $url;
    }
    // No human could be associated with this link, use the URL as the contact name
    if ($network === NETWORK_FEED && $poll && !x($vcard, 'fn')) {
        $vcard['fn'] = $url;
    }
    $vcard['fn'] = notags($vcard['fn']);
    $vcard['nick'] = str_replace(' ', '', notags($vcard['nick']));
    $result['name'] = $vcard['fn'];
    $result['nick'] = $vcard['nick'];
    $result['url'] = $profile;
    $result['addr'] = $addr;
    $result['batch'] = $batch;
    $result['notify'] = $notify;
    $result['poll'] = $poll;
    $result['request'] = $request;
    $result['confirm'] = $confirm;
    $result['poco'] = $poco;
    $result['photo'] = $vcard['photo'];
    $result['priority'] = $priority;
    $result['network'] = $network;
    $result['alias'] = $alias;
    $result['pubkey'] = $pubkey;
    logger('probe_url: ' . print_r($result, true), LOGGER_DEBUG);
    return $result;
}
コード例 #2
0
ファイル: Scrape.php プロジェクト: vinzv/friendica
function probe_url($url, $mode = PROBE_NORMAL, $level = 1)
{
    require_once 'include/email.php';
    $result = array();
    if (!$url) {
        return $result;
    }
    $result = Cache::get("probe_url:" . $mode . ":" . $url);
    if (!is_null($result)) {
        $result = unserialize($result);
        return $result;
    }
    $network = null;
    $diaspora = false;
    $diaspora_base = '';
    $diaspora_guid = '';
    $diaspora_key = '';
    $has_lrdd = false;
    $email_conversant = false;
    $connectornetworks = false;
    $appnet = false;
    if (strpos($url, 'twitter.com')) {
        $connectornetworks = true;
        $network = NETWORK_TWITTER;
    }
    // Twitter is deactivated since twitter closed its old API
    //$twitter = ((strpos($url,'twitter.com') !== false) ? true : false);
    $lastfm = strpos($url, 'last.fm/user') !== false ? true : false;
    $at_addr = strpos($url, '@') !== false ? true : false;
    if (!$appnet && !$lastfm && !$connectornetworks) {
        if (strpos($url, 'mailto:') !== false && $at_addr) {
            $url = str_replace('mailto:', '', $url);
            $links = array();
        } else {
            $links = lrdd($url);
        }
        if (count($links)) {
            $has_lrdd = true;
            logger('probe_url: found lrdd links: ' . print_r($links, true), LOGGER_DATA);
            foreach ($links as $link) {
                if ($link['@attributes']['rel'] === NAMESPACE_ZOT) {
                    $zot = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === NAMESPACE_DFRN) {
                    $dfrn = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'salmon') {
                    $notify = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === NAMESPACE_FEED) {
                    $poll = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard') {
                    $hcard = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') {
                    $profile = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0') {
                    $poco = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
                    $diaspora_base = unamp($link['@attributes']['href']);
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
                    $diaspora_guid = unamp($link['@attributes']['href']);
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'diaspora-public-key') {
                    $diaspora_key = base64_decode(unamp($link['@attributes']['href']));
                    if (strstr($diaspora_key, 'RSA ')) {
                        $pubkey = rsatopem($diaspora_key);
                    } else {
                        $pubkey = $diaspora_key;
                    }
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'http://ostatus.org/schema/1.0/subscribe' and $mode == PROBE_NORMAL) {
                    $diaspora = false;
                }
            }
            // Status.Net can have more than one profile URL. We need to match the profile URL
            // to a contact on incoming messages to prevent spam, and we won't know which one
            // to match. So in case of two, one of them is stored as an alias. Only store URL's
            // and not webfinger user@host aliases. If they've got more than two non-email style
            // aliases, let's hope we're lucky and get one that matches the feed author-uri because
            // otherwise we're screwed.
            foreach ($links as $link) {
                if ($link['@attributes']['rel'] === 'alias') {
                    if (strpos($link['@attributes']['href'], '@') === false) {
                        if (isset($profile)) {
                            if ($link['@attributes']['href'] !== $profile) {
                                $alias = unamp($link['@attributes']['href']);
                            }
                        } else {
                            $profile = unamp($link['@attributes']['href']);
                        }
                    }
                }
            }
            // If the profile is different from the url then the url is abviously an alias
            if ($alias == "" and $profile != "" and !$at_addr and normalise_link($profile) != normalise_link($url)) {
                $alias = $url;
            }
        } elseif ($mode == PROBE_NORMAL) {
            // Check email
            $orig_url = $url;
            if (strpos($orig_url, '@') && validate_email($orig_url)) {
                $x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1", intval(local_user()));
                $r = q("SELECT * FROM `mailacct` WHERE `uid` = %d AND `server` != '' LIMIT 1", intval(local_user()));
                if (count($x) && count($r)) {
                    $mailbox = construct_mailbox_name($r[0]);
                    $password = '';
                    openssl_private_decrypt(hex2bin($r[0]['pass']), $password, $x[0]['prvkey']);
                    $mbox = email_connect($mailbox, $r[0]['user'], $password);
                    if (!$mbox) {
                        logger('probe_url: email_connect failed.');
                    }
                    unset($password);
                }
                if ($mbox) {
                    $msgs = email_poll($mbox, $orig_url);
                    logger('probe_url: searching ' . $orig_url . ', ' . count($msgs) . ' messages found.', LOGGER_DEBUG);
                    if (count($msgs)) {
                        $addr = $orig_url;
                        $network = NETWORK_MAIL;
                        $name = substr($url, 0, strpos($url, '@'));
                        $phost = substr($url, strpos($url, '@') + 1);
                        $profile = 'http://' . $phost;
                        // fix nick character range
                        $vcard = array('fn' => $name, 'nick' => $name, 'photo' => avatar_img($url));
                        $notify = 'smtp ' . random_string();
                        $poll = 'email ' . random_string();
                        $priority = 0;
                        $x = email_msg_meta($mbox, $msgs[0]);
                        if (stristr($x[0]->from, $orig_url)) {
                            $adr = imap_rfc822_parse_adrlist($x[0]->from, '');
                        } elseif (stristr($x[0]->to, $orig_url)) {
                            $adr = imap_rfc822_parse_adrlist($x[0]->to, '');
                        }
                        if (isset($adr)) {
                            foreach ($adr as $feadr) {
                                if (strcasecmp($feadr->mailbox, $name) == 0 && strcasecmp($feadr->host, $phost) == 0 && strlen($feadr->personal)) {
                                    $personal = imap_mime_header_decode($feadr->personal);
                                    $vcard['fn'] = "";
                                    foreach ($personal as $perspart) {
                                        if ($perspart->charset != "default") {
                                            $vcard['fn'] .= iconv($perspart->charset, 'UTF-8//IGNORE', $perspart->text);
                                        } else {
                                            $vcard['fn'] .= $perspart->text;
                                        }
                                    }
                                    $vcard['fn'] = notags($vcard['fn']);
                                }
                            }
                        }
                    }
                    imap_close($mbox);
                }
            }
        }
    }
    if ($mode == PROBE_NORMAL) {
        if (strlen($zot)) {
            $s = fetch_url($zot);
            if ($s) {
                $j = json_decode($s);
                if ($j) {
                    $network = NETWORK_ZOT;
                    $vcard = array('fn' => $j->fullname, 'nick' => $j->nickname, 'photo' => $j->photo);
                    $profile = $j->url;
                    $notify = $j->post;
                    $pubkey = $j->pubkey;
                    $poll = 'N/A';
                }
            }
        }
        if (strlen($dfrn)) {
            $ret = scrape_dfrn($hcard ? $hcard : $dfrn, true);
            if (is_array($ret) && x($ret, 'dfrn-request')) {
                $network = NETWORK_DFRN;
                $request = $ret['dfrn-request'];
                $confirm = $ret['dfrn-confirm'];
                $notify = $ret['dfrn-notify'];
                $poll = $ret['dfrn-poll'];
                $vcard = array();
                $vcard['fn'] = $ret['fn'];
                $vcard['nick'] = $ret['nick'];
                $vcard['photo'] = $ret['photo'];
            }
        }
    }
    if ($diaspora && $diaspora_base && $diaspora_guid) {
        if ($mode == PROBE_DIASPORA || !$notify) {
            $notify = $diaspora_base . 'receive/users/' . $diaspora_guid;
            $batch = $diaspora_base . 'receive/public';
        }
        if (strpos($url, '@')) {
            $addr = str_replace('acct:', '', $url);
        }
    }
    if ($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) {
        if ($diaspora) {
            $network = NETWORK_DIASPORA;
        } elseif ($has_lrdd and $notify) {
            $network = NETWORK_OSTATUS;
        }
        if (strpos($url, '@')) {
            $addr = str_replace('acct:', '', $url);
        }
        $priority = 0;
        if ($hcard && !$vcard) {
            $vcard = scrape_vcard($hcard);
            // Google doesn't use absolute url in profile photos
            if (x($vcard, 'photo') && substr($vcard['photo'], 0, 1) == '/') {
                $h = @parse_url($hcard);
                if ($h) {
                    $vcard['photo'] = $h['scheme'] . '://' . $h['host'] . $vcard['photo'];
                }
            }
            logger('probe_url: scrape_vcard: ' . print_r($vcard, true), LOGGER_DATA);
        }
        if ($diaspora && $addr) {
            // Diaspora returns the name as the nick. As the nick will never be updated,
            // let's use the Diaspora nickname (the first part of the handle) as the nick instead
            $addr_parts = explode('@', $addr);
            $vcard['nick'] = $addr_parts[0];
        }
        /* if($twitter) {
        			logger('twitter: setup');
        			$tid = basename($url);
        			$tapi = 'https://api.twitter.com/1/statuses/user_timeline.rss';
        			if(intval($tid))
        				$poll = $tapi . '?user_id=' . $tid;
        			else
        				$poll = $tapi . '?screen_name=' . $tid;
        			$profile = 'http://twitter.com/#!/' . $tid;
        			//$vcard['photo'] = 'https://api.twitter.com/1/users/profile_image/' . $tid;
        			$vcard['photo'] = 'https://api.twitter.com/1/users/profile_image?screen_name=' . $tid . '&size=bigger';
        			$vcard['nick'] = $tid;
        			$vcard['fn'] = $tid;
        		} */
        if ($lastfm) {
            $profile = $url;
            $poll = str_replace(array('www.', 'last.fm/'), array('', 'ws.audioscrobbler.com/1.0/'), $url) . '/recenttracks.rss';
            $vcard['nick'] = basename($url);
            $vcard['fn'] = $vcard['nick'] . t(' on Last.fm');
            $network = NETWORK_FEED;
        }
        if (!x($vcard, 'fn')) {
            if (x($vcard, 'nick')) {
                $vcard['fn'] = $vcard['nick'];
            }
        }
        $check_feed = false;
        if (stristr($url, 'tumblr.com') && !stristr($url, '/rss')) {
            $poll = $url . '/rss';
            $check_feed = true;
            // Will leave it to others to figure out how to grab the avatar, which is on the $url page in the open graph meta links
        }
        if ($appnet || !$poll) {
            $check_feed = true;
        }
        if (!isset($vcard) || !x($vcard, 'fn') || !$profile) {
            $check_feed = true;
        }
        if ($at_addr && !count($links)) {
            $check_feed = false;
        }
        if ($connectornetworks) {
            $check_feed = false;
        }
        if ($check_feed) {
            $feedret = scrape_feed($poll ? $poll : $url);
            logger('probe_url: scrape_feed ' . ($poll ? $poll : $url) . ' returns: ' . print_r($feedret, true), LOGGER_DATA);
            if (count($feedret) && ($feedret['feed_atom'] || $feedret['feed_rss'])) {
                $poll = x($feedret, 'feed_atom') ? unamp($feedret['feed_atom']) : unamp($feedret['feed_rss']);
                if (!x($vcard)) {
                    $vcard = array();
                }
            }
            if (x($feedret, 'photo') && !x($vcard, 'photo')) {
                $vcard['photo'] = $feedret['photo'];
            }
            require_once 'library/simplepie/simplepie.inc';
            $feed = new SimplePie();
            $xml = fetch_url($poll);
            logger('probe_url: fetch feed: ' . $poll . ' returns: ' . $xml, LOGGER_DATA);
            $a = get_app();
            logger('probe_url: scrape_feed: headers: ' . $a->get_curl_headers(), LOGGER_DATA);
            // Don't try and parse an empty string
            $feed->set_raw_data($xml ? $xml : '<?xml version="1.0" encoding="utf-8" ?><xml></xml>');
            $feed->init();
            if ($feed->error()) {
                logger('probe_url: scrape_feed: Error parsing XML: ' . $feed->error());
                $network = NETWORK_PHANTOM;
            }
            if (!x($vcard, 'photo')) {
                $vcard['photo'] = $feed->get_image_url();
            }
            $author = $feed->get_author();
            if ($author) {
                $vcard['fn'] = unxmlify(trim($author->get_name()));
                if (!$vcard['fn']) {
                    $vcard['fn'] = trim(unxmlify($author->get_email()));
                }
                if (strpos($vcard['fn'], '@') !== false) {
                    $vcard['fn'] = substr($vcard['fn'], 0, strpos($vcard['fn'], '@'));
                }
                $email = unxmlify($author->get_email());
                if (!$profile && $author->get_link()) {
                    $profile = trim(unxmlify($author->get_link()));
                }
                if (!$vcard['photo']) {
                    $rawtags = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
                    if ($rawtags) {
                        $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
                        if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo') {
                            $vcard['photo'] = $elems['link'][0]['attribs']['']['href'];
                        }
                    }
                }
                // Fetch fullname via poco:displayName
                $pocotags = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
                if ($pocotags) {
                    $elems = $pocotags[0]['child']['http://portablecontacts.net/spec/1.0'];
                    if (isset($elems["displayName"])) {
                        $vcard['fn'] = $elems["displayName"][0]["data"];
                    }
                    if (isset($elems["preferredUsername"])) {
                        $vcard['nick'] = $elems["preferredUsername"][0]["data"];
                    }
                }
            } else {
                $item = $feed->get_item(0);
                if ($item) {
                    $author = $item->get_author();
                    if ($author) {
                        $vcard['fn'] = trim(unxmlify($author->get_name()));
                        if (!$vcard['fn']) {
                            $vcard['fn'] = trim(unxmlify($author->get_email()));
                        }
                        if (strpos($vcard['fn'], '@') !== false) {
                            $vcard['fn'] = substr($vcard['fn'], 0, strpos($vcard['fn'], '@'));
                        }
                        $email = unxmlify($author->get_email());
                        if (!$profile && $author->get_link()) {
                            $profile = trim(unxmlify($author->get_link()));
                        }
                    }
                    if (!$vcard['photo']) {
                        $rawmedia = $item->get_item_tags('http://search.yahoo.com/mrss/', 'thumbnail');
                        if ($rawmedia && $rawmedia[0]['attribs']['']['url']) {
                            $vcard['photo'] = unxmlify($rawmedia[0]['attribs']['']['url']);
                        }
                    }
                    if (!$vcard['photo']) {
                        $rawtags = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
                        if ($rawtags) {
                            $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
                            if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo') {
                                $vcard['photo'] = $elems['link'][0]['attribs']['']['href'];
                            }
                        }
                    }
                }
            }
            // Workaround for misconfigured Friendica servers
            if ($network == "" and strstr($url, "/profile/")) {
                $noscrape = str_replace("/profile/", "/noscrape/", $url);
                $noscrapejson = fetch_url($noscrape);
                if ($noscrapejson) {
                    $network = NETWORK_DFRN;
                    $poco = str_replace("/profile/", "/poco/", $url);
                    $noscrapedata = json_decode($noscrapejson, true);
                    if (isset($noscrapedata["addr"])) {
                        $addr = $noscrapedata["addr"];
                    }
                    if (isset($noscrapedata["fn"])) {
                        $vcard["fn"] = $noscrapedata["fn"];
                    }
                    if (isset($noscrapedata["key"])) {
                        $pubkey = $noscrapedata["key"];
                    }
                    if (isset($noscrapedata["photo"])) {
                        $vcard["photo"] = $noscrapedata["photo"];
                    }
                    if (isset($noscrapedata["dfrn-request"])) {
                        $request = $noscrapedata["dfrn-request"];
                    }
                    if (isset($noscrapedata["dfrn-confirm"])) {
                        $confirm = $noscrapedata["dfrn-confirm"];
                    }
                    if (isset($noscrapedata["dfrn-notify"])) {
                        $notify = $noscrapedata["dfrn-notify"];
                    }
                    if (isset($noscrapedata["dfrn-poll"])) {
                        $poll = $noscrapedata["dfrn-poll"];
                    }
                }
            }
            if (!$vcard['photo'] && strlen($email)) {
                $vcard['photo'] = avatar_img($email);
            }
            if ($poll === $profile) {
                $lnk = $feed->get_permalink();
            }
            if (isset($lnk) && strlen($lnk)) {
                $profile = $lnk;
            }
            if (!$network) {
                $network = NETWORK_FEED;
                // If it is a feed, don't take the author name as feed name
                unset($vcard['fn']);
            }
            if (!x($vcard, 'fn')) {
                $vcard['fn'] = notags($feed->get_title());
            }
            if (!x($vcard, 'fn')) {
                $vcard['fn'] = notags($feed->get_description());
            }
            if (strpos($vcard['fn'], 'Twitter / ') !== false) {
                $vcard['fn'] = substr($vcard['fn'], strpos($vcard['fn'], '/') + 1);
                $vcard['fn'] = trim($vcard['fn']);
            }
            if (!x($vcard, 'nick')) {
                $vcard['nick'] = strtolower(notags(unxmlify($vcard['fn'])));
                if (strpos($vcard['nick'], ' ')) {
                    $vcard['nick'] = trim(substr($vcard['nick'], 0, strpos($vcard['nick'], ' ')));
                }
            }
            if (!$priority) {
                $priority = 2;
            }
        }
    }
    if (!x($vcard, 'photo')) {
        $a = get_app();
        $vcard['photo'] = $a->get_baseurl() . '/images/person-175.jpg';
    }
    if (!$profile) {
        $profile = $url;
    }
    // No human could be associated with this link, use the URL as the contact name
    if ($network === NETWORK_FEED && $poll && !x($vcard, 'fn')) {
        $vcard['fn'] = $url;
    }
    if ($notify != "" and $poll != "") {
        $baseurl = matching(normalise_link($notify), normalise_link($poll));
        $baseurl2 = matching($baseurl, normalise_link($profile));
        if ($baseurl2 != "") {
            $baseurl = $baseurl2;
        }
    }
    if ($baseurl == "" and $notify != "") {
        $baseurl = matching(normalise_link($profile), normalise_link($notify));
    }
    if ($baseurl == "" and $poll != "") {
        $baseurl = matching(normalise_link($profile), normalise_link($poll));
    }
    $baseurl = rtrim($baseurl, "/");
    if (strpos($url, '@') and $addr == "" and $network == NETWORK_DFRN) {
        $addr = str_replace('acct:', '', $url);
    }
    $vcard['fn'] = notags($vcard['fn']);
    $vcard['nick'] = str_replace(' ', '', notags($vcard['nick']));
    $result['name'] = $vcard['fn'];
    $result['nick'] = $vcard['nick'];
    $result['url'] = $profile;
    $result['addr'] = $addr;
    $result['batch'] = $batch;
    $result['notify'] = $notify;
    $result['poll'] = $poll;
    $result['request'] = $request;
    $result['confirm'] = $confirm;
    $result['poco'] = $poco;
    $result['photo'] = $vcard['photo'];
    $result['priority'] = $priority;
    $result['network'] = $network;
    $result['alias'] = $alias;
    $result['pubkey'] = $pubkey;
    $result['baseurl'] = $baseurl;
    logger('probe_url: ' . print_r($result, true), LOGGER_DEBUG);
    if ($level == 1) {
        // Trying if it maybe a diaspora account
        if ($result['network'] == NETWORK_FEED or $result['addr'] == "") {
            require_once 'include/bbcode.php';
            $address = GetProfileUsername($url, "", true);
            $result2 = probe_url($address, $mode, ++$level);
            if ($result2['network'] != "") {
                $result = $result2;
            }
        }
        // Maybe it's some non standard GNU Social installation (Single user, subfolder or no uri rewrite)
        if ($result['network'] == NETWORK_FEED and $result['baseurl'] != "" and $result['nick'] != "") {
            $addr = $result['nick'] . '@' . str_replace("http://", "", $result['baseurl']);
            $result2 = probe_url($addr, $mode, ++$level);
            if ($result2['network'] != "" and $result2['network'] != NETWORK_FEED) {
                $result = $result2;
            }
        }
    }
    // Only store into the cache if the value seems to be valid
    if ($result['network'] != NETWORK_PHANTOM) {
        Cache::set("probe_url:" . $mode . ":" . $url, serialize($result), CACHE_DAY);
    }
    return $result;
}
コード例 #3
0
ファイル: dfrn_request.php プロジェクト: nextgensh/friendica
 function dfrn_request_post(&$a)
 {
     if ($a->argc != 2 || !count($a->profile)) {
         return;
     }
     if ($_POST['cancel']) {
         goaway(z_root());
     }
     /**
      *
      * Scenario 2: We've introduced ourself to another cell, then have been returned to our own cell
      * to confirm the request, and then we've clicked submit (perhaps after logging in). 
      * That brings us here:
      *
      */
     if (x($_POST, 'localconfirm') && $_POST['localconfirm'] == 1) {
         /**
          * Ensure this is a valid request
          */
         if (local_user() && $a->user['nickname'] == $a->argv[1] && x($_POST, 'dfrn_url')) {
             $dfrn_url = notags(trim($_POST['dfrn_url']));
             $aes_allow = x($_POST, 'aes_allow') && $_POST['aes_allow'] == 1 ? 1 : 0;
             $confirm_key = x($_POST, 'confirm_key') ? $_POST['confirm_key'] : "";
             $contact_record = null;
             if (x($dfrn_url)) {
                 /**
                  * Lookup the contact based on their URL (which is the only unique thing we have at the moment)
                  */
                 $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `self` = 0 LIMIT 1", intval(local_user()), dbesc($dfrn_url));
                 if (count($r)) {
                     if (strlen($r[0]['dfrn-id'])) {
                         /**
                          * We don't need to be here. It has already happened.
                          */
                         notice(t("This introduction has already been accepted.") . EOL);
                         return;
                     } else {
                         $contact_record = $r[0];
                     }
                 }
                 if (is_array($contact_record)) {
                     $r = q("UPDATE `contact` SET `ret-aes` = %d WHERE `id` = %d LIMIT 1", intval($aes_allow), intval($contact_record['id']));
                 } else {
                     /**
                      * Scrape the other site's profile page to pick up the dfrn links, key, fn, and photo
                      */
                     require_once 'Scrape.php';
                     $parms = scrape_dfrn($dfrn_url);
                     if (!count($parms)) {
                         notice(t('Profile location is not valid or does not contain profile information.') . EOL);
                         return;
                     } else {
                         if (!x($parms, 'fn')) {
                             notice(t('Warning: profile location has no identifiable owner name.') . EOL);
                         }
                         if (!x($parms, 'photo')) {
                             notice(t('Warning: profile location has no profile photo.') . EOL);
                         }
                         $invalid = validate_dfrn($parms);
                         if ($invalid) {
                             notice(sprintf(tt("%d required parameter was not found at the given location", "%d required parameters were not found at the given location", $invalid), $invalid) . EOL);
                             return;
                         }
                     }
                     $dfrn_request = $parms['dfrn-request'];
                     /********* Escape the entire array ********/
                     dbesc_array($parms);
                     /******************************************/
                     /**
                      * Create a contact record on our site for the other person
                      */
                     $r = q("INSERT INTO `contact` ( `uid`, `created`,`url`, `nurl`, `name`, `nick`, `photo`, `site-pubkey`,\n\t\t\t\t\t\t`request`, `confirm`, `notify`, `poll`, `poco`, `network`, `aes_allow`) \n\t\t\t\t\t\tVALUES ( %d, '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", intval(local_user()), datetime_convert(), dbesc($dfrn_url), dbesc(normalise_link($dfrn_url)), $parms['fn'], $parms['nick'], $parms['photo'], $parms['key'], $parms['dfrn-request'], $parms['dfrn-confirm'], $parms['dfrn-notify'], $parms['dfrn-poll'], $parms['dfrn-poco'], dbesc(NETWORK_DFRN), intval($aes_allow));
                 }
                 if ($r) {
                     info(t("Introduction complete.") . EOL);
                 }
                 /**
                  * Allow the blocked remote notification to complete
                  */
                 if (is_array($contact_record)) {
                     $dfrn_request = $contact_record['request'];
                 }
                 if (strlen($dfrn_request) && strlen($confirm_key)) {
                     $s = fetch_url($dfrn_request . '?confirm_key=' . $confirm_key);
                 }
                 // (ignore reply, nothing we can do it failed)
                 goaway($dfrn_url);
                 return;
                 // NOTREACHED
             }
         }
         // invalid/bogus request
         notice(t('Unrecoverable protocol error.') . EOL);
         goaway(z_root());
         return;
         // NOTREACHED
     }
     /**
      * Otherwise:
      * 
      * Scenario 1:
      * We are the requestee. A person from a remote cell has made an introduction 
      * on our profile web page and clicked submit. We will use their DFRN-URL to 
      * figure out how to contact their cell.  
      *
      * Scrape the originating DFRN-URL for everything we need. Create a contact record
      * and an introduction to show our user next time he/she logs in.
      * Finally redirect back to the requestor so that their site can record the request.
      * If our user (the requestee) later confirms this request, a record of it will need 
      * to exist on the requestor's cell in order for the confirmation process to complete.. 
      *
      * It's possible that neither the requestor or the requestee are logged in at the moment,
      * and the requestor does not yet have any credentials to the requestee profile.
      *
      * Who is the requestee? We've already loaded their profile which means their nickname should be
      * in $a->argv[1] and we should have their complete info in $a->profile.
      *
      */
     if (!(is_array($a->profile) && count($a->profile))) {
         notice(t('Profile unavailable.') . EOL);
         return;
     }
     $nickname = $a->profile['nickname'];
     $notify_flags = $a->profile['notify-flags'];
     $uid = $a->profile['uid'];
     $maxreq = intval($a->profile['maxreq']);
     $contact_record = null;
     $failed = false;
     $parms = null;
     if (x($_POST, 'dfrn_url')) {
         /**
          * Block friend request spam
          */
         if ($maxreq) {
             $r = q("SELECT * FROM `intro` WHERE `datetime` > '%s' AND `uid` = %d", dbesc(datetime_convert('UTC', 'UTC', 'now - 24 hours')), intval($uid));
             if (count($r) > $maxreq) {
                 notice(sprintf(t('%s has received too many connection requests today.'), $a->profile['name']) . EOL);
                 notice(t('Spam protection measures have been invoked.') . EOL);
                 notice(t('Friends are advised to please try again in 24 hours.') . EOL);
                 return;
             }
         }
         /**
          *
          * Cleanup old introductions that remain blocked. 
          * Also remove the contact record, but only if there is no existing relationship
          * Do not remove email contacts as these may be awaiting email verification
          */
         $r = q("SELECT `intro`.*, `intro`.`id` AS `iid`, `contact`.`id` AS `cid`, `contact`.`rel` \n\t\t\tFROM `intro` LEFT JOIN `contact` on `intro`.`contact-id` = `contact`.`id`\n\t\t\tWHERE `intro`.`blocked` = 1 AND `contact`.`self` = 0 \n\t\t\tAND `contact`.`network` != '%s'\n\t\t\tAND `intro`.`datetime` < UTC_TIMESTAMP() - INTERVAL 30 MINUTE ", dbesc(NETWORK_MAIL));
         if (count($r)) {
             foreach ($r as $rr) {
                 if (!$rr['rel']) {
                     q("DELETE FROM `contact` WHERE `id` = %d LIMIT 1", intval($rr['cid']));
                 }
                 q("DELETE FROM `intro` WHERE `id` = %d LIMIT 1", intval($rr['iid']));
             }
         }
         /**
          *
          * Cleanup any old email intros - which will have a greater lifetime
          */
         $r = q("SELECT `intro`.*, `intro`.`id` AS `iid`, `contact`.`id` AS `cid`, `contact`.`rel` \n\t\t\tFROM `intro` LEFT JOIN `contact` on `intro`.`contact-id` = `contact`.`id`\n\t\t\tWHERE `intro`.`blocked` = 1 AND `contact`.`self` = 0 \n\t\t\tAND `contact`.`network` = '%s'\n\t\t\tAND `intro`.`datetime` < UTC_TIMESTAMP() - INTERVAL 3 DAY ", dbesc(NETWORK_MAIL));
         if (count($r)) {
             foreach ($r as $rr) {
                 if (!$rr['rel']) {
                     q("DELETE FROM `contact` WHERE `id` = %d LIMIT 1", intval($rr['cid']));
                 }
                 q("DELETE FROM `intro` WHERE `id` = %d LIMIT 1", intval($rr['iid']));
             }
         }
         $url = trim($_POST['dfrn_url']);
         if (!strlen($url)) {
             notice(t("Invalid locator") . EOL);
             return;
         }
         // Canonicalise email-style profile locator
         $hcard = '';
         $url = webfinger_dfrn($url, $hcard);
         if (substr($url, 0, 5) === 'stat:') {
             $network = NETWORK_OSTATUS;
             $url = substr($url, 5);
         } else {
             $network = NETWORK_DFRN;
         }
         logger('dfrn_request: url: ' . $url);
         if (!strlen($url)) {
             notice(t("Unable to resolve your name at the provided location.") . EOL);
             return;
         }
         if ($network === NETWORK_DFRN) {
             $ret = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `self` = 0 LIMIT 1", intval($uid), dbesc($url));
             if (count($ret)) {
                 if (strlen($ret[0]['issued-id'])) {
                     notice(t('You have already introduced yourself here.') . EOL);
                     return;
                 } elseif ($ret[0]['rel'] == CONTACT_IS_FRIEND) {
                     notice(sprintf(t('Apparently you are already friends with %s.'), $a->profile['name']) . EOL);
                     return;
                 } else {
                     $contact_record = $ret[0];
                     $parms = array('dfrn-request' => $ret[0]['request']);
                 }
             }
             $issued_id = random_string();
             if (is_array($contact_record)) {
                 // There is a contact record but no issued-id, so this
                 // is a reciprocal introduction from a known contact
                 $r = q("UPDATE `contact` SET `issued-id` = '%s' WHERE `id` = %d LIMIT 1", dbesc($issued_id), intval($contact_record['id']));
             } else {
                 if (!validate_url($url)) {
                     notice(t('Invalid profile URL.') . EOL);
                     goaway($a->get_baseurl() . '/' . $a->cmd);
                     return;
                     // NOTREACHED
                 }
                 if (!allowed_url($url)) {
                     notice(t('Disallowed profile URL.') . EOL);
                     goaway($a->get_baseurl() . '/' . $a->cmd);
                     return;
                     // NOTREACHED
                 }
                 require_once 'Scrape.php';
                 $parms = scrape_dfrn($hcard ? $hcard : $url);
                 if (!count($parms)) {
                     notice(t('Profile location is not valid or does not contain profile information.') . EOL);
                     goaway($a->get_baseurl() . '/' . $a->cmd);
                 } else {
                     if (!x($parms, 'fn')) {
                         notice(t('Warning: profile location has no identifiable owner name.') . EOL);
                     }
                     if (!x($parms, 'photo')) {
                         notice(t('Warning: profile location has no profile photo.') . EOL);
                     }
                     $invalid = validate_dfrn($parms);
                     if ($invalid) {
                         notice(sprintf(tt("%d required parameter was not found at the given location", "%d required parameters were not found at the given location", $invalid), $invalid) . EOL);
                         return;
                     }
                 }
                 $parms['url'] = $url;
                 $parms['issued-id'] = $issued_id;
                 dbesc_array($parms);
                 $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`,`name`, `nick`, `issued-id`, `photo`, `site-pubkey`,\n\t\t\t\t\t`request`, `confirm`, `notify`, `poll`, `poco`, `network` )\n\t\t\t\t\tVALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )", intval($uid), dbesc(datetime_convert()), $parms['url'], dbesc(normalise_link($parms['url'])), $parms['fn'], $parms['nick'], $parms['issued-id'], $parms['photo'], $parms['key'], $parms['dfrn-request'], $parms['dfrn-confirm'], $parms['dfrn-notify'], $parms['dfrn-poll'], $parms['dfrn-poco'], dbesc(NETWORK_DFRN));
                 // find the contact record we just created
                 if ($r) {
                     $r = q("SELECT `id` FROM `contact` \n\t\t\t\t\t\tWHERE `uid` = %d AND `url` = '%s' AND `issued-id` = '%s' LIMIT 1", intval($uid), $parms['url'], $parms['issued-id']);
                     if (count($r)) {
                         $contact_record = $r[0];
                     }
                 }
             }
             if ($r === false) {
                 notice(t('Failed to update contact record.') . EOL);
                 return;
             }
             $hash = random_string() . (string) time();
             // Generate a confirm_key
             if (is_array($contact_record)) {
                 $ret = q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime`)\n\t\t\t\t\tVALUES ( %d, %d, 1, %d, '%s', '%s', '%s' )", intval($uid), intval($contact_record['id']), x($_POST, 'knowyou') && $_POST['knowyou'] == 1 ? 1 : 0, dbesc(notags(trim($_POST['dfrn-request-message']))), dbesc($hash), dbesc(datetime_convert()));
             }
             // This notice will only be seen by the requestor if the requestor and requestee are on the same server.
             if (!$failed) {
                 info(t('Your introduction has been sent.') . EOL);
             }
             // "Homecoming" - send the requestor back to their site to record the introduction.
             $dfrn_url = bin2hex($a->get_baseurl() . '/profile/' . $nickname);
             $aes_allow = function_exists('openssl_encrypt') ? 1 : 0;
             goaway($parms['dfrn-request'] . "?dfrn_url={$dfrn_url}" . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . '&confirm_key=' . $hash . ($aes_allow ? "&aes_allow=1" : ""));
             // NOTREACHED
             // END $network === NETWORK_DFRN
         } elseif ($network === NETWORK_OSTATUS) {
             /**
              *
              * OStatus network
              * Check contact existence
              * Try and scrape together enough information to create a contact record, 
              * with us as CONTACT_IS_FOLLOWER
              * Substitute our user's feed URL into $url template
              * Send the subscriber home to subscribe
              *
              */
             $url = str_replace('{uri}', $a->get_baseurl() . '/dfrn_poll/' . $nickname, $url);
             goaway($url);
             // NOTREACHED
             // END $network === NETWORK_OSTATUS
         }
     }
     return;
 }
コード例 #4
0
ファイル: submit.php プロジェクト: rabuzarus/dir
function run_submit($url)
{
    global $a;
    if (!strlen($url)) {
        return false;
    }
    logger('Updating: ' . $url);
    //First run a notice script for the site it is hosted on.
    $site_health = notice_site($url, true);
    $submit_start = microtime(true);
    $nurl = str_replace(array('https:', '//www.'), array('http:', '//'), $url);
    $profile_exists = false;
    $r = q("SELECT * FROM `profile` WHERE ( `homepage` = '%s' OR `nurl` = '%s' )", dbesc($url), dbesc($nurl));
    if (count($r)) {
        $profile_exists = true;
        $profile_id = $r[0]['id'];
    }
    //Remove duplicates.
    if (count($r) > 1) {
        for ($i = 1; $i < count($r); $i++) {
            logger('Removed duplicate profile ' . intval($r[$i]['id']));
            q("DELETE FROM `photo` WHERE `profile-id` = %d LIMIT 1", intval($r[$i]['id']));
            q("DELETE FROM `profile` WHERE `id` = %d LIMIT 1", intval($r[$i]['id']));
        }
    }
    require_once 'Scrape.php';
    //Skip the scrape? :D
    $noscrape = $site_health && $site_health['no_scrape_url'];
    if ($noscrape) {
        //Find out who to look up.
        $which = str_replace($site_health['base_url'], '', $url);
        $noscrape = preg_match('~/profile/([^/]+)~', $which, $matches) === 1;
        //If that did not fail...
        if ($noscrape) {
            $parms = noscrape_dfrn($site_health['no_scrape_url'] . '/' . $matches[1]);
            $noscrape = !!$parms;
            //If the result was false, do a scrape after all.
        }
    }
    if (!$noscrape) {
        $parms = scrape_dfrn($url);
    }
    //Empty result is due to an offline site.
    if (!count($parms)) {
        //For large sites this could lower the health too quickly, so don't track health.
        //But for sites that are already in bad status. Do a cleanup now.
        if ($profile_exists && $site_health['health_score'] < $a->config['maintenance']['remove_profile_health_threshold']) {
            logger('Nuked bad health record.');
            nuke_record($url);
        }
        return false;
    } elseif ($parms['explicit-hide'] && $profile_exists) {
        logger('User opted out of the directory.');
        nuke_record($url);
        return true;
        //This is a good update.
    } elseif (validate_dfrn($parms)) {
        return false;
    }
    if (x($parms, 'hide') || !x($parms, 'fn') && x($parms, 'photo')) {
        if ($profile_exists) {
            nuke_record($url);
        }
        return true;
        //This is a good update.
    }
    $photo = $parms['photo'];
    dbesc_array($parms);
    if (x($parms, 'comm')) {
        $parms['comm'] = intval($parms['comm']);
    }
    if ($profile_exists) {
        $r = q("UPDATE `profile` SET \n\t\t\t`name` = '%s', \n\t\t\t`pdesc` = '%s',\n\t\t\t`locality` = '%s', \n\t\t\t`region` = '%s', \n\t\t\t`postal-code` = '%s', \n\t\t\t`country-name` = '%s', \n\t\t\t`gender` = '%s', \n\t\t\t`marital` = '%s', \n\t\t\t`homepage` = '%s',\n\t\t\t`nurl` = '%s',\n\t\t\t`comm` = %d,\n\t\t\t`tags` = '%s',\n\t\t\t`updated` = '%s' \n\t\t\tWHERE `id` = %d LIMIT 1", $parms['fn'], $parms['pdesc'], $parms['locality'], $parms['region'], $parms['postal-code'], $parms['country-name'], $parms['gender'], $parms['marital'], dbesc($url), dbesc($nurl), intval($parms['comm']), $parms['tags'], dbesc(datetime_convert()), intval($profile_id));
        logger('Update returns: ' . $r);
    } else {
        $r = q("INSERT INTO `profile` ( `name`, `pdesc`, `locality`, `region`, `postal-code`, `country-name`, `gender`, `marital`, `homepage`, `nurl`, `comm`, `tags`, `created`, `updated` )\n\t\t\tVALUES ( '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s' )", $parms['fn'], $parms['pdesc'], $parms['locality'], $parms['region'], $parms['postal-code'], $parms['country-name'], $parms['gender'], $parms['marital'], dbesc($url), dbesc($nurl), intval($parms['comm']), $parms['tags'], dbesc(datetime_convert()), dbesc(datetime_convert()));
        logger('Insert returns: ' . $r);
        $r = q("SELECT `id` FROM `profile` WHERE ( `homepage` = '%s' or `nurl` = '%s' ) order by id asc", dbesc($url), dbesc($nurl));
        if (count($r)) {
            $profile_id = $r[count($r) - 1]['id'];
        }
        if (count($r) > 1) {
            q("DELETE FROM `photo` WHERE `profile-id` = %d LIMIT 1", intval($r[0]['id']));
            q("DELETE FROM `profile` WHERE `id` = %d LIMIT 1", intval($r[0]['id']));
        }
    }
    if ($parms['tags']) {
        $arr = explode(' ', $parms['tags']);
        if (count($arr)) {
            foreach ($arr as $t) {
                $t = strip_tags(trim($t));
                $t = substr($t, 0, 254);
                if (strlen($t)) {
                    $r = q("SELECT `id` FROM `tag` WHERE `term` = '%s' and `nurl` = '%s' LIMIT 1", dbesc($t), dbesc($nurl));
                    if (!count($r)) {
                        $r = q("INSERT INTO `tag` (`term`, `nurl`) VALUES ('%s', '%s') ", dbesc($t), dbesc($nurl));
                    }
                }
            }
        }
    }
    $submit_photo_start = microtime(true);
    require_once "Photo.php";
    $photo_failure = false;
    $status = false;
    if ($profile_id) {
        $img_str = fetch_url($photo, true);
        $img = new Photo($img_str);
        if ($img) {
            $img->scaleImageSquare(80);
            $r = $img->store($profile_id);
        }
        $r = q("UPDATE `profile` SET `photo` = '%s' WHERE `id` = %d LIMIT 1", dbesc($a->get_baseurl() . '/photo/' . $profile_id . '.jpg'), intval($profile_id));
        $status = true;
    } else {
        nuke_record($url);
        return false;
    }
    $submit_end = microtime(true);
    $photo_time = round(($submit_end - $submit_photo_start) * 1000);
    $time = round(($submit_end - $submit_start) * 1000);
    //Record the scrape speed in a scrapes table.
    if ($site_health && $status) {
        q("INSERT INTO `site-scrape` (`site_health_id`, `dt_performed`, `request_time`, `scrape_time`, `photo_time`, `total_time`)" . "VALUES (%u, NOW(), %u, %u, %u, %u)", $site_health['id'], $parms['_timings']['fetch'], $parms['_timings']['scrape'], $photo_time, $time);
    }
    return $status;
}