aboutsummaryrefslogtreecommitdiffstats
path: root/include/network.php
diff options
context:
space:
mode:
Diffstat (limited to 'include/network.php')
-rw-r--r--include/network.php851
1 files changed, 187 insertions, 664 deletions
diff --git a/include/network.php b/include/network.php
index c03ca70f5..5f814ef32 100644
--- a/include/network.php
+++ b/include/network.php
@@ -343,7 +343,7 @@ function z_post_url($url,$params, $redirects = 0, $opts = array()) {
if (isset($url_parsed)) {
curl_close($ch);
if($http_code == 303) {
- return z_fetch_url($newurl,false,$redirects++,$opts);
+ return z_fetch_url($newurl,false,++$redirects,$opts);
} else {
return z_post_url($newurl,$params,++$redirects,$opts);
}
@@ -397,31 +397,6 @@ function json_return_and_die($x, $content_type = 'application/json') {
killme();
}
-
-/**
- * @brief Generic XML return.
- *
- * Outputs a basic dfrn XML status structure to STDOUT, with a <status> variable
- * of $st and an optional text <message> of $message and terminates the current
- * process.
- *
- * @param string $st
- * @param string $message
- */
-function xml_status($st, $message = '') {
-
- $xml_message = ((strlen($message)) ? "\t<message>" . xmlify($message) . "</message>\r\n" : '');
-
- if($st)
- logger('Returning non_zero: ' . $st . " message=" . $message);
-
- header( "Content-type: text/xml" );
- echo '<?xml version="1.0" encoding="UTF-8"?>'."\r\n";
- echo "<result>\r\n\t<status>$st</status>\r\n$xml_message</result>\r\n";
- killme();
-}
-
-
/**
* @brief Send HTTP status header.
*
@@ -696,11 +671,12 @@ function parse_xml_string($s,$strict = true) {
libxml_use_internal_errors(true);
$x = @simplexml_load_string($s2);
- if(! $x) {
+ if($x === false) {
logger('libxml: parse: error: ' . $s2, LOGGER_DATA);
- foreach(libxml_get_errors() as $err)
- logger('libxml: parse: ' . $err->code." at ".$err->line.":".$err->column." : ".$err->message, LOGGER_DATA);
-
+ foreach(libxml_get_errors() as $err) {
+ logger('libxml: parse: ' . $err->code . ' at ' . $err->line
+ . ':' . $err->column . ' : ' . $err->message, LOGGER_DATA);
+ }
libxml_clear_errors();
}
@@ -1007,39 +983,6 @@ function email_header_encode($in_str, $charset = 'UTF-8') {
return $out_str;
}
-function email_send($addr, $subject, $headers, $item) {
- //$headers .= 'MIME-Version: 1.0' . "\n";
- //$headers .= 'Content-Type: text/html; charset=UTF-8' . "\n";
- //$headers .= 'Content-Type: text/plain; charset=UTF-8' . "\n";
- //$headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n";
-
- $part = uniqid("", true);
-
- $html = prepare_body($item);
-
- $headers .= "Mime-Version: 1.0\n";
- $headers .= 'Content-Type: multipart/alternative; boundary="=_'.$part.'"'."\n\n";
-
- $body = "\n--=_".$part."\n";
- $body .= "Content-Transfer-Encoding: 8bit\n";
- $body .= "Content-Type: text/plain; charset=utf-8; format=flowed\n\n";
-
- $body .= html2plain($html)."\n";
-
- $body .= "--=_".$part."\n";
- $body .= "Content-Transfer-Encoding: 8bit\n";
- $body .= "Content-Type: text/html; charset=utf-8\n\n";
-
- $body .= '<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">'.$html."</body></html>\n";
-
- $body .= "--=_".$part."--";
-
- //$message = '<html><body>' . $html . '</body></html>';
- //$message = html2plain($html);
- logger('notifier: email delivery to ' . $addr);
- mail($addr, $subject, $body, $headers);
-}
-
/**
* @brief Creates an xchan entry for URL.
*
@@ -1056,10 +999,10 @@ function discover_by_url($url, $arr = null) {
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;
+ $name = (($arr['name']) ? $arr['name'] : 'unknown');
+ $photo = (($arr['photo']) ? $arr['photo'] : '');
+ $addr = (($arr['addr']) ? $arr['addr'] : '');
+ $guid = $url;
}
$profile = $url;
@@ -1095,8 +1038,8 @@ function discover_by_url($url, $arr = null) {
if($feed->error())
logger('scrape_feed: Error parsing XML: ' . $feed->error());
- $name = unxmlify(trim($feed->get_title()));
- $photo = $feed->get_image_url();
+ $name = unxmlify(trim($feed->get_title()));
+ $photo = $feed->get_image_url();
$author = $feed->get_author();
if($author) {
@@ -1195,23 +1138,11 @@ function discover_by_url($url, $arr = null) {
}
function discover_by_webbie($webbie) {
- require_once('library/HTML5/Parser.php');
- $result = array();
+ $result = [];
$network = null;
- $diaspora = false;
- $gnusoc = false;
- $dfrn = false;
-
- $has_salmon = false;
- $salmon_key = false;
- $atom_feed = false;
- $diaspora_base = '';
- $diaspora_guid = '';
- $diaspora_key = '';
-
$webbie = strtolower($webbie);
$x = webfinger_rfc7033($webbie,true);
@@ -1237,21 +1168,6 @@ function discover_by_webbie($webbie) {
}
}
}
- if($link['rel'] == NAMESPACE_DFRN) {
- $dfrn = $link['href'];
- }
- if($link['rel'] == 'magic-public-key') {
- if(substr($link['href'],0,5) === 'data:') {
- $salmon_key = convert_salmon_key($link['href']);
- }
- }
- if($link['rel'] == 'salmon') {
- $has_salmon = true;
- $salmon = $link['href'];
- }
- if($link['rel'] == 'http://schemas.google.com/g/2010#updates-from') {
- $atom_feed = $link['href'];
- }
}
}
}
@@ -1263,275 +1179,9 @@ function discover_by_webbie($webbie) {
if($arr['success'])
return true;
- $aliases = array();
-
- // Now let's make some decisions on what we may need
- // to obtain further info
-
- $probe_atom = false;
- $probe_old = false;
- $probe_hcard = false;
-
- $address = '';
- $location = '';
- $nickname = '';
- $fullname = '';
- $avatar = '';
- $pubkey = '';
-
- if(is_array($x)) {
- if(array_key_exists('address',$x))
- $address = $x['address'];
- if(array_key_exists('location',$x))
- $location = $x['location'];
- if(array_key_exists('nickname',$x))
- $nickname = $x['nickname'];
- }
-
- if(! $x)
- $probe_old = true;
-
- if((! $dfrn) && (! $has_salmon))
- $probe_old = true;
-
- if($probe_old) {
- $y = old_webfinger($webbie);
- if($y) {
- logger('old_webfinger: ' . print_r($x,true));
- foreach($y as $link) {
- 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'] == 'magic-public-key') {
- if(substr($link['@attributes']['href'],0,5) === 'data:') {
- $salmon_key = convert_salmon_key($link['@attributes']['href']);
- }
- }
- if($link['@attributes']['rel'] == 'salmon') {
- $has_salmon = true;
- $salmon = $link['@attributes']['href'];
- }
-
- if($link['@attributes']['rel'] == 'http://schemas.google.com/g/2010#updates-from') {
- $atom_feed = $link['@attributes']['href'];
- }
- if($link['@attributes']['rel'] === 'alias') {
- $aliases[] = $link['@attributes']['href'];
- }
- if($link['@attributes']['rel'] === 'subject') {
- $subject = $link['@attributes']['href'];
- }
- }
- }
- }
-
- if($subject || $aliases) {
- if(strpos($webbie,'@')) {
- $rhs = substr($webbie,strpos($webbie,'@')+1);
- }
- else {
- $m = parse_url($webbie);
- if($m) {
- $rhs = $m['host'] . (($m['port']) ? ':' . $m['port'] : '');
- }
- }
-
- $v = array('subject' => $subject,'aliases' => $aliases);
- $address = find_webfinger_address($v,$rhs);
- $location = find_webfinger_location($v,$rhs);
- if($address)
- $nickname = substr($address,0,strpos($address,'@'));
- }
-
- if($salmon_key && $has_salmon && $atom_feed && (! $dfrn) && (! $diaspora)) {
- $gnusoc = true;
- $probe_atom = true;
- }
-
- if(! $pubkey)
- $pubkey = $salmon_key;
-
- if(($dfrn || $diaspora) && $hcard)
- $probe_hcard = true;
-
- if(! $fullname)
- $fullname = $nickname;
-
- if($probe_atom) {
- $k = z_fetch_url($atom_feed);
- if($k['success'])
- $feed_meta = feed_meta($k['body']);
- if($feed_meta) {
-
- // stash any discovered pubsubhubbub hubs in case we need to follow them
- // this will save an expensive lookup later
-
- if($feed_meta['hubs'] && $address) {
- set_xconfig($address,'system','push_hubs',$feed_meta['hubs']);
- set_xconfig($address,'system','feed_url',$atom_feed);
- }
- if($feed_meta['author']['author_name']) {
- $fullname = $feed_meta['author']['author_name'];
- }
- if(! $avatar) {
- if($feed_meta['author']['author_photo'])
- $avatar = $feed_meta['author']['author_photo'];
- }
-
- // for GNU-social over-ride any url aliases we may have picked up in webfinger
- // The author.uri element in the feed is likely to be more accurate
-
- if($gnusoc && $feed_meta['author']['author_uri'])
- $location = $feed_meta['author']['author_uri'];
- }
- }
- else {
- if($probe_hcard) {
- $vcard = scrape_vcard($hcard);
- if($vcard) {
- logger('vcard: ' . print_r($vcard,true), LOGGER_DATA);
- if($vcard['fn'])
- $fullname = $vcard['fn'];
- if($vcard['photo'] && (strpos($vcard['photo'],'http') !== 0))
- $vcard['photo'] = $diaspora_base . '/' . $vcard['photo'];
- if(($vcard['public_key']) && (! $pubkey)) {
- $diaspora_key = $vcard['public_key'];
- if(strstr($diaspora_key,'RSA '))
- $pubkey = rsatopem($diaspora_key);
- else
- $pubkey = $diaspora_key;
- }
- if(! $avatar)
- $avatar = $vcard['photo'];
- if($diaspora) {
- if(($vcard['uid']) && (! $diaspora_guid))
- $diaspora_guid = $vcard['uid'];
- if(($vcard['url']) && (! $diaspora_base))
- $diaspora_base = $vcard['url'];
- }
- }
- }
- }
-
- if(($profile) && (! $location))
- $location = $profile;
-
- if($location) {
- $m = parse_url($location);
- $base = $m['scheme'] . '://' . $m['host'];
- $host = $m['host'];
- }
-
- if($diaspora && $diaspora_base && $diaspora_guid) {
- if($dfrn)
- $network = 'friendica-over-diaspora';
- else
- $network = 'diaspora';
-
- $base = trim($diaspora_base, '/');
- $notify = $base . '/receive';
- }
- else {
- if($gnusoc) {
- $network = 'gnusoc';
- $notify = $salmon;
- }
- }
-
- logger('network: ' . $network);
- logger('address: ' . $address);
- logger('fullname: ' . $fullname);
- logger('pubkey: ' . $pubkey);
- logger('location: ' . $location);
-
- // if we have everything we need, let's create the records
-
- if($network && $address && $fullname && $pubkey && $location) {
- $r = q("select * from xchan where xchan_hash = '%s' limit 1",
- dbesc($address)
- );
- if($r) {
- $r = q("update xchan set xchan_name = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s'",
- dbesc($fullname),
- dbesc($network),
- dbesc(datetime_convert()),
- dbesc($address)
- );
- }
- else {
- $r = xchan_store_lowlevel(
- [
- 'xchan_hash' => $address,
- 'xchan_guid' => (($diaspora_guid) ? $diaspora_guid : $location),
- 'xchan_pubkey' => $pubkey,
- 'xchan_addr' => $address,
- 'xchan_url' => $location,
- 'xchan_name' => $fullname,
- 'xchan_name_date' => datetime_convert(),
- 'xchan_network' => $network
- ]
- );
- }
-
- $r = q("select * from hubloc where hubloc_hash = '%s' limit 1",
- dbesc($address)
- );
-
- if(! $r) {
- $r = hubloc_store_lowlevel(
- [
- 'hubloc_guid' => (($diaspora_guid) ? $diaspora_guid : $location),
- 'hubloc_hash' => $address,
- 'hubloc_addr' => $address,
- 'hubloc_network' => $network,
- 'hubloc_url' => $base,
- 'hubloc_host' => $host,
- 'hubloc_callback' => $notify,
- 'hubloc_updated' => datetime_convert(),
- 'hubloc_primary' => 1
- ]
- );
- }
- $photos = import_xchan_photo($avatar,$address);
- $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'",
- dbescdate(datetime_convert()),
- dbesc($photos[0]),
- dbesc($photos[1]),
- dbesc($photos[2]),
- dbesc($photos[3]),
- dbesc($address)
- );
- return true;
- }
return false;
-}
-
+}
function webfinger_rfc7033($webbie,$zot = false) {
@@ -1557,105 +1207,22 @@ function webfinger_rfc7033($webbie,$zot = false) {
// and results in a 406 (Not Acceptable) response, and will also incorrectly produce an XML
// document if you use 'application/jrd+json, */*'. We could set this to application/jrd+json,
// but some test webfinger servers may not explicitly set the content type and they would be
- // blocked. The best compromise until Mastodon is fixed is to remove the Accept header which is
- // accomplished by setting it to nothing.
+ // blocked. The best compromise until Mastodon is fixed is to remove the Accept header which is
+ // accomplished by setting it to nothing.
$counter = 0;
- $s = z_fetch_url('https://' . $rhs . '/.well-known/webfinger?f=&resource=' . $resource . (($zot) ? '&zot=1' : ''),
+ $s = z_fetch_url('https://' . $rhs . '/.well-known/webfinger?f=&resource=' . $resource . (($zot) ? '&zot=1' : ''),
false, $counter, [ 'headers' => [ 'Accept:' ] ]);
if($s['success']) {
$j = json_decode($s['body'],true);
-
- // We could have a number of URL aliases and webbies
- // make an executive decision about the most likely "best" of each
- // by comparing against some examples from known networks we're likely to encounter.
- // Otherwise we have to store every alias that we may ever encounter and
- // validate every URL we ever find against every possible alias
-
- /**
- * @FIXME pump.io is going to be a real bugger since it doesn't return
- * subject or aliases or provide lookup by url
- */
-
- $j['address'] = find_webfinger_address($j,$rhs);
- $j['location'] = find_webfinger_location($j,$rhs);
- if($j['address'])
- $j['nickname'] = substr($j['address'],0,strpos($j['address'],'@'));
- }
- else
- return false;
-
- return($j);
-}
-
-function find_webfinger_address($j,$rhs) {
- if(is_array($j) && ($j)) {
- if(strpos($j['subject'],'acct:') !== false && strpos($j['subject'],'@' . $rhs))
- return str_replace('acct:','',$j['subject']);
- if($j['aliases']) {
- foreach($j['aliases'] as $alias) {
- if(strpos($alias,'acct:') !== false && strpos($alias,'@' . $rhs)) {
- return str_replace('acct:','',$alias);
- }
- }
- }
+ return($j);
}
- return '';
-}
-
-function find_webfinger_location($j,$rhs) {
- if(is_array($j) && ($j)) {
- if(strpos($j['subject'],'http') === 0) {
- $x = match_webfinger_location($j['subject'],$rhs);
- if($x)
- return $x;
- }
- if($j['aliases']) {
- foreach($j['aliases'] as $alias) {
- if(strpos($alias,'http') === 0) {
- $x = match_webfinger_location($alias,$rhs);
- if($x)
- return($x);
- }
- }
- }
- }
- return '';
-}
-
-/**
- * @brief Match the webfinger location for the different networks.
- *
- * @param string $s The string to search in
- * @param string $h The host
- * @return string
- */
-function match_webfinger_location($s, $h) {
-
- // GNU-social and the older StatusNet - the $host/user/123 form doesn't work
- if(preg_match('|' . $h . '/index.php/user/([0-9]*?)$|', $s))
- return $s;
- // Redmatrix / hubzilla
- if(preg_match('|' . $h . '/channel/|', $s))
- return $s;
- // Friendica
- if(preg_match('|' . $h . '/profile/|', $s))
- return $s;
-
- $arr = array('test' => $s, 'host' => $h, 'success' => false);
- call_hooks('match_webfinger_location', $arr);
- if($arr['success'])
- return $s;
+ return false;
- return '';
}
-
-
-
-
function old_webfinger($webbie) {
$host = '';
@@ -1723,9 +1290,6 @@ function fetch_xrd_links($url) {
if ((! $xml) || (! stristr($xml,'<xrd')))
return array();
- // fix diaspora's bad xml
- $xml = str_replace(array('href=&quot;','&quot;/>'),array('href="','"/>'),$xml);
-
$h = parse_xml_string($xml);
if(! $h)
return array();
@@ -1765,89 +1329,13 @@ function fetch_xrd_links($url) {
}
-function scrape_vcard($url) {
-
- $ret = array();
-
- logger('url=' . $url);
-
- $x = z_fetch_url($url);
- if(! $x['success'])
- return $ret;
-
- $s = $x['body'];
-
- if(! $s)
- return $ret;
-
- $headers = $x['header'];
- $lines = explode("\n",$headers);
- if(count($lines)) {
- foreach($lines as $line) {
- // don't try and run feeds through the html5 parser
- if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
- return ret;
- }
- }
-
- try {
- $dom = HTML5_Parser::parse($s);
- } catch (DOMException $e) {
- logger('Parse error: ' . $e);
- }
-
- if(! $dom)
- return $ret;
-
- // Pull out hCard profile elements
-
- $largest_photo = 0;
-
- $items = $dom->getElementsByTagName('*');
- foreach($items as $item) {
- if(attribute_contains($item->getAttribute('class'), 'vcard')) {
- $level2 = $item->getElementsByTagName('*');
- foreach($level2 as $x) {
- if(attribute_contains($x->getAttribute('id'),'pod_location'))
- $ret['pod_location'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'fn'))
- $ret['fn'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'uid'))
- $ret['uid'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'nickname'))
- $ret['nick'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'searchable'))
- $ret['searchable'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'key'))
- $ret['public_key'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'given_name'))
- $ret['given_name'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'family_name'))
- $ret['family_name'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'url'))
- $ret['url'] = $x->textContent;
-
- if((attribute_contains($x->getAttribute('class'),'photo'))
- || (attribute_contains($x->getAttribute('class'),'avatar'))) {
- $size = intval($x->getAttribute('width'));
- if(($size > $largest_photo) || (! $largest_photo)) {
- $ret['photo'] = $x->getAttribute('src');
- $largest_photo = $size;
- }
- }
- }
- }
- }
-
- return $ret;
-}
-
/**
* @brief
*
* @param string $url The URL to scrape
* @return array
*/
+
function scrape_feed($url) {
require_once('library/HTML5/Parser.php');
@@ -1941,112 +1429,6 @@ function scrape_feed($url) {
-function service_plink($contact, $guid) {
-
- $plink = '';
-
- $m = parse_url($contact['xchan_url']);
- if($m) {
- $url = $m['scheme'] . '://' . $m['host'] . (($m['port']) ? ':' . $m['port'] : '');
- }
- else
- $url = 'https://' . substr($contact['xchan_addr'],strpos($contact['xchan_addr'],'@')+1);
-
- $handle = substr($contact['xchan_addr'], 0, strpos($contact['xchan_addr'],'@'));
-
- if($contact['xchan_network'] === 'diaspora')
- $plink = $url . '/posts/' . $guid;
- if($contact['xchan_network'] === 'friendica-over-diaspora')
- $plink = $url . '/display/' . $handle . '/' . $guid;
- if($contact['xchan_network'] === 'zot')
- $plink = $url . '/channel/' . $handle . '?f=&mid=' . $guid;
-
- return $plink;
-}
-
-
-function format_and_send_email($sender,$xchan,$item) {
-
- $title = $item['title'];
- $body = $item['body'];
-
- $textversion = strip_tags(html_entity_decode(bbcode(str_replace(array("\\r", "\\n"), array( "", "\n"), $body)),ENT_QUOTES,'UTF-8'));
-
- $htmlversion = bbcode(str_replace(array("\\r","\\n"), array("","<br />\n"),$body));
-
- $banner = t('$Projectname Notification');
- $product = t('$projectname'); // PLATFORM_NAME;
- $siteurl = z_root();
- $thanks = t('Thank You,');
- $sitename = get_config('system', 'sitename');
- $site_admin = sprintf( t('%s Administrator'), $sitename);
-
- // load the template for private message notifications
- $tpl = get_markup_template('email_notify_html.tpl');
- $email_html_body = replace_macros($tpl, array(
- '$banner' => $banner,
- '$notify_icon' => Zotlabs\Lib\System::get_notify_icon(),
- '$product' => $product,
- '$preamble' => '',
- '$sitename' => $sitename,
- '$siteurl' => $siteurl,
- '$source_name' => $sender['xchan_name'],
- '$source_link' => $sender['xchan_url'],
- '$source_photo' => $sender['xchan_photo_m'],
- '$username' => $xchan['xchan_name'],
- '$hsitelink' => $datarray['hsitelink'], /// @FIXME $datarray is undefined
- '$hitemlink' => $datarray['hitemlink'], /// @FIXME $datarray is undefined
- '$thanks' => $thanks,
- '$site_admin' => $site_admin,
- '$title' => $title,
- '$htmlversion' => $htmlversion,
- ));
-
- // load the template for private message notifications
- $tpl = get_markup_template('email_notify_text.tpl');
- $email_text_body = replace_macros($tpl, array(
- '$banner' => $banner,
- '$product' => $product,
- '$preamble' => '',
- '$sitename' => $sitename,
- '$siteurl' => $siteurl,
- '$source_name' => $sender['xchan_name'],
- '$source_link' => $sender['xchan_url'],
- '$source_photo' => $sender['xchan_photo_m'],
- '$username' => $xchan['xchan_name'],
- '$hsitelink' => $datarray['hsitelink'],
- '$hitemlink' => $datarray['hitemlink'],
- '$thanks' => $thanks,
- '$site_admin' => $site_admin,
- '$title' => $title,
- '$textversion' => $textversion
- ));
-
- $sender_name = t('Administrator');
-
- $hostname = App::get_hostname();
- if(strpos($hostname, ':'))
- $hostname = substr($hostname,0,strpos($hostname,':'));
-
- $sender_email = get_config('system', 'reply_address');
- if(! $sender_email)
- $sender_email = 'noreply' . '@' . $hostname;
-
- // use the EmailNotification library to send the message
-
- Zotlabs\Lib\Enotify::send(array(
- 'fromName' => $product,
- 'fromEmail' => $sender_email,
- 'replyTo' => $sender_email,
- 'toEmail' => str_replace('mailto:','',$xchan['xchan_addr']),
- 'messageSubject' => (($title) ? $title : t('No Subject')),
- 'htmlVersion' => $email_html_body,
- 'textVersion' => $email_text_body,
- 'additionalMailHeader' => '',
- ));
-}
-
-
function do_delivery($deliveries) {
if(! (is_array($deliveries) && count($deliveries)))
@@ -2160,33 +1542,33 @@ function get_site_info() {
}
- $data = Array(
- 'version' => $version,
- 'version_tag' => $tag,
- 'server_role' => Zotlabs\Lib\System::get_server_role(),
- 'commit' => $commit,
- 'url' => z_root(),
- 'plugins' => $visible_plugins,
- 'register_policy' => $register_policy[get_config('system','register_policy')],
- 'invitation_only' => intval(get_config('system','invitation_only')),
- 'directory_mode' => $directory_mode[get_config('system','directory_mode')],
- 'language' => get_config('system','language'),
- 'rss_connections' => intval(get_config('system','feed_contacts')),
- 'expiration' => $site_expire,
+ $data = [
+ 'url' => z_root(),
+ 'platform' => Zotlabs\Lib\System::get_platform_name(),
+ 'site_name' => (($site_name) ? $site_name : ''),
+ 'version' => $version,
+ 'version_tag' => $tag,
+ 'server_role' => Zotlabs\Lib\System::get_server_role(),
+ 'commit' => $commit,
+ 'plugins' => $visible_plugins,
+ 'register_policy' => $register_policy[get_config('system','register_policy')],
+ 'invitation_only' => intval(get_config('system','invitation_only')),
+ 'directory_mode' => $directory_mode[get_config('system','directory_mode')],
+ 'language' => get_config('system','language'),
+ 'rss_connections' => intval(get_config('system','feed_contacts')),
+ 'expiration' => $site_expire,
'default_service_restrictions' => $service_class,
- 'locked_features' => $locked_features,
- 'admin' => $admin,
- 'site_name' => (($site_name) ? $site_name : ''),
- 'platform' => Zotlabs\Lib\System::get_platform_name(),
- 'dbdriver' => DBA::$dba->getdriver(),
- 'lastpoll' => get_config('system','lastpoll'),
- 'info' => (($site_info) ? $site_info : ''),
- 'channels_total' => $channels_total_stat,
- 'channels_active_halfyear' => $channels_active_halfyear_stat,
- 'channels_active_monthly' => $channels_active_monthly_stat,
- 'local_posts' => $local_posts_stat,
- 'hide_in_statistics' => $hide_in_statistics
- );
+ 'locked_features' => $locked_features,
+ 'admin' => $admin,
+ 'dbdriver' => DBA::$dba->getdriver(),
+ 'lastpoll' => get_config('system','lastpoll'),
+ 'info' => (($site_info) ? $site_info : ''),
+ 'channels_total' => $channels_total_stat,
+ 'channels_active_halfyear' => $channels_active_halfyear_stat,
+ 'channels_active_monthly' => $channels_active_monthly_stat,
+ 'local_posts' => $local_posts_stat,
+ 'hide_in_statistics' => $hide_in_statistics
+ ];
return $data;
}
@@ -2412,3 +1794,144 @@ function probe_api_path($host) {
return '';
}
+
+
+function scrape_vcard($url) {
+
+ require_once('library/HTML5/Parser.php');
+
+ $ret = array();
+
+ logger('url=' . $url);
+
+ $x = z_fetch_url($url);
+ if(! $x['success'])
+ return $ret;
+
+ $s = $x['body'];
+
+ if(! $s)
+ return $ret;
+
+ $headers = $x['header'];
+ $lines = explode("\n",$headers);
+ if(count($lines)) {
+ foreach($lines as $line) {
+ // don't try and run feeds through the html5 parser
+ if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
+ return ret;
+ }
+ }
+
+ try {
+ $dom = HTML5_Parser::parse($s);
+ } catch (DOMException $e) {
+ logger('Parse error: ' . $e);
+ }
+
+ if(! $dom)
+ return $ret;
+
+ // Pull out hCard profile elements
+
+ $largest_photo = 0;
+
+ $items = $dom->getElementsByTagName('*');
+ foreach($items as $item) {
+ if(attribute_contains($item->getAttribute('class'), 'vcard')) {
+ $level2 = $item->getElementsByTagName('*');
+ foreach($level2 as $x) {
+ if(attribute_contains($x->getAttribute('id'),'pod_location'))
+ $ret['pod_location'] = $x->textContent;
+ if(attribute_contains($x->getAttribute('class'),'fn'))
+ $ret['fn'] = $x->textContent;
+ if(attribute_contains($x->getAttribute('class'),'uid'))
+ $ret['uid'] = $x->textContent;
+ if(attribute_contains($x->getAttribute('class'),'nickname'))
+ $ret['nick'] = $x->textContent;
+ if(attribute_contains($x->getAttribute('class'),'searchable'))
+ $ret['searchable'] = $x->textContent;
+ if(attribute_contains($x->getAttribute('class'),'key'))
+ $ret['public_key'] = $x->textContent;
+ if(attribute_contains($x->getAttribute('class'),'given_name'))
+ $ret['given_name'] = $x->textContent;
+ if(attribute_contains($x->getAttribute('class'),'family_name'))
+ $ret['family_name'] = $x->textContent;
+ if(attribute_contains($x->getAttribute('class'),'url'))
+ $ret['url'] = $x->textContent;
+
+ if((attribute_contains($x->getAttribute('class'),'photo'))
+ || (attribute_contains($x->getAttribute('class'),'avatar'))) {
+ $size = intval($x->getAttribute('width'));
+ if(($size > $largest_photo) || (! $largest_photo)) {
+ $ret['photo'] = $x->getAttribute('src');
+ $largest_photo = $size;
+ }
+ }
+ }
+ }
+ }
+
+ return $ret;
+}
+
+function service_plink($contact, $guid) {
+
+ $plink = '';
+
+ $m = parse_url($contact['xchan_url']);
+ if($m) {
+ $url = $m['scheme'] . '://' . $m['host'] . (($m['port']) ? ':' . $m['port'] : '');
+ }
+ else {
+ $url = 'https://' . substr($contact['xchan_addr'],strpos($contact['xchan_addr'],'@')+1);
+ }
+
+ $handle = substr($contact['xchan_addr'], 0, strpos($contact['xchan_addr'],'@'));
+
+ $plink = $url . '/channel/' . $handle . '?f=&mid=' . $guid;
+
+ $x = [ 'xchan' => $contact, 'guid' => $guid, 'url' => $url, 'plink' => $plink ];
+ call_hooks('service_plink', $x);
+
+ return $x['plink'];
+}
+
+function getBestSupportedMimeType($mimeTypes = null, $acceptedTypes = false) {
+ // Values will be stored in this array
+
+ if($acceptedTypes === false)
+ $acceptedTypes = $_SERVER['HTTP_ACCEPT'];
+
+ $AcceptTypes = Array ();
+
+ // Accept header is case insensitive, and whitespace isn’t important
+ $accept = strtolower(str_replace(' ', '', $acceptedTypes));
+ // divide it into parts in the place of a ","
+ $accept = explode(',', $accept);
+ foreach ($accept as $a) {
+ // the default quality is 1.
+ $q = 1;
+ // check if there is a different quality
+ if (strpos($a, ';q=')) {
+ // divide "mime/type;q=X" into two parts: "mime/type" i "X"
+ list($a, $q) = explode(';q=', $a);
+ }
+ // mime-type $a is accepted with the quality $q
+ // WARNING: $q == 0 means, that mime-type isn’t supported!
+ $AcceptTypes[$a] = $q;
+ }
+ arsort($AcceptTypes);
+
+ // if no parameter was passed, just return parsed data
+ if (!$mimeTypes) return $AcceptTypes;
+
+ $mimeTypes = array_map('strtolower', (array)$mimeTypes);
+
+ // let’s check our supported types:
+ foreach ($AcceptTypes as $mime => $q) {
+ if ($q && in_array($mime, $mimeTypes)) return $mime;
+ }
+ // no mime-type found
+ return null;
+} \ No newline at end of file