Merge remote-tracking branch 'upstream/master'

Conflicts:
	view/theme/redbasic/css/style.css
This commit is contained in:
Thomas Willingham 2013-03-14 22:50:30 +00:00
commit d07971b909
36 changed files with 5587 additions and 8167 deletions

View File

@ -17,7 +17,7 @@ require_once('include/features.php');
define ( 'FRIENDICA_PLATFORM', 'Friendica Red');
define ( 'FRIENDICA_VERSION', trim(file_get_contents('version.inc')) . 'R');
define ( 'ZOT_REVISION', 1 );
define ( 'DB_UPDATE_VERSION', 1034 );
define ( 'DB_UPDATE_VERSION', 1035 );
define ( 'EOL', '<br />' . "\r\n" );
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
@ -992,6 +992,18 @@ function check_config(&$a) {
if(! x($build))
$build = set_config('system','db_version',DB_UPDATE_VERSION);
$saved = get_config('system','urlverify');
if(! $saved)
set_config('system','urlverify',bin2hex(z_root()));
if(($saved) && ($saved != bin2hex(z_root()))) {
// our URL changed. Do something.
$oldurl = hex2bin($saved);
fix_system_urls($oldurl,z_root());
set_config('system','urlverify',bin2hex(z_root()));
}
// $url = get_config('system','baseurl');
// if the url isn't set or the stored url is radically different
@ -1130,6 +1142,53 @@ function check_config(&$a) {
function fix_system_urls($oldurl,$newurl) {
require_once('include/crypto.php');
// Basically a site rename, but this can happen if you change from http to https for instance - even if the site name didn't change
// This should fix URL changes on our site, but other sites will end up with orphan hublocs which they will try to contact and will
// cause wasted communications.
// What we need to do after fixing this up is to send a revocation of the old URL to every other site that we communicate with so
// that they can clean up their hubloc tables (this includes directories).
// It's a very expensive operation so you don't want to have to do it often or after your site gets to be large.
$r = q("select xchan_hash, channel_prvkey from xchan left join channel on channel_hash = xchan_hash where xchan_url = '%s'",
dbesc($oldurl)
);
if($r) {
foreach($r as $rr) {
$channel = substr($rr['xchan_addr'],0,strpos($rr['xchan_addr'],'@'));
$parsed = @parse_url($rr['xchan_url']);
if(! $parsed)
continue;
$newhost = $parsed['host'];
$rhs = $newhost . (($parsed['port']) ? ':' . $parsed['port'] : '') . (($parsed['path']) ? $parsed['path'] : '');
$x = q("update xchan set xchan_addr = '%s', xchan_url = '%s', xchan_connurl = '%s' where xchan_hash = '%s' limit 1",
dbesc($channel . '@' . $rhs),
dbesc($newurl),
dbesc($newurl . '/poco/' . $channel),
dbesc($rr['xchan_hash'])
);
$y = q("update hubloc set hubloc_addr = '%s', hubloc_url = '%s', hubloc_url_sig = '%s', hubloc_host = '%s', hubloc_callback = '%s' where hubloc_hash = '%s' and hubloc_url = '%s' limit 1",
dbesc($channel . '@' . $rhs),
dbesc($newurl),
dbesc(base64url_encode(rsa_sign($newurl,$rr['channel_prvkey']))),
dbesc($newhost),
dbesc($newurl . '/post'),
dbesc($rr['xchan_hash']),
dbesc($oldurl)
);
}
}
}
// wrapper for adding a login box. If $register == true provide a registration
// link. This will most always depend on the value of $a->config['system']['register_policy'].
// returns the complete html for inserting into the page

4
bugs Normal file
View File

@ -0,0 +1,4 @@
- send refresh posts to everybody that needs to see it, e.g. when site url changes
- when you clear one type of notification or view the target item, clear the corresponding system notification. Issue: what to do about matrix/network posts where you might not have actually seen it.

14
done
View File

@ -32,18 +32,15 @@ include/
? dba.php
? delivery.php
+ directory.php
- email.php
+ enotify.php
+ event.php
+ expire.php
fcontact.php
? follow.php
gprobe.php
+ gprobe.php
+ group.php
html2bbcode.php
html2plain.php
= html2bbcode.php
= html2plain.php
+ identity.php
iquery.php
? items.php
+ js_strings.php
+ language.php
@ -63,7 +60,6 @@ include/
? queue_fn.php
? queue.php
- salmon.php
= Scrape.php
+ security.php
? session.php
? socgraph.php
@ -79,8 +75,8 @@ mod/
+ abook.php -> moved to connections.php
? acl.php
admin.php
allfriends.php
api.php
+ allfriends.php
+ api.php
+ apps.php
+ attach.php
- auth.php

View File

@ -1,712 +0,0 @@
<?php /** @file */
require_once('library/HTML5/Parser.php');
require_once('include/crypto.php');
if(! function_exists('scrape_dfrn')) {
function scrape_dfrn($url) {
$a = get_app();
$ret = array();
logger('scrape_dfrn: url=' . $url);
$s = fetch_url($url);
if(! $s)
return $ret;
$headers = $a->get_curl_headers();
logger('scrape_dfrn: headers=' . $headers, LOGGER_DEBUG);
$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('scrape_dfrn: parse error: ' . $e);
}
if(! $dom)
return $ret;
$items = $dom->getElementsByTagName('link');
// get DFRN link elements
foreach($items as $item) {
$x = $item->getAttribute('rel');
if(($x === 'alternate') && ($item->getAttribute('type') === 'application/atom+xml'))
$ret['feed_atom'] = $item->getAttribute('href');
if(substr($x,0,5) == "dfrn-") {
$ret[$x] = $item->getAttribute('href');
}
if($x === 'lrdd') {
$decoded = urldecode($item->getAttribute('href'));
if(preg_match('/acct:([^@]*)@/',$decoded,$matches))
$ret['nick'] = $matches[1];
}
}
// 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('class'),'fn')) {
$ret['fn'] = $x->textContent;
}
if((attribute_contains($x->getAttribute('class'),'photo'))
|| (attribute_contains($x->getAttribute('class'),'avatar'))) {
$size = intval($x->getAttribute('width'));
// dfrn prefers 175, so if we find this, we set largest_size so it can't be topped.
if(($size > $largest_photo) || ($size == 175) || (! $largest_photo)) {
$ret['photo'] = $x->getAttribute('src');
$largest_photo = (($size == 175) ? 9999 : $size);
}
}
if(attribute_contains($x->getAttribute('class'),'key')) {
$ret['key'] = $x->textContent;
}
}
}
}
return $ret;
}}
if(! function_exists('validate_dfrn')) {
function validate_dfrn($a) {
$errors = 0;
if(! x($a,'key'))
$errors ++;
if(! x($a,'dfrn-request'))
$errors ++;
if(! x($a,'dfrn-confirm'))
$errors ++;
if(! x($a,'dfrn-notify'))
$errors ++;
if(! x($a,'dfrn-poll'))
$errors ++;
return $errors;
}}
if(! function_exists('scrape_meta')) {
function scrape_meta($url) {
$a = get_app();
$ret = array();
logger('scrape_meta: url=' . $url);
$s = fetch_url($url);
if(! $s)
return $ret;
$headers = $a->get_curl_headers();
logger('scrape_meta: headers=' . $headers, LOGGER_DEBUG);
$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('scrape_meta: parse error: ' . $e);
}
if(! $dom)
return $ret;
$items = $dom->getElementsByTagName('meta');
// get DFRN link elements
foreach($items as $item) {
$x = $item->getAttribute('name');
if(substr($x,0,5) == "dfrn-")
$ret[$x] = $item->getAttribute('content');
}
return $ret;
}}
if(! function_exists('scrape_vcard')) {
function scrape_vcard($url) {
$a = get_app();
$ret = array();
logger('scrape_vcard: url=' . $url);
$s = fetch_url($url);
if(! $s)
return $ret;
$headers = $a->get_curl_headers();
$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('scrape_vcard: 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('class'),'fn'))
$ret['fn'] = $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;
}
}
if((attribute_contains($x->getAttribute('class'),'nickname'))
|| (attribute_contains($x->getAttribute('class'),'uid'))) {
$ret['nick'] = $x->textContent;
}
}
}
}
return $ret;
}}
if(! function_exists('scrape_feed')) {
function scrape_feed($url) {
$a = get_app();
$ret = array();
$s = fetch_url($url);
$headers = $a->get_curl_headers();
$code = $a->get_curl_code();
logger('scrape_feed: returns: ' . $code . ' headers=' . $headers, LOGGER_DEBUG);
if(! $s) {
logger('scrape_feed: no data returned for ' . $url);
return $ret;
}
$lines = explode("\n",$headers);
if(count($lines)) {
foreach($lines as $line) {
if(stristr($line,'content-type:')) {
if(stristr($line,'application/atom+xml') || stristr($s,'<feed')) {
$ret['feed_atom'] = $url;
return $ret;
}
if(stristr($line,'application/rss+xml') || stristr($s,'<rss')) {
$ret['feed_rss'] = $url;
return $ret;
}
}
}
// perhaps an RSS version 1 feed with a generic or incorrect content-type?
if(stristr($s,'</item>')) {
$ret['feed_rss'] = $url;
return $ret;
}
}
try {
$dom = HTML5_Parser::parse($s);
} catch (DOMException $e) {
logger('scrape_feed: parse error: ' . $e);
}
if(! $dom) {
logger('scrape_feed: failed to parse.');
return $ret;
}
$head = $dom->getElementsByTagName('base');
if($head) {
foreach($head as $head0) {
$basename = $head0->getAttribute('href');
break;
}
}
if(! $basename)
$basename = implode('/', array_slice(explode('/',$url),0,3)) . '/';
$items = $dom->getElementsByTagName('link');
// get Atom/RSS link elements, take the first one of either.
if($items) {
foreach($items as $item) {
$x = $item->getAttribute('rel');
if(($x === 'alternate') && ($item->getAttribute('type') === 'application/atom+xml')) {
if(! x($ret,'feed_atom'))
$ret['feed_atom'] = $item->getAttribute('href');
}
if(($x === 'alternate') && ($item->getAttribute('type') === 'application/rss+xml')) {
if(! x($ret,'feed_rss'))
$ret['feed_rss'] = $item->getAttribute('href');
}
}
}
// Drupal and perhaps others only provide relative URL's. Turn them into absolute.
if(x($ret,'feed_atom') && (! strstr($ret['feed_atom'],'://')))
$ret['feed_atom'] = $basename . $ret['feed_atom'];
if(x($ret,'feed_rss') && (! strstr($ret['feed_rss'],'://')))
$ret['feed_rss'] = $basename . $ret['feed_rss'];
return $ret;
}}
/**
*
* Probe a network address to discover what kind of protocols we need to communicate with it.
*
* Warning: this function is a bit touchy and there are some subtle dependencies within the logic flow.
* Edit with care.
*
*/
/**
*
* PROBE_DIASPORA has a bias towards returning Diaspora information
* while PROBE_NORMAL has a bias towards dfrn/zot - in the case where
* an address (such as a Friendica address) supports more than one type
* of network.
*
*/
define ( 'PROBE_NORMAL', 0);
function probe_url($url, $mode = PROBE_NORMAL) {
require_once('include/email.php');
$result = array();
if(! $url)
return $result;
$network = null;
$has_lrdd = false;
$email_conversant = false;
$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((! $twitter) && (! $lastfm)) {
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']);
}
// 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[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);
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($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) {
if($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($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($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;
}

View File

@ -229,41 +229,6 @@ function populate_acl($user = null,$celeb = false) {
array_walk($deny_cid,'fixacl');
array_walk($deny_gid,'fixacl');
}
/*$o = '';
$o .= '<div id="acl-wrapper">';
$o .= '<div id="acl-permit-outer-wrapper">';
$o .= '<div id="acl-permit-text">' . t('Visible To:') . '</div><div id="jot-public">' . t('everybody') . '</div>';
$o .= '<div id="acl-permit-text-end"></div>';
$o .= '<div id="acl-permit-wrapper">';
$o .= '<div id="group_allow_wrapper">';
$o .= '<label id="acl-allow-group-label" for="group_allow" >' . t('Groups') . '</label>';
$o .= group_select('group_allow','group_allow',$allow_gid);
$o .= '</div>';
$o .= '<div id="contact_allow_wrapper">';
$o .= '<label id="acl-allow-contact-label" for="contact_allow" >' . t('Contacts') . '</label>';
$o .= contact_select('contact_allow','contact_allow',$allow_cid,4,false,$celeb,true);
$o .= '</div>';
$o .= '</div>' . "\r\n";
$o .= '<div id="acl-allow-end"></div>' . "\r\n";
$o .= '</div>';
$o .= '<div id="acl-deny-outer-wrapper">';
$o .= '<div id="acl-deny-text">' . t('Except For:') . '</div>';
$o .= '<div id="acl-deny-text-end"></div>';
$o .= '<div id="acl-deny-wrapper">';
$o .= '<div id="group_deny_wrapper" >';
$o .= '<label id="acl-deny-group-label" for="group_deny" >' . t('Groups') . '</label>';
$o .= group_select('group_deny','group_deny', $deny_gid);
$o .= '</div>';
$o .= '<div id="contact_deny_wrapper" >';
$o .= '<label id="acl-deny-contact-label" for="contact_deny" >' . t('Contacts') . '</label>';
$o .= contact_select('contact_deny','contact_deny', $deny_cid,4,false, $celeb,true);
$o .= '</div>';
$o .= '</div>' . "\r\n";
$o .= '<div id="acl-deny-end"></div>' . "\r\n";
$o .= '</div>';
$o .= '</div>' . "\r\n";
$o .= '<div id="acl-wrapper-end"></div>' . "\r\n";*/
$tpl = get_markup_template("acl_selector.tpl");
$o = replace_macros($tpl, array(

View File

@ -1452,7 +1452,7 @@ require_once('include/security.php');
return api_apply_template('test', $type, array('$ok' => $ok));
}
api_register_func('api/help/test','api_help_test',true);
api_register_func('api/help/test','api_help_test',false);
/**
* https://dev.twitter.com/docs/api/1/get/statuses/friends

View File

@ -101,93 +101,101 @@ function bb_replace_images($body, $images) {
function bb_ShareAttributes($match) {
$attributes = $match[1];
$attributes = $match[1];
$author = "";
preg_match("/author='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$author = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
$author = "";
preg_match("/author='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$author = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
preg_match('/author="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$author = $matches[1];
preg_match('/author="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$author = $matches[1];
$link = "";
preg_match("/link='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$link = $matches[1];
$link = "";
preg_match("/link='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$link = $matches[1];
preg_match('/link="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$link = $matches[1];
preg_match('/link="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$link = $matches[1];
$avatar = "";
preg_match("/avatar='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$avatar = $matches[1];
$avatar = "";
preg_match("/avatar='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$avatar = $matches[1];
preg_match('/avatar="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$avatar = $matches[1];
preg_match('/avatar="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$avatar = $matches[1];
$profile = "";
preg_match("/profile='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$profile = $matches[1];
$profile = "";
preg_match("/profile='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$profile = $matches[1];
preg_match('/profile="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$profile = $matches[1];
preg_match('/profile="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$profile = $matches[1];
$posted = "";
preg_match("/posted='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$posted = $matches[1];
$posted = "";
preg_match("/posted='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$posted = $matches[1];
preg_match('/posted="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$posted = $matches[1];
$reldate = (($posted) ? " " . relative_date($posted) : '');
preg_match('/posted="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$posted = $matches[1];
$headline = '<div class="shared_header">';
// FIXME - this should really be a wall-item-ago so it will get updated on the client
$reldate = (($posted) ? relative_date($posted) : '');
$headline = '<div class="shared_header">';
if ($avatar != "")
$headline .= '<img src="'.$avatar.'" height="32" width="32" >';
$headline .= '<img src="' . $avatar . '" alt="' . $author . '" height="32" width="32" />';
$headline .= sprintf(t('<span><a href="%s" target="external-link">%s</a> wrote the following <a href="%s" target="external-link">post</a>'.$reldate.':</span>'), $profile, $author, $link);
// Bob Smith wrote the following post 2 hours ago
$headline .= "</div>";
$fmt = sprintf( t('%1$s wrote the following %2$s %3$s'),
'<a href="' . zid($profile) . '" >' . $author . '</a>',
'<a href="' . zid($link) . '" >' . t('post') . '</a>',
$reldate
);
$text = $headline.'<blockquote class="shared_content">'.trim($match[2])."</blockquote>";
$headline .= '<span>' . $fmt . '</span></div>';
return($text);
$text = $headline . '<div class="reshared-content">' . trim($match[2]) . '</div>';
return($text);
}
function bb_ShareAttributesSimple($match) {
$attributes = $match[1];
$attributes = $match[1];
$author = "";
preg_match("/author='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$author = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
$author = "";
preg_match("/author='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$author = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
preg_match('/author="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$author = $matches[1];
preg_match('/author="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$author = $matches[1];
$profile = "";
preg_match("/profile='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$profile = $matches[1];
$profile = "";
preg_match("/profile='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
$profile = $matches[1];
preg_match('/profile="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$profile = $matches[1];
preg_match('/profile="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
$profile = $matches[1];
$text = "<br />".html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8').' <a href="'.$profile.'">'.$author."</a>: <br />»".$match[2]."«";
$text = "<br />".html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8').' <a href="'.$profile.'">'.$author."</a>: div class=\"reshared-content\">" .$match[2]."</div>";
return($text);
return($text);
}
// BBcode 2 HTML was written by WAY2WEB.net
@ -195,7 +203,6 @@ function bb_ShareAttributesSimple($match) {
function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
$a = get_app();
// Extract the private images which use data url's since preg has issues with
@ -232,9 +239,6 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
$Text = str_replace("<", "&lt;", $Text);
$Text = str_replace(">", "&gt;", $Text);
// This only matters when looking for tags - otherwise has no meaning
$Text = str_replace(array('[share]','[/share]'), array('',''), $Text);
// Convert new line chars to html <br /> tags
@ -259,13 +263,15 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
// Perform URL Search
$Text = preg_replace("/([^\]\=]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1<a href="$2" >$2</a>', $Text);
$Text = preg_replace("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1<a href="$2" >$2</a>', $Text);
if ($tryoembed)
$Text = preg_replace_callback("/\[bookmark\=([^\]]*)\].*?\[\/bookmark\]/ism",'tryoembed',$Text);
$Text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism",'[url=$1]$2[/url]',$Text);
$Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism","bb_ShareAttributes",$Text);
if ($tryoembed)
$Text = preg_replace_callback("/\[url\]([$URLSearchString]*)\[\/url\]/ism",'tryoembed',$Text);
@ -296,7 +302,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
$Text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])ism","<span style=\"color: $1;\">$2</span>",$Text);
// Check for sized text
// [size=50] --> font-size: 50px (with the unit).
// [size=50] --> font-size: 50px (with the unit).
$Text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism","<span style=\"font-size: $1px;\">$2</span>",$Text);
$Text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism","<span style=\"font-size: $1;\">$2</span>",$Text);
@ -316,9 +322,9 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
$endlessloop = 0;
while ((((strpos($Text, "[/list]") !== false) && (strpos($Text, "[list") !== false)) ||
((strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false)) ||
((strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false)) ||
((strpos($Text, "[/li]") !== false) && (strpos($Text, "[li]") !== false))) && (++$endlessloop < 20)) {
((strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false)) ||
((strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false)) ||
((strpos($Text, "[/li]") !== false) && (strpos($Text, "[li]") !== false))) && (++$endlessloop < 20)) {
$Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '<ul class="listnone" style="list-style-type: none;">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>' ,$Text);
@ -371,8 +377,8 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
$endlessloop = 0;
while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler=") !== false) and (++$endlessloop < 20))
$Text = preg_replace("/\[spoiler=[\"\']*(.*?)[\"\']*\](.*?)\[\/spoiler\]/ism",
"<br /><strong class=".'"spoiler"'.">" . $t_wrote . "</strong><blockquote class=".'"spoiler"'.">$2</blockquote>",
$Text);
"<br /><strong class=".'"spoiler"'.">" . $t_wrote . "</strong><blockquote class=".'"spoiler"'.">$2</blockquote>",
$Text);
// Declare the format for [quote] layout
$QuoteLayout = '<blockquote>$1</blockquote>';
@ -391,8 +397,8 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
$endlessloop = 0;
while ((strpos($Text, "[/quote]")!== false) and (strpos($Text, "[quote=") !== false) and (++$endlessloop < 20))
$Text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism",
"<br /><strong class=".'"author"'.">" . $t_wrote . "</strong><blockquote>$2</blockquote>",
$Text);
"<br /><strong class=".'"author"'.">" . $t_wrote . "</strong><blockquote>$2</blockquote>",
$Text);
// [img=widthxheight]image source[/img]
//$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '<img src="$3" style="height: $2px; width: $1px;" >', $Text);
@ -402,7 +408,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
// [img]pathtoimage[/img]
$Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '<img src="$1" alt="' . t('Image/photo') . '" />', $Text);
$Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism","bb_ShareAttributes",$Text);
$Text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism",'<br/><img src="' .$a->get_baseurl() . '/images/lock_icon.gif" alt="' . t('Encrypted content') . '" title="' . t('Encrypted content') . '" /><br />', $Text);
$Text = preg_replace("/\[crypt=(.*?)\](.*?)\[\/crypt\]/ism",'<br/><img src="' .$a->get_baseurl() . '/images/lock_icon.gif" alt="' . t('Encrypted content') . '" title="' . '$1' . ' ' . t('Encrypted content') . '" /><br />', $Text);
@ -429,8 +435,8 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
// Youtube extensions
if ($tryoembed) {
$Text = preg_replace_callback("/\[youtube\](https?:\/\/www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
$Text = preg_replace_callback("/\[youtube\](www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
$Text = preg_replace_callback("/\[youtube\](https?:\/\/www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
$Text = preg_replace_callback("/\[youtube\](www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
$Text = preg_replace_callback("/\[youtube\](https?:\/\/youtu.be\/.*?)\[\/youtube\]/ism",'tryoembed',$Text);
}

View File

@ -652,6 +652,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional') {
else
{
// Normal View
// logger('conv: items: ' . print_r($items,true));
require_once('include/ConversationObject.php');
require_once('include/ItemObject.php');

View File

@ -45,74 +45,6 @@ function format_event_html($ev) {
return $o;
}
/*
function parse_event($h) {
require_once('include/Scrape.php');
require_once('library/HTMLPurifier.auto.php');
require_once('include/html2bbcode');
$h = '<html><body>' . $h . '</body></html>';
$ret = array();
try {
$dom = HTML5_Parser::parse($h);
} catch (DOMException $e) {
logger('parse_event: parse error: ' . $e);
}
if(! $dom)
return $ret;
$items = $dom->getElementsByTagName('*');
foreach($items as $item) {
if(attribute_contains($item->getAttribute('class'), 'vevent')) {
$level2 = $item->getElementsByTagName('*');
foreach($level2 as $x) {
if(attribute_contains($x->getAttribute('class'),'dtstart') && $x->getAttribute('title')) {
$ret['start'] = $x->getAttribute('title');
if(! strpos($ret['start'],'Z'))
$ret['adjust'] = true;
}
if(attribute_contains($x->getAttribute('class'),'dtend') && $x->getAttribute('title'))
$ret['finish'] = $x->getAttribute('title');
if(attribute_contains($x->getAttribute('class'),'description'))
$ret['desc'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'location'))
$ret['location'] = $x->textContent;
}
}
}
// sanitise
if((x($ret,'desc')) && ((strpos($ret['desc'],'<') !== false) || (strpos($ret['desc'],'>') !== false))) {
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache.DefinitionImpl', null);
$purifier = new HTMLPurifier($config);
$ret['desc'] = html2bbcode($purifier->purify($ret['desc']));
}
if((x($ret,'location')) && ((strpos($ret['location'],'<') !== false) || (strpos($ret['location'],'>') !== false))) {
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache.DefinitionImpl', null);
$purifier = new HTMLPurifier($config);
$ret['location'] = html2bbcode($purifier->purify($ret['location']));
}
if(x($ret,'start'))
$ret['start'] = datetime_convert('UTC','UTC',$ret['start']);
if(x($ret,'finish'))
$ret['finish'] = datetime_convert('UTC','UTC',$ret['finish']);
return $ret;
}
*/
function format_event_bbcode($ev) {
$o = '';

View File

@ -1,41 +0,0 @@
<?php /** @file */
function fcontact_store($url,$name,$photo) {
$nurl = str_replace(array('https:','//www.'), array('http:','//'), $url);
$r = q("SELECT `id` FROM `fcontact` WHERE `url` = '%s' LIMIT 1",
dbesc($nurl)
);
if(count($r))
return $r[0]['id'];
$r = q("INSERT INTO `fcontact` ( `url`, `name`, `photo` ) VALUES ( '%s', '%s', '%s' ) ",
dbesc($nurl),
dbesc($name),
dbesc($photo)
);
if($r) {
$r = q("SELECT `id` FROM `fcontact` WHERE `url` = '%s' LIMIT 1",
dbesc($nurl)
);
if(count($r))
return $r[0]['id'];
}
return 0;
}
function ffinder_store($uid,$cid,$fid) {
$r = q("INSERT INTO `ffinder` ( `uid`, `cid`, `fid` ) VALUES ( %d, %d, %d ) ",
intval($uid),
intval($cid),
intval($fid)
);
return $r;
}

View File

@ -219,4 +219,4 @@ function html2plain($html, $wraplength = 75, $compact = false)
return(trim($message));
}
?>

View File

@ -1,139 +0,0 @@
<?php /** @file */
function network_query($a,$arr) {
$parent_options = '';
$child_options = '';
$ordering = (($arr['order'] === 'post') ? "`created`" : "`commented`") . " DESC ";
$itemspage = get_pconfig($arr['uid'],'system','itemspage');
$a->set_pager_itemspage(((intval($itemspage)) ? $itemspage : 40));
$pager_sql = ((intval($arr['update'])) ? '' : sprintf(" LIMIT %d, %d ",intval($a->pager['start']), intval($a->pager['itemspage'])));
$arr['cmin'] = ((x($arr,'cmin')) ? $arr['cmin'] : 0);
$arr['cmax'] = ((x($arr,'cmax')) ? $arr['cmax'] : 0);
$simple_update = (($arr['update']) ? " and `item`.`unseen` = 1 " : '');
if($arr['new']) {
// "New Item View" - show all items unthreaded in reverse created date order
$items = q("SELECT `item`.*, `item`.`id` AS `item_id`,
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, `contact`.`writable`,
`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn_id`, `contact`.`self`,
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
FROM `item`, `contact`
WHERE `item`.`uid` = %d AND `item`.`visible` = 1
AND `item`.`deleted` = 0 and `item`.`moderated` = 0
$simple_update
AND `contact`.`closeness` >= %d and `contact`.`closeness` <= %d
AND `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
$sql_extra $sql_nets
ORDER BY `item`.`received` DESC $pager_sql ",
intval($arr['uid']),
intval($arr['cmin']),
intval($arr['cmax'])
);
$items = fetch_post_tags($items);
return $items;
}
if($update) {
$r = q("SELECT `parent` AS `item_id`, `contact`.`uid` AS `contact_uid`
FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND
`contact`.`closeness` >= %d and `contact`.`closeness` <= %d
(`item`.`deleted` = 0 OR item.verb = '" . ACTIVITY_LIKE ."' OR item.verb = '" . ACTIVITY_DISLIKE . "')
and `item`.`moderated` = 0 $simple_update
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
$sql_extra3 $sql_extra $sql_nets ",
intval($arr['uid']),
intval($arr['cmin']),
intval($arr['cmax'])
);
}
else {
$r = q("SELECT `item`.`id` AS `item_id`, `contact`.`uid` AS `contact_uid`
FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0
AND `item`.`moderated` = 0 AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
AND `contact`.`closeness` >= %d and `contact`.`closeness` <= %d
AND `item`.`parent` = `item`.`id`
$sql_extra3 $sql_extra $sql_nets
ORDER BY `item`.$ordering $pager_sql ",
intval($arr['uid']),
intval($arr['cmin']),
intval($arr['cmax'])
);
}
// Then fetch all the children of the parents that are on this page
$parents_arr = array();
$parents_str = '';
if(count($r)) {
foreach($r as $rr)
if(! in_array($rr['item_id'],$parents_arr))
$parents_arr[] = $rr['item_id'];
$parents_str = implode(', ', $parents_arr);
$items = q("SELECT `item`.*, `item`.`id` AS `item_id`,
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`,
`contact`.`rel`, `contact`.`writable`,
`contact`.`network`, `contact`.`thumb`, `contact`.`self`,
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
FROM `item`, `contact`
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0
AND `item`.`moderated` = 0 AND `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
AND `item`.`parent` IN ( %s )
$sql_extra ",
intval($arr['uid']),
dbesc($parents_str)
);
$items = fetch_post_tags($items);
$items = conv_sort($items,$ordering);
}
else {
$items = array();
}
return $items;
}

View File

@ -15,35 +15,33 @@
*
*/
if(! function_exists('get_browser_language')) {
function get_browser_language() {
$langs = array();
if (x($_SERVER,'HTTP_ACCEPT_LANGUAGE')) {
// break up string into pieces (languages and q factors)
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i',
// break up string into pieces (languages and q factors)
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i',
$_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);
if (count($lang_parse[1])) {
// create a list like "en" => 0.8
$langs = array_combine($lang_parse[1], $lang_parse[4]);
// set default to 1 for any without q factor
foreach ($langs as $lang => $val) {
if ($val === '') $langs[$lang] = 1;
}
if (count($lang_parse[1])) {
// create a list like "en" => 0.8
$langs = array_combine($lang_parse[1], $lang_parse[4]);
// set default to 1 for any without q factor
foreach ($langs as $lang => $val) {
if ($val === '') $langs[$lang] = 1;
}
// sort list based on value
arsort($langs, SORT_NUMERIC);
}
// sort list based on value
arsort($langs, SORT_NUMERIC);
}
}
else
$langs['en'] = 1;
return $langs;
}}
}
function get_best_language() {
@ -62,7 +60,7 @@ function get_best_language() {
if(isset($preferred))
return $preferred;
$a = get_app();
$a = get_app();
return ((isset($a->config['system']['language'])) ? $a->config['system']['language'] : 'en');
}
@ -101,15 +99,25 @@ function pop_lang() {
// load string translation table for alternate language
if(! function_exists('load_translation_table')) {
function load_translation_table($lang) {
function load_translation_table($lang, $install = false) {
global $a;
$a->strings = array();
if(file_exists("view/$lang/strings.php")) {
include("view/$lang/strings.php");
}
else
$a->strings = array();
if(! $install) {
$plugins = q("SELECT name FROM addon WHERE installed=1;");
if ($plugins!==false) {
foreach($plugins as $p) {
$name = $p['name'];
if(file_exists("addon/$name/lang/$lang/strings.php")) {
include("addon/$name/lang/$lang/strings.php");
}
}
}
}
// Allow individual strings to be over-ridden on this site
// Either for the default language or for all languages
@ -118,11 +126,10 @@ function load_translation_table($lang) {
include("view/local-$lang/strings.php");
}
}}
}
// translate string if translation exists
if(! function_exists('t')) {
function t($s) {
global $a;
@ -132,9 +139,9 @@ function t($s) {
return is_array($t)?$t[0]:$t;
}
return $s;
}}
}
if(! function_exists('tt')){
function tt($singular, $plural, $count){
$a = get_app();
@ -152,15 +159,14 @@ function tt($singular, $plural, $count){
} else {
return $singular;
}
}}
}
// provide a fallback which will not collide with
// a function defined in any language file
if(! function_exists('string_plural_select_default')) {
function string_plural_select_default($n) {
return ($n != 1);
}}
}

View File

@ -40,14 +40,14 @@ function queue_run($argv, $argc){
return;
foreach($r as $rr) {
if(in_array($rr['outq_hub'],$deadguys))
if(in_array($rr['outq_posturl'],$deadguys))
continue;
$result = zot_zot($rr['outq_posturl'],$rr['outq_notify']);
if($result['success']) {
zot_process_response($rr['outq_posturl'],$result, $rr);
}
else {
$deadguys[] = $rr['outq_hub'];
$deadguys[] = $rr['outq_posturl'];
$y = q("update outq set outq_updated = '%s' where outq_hash = '%s' limit 1",
dbesc(datetime_convert()),
dbesc($rr['outq_hash'])

View File

@ -454,12 +454,19 @@ function import_xchan($arr) {
$new_flags = $r[0]['xchan_flags'];
if(($r[0]['xchan_name_date'] != $arr['name_updated']) || ($r[0]['xchan_connurl'] != $arr['connections_url']) || ($r[0]['xchan_flags'] != $new_flags)) {
$r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s', xchan_connurl = '%s', xchan_flags = %d where xchan_hash = '%s' limit 1",
if(($r[0]['xchan_name_date'] != $arr['name_updated'])
|| ($r[0]['xchan_connurl'] != $arr['connections_url'])
|| ($r[0]['xchan_flags'] != $new_flags)
|| ($r[0]['xchan_addr'] != $arr['address'])
|| ($r[0]['xchan_url'] != $arr['url'])) {
$r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s', xchan_connurl = '%s', xchan_flags = %d,
xchan_addr = '%s', xchan_url = '%s' where xchan_hash = '%s' limit 1",
dbesc($arr['name']),
dbesc($arr['name_updated']),
dbesc($arr['connections_url']),
intval($new_flags),
dbesc($arr['address']),
dbesc($arr['url']),
dbesc($xchan_hash)
);
}
@ -503,7 +510,15 @@ function import_xchan($arr) {
);
}
// what we are missing for true hub independence is for any changes in the primary hub to
// get reflected not only in the hublocs, but also to update the URLs and addr in the appropriate xchan
if($arr['locations']) {
$xisting = q("select hubloc_id, hubloc_url from hubloc where hubloc_hash = '%s'",
dbesc($xchan_hash)
);
foreach($arr['locations'] as $location) {
if(! rsa_verify($location['url'],base64url_decode($location['url_sig']),$arr['key'])) {
logger('import_xchan: Unable to verify site signature for ' . $location['url']);
@ -511,12 +526,19 @@ function import_xchan($arr) {
continue;
}
for($x = 0; $x < count($xisting); $x ++) {
if($xisting[$x]['hubloc_url'] == $location['url']) {
$xisting[$x]['updated'] = true;
}
}
$r = q("select * from hubloc where hubloc_hash = '%s' and hubloc_url = '%s' limit 1",
dbesc($xchan_hash),
dbesc($location['url'])
);
if($r) {
if(($r[0]['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY) && (! $location['primary'])) {
if((($r[0]['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY) && (! $location['primary']))
|| ((! ($r[0]['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY)) && ($location['primary']))) {
$r = q("update hubloc set hubloc_flags = (hubloc_flags ^ %d) where hubloc_id = %d limit 1",
intval(HUBLOC_FLAGS_PRIMARY),
intval($r[0]['hubloc_id'])
@ -525,6 +547,16 @@ function import_xchan($arr) {
continue;
}
// new hub claiming to be primary. Make it so.
if(intval($location['primary'])) {
$r = q("update hubloc set hubloc_flags = (hubloc_flags ^ %d) where hubloc_hash = '%s' and (hubloc_flags & %d )",
intval(HUBLOC_FLAGS_PRIMARY),
dbesc($xchan_hash),
intval(HUBLOC_FLAGS_PRIMARY)
);
}
$r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_flags, hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey)
values ( '%s','%s','%s','%s', %d ,'%s','%s','%s','%s','%s')",
dbesc($arr['guid']),
@ -541,6 +573,18 @@ function import_xchan($arr) {
}
// get rid of any hubs we have for this channel which weren't reported.
if($xisting) {
foreach($xisting as $x) {
if(! array_key_exists('updated',$x)) {
logger('import_xchan: removing unreferenced hub location ' . $x['hubloc_url']);
$r = q("delete from hubloc where hubloc_id = %d limit 1",
intval($x['hubloc_id'])
);
}
}
}
}
if(! x($ret,'message')) {

View File

@ -29,7 +29,6 @@ $install = ((file_exists('.htconfig.php') && filesize('.htconfig.php')) ? false
$a->language = get_best_language();
load_translation_table($a->language);
/**
*
@ -53,7 +52,15 @@ if(! $install) {
require_once("session.php");
load_hooks();
call_hooks('init_1');
load_translation_table($a->language);
}
else {
// load translations but do not check plugins as we have no database
load_translation_table($a->language,true);
}
/**

View File

@ -107,10 +107,10 @@ You can generally find the location of PHP by executing "which php". If you
have troubles with this section please contact your hosting provider for
assistance. Friendica will not work correctly if you cannot perform this step.
You should also be sure that $a->config['php_path'] is set correctly, it should
You should also be sure that $a->config['system']['php_path'] is set correctly, it should
look like (changing it to the correct PHP location)
$a->config['php_path'] = '/usr/local/php53/bin/php'
$a->config['system']['php_path'] = '/usr/local/php53/bin/php';
Alternative: You may be able to use the 'poormancron' plugin to perform this
step if you are using a recent Friendica release. 'poormancron' may result in
@ -260,7 +260,7 @@ are NOT called with -d suhosin.executor.func.blacklist=none.
So the simple solution is to put the correct parameters into .htconfig.php:
// Location of PHP command line processor
$a->config['php_path'] = '/usr/bin/php -d suhosin.executor.func.blacklist=none
$a->config['system']['php_path'] = '/usr/bin/php -d suhosin.executor.func.blacklist=none
-d suhosin.executor.eval.blacklist=none';

View File

@ -840,6 +840,13 @@ CREATE TABLE IF NOT EXISTS `tokens` (
KEY `uid` (`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `updates` (
`ud_hash` char(128) NOT NULL,
`ud_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`ud_hash`),
KEY `ud_date` (`ud_date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `verify` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`channel` int(10) unsigned NOT NULL DEFAULT '0',

View File

@ -1,6 +1,6 @@
<?php
define( 'UPDATE_VERSION' , 1034 );
define( 'UPDATE_VERSION' , 1035 );
/**
*
@ -433,3 +433,15 @@ KEY `share_xchan` (`share_xchan`)
return UPDATE_FAILED;
}
function update_r1034() {
$r = q("CREATE TABLE if not exists `updates` (
`ud_hash` CHAR( 128 ) NOT NULL ,
`ud_date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY ( `ud_hash` ),
KEY `ud_date` ( `ud_date` )
) ENGINE = MYISAM DEFAULT CHARSET = utf8");
if($r)
return UPDATE_SUCCESS;
return UPDATE_FAILED;
}

View File

@ -18,13 +18,14 @@ function editpost_content(&$a) {
return;
}
$itm = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
$itm = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d and author_xchan = '%s' LIMIT 1",
intval($post_id),
intval(local_user())
intval(local_user()),
dbesc(get_observer_hash())
);
if(! count($itm)) {
notice( t('Item not found') . EOL);
notice( t('Item is not editable') . EOL);
return;
}

View File

@ -100,8 +100,9 @@ function fsuggest_content(&$a) {
$o .= '<form id="fsuggest-form" action="fsuggest/' . $contact_id . '" method="post" >';
$o .= contact_selector('suggest','suggest-select', false,
array('size' => 4, 'exclude' => $contact_id, 'networks' => 'DFRN_ONLY', 'single' => true));
// FIXME contact_selector deprecated, removed
// $o .= contact_selector('suggest','suggest-select', false,
// array('size' => 4, 'exclude' => $contact_id, 'networks' => 'DFRN_ONLY', 'single' => true));
$o .= '<div id="fsuggest-submit-wrapper"><input id="fsuggest-submit" type="submit" name="submit" value="' . t('Submit') . '" /></div>';

View File

@ -149,11 +149,11 @@ function like_content(&$a) {
$arr['author_xchan'] = $observer['xchan_hash'];
$ulink = '[url=' . $item_owner['xchan_url'] . ']' . $item_owner['xchan_name'] . '[/url]';
$ulink = '[url=' . $thread_owner['xchan_url'] . ']' . $thread_owner['xchan_name'] . '[/url]';
$alink = '[url=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/url]';
$plink = '[url=' . $a->get_baseurl() . '/display/' . $item['uri'] . ']' . $post_type . '[/url]';
$arr['body'] = sprintf( $bodyverb, $ulink, $alink, $plink );
$arr['body'] = sprintf( $bodyverb, $alink, $ulink, $plink );
$arr['verb'] = $activity;
$arr['obj_type'] = $objtype;

View File

@ -261,6 +261,7 @@ function post_post(&$a) {
}
}
if($msgtype === 'refresh') {
// remote channel info (such as permissions or photo or something)

View File

@ -1,6 +1,5 @@
<?php
require_once('include/Scrape.php');
require_once('include/zot.php');
function probe_content(&$a) {

View File

@ -145,6 +145,12 @@ function zfinger_init(&$a) {
// array of (verified) hubs this channel uses
$ret['locations'] = array();
$x = zot_get_hubloc(array($e['channel_hash']));
if($x && count($x)) {
foreach($x as $hub) {

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +1,81 @@
#!/bin/bash
FULLPATH=$(dirname $(readlink -f "$0"))
cd "$FULLPATH/../view/en/"
ADDONMODE=
ADDONNAME=
if [ "$1" == "--addon" -o "$1" == "-a" ]
then
ADDONMODE=1
if [ -z $2 ]; then echo -e "ERROR: missing addon name\n\nrun_xgettext.sh -a <addonname>"; exit 1; fi
ADDONNAME=$2
if [ ! -d "$FULLPATH/../addon/$ADDONNAME" ]; then echo "ERROR: addon '$ADDONNAME' not found"; exit 2; fi
fi
if [ $ADDONMODE ]
then
cd "$FULLPATH/../addon/$ADDONNAME"
mkdir -p "$FULLPATH/../addon/$ADDONNAME/lang/C"
OUTFILE="$FULLPATH/../addon/$ADDONNAME/lang/C/messages.po"
FINDSTARTDIR="."
FINDOPTS=
else
cd "$FULLPATH/../view/en/"
OUTFILE="$FULLPATH/messages.po"
FINDSTARTDIR="../../"
# skip addon folder
FINDOPTS="-wholename */addon -prune -o"
fi
F9KVERSION=$(sed -n "s/.*'FRIENDICA_VERSION'.*'\([0-9.]*\)'.*/\1/p" ../../boot.php);
echo "Friendica version $F9KVERSION"
OPTS=
OUTFILE="$FULLPATH/messages.po"
if [ "" != "$1" ]
then
OUTFILE="$(readlink -f ${FULLPATH}/$1)"
if [ -e "$OUTFILE" ]
then
echo "join extracted strings"
OPTS="-j"
fi
fi
#if [ "" != "$1" ]
#then
# OUTFILE="$(readlink -f ${FULLPATH}/$1)"
# if [ -e "$OUTFILE" ]
# then
# echo "join extracted strings"
# OPTS="-j"
# fi
#fi
KEYWORDS="-k -kt -ktt:1,2"
echo "extract strings to $OUTFILE.."
find ../../ -name "*.php" | xargs xgettext $KEYWORDS $OPTS -o "$OUTFILE" --from-code=UTF-8
echo "extract strings to $OUTFILE.."
rm "$OUTFILE"; touch "$OUTFILE"
for f in $(find "$FINDSTARTDIR" $FINDOPTS -name "*.php" -type f)
do
if [ ! -d "$f" ]
then
xgettext $KEYWORDS $OPTS -j -o "$OUTFILE" --from-code=UTF-8 "$f" > /dev/null 2>&1
fi
done
echo "setup base info.."
sed -i "s/SOME DESCRIPTIVE TITLE./FRIENDICA Distributed Social Network/g" "$OUTFILE"
sed -i "s/YEAR THE PACKAGE'S COPYRIGHT HOLDER/2010, 2011 the Friendica Project/g" "$OUTFILE"
sed -i "s/FIRST AUTHOR <EMAIL@ADDRESS>, YEAR./Mike Macgirvin, 2010/g" "$OUTFILE"
sed -i "s/PACKAGE VERSION/$F9KVERSION/g" "$OUTFILE"
sed -i "s/PACKAGE/Friendica/g" "$OUTFILE"
sed -i "s/CHARSET/UTF-8/g" "$OUTFILE"
sed -i "s/^\"Plural-Forms/#\"Plural-Forms/g" "$OUTFILE"
if [ $ADDONMODE ]
then
sed -i "s/SOME DESCRIPTIVE TITLE./ADDON $ADDONNAME/g" "$OUTFILE"
sed -i "s/YEAR THE PACKAGE'S COPYRIGHT HOLDER//g" "$OUTFILE"
sed -i "s/FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.//g" "$OUTFILE"
sed -i "s/PACKAGE VERSION//g" "$OUTFILE"
sed -i "s/PACKAGE/Friendica $ADDONNAME addon/g" "$OUTFILE"
sed -i "s/CHARSET/UTF-8/g" "$OUTFILE"
sed -i "s/^\"Plural-Forms/#\"Plural-Forms/g" "$OUTFILE"
else
sed -i "s/SOME DESCRIPTIVE TITLE./Red Communications Project/g" "$OUTFILE"
sed -i "s/YEAR THE PACKAGE'S COPYRIGHT HOLDER/2013 the Friendica Project/g" "$OUTFILE"
sed -i "s/FIRST AUTHOR <EMAIL@ADDRESS>, YEAR./Mike Macgirvin, 2013/g" "$OUTFILE"
sed -i "s/PACKAGE VERSION/$F9KVERSION/g" "$OUTFILE"
sed -i "s/PACKAGE/Red/g" "$OUTFILE"
sed -i "s/CHARSET/UTF-8/g" "$OUTFILE"
sed -i "s/^\"Plural-Forms/#\"Plural-Forms/g" "$OUTFILE"
fi
echo "done."

View File

@ -38,8 +38,8 @@
}
}
if(x($a->config,'php_path'))
$phpath = $a->config['php_path'];
if(x($a->config,'system') && x($a->config['system'],'php_path'))
$phpath = $a->config['system']['php_path'];
else
$phpath = 'php';

View File

@ -1 +1 @@
2013-03-06.244
2013-03-13.251

View File

@ -1090,7 +1090,8 @@ footer {
}
.wall-item-content img {
max-width: 95% !important;
max-height: 95% !important;
max-width: 95% !important;
/* box-shadow: 8px 8px 8px #666; can't really have this because of smileys */
}
@ -2257,36 +2258,10 @@ aside input[type='text'] {
}
#profile-jot-desc {
/*float: left;*/
width: 480px;
color: #FF0000;
margin-top: 10px;
margin-bottom: 10px;
#profile-jot-wrapper {
margin-top: 25px;
}
#character-counter {
float: right;
font-size: 120%;
}
#character-counter.grey {
color: #888888;
}
#character-counter.orange {
color: orange;
}
#character-counter.red {
color: red;
}
#profile-jot-banner-end {
/* clear: both; */
}
#settings-default-perms-menu {
margin-top: 15px;
@ -3777,3 +3752,6 @@ ul.menu-popup {
}
.profile-match-connect { margin-top: 5px; }
.reshared-content { margin-left: 30px; }
.shared_header img { margin-right: 10px; }

View File

@ -74,24 +74,6 @@ function initEditor(cb){
$('#profile-jot-desc').html('&nbsp;');
}
//Character count
if(textlen <= 140) {
$('#character-counter').removeClass('red');
$('#character-counter').removeClass('orange');
$('#character-counter').addClass('grey');
}
if((textlen > 140) && (textlen <= 420)) {
$('#character-counter').removeClass('grey');
$('#character-counter').removeClass('red');
$('#character-counter').addClass('orange');
}
if(textlen > 420) {
$('#character-counter').removeClass('grey');
$('#character-counter').removeClass('orange');
$('#character-counter').addClass('red');
}
$('#character-counter').text(textlen);
});
ed.onInit.add(function(ed) {

View File

@ -1,10 +1,5 @@
<div id="profile-jot-wrapper" >
<div id="profile-jot-banner-wrapper">
<div id="profile-jot-desc" >&nbsp;</div>
<div id="character-counter" class="grey"></div>
</div>
<div id="profile-jot-banner-end"></div>
<form id="profile-jot-form" action="$action" method="post" >
<input type="hidden" name="type" value="$ptyp" />

View File

@ -3,7 +3,7 @@
{{ if $albums }}
<ul>
{{ for $albums as $al }}
<li><a href="$baseurl/photos/$nick/$al.bin2hex">$al.album</a></li>
<li><a href="$baseurl/photos/$nick/album/$al.bin2hex">$al.album</a></li>
{{ endfor }}
</ul>
{{ endif }}

View File

@ -79,24 +79,6 @@ function initEditor(cb){
$('#profile-jot-desc').html('&nbsp;');
}
//Character count
if(textlen <= 140) {
$('#character-counter').removeClass('red');
$('#character-counter').removeClass('orange');
$('#character-counter').addClass('grey');
}
if((textlen > 140) && (textlen <= 420)) {
$('#character-counter').removeClass('grey');
$('#character-counter').removeClass('red');
$('#character-counter').addClass('orange');
}
if(textlen > 420) {
$('#character-counter').removeClass('grey');
$('#character-counter').removeClass('orange');
$('#character-counter').addClass('red');
}
$('#character-counter').text(textlen);
});
ed.onInit.add(function(ed) {

View File

@ -5,11 +5,6 @@
*}}
<div id="profile-jot-wrapper" >
<div id="profile-jot-banner-wrapper">
<div id="profile-jot-desc" >&nbsp;</div>
<div id="character-counter" class="grey"></div>
</div>
<div id="profile-jot-banner-end"></div>
<form id="profile-jot-form" action="{{$action}}" method="post" >
<input type="hidden" name="type" value="{{$ptyp}}" />

View File

@ -8,7 +8,7 @@
{{if $albums}}
<ul>
{{foreach $albums as $al}}
<li><a href="{{$baseurl}}/photos/{{$nick}}/{{$al.bin2hex}}">{{$al.album}}</a></li>
<li><a href="{{$baseurl}}/photos/{{$nick}}/album/{{$al.bin2hex}}">{{$al.album}}</a></li>
{{/foreach}}
</ul>
{{/if}}