This commit is contained in:
friendica 2015-04-09 19:52:19 -07:00
commit 8f22b927b1
2 changed files with 557 additions and 382 deletions

View File

@ -3,6 +3,9 @@
* @file include/items.php * @file include/items.php
*/ */
/** @todo deprecated in newer SabreDAV releases Sabre\HTTP\URLUtil */
use Sabre\DAV\URLUtil;
require_once('include/bbcode.php'); require_once('include/bbcode.php');
require_once('include/oembed.php'); require_once('include/oembed.php');
require_once('include/crypto.php'); require_once('include/crypto.php');
@ -595,10 +598,17 @@ function get_feed_for($channel, $observer_hash, $params) {
return $atom; return $atom;
} }
/**
* @brief
*
* @param array $item an associative array with
* * \b string \b verb
* @return string item's verb if set, default ACTIVITY_POST see boot.php
*/
function construct_verb($item) { function construct_verb($item) {
if($item['verb']) if ($item['verb'])
return $item['verb']; return $item['verb'];
return ACTIVITY_POST; return ACTIVITY_POST;
} }
@ -660,7 +670,9 @@ function construct_activity_target($item) {
} }
if($r->content) if($r->content)
$o .= '<content type="html" >' . xmlify(bbcode($r->content)) . '</content>' . "\r\n"; $o .= '<content type="html" >' . xmlify(bbcode($r->content)) . '</content>' . "\r\n";
$o .= '</as:target>' . "\r\n"; $o .= '</as:target>' . "\r\n";
return $o; return $o;
} }
@ -674,7 +686,7 @@ function construct_activity_target($item) {
* imported messages without including any embedded photos in the length. * imported messages without including any embedded photos in the length.
* *
* @param string $body * @param string $body
* @return string|unknown * @return string
*/ */
function limit_body_size($body) { function limit_body_size($body) {
@ -918,7 +930,6 @@ function get_item_elements($x) {
$arr['item_restrict'] = $x['item_restrict']; $arr['item_restrict'] = $x['item_restrict'];
$arr['item_flags'] = $x['item_flags']; $arr['item_flags'] = $x['item_flags'];
$arr['attach'] = $x['attach']; $arr['attach'] = $x['attach'];
} }
return $arr; return $arr;
@ -949,10 +960,17 @@ function import_author_xchan($x) {
return(($y) ? $y : false); return(($y) ? $y : false);
} }
/**
* @brief Imports an author from Diaspora.
*
* @param array $x an associative array with
* * \e string \b address
* @return boolean|string false on error, otherwise xchan_hash of the new entry
*/
function import_author_diaspora($x) { function import_author_diaspora($x) {
if(! $x['address']) if(! $x['address'])
return false; return false;
if(discover_by_webbie($x['address'])) { if(discover_by_webbie($x['address'])) {
$r = q("select xchan_hash from xchan where xchan_addr = '%s' limit 1", $r = q("select xchan_hash from xchan where xchan_addr = '%s' limit 1",
dbesc($x['address']) dbesc($x['address'])
@ -960,12 +978,20 @@ function import_author_diaspora($x) {
if($r) if($r)
return $r[0]['xchan_hash']; return $r[0]['xchan_hash'];
} }
return false; return false;
} }
/**
* @brief Imports an author from a RSS feed.
*
* @param array $x an associative array with
* * \e string \b url
* * \e string \b name
* * \e string \b guid
* @return boolean|string
*/
function import_author_rss($x) { function import_author_rss($x) {
if(! $x['url']) if(! $x['url'])
return false; return false;
@ -986,13 +1012,15 @@ function import_author_rss($x) {
dbesc(($name) ? $name : t('(Unknown)')), dbesc(($name) ? $name : t('(Unknown)')),
dbesc('rss') dbesc('rss')
); );
if($r && $x['photo']) { if($r && $x['photo']) {
$photos = import_profile_photo($x['photo']['src'],$x['url']); $photos = import_profile_photo($x['photo']['src'],$x['url']);
if($photos) { if($photos) {
/** @bug $arr is undefined in this SQL query */
$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_url = '%s' and xchan_network = 'rss'", $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_url = '%s' and xchan_network = 'rss'",
dbesc(datetime_convert('UTC','UTC',$arr['photo_updated'])), dbesc(datetime_convert('UTC', 'UTC', $arr['photo_updated'])),
dbesc($photos[0]), dbesc($photos[0]),
dbesc($photos[1]), dbesc($photos[1]),
dbesc($photos[2]), dbesc($photos[2]),
@ -1035,6 +1063,7 @@ function import_author_unknown($x) {
$photos = import_profile_photo($x['photo']['src'],$x['url']); $photos = import_profile_photo($x['photo']['src'],$x['url']);
if($photos) { if($photos) {
/** @bug $arr is undefined in this SQL query */
$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_url = '%s' and xchan_network = 'unknown'", $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_url = '%s' and xchan_network = 'unknown'",
dbesc(datetime_convert('UTC','UTC',$arr['photo_updated'])), dbesc(datetime_convert('UTC','UTC',$arr['photo_updated'])),
dbesc($photos[0]), dbesc($photos[0]),
@ -1157,8 +1186,14 @@ function encode_item($item,$mirror = false) {
return $x; return $x;
} }
/**
function map_scope($scope,$strip = false) { * @brief
*
* @param int $scope
* @param boolean $strip (optional) default false
* @return string
*/
function map_scope($scope, $strip = false) {
switch($scope) { switch($scope) {
case 0: case 0:
return 'self'; return 'self';
@ -1180,6 +1215,12 @@ function map_scope($scope,$strip = false) {
} }
} }
/**
* @brief Returns a descriptive text for a given $scope.
*
* @param string $scope
* @return string translated string describing the scope
*/
function translate_scope($scope) { function translate_scope($scope) {
if(! $scope || $scope === 'public') if(! $scope || $scope === 'public')
return t('Visible to anybody on the internet.'); return t('Visible to anybody on the internet.');
@ -1199,9 +1240,15 @@ function translate_scope($scope) {
return t('Visible to specific connections.'); return t('Visible to specific connections.');
} }
/**
* @brief
*
* @param array $xchan
* @return array an associative array
*/
function encode_item_xchan($xchan) { function encode_item_xchan($xchan) {
$ret = array(); $ret = array();
$ret['name'] = $xchan['xchan_name']; $ret['name'] = $xchan['xchan_name'];
$ret['address'] = $xchan['xchan_addr']; $ret['address'] = $xchan['xchan_addr'];
$ret['url'] = (($xchan['hubloc_url']) ? $xchan['hubloc_url'] : $xchan['xchan_url']); $ret['url'] = (($xchan['hubloc_url']) ? $xchan['hubloc_url'] : $xchan['xchan_url']);
@ -1209,6 +1256,7 @@ function encode_item_xchan($xchan) {
$ret['photo'] = array('mimetype' => $xchan['xchan_photo_mimetype'], 'src' => $xchan['xchan_photo_m']); $ret['photo'] = array('mimetype' => $xchan['xchan_photo_mimetype'], 'src' => $xchan['xchan_photo_m']);
$ret['guid'] = $xchan['xchan_guid']; $ret['guid'] = $xchan['xchan_guid'];
$ret['guid_sig'] = $xchan['xchan_guid_sig']; $ret['guid_sig'] = $xchan['xchan_guid_sig'];
return $ret; return $ret;
} }
@ -1223,22 +1271,38 @@ function encode_item_terms($terms) {
$ret[] = array('tag' => $term['term'], 'url' => $term['url'], 'type' => termtype($term['type'])); $ret[] = array('tag' => $term['term'], 'url' => $term['url'], 'type' => termtype($term['type']));
} }
} }
return $ret; return $ret;
} }
/**
* @brief
*
* @param int $t
* @return string
*/
function termtype($t) { function termtype($t) {
$types = array('unknown','hashtag','mention','category','private_category','file','search','thing','bookmark'); $types = array('unknown','hashtag','mention','category','private_category','file','search','thing','bookmark');
return(($types[$t]) ? $types[$t] : 'unknown'); return(($types[$t]) ? $types[$t] : 'unknown');
} }
/**
* @brief
*
* @param array $t
* @return array|string empty string or array containing associative arrays with
* * \e string \b term
* * \e string \b url
* * \e int \b type
*/
function decode_tags($t) { function decode_tags($t) {
if($t) { if($t) {
$ret = array(); $ret = array();
foreach($t as $x) { foreach($t as $x) {
$tag = array(); $tag = array();
$tag['term'] = htmlspecialchars($x['tag'], ENT_COMPAT,'UTF-8',false); $tag['term'] = htmlspecialchars($x['tag'], ENT_COMPAT, 'UTF-8', false);
$tag['url'] = htmlspecialchars($x['url'], ENT_COMPAT,'UTF-8',false); $tag['url'] = htmlspecialchars($x['url'], ENT_COMPAT, 'UTF-8', false);
switch($x['type']) { switch($x['type']) {
case 'hashtag': case 'hashtag':
$tag['type'] = TERM_HASHTAG; $tag['type'] = TERM_HASHTAG;
@ -1271,6 +1335,7 @@ function decode_tags($t) {
} }
$ret[] = $tag; $ret[] = $tag;
} }
return $ret; return $ret;
} }
@ -1291,12 +1356,12 @@ function activity_sanitise($arr) {
if(is_array($x)) if(is_array($x))
$ret[$k] = activity_sanitise($x); $ret[$k] = activity_sanitise($x);
else else
$ret[$k] = htmlspecialchars($x, ENT_COMPAT,'UTF-8',false); $ret[$k] = htmlspecialchars($x, ENT_COMPAT, 'UTF-8', false);
} }
return $ret; return $ret;
} }
else { else {
return htmlspecialchars($arr, ENT_COMPAT,'UTF-8', false); return htmlspecialchars($arr, ENT_COMPAT, 'UTF-8', false);
} }
} }
@ -1783,7 +1848,6 @@ function get_atom_elements($feed, $item, &$author) {
$attach = $item->get_enclosures(); $attach = $item->get_enclosures();
if($attach) { if($attach) {
$res['attach'] = array(); $res['attach'] = array();
$att_arr = array();
foreach($attach as $att) { foreach($attach as $att) {
$len = intval($att->get_length()); $len = intval($att->get_length());
$link = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_link())))); $link = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_link()))));
@ -1906,14 +1970,22 @@ function encode_rel_links($links) {
return xmlify($o); return xmlify($o);
} }
function item_store($arr,$allow_exec = false) { /**
* @brief
*
* @param array $arr
* @param boolean $allow_exec (optional) default false
* @return array
* * \e boolean \b success
* * \e int \b item_id
*/
function item_store($arr, $allow_exec = false) {
$d = array('item' => $arr, 'allow_exec' => $allow_exec); $d = array('item' => $arr, 'allow_exec' => $allow_exec);
call_hooks('item_store', $d ); call_hooks('item_store', $d );
$arr = $d['item']; $arr = $d['item'];
$allow_exec = $d['allow_exec']; $allow_exec = $d['allow_exec'];
$ret = array('success' => false, 'item_id' => 0); $ret = array('success' => false, 'item_id' => 0);
if(! $arr['uid']) { if(! $arr['uid']) {
@ -4496,12 +4568,12 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
} }
if($arr['search']) { if($arr['search']) {
if(strpos($arr['search'],'#') === 0) if(strpos($arr['search'],'#') === 0)
$sql_extra .= term_query('item',substr($arr['search'],1),TERM_HASHTAG); $sql_extra .= term_query('item',substr($arr['search'],1),TERM_HASHTAG);
else else
$sql_extra .= sprintf(" AND item.body like '%s' ", $sql_extra .= sprintf(" AND item.body like '%s' ",
dbesc(protect_sprintf('%' . $arr['search'] . '%')) dbesc(protect_sprintf('%' . $arr['search'] . '%'))
); );
} }
if (strlen($arr['file'])) { if (strlen($arr['file'])) {
@ -4542,6 +4614,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
$sql_nets .= "( abook.abook_closeness >= " . intval($arr['cmin']) . " "; $sql_nets .= "( abook.abook_closeness >= " . intval($arr['cmin']) . " ";
$sql_nets .= " AND abook.abook_closeness <= " . intval($arr['cmax']) . " ) "; $sql_nets .= " AND abook.abook_closeness <= " . intval($arr['cmax']) . " ) ";
/** @fixme dead code, $cmax is undefined */
if ($cmax == 99) if ($cmax == 99)
$sql_nets .= " OR abook.abook_closeness IS NULL ) "; $sql_nets .= " OR abook.abook_closeness IS NULL ) ";
} }
@ -4564,12 +4637,12 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
if ($arr['nouveau'] && ($client_mode & CLIENT_MODE_LOAD) && $channel) { if ($arr['nouveau'] && ($client_mode & CLIENT_MODE_LOAD) && $channel) {
// "New Item View" - show all items unthreaded in reverse created date order // "New Item View" - show all items unthreaded in reverse created date order
$items = q("SELECT item.*, item.id AS item_id FROM item $items = q("SELECT item.*, item.id AS item_id FROM item
WHERE $item_uids $item_restrict WHERE $item_uids $item_restrict
$simple_update $simple_update
$sql_extra $sql_nets $sql_extra $sql_nets
ORDER BY item.received DESC $pager_sql " ORDER BY item.received DESC $pager_sql"
); );
require_once('include/items.php'); require_once('include/items.php');
@ -4629,7 +4702,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
dbesc($parents_str) dbesc($parents_str)
); );
$second = dba_timer(); //$second = dba_timer();
xchan_query($items); xchan_query($items);

View File

@ -32,6 +32,7 @@ require_once('include/hubloc.php');
*/ */
function zot_new_uid($channel_nick) { function zot_new_uid($channel_nick) {
$rawstr = z_root() . '/' . $channel_nick . '.' . mt_rand(); $rawstr = z_root() . '/' . $channel_nick . '.' . mt_rand();
return(base64url_encode(hash('whirlpool', $rawstr, true), true)); return(base64url_encode(hash('whirlpool', $rawstr, true), true));
} }
@ -40,8 +41,9 @@ function zot_new_uid($channel_nick) {
* *
* Generates a portable hash identifier for the channel identified by $guid and * Generates a portable hash identifier for the channel identified by $guid and
* signed with $guid_sig. * signed with $guid_sig.
* This ID is portable across the network but MUST be calculated locally by *
* verifying the signature and can not be trusted as an identity. * @note This ID is portable across the network but MUST be calculated locally
* by verifying the signature and can not be trusted as an identity.
* *
* @param string $guid * @param string $guid
* @param string $guid_sig * @param string $guid_sig
@ -124,6 +126,7 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot
if ($recipients) { if ($recipients) {
for ($x = 0; $x < count($recipients); $x ++) for ($x = 0; $x < count($recipients); $x ++)
unset($recipients[$x]['hash']); unset($recipients[$x]['hash']);
$data['recipients'] = $recipients; $data['recipients'] = $recipients;
} }
@ -493,10 +496,10 @@ function zot_refresh($them, $channel = null, $force = false) {
if($new_connection) { if($new_connection) {
require_once('include/enotify.php'); require_once('include/enotify.php');
notification(array( notification(array(
'type' => NOTIFY_INTRO, 'type' => NOTIFY_INTRO,
'from_xchan' => $x['hash'], 'from_xchan' => $x['hash'],
'to_xchan' => $channel['channel_hash'], 'to_xchan' => $channel['channel_hash'],
'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id'], 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id'],
)); ));
} }
@ -510,6 +513,7 @@ function zot_refresh($them, $channel = null, $force = false) {
} }
return true; return true;
} }
return false; return false;
} }
@ -521,7 +525,7 @@ function zot_refresh($them, $channel = null, $force = false) {
* This function looks these up to see if the channel is known and therefore * This function looks these up to see if the channel is known and therefore
* previously verified. If not, we will need to verify it. * previously verified. If not, we will need to verify it.
* *
* @param array $arr an assoziative array which must contain: * @param array $arr an associative array which must contain:
* * \e string \b guid => guid of conversant * * \e string \b guid => guid of conversant
* * \e string \b guid_sig => guid signed with conversant's private key * * \e string \b guid_sig => guid signed with conversant's private key
* * \e string \b url => URL of the origination hub of this communication * * \e string \b url => URL of the origination hub of this communication
@ -564,6 +568,7 @@ function zot_gethub($arr) {
} }
} }
logger('zot_gethub: not found: ' . print_r($arr,true), LOGGER_DEBUG); logger('zot_gethub: not found: ' . print_r($arr,true), LOGGER_DEBUG);
return null; return null;
} }
@ -575,13 +580,13 @@ function zot_gethub($arr) {
* origination address. This will fetch the discovery packet of the sender, * origination address. This will fetch the discovery packet of the sender,
* which contains the public key we need to verify our guid and url signatures. * which contains the public key we need to verify our guid and url signatures.
* *
* @param array $arr an assoziative array which must contain: * @param array $arr an associative array which must contain:
* * \e string \b guid => guid of conversant * * \e string \b guid => guid of conversant
* * \e string \b guid_sig => guid signed with conversant's private key * * \e string \b guid_sig => guid signed with conversant's private key
* * \e string \b url => URL of the origination hub of this communication * * \e string \b url => URL of the origination hub of this communication
* * \e string \b url_sig => URL signed with conversant's private key * * \e string \b url_sig => URL signed with conversant's private key
* *
* @returns array an assoziative array with: * @returns array an associative array with
* * \b success boolean true or false * * \b success boolean true or false
* * \b message (optional) error string only if success is false * * \b message (optional) error string only if success is false
*/ */
@ -754,8 +759,9 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
} else { } else {
$import_photos = true; $import_photos = true;
if((($arr['site']['directory_mode'] === 'standalone') || ($dirmode & DIRECTORY_MODE_STANDALONE)) if((($arr['site']['directory_mode'] === 'standalone')
&& ($arr['site']['url'] != z_root())) || ($dirmode & DIRECTORY_MODE_STANDALONE))
&& ($arr['site']['url'] != z_root()))
$arr['searchable'] = false; $arr['searchable'] = false;
$hidden = (1 - intval($arr['searchable'])); $hidden = (1 - intval($arr['searchable']));
@ -882,7 +888,6 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
// including the parent realm in the name. e.g. 'RED_GLOBAL:foo' would allow an entry to // including the parent realm in the name. e.g. 'RED_GLOBAL:foo' would allow an entry to
// be in directories for the local realm (foo) and also the RED_GLOBAL realm. // be in directories for the local realm (foo) and also the RED_GLOBAL realm.
if(array_key_exists('profile',$arr) && is_array($arr['profile']) && (! $other_realm)) { if(array_key_exists('profile',$arr) && is_array($arr['profile']) && (! $other_realm)) {
$profile_changed = import_directory_profile($xchan_hash,$arr['profile'],$address,$ud_flags, 1); $profile_changed = import_directory_profile($xchan_hash,$arr['profile'],$address,$ud_flags, 1);
if($profile_changed) { if($profile_changed) {
@ -1051,14 +1056,14 @@ function zot_fetch($arr) {
*/ */
function zot_import($arr, $sender_url) { function zot_import($arr, $sender_url) {
$data = json_decode($arr['body'],true); $data = json_decode($arr['body'], true);
if(! $data) { if(! $data) {
logger('zot_import: empty body'); logger('zot_import: empty body');
return array(); return array();
} }
if(array_key_exists('iv',$data)) { if(array_key_exists('iv', $data)) {
$data = json_decode(crypto_unencapsulate($data,get_config('system','prvkey')),true); $data = json_decode(crypto_unencapsulate($data,get_config('system','prvkey')),true);
} }
@ -1244,19 +1249,18 @@ function zot_import($arr, $sender_url) {
return $return; return $return;
} }
// A public message with no listed recipients can be delivered to anybody who
// has PERMS_NETWORK for that type of post, PERMS_AUTHED (in-network senders are
// by definition authenticated) or PERMS_SITE and is one the same
// site, or PERMS_SPECIFIC and the sender is a contact who is granted
// permissions via their connection permissions in the address book.
// Here we take a given message and construct a list of hashes of everybody
// on the site that we should try and deliver to.
// Some of these will be rejected, but this gives us a place to start.
/** /**
* @brief * @brief
* *
* A public message with no listed recipients can be delivered to anybody who
* has PERMS_NETWORK for that type of post, PERMS_AUTHED (in-network senders are
* by definition authenticated) or PERMS_SITE and is one the same site,
* or PERMS_SPECIFIC and the sender is a contact who is granted permissions via
* their connection permissions in the address book.
* Here we take a given message and construct a list of hashes of everybody
* on the site that we should try and deliver to.
* Some of these will be rejected, but this gives us a place to start.
*
* @param array $msg * @param array $msg
* @return NULL|array * @return NULL|array
*/ */
@ -1320,15 +1324,16 @@ function public_recips($msg) {
// First find those channels who are accepting posts from anybody, or at least // First find those channels who are accepting posts from anybody, or at least
// something greater than just their connections. // something greater than just their connections.
if($msg['notify']['sender']['url'] === z_root()) if($msg['notify']['sender']['url'] === z_root()) {
$sql = " where (( " . $col . " & " . intval(PERMS_NETWORK) . " ) > 0 $sql = " where (( " . $col . " & " . intval(PERMS_NETWORK) . " ) > 0
or ( " . $col . " & " . intval(PERMS_SITE) . " ) > 0 or ( " . $col . " & " . intval(PERMS_SITE) . " ) > 0
or ( " . $col . " & " . intval(PERMS_PUBLIC) . ") > 0 or ( " . $col . " & " . intval(PERMS_PUBLIC) . ") > 0
or ( " . $col . " & " . intval(PERMS_AUTHED) . ") > 0 ) "; or ( " . $col . " & " . intval(PERMS_AUTHED) . ") > 0 ) ";
else } else {
$sql = " where (( " . $col . " & " . intval(PERMS_NETWORK) . " ) > 0 $sql = " where (( " . $col . " & " . intval(PERMS_NETWORK) . " ) > 0
or ( " . $col . " & " . intval(PERMS_PUBLIC) . ") > 0 or ( " . $col . " & " . intval(PERMS_PUBLIC) . ") > 0
or ( " . $col . " & " . intval(PERMS_AUTHED) . ") > 0 ) "; or ( " . $col . " & " . intval(PERMS_AUTHED) . ") > 0 ) ";
}
$r = q("select channel_hash as hash from channel $sql or channel_hash = '%s' $r = q("select channel_hash as hash from channel $sql or channel_hash = '%s'
and ( channel_pageflags & " . intval(PAGE_REMOVED) . " ) = 0 ", and ( channel_pageflags & " . intval(PAGE_REMOVED) . " ) = 0 ",
@ -1419,9 +1424,18 @@ function public_recips($msg) {
return $r; return $r;
} }
// This is the second part of the above function. We'll find all the channels willing to accept public posts from us, /**
// then match them against the sender privacy scope and see who in that list that the sender is allowing. * @brief
*
* This is the second part of public_recipes().
* We'll find all the channels willing to accept public posts from us, then
* match them against the sender privacy scope and see who in that list that
* the sender is allowing.
*
* @see public_recipes()
* @param array $msg
* @return array
*/
function allowed_public_recips($msg) { function allowed_public_recips($msg) {
logger('allowed_public_recips: ' . print_r($msg,true),LOGGER_DATA); logger('allowed_public_recips: ' . print_r($msg,true),LOGGER_DATA);
@ -1483,12 +1497,21 @@ function allowed_public_recips($msg) {
return array(); return array();
} }
/**
function process_delivery($sender,$arr,$deliveries,$relay,$public = false,$request = false) { * @brief
*
* @param array $sender
* @param array $arr
* @param array $deliveries
* @param boolean $relay
* @param boolean $public (optional) default false
* @param boolean $request (optional) default false
* @return array
*/
function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $request = false) {
$result = array(); $result = array();
// We've validated the sender. Now make sure that the sender is the owner or author // We've validated the sender. Now make sure that the sender is the owner or author
if(! $public) { if(! $public) {
@ -1505,7 +1528,7 @@ function process_delivery($sender,$arr,$deliveries,$relay,$public = false,$reque
); );
if(! $r) { if(! $r) {
$result[] = array($d['hash'],'recipients not found'); $result[] = array($d['hash'], 'recipients not found');
continue; continue;
} }
@ -1689,8 +1712,8 @@ function process_delivery($sender,$arr,$deliveries,$relay,$public = false,$reque
// if it's a sourced post, call the post_local hooks as if it were // if it's a sourced post, call the post_local hooks as if it were
// posted locally so that crosspost connectors will be triggered. // posted locally so that crosspost connectors will be triggered.
if(check_item_source($arr['uid'],$arr)) if(check_item_source($arr['uid'], $arr))
call_hooks('post_local',$arr); call_hooks('post_local', $arr);
$item_result = item_store($arr); $item_result = item_store($arr);
$item_id = 0; $item_id = 0;
@ -1713,17 +1736,27 @@ function process_delivery($sender,$arr,$deliveries,$relay,$public = false,$reque
} }
if(! $deliveries) if(! $deliveries)
$result[] = array('','no recipients','',$arr['mid']); $result[] = array('', 'no recipients', '', $arr['mid']);
logger('process_delivery: local results: ' . print_r($result,true), LOGGER_DEBUG); logger('process_delivery: local results: ' . print_r($result, true), LOGGER_DEBUG);
return $result; return $result;
} }
/**
* @brief
*
* @param array $sender an associative array with
* * \e string \b hash a xchan_hash
* @param array $arr an associative array
* * \e int \b verb
* * \e int \b obj_type
* * \e int \b mid
* @param int $uid
*/
function remove_community_tag($sender, $arr, $uid) {
function remove_community_tag($sender,$arr,$uid) { if(! (activity_match($arr['verb'], ACTIVITY_TAG) && ($arr['obj_type'] == ACTIVITY_OBJ_TAGTERM)))
if(! (activity_match($arr['verb'],ACTIVITY_TAG) && ($arr['obj_type'] == ACTIVITY_OBJ_TAGTERM)))
return; return;
logger('remove_community_tag: invoked'); logger('remove_community_tag: invoked');
@ -1780,7 +1813,15 @@ function remove_community_tag($sender,$arr,$uid) {
); );
} }
function update_imported_item($sender,$item,$uid) { /**
* @brief Just calls item_store_update() and logs result.
*
* @see item_store_update()
* @param array $sender (unused)
* @param array $item
* @param int $uid (unused)
*/
function update_imported_item($sender, $item, $uid) {
$x = item_store_update($item); $x = item_store_update($item);
if(! $x['item_id']) if(! $x['item_id'])
@ -1793,9 +1834,10 @@ function update_imported_item($sender,$item,$uid) {
* @brief Deletes an imported item. * @brief Deletes an imported item.
* *
* @param array $sender * @param array $sender
* * \e string \b hash a xchan_hash
* @param array $item * @param array $item
* @param int $uid * @param int $uid
* @param unknown $relay * @param boolean $relay
* @return boolean|int post_id * @return boolean|int post_id
*/ */
function delete_imported_item($sender, $item, $uid, $relay) { function delete_imported_item($sender, $item, $uid, $relay) {
@ -1872,7 +1914,7 @@ function delete_imported_item($sender, $item, $uid, $relay) {
return $post_id; return $post_id;
} }
function process_mail_delivery($sender,$arr,$deliveries) { function process_mail_delivery($sender, $arr, $deliveries) {
$result = array(); $result = array();
@ -1923,13 +1965,20 @@ function process_mail_delivery($sender,$arr,$deliveries) {
$arr['channel_id'] = $channel['channel_id']; $arr['channel_id'] = $channel['channel_id'];
$item_id = mail_store($arr); $item_id = mail_store($arr);
$result[] = array($d['hash'],'mail delivered',$channel['channel_name'],$arr['mid']); $result[] = array($d['hash'],'mail delivered',$channel['channel_name'],$arr['mid']);
} }
} }
return $result; return $result;
} }
function process_rating_delivery($sender,$arr) { /**
* @brief Processes delivery of rating.
*
* @param array $sender
* * \e string \b hash a xchan_hash
* @param array $arr
*/
function process_rating_delivery($sender, $arr) {
logger('process_rating_delivery: ' . print_r($arr,true)); logger('process_rating_delivery: ' . print_r($arr,true));
@ -1979,8 +2028,16 @@ function process_rating_delivery($sender,$arr) {
} }
} }
/**
function process_profile_delivery($sender,$arr,$deliveries) { * @brief Processes delivery of profile.
*
* @see import_directory_profile()
* @param array $sender an associative array
* * \e string \b hash a xchan_hash
* @param array $arr
* @param array $deliveries (unused)
*/
function process_profile_delivery($sender, $arr, $deliveries) {
logger('process_profile_delivery', LOGGER_DEBUG); logger('process_profile_delivery', LOGGER_DEBUG);
@ -1988,7 +2045,7 @@ function process_profile_delivery($sender,$arr,$deliveries) {
dbesc($sender['hash']) dbesc($sender['hash'])
); );
if($r) if($r)
import_directory_profile($sender['hash'],$arr,$r[0]['xchan_addr'], UPDATE_FLAGS_UPDATED, 0); import_directory_profile($sender['hash'], $arr, $r[0]['xchan_addr'], UPDATE_FLAGS_UPDATED, 0);
} }
function process_location_delivery($sender,$arr,$deliveries) { function process_location_delivery($sender,$arr,$deliveries) {
@ -2001,6 +2058,7 @@ function process_location_delivery($sender,$arr,$deliveries) {
); );
if($r) if($r)
$sender['key'] = $r[0]['xchan_pubkey']; $sender['key'] = $r[0]['xchan_pubkey'];
if(array_key_exists('locations',$arr) && $arr['locations']) { if(array_key_exists('locations',$arr) && $arr['locations']) {
$x = sync_locations($sender,$arr,true); $x = sync_locations($sender,$arr,true);
logger('process_location_delivery: results: ' . print_r($x,true), LOGGER_DEBUG); logger('process_location_delivery: results: ' . print_r($x,true), LOGGER_DEBUG);
@ -2011,8 +2069,15 @@ function process_location_delivery($sender,$arr,$deliveries) {
} }
} }
/**
function sync_locations($sender,$arr,$absolute = false) { * @brief Synchronises locations.
*
* @param array $sender
* @param array $arr
* @param boolean $absolute (optional) default false
* @return array
*/
function sync_locations($sender, $arr, $absolute = false) {
$ret = array(); $ret = array();
@ -2244,9 +2309,9 @@ function sync_locations($sender,$arr,$absolute = false) {
* @brief Returns an array with all known distinct hubs for this channel. * @brief Returns an array with all known distinct hubs for this channel.
* *
* @see zot_get_hublocs() * @see zot_get_hublocs()
* @param array $channel an assoziative array which must contain * @param array $channel an associative array which must contain
* * \e string \b channel_hash the hash of the channel * * \e string \b channel_hash the hash of the channel
* @return array an array with assoziated arrays * @return array an array with associative arrays
*/ */
function zot_encode_locations($channel) { function zot_encode_locations($channel) {
$ret = array(); $ret = array();
@ -2272,7 +2337,6 @@ function zot_encode_locations($channel) {
return $ret; return $ret;
} }
/** /**
* @brief Imports a directory profile. * @brief Imports a directory profile.
* *
@ -2412,7 +2476,13 @@ function import_directory_profile($hash, $profile, $addr, $ud_flags = UPDATE_FLA
return $d['update']; return $d['update'];
} }
function import_directory_keywords($hash,$keywords) { /**
* @brief
*
* @param string $hash
* @param array $keywords
*/
function import_directory_keywords($hash, $keywords) {
$existing = array(); $existing = array();
$r = q("select * from xtag where xtag_hash = '%s'", $r = q("select * from xtag where xtag_hash = '%s'",
@ -2426,31 +2496,39 @@ function import_directory_keywords($hash,$keywords) {
$clean = array(); $clean = array();
foreach($keywords as $kw) { foreach($keywords as $kw) {
$kw = trim(htmlspecialchars($kw,ENT_COMPAT,'UTF-8',false)); $kw = trim(htmlspecialchars($kw,ENT_COMPAT, 'UTF-8', false));
$kw = trim($kw,','); $kw = trim($kw, ',');
$clean[] = $kw; $clean[] = $kw;
} }
foreach($existing as $x) { foreach($existing as $x) {
if(! in_array($x,$clean)) if(! in_array($x, $clean))
$r = q("delete from xtag where xtag_hash = '%s' and xtag_term = '%s'", $r = q("delete from xtag where xtag_hash = '%s' and xtag_term = '%s'",
dbesc($hash), dbesc($hash),
dbesc($x) dbesc($x)
); );
} }
foreach($clean as $x) { foreach($clean as $x) {
if(! in_array($x,$existing)) if(! in_array($x, $existing)) {
$r = q("insert into xtag ( xtag_hash, xtag_term) values ( '%s' ,'%s' )", $r = q("insert into xtag ( xtag_hash, xtag_term) values ( '%s' ,'%s' )",
dbesc($hash), dbesc($hash),
dbesc($x) dbesc($x)
); );
}
} }
} }
/**
* @brief
*
* @param string $hash
* @param string $guid
* @param string $addr
* @param int $flags (optional) default 0
*/
function update_modtime($hash, $guid, $addr, $flags = 0) {
function update_modtime($hash,$guid,$addr,$flags = 0) { $dirmode = intval(get_config('system', 'directory_mode'));
$dirmode = intval(get_config('system','directory_mode'));
if($dirmode == DIRECTORY_MODE_NORMAL) if($dirmode == DIRECTORY_MODE_NORMAL)
return; return;
@ -2473,12 +2551,18 @@ function update_modtime($hash,$guid,$addr,$flags = 0) {
} }
} }
/**
function import_site($arr,$pubkey) { * @brief
*
* @param array $arr
* @param string $pubkey
* @return boolean true if updated or inserted
*/
function import_site($arr, $pubkey) {
if( (! is_array($arr)) || (! $arr['url']) || (! $arr['url_sig'])) if( (! is_array($arr)) || (! $arr['url']) || (! $arr['url_sig']))
return false; return false;
if(! rsa_verify($arr['url'],base64url_decode($arr['url_sig']),$pubkey)) { if(! rsa_verify($arr['url'], base64url_decode($arr['url_sig']), $pubkey)) {
logger('import_site: bad url_sig'); logger('import_site: bad url_sig');
return false; return false;
} }
@ -2546,8 +2630,8 @@ function import_site($arr,$pubkey) {
// flubbed up this badly already, don't let them be directory servers at all. // flubbed up this badly already, don't let them be directory servers at all.
if(($site_directory === DIRECTORY_MODE_PRIMARY) if(($site_directory === DIRECTORY_MODE_PRIMARY)
&& ($site_realm === get_directory_realm()) && ($site_realm === get_directory_realm())
&& ($arr['url'] != get_directory_primary())) { && ($arr['url'] != get_directory_primary())) {
$site_directory = DIRECTORY_MODE_NORMAL; $site_directory = DIRECTORY_MODE_NORMAL;
} }
@ -2614,8 +2698,11 @@ function import_site($arr,$pubkey) {
/** /**
* Send a zot packet to all hubs where this channel is duplicated, refreshing * Send a zot packet to all hubs where this channel is duplicated, refreshing
* such things as personal settings, channel permissions, address book updates, etc. * such things as personal settings, channel permissions, address book updates, etc.
*
* @param int $uid
* @param array $packet (optional) default null
* @param boolean $groups_changed (optional) default false
*/ */
function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) { function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
$a = get_app(); $a = get_app();
@ -2623,7 +2710,7 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
logger('build_sync_packet'); logger('build_sync_packet');
if($packet) if($packet)
logger('packet: ' . print_r($packet,true),LOGGER_DATA); logger('packet: ' . print_r($packet, true),LOGGER_DATA);
if(! $uid) if(! $uid)
$uid = local_channel(); $uid = local_channel();
@ -2651,6 +2738,7 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
foreach($h as $x) { foreach($h as $x) {
if($x['hubloc_host'] == $a->get_hostname()) if($x['hubloc_host'] == $a->get_hostname())
continue; continue;
$synchubs[] = $x; $synchubs[] = $x;
} }
@ -2708,7 +2796,6 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
); );
if($r) if($r)
$info['collection_members'] = $r; $info['collection_members'] = $r;
} }
$interval = ((get_config('system','delivery_interval') !== false) $interval = ((get_config('system','delivery_interval') !== false)
@ -2733,13 +2820,21 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
dbesc(json_encode($info)) dbesc(json_encode($info))
); );
proc_run('php','include/deliver.php',$hash); proc_run('php', 'include/deliver.php', $hash);
if($interval) if($interval)
@time_sleep_until(microtime(true) + (float) $interval); @time_sleep_until(microtime(true) + (float) $interval);
} }
} }
function process_channel_sync_delivery($sender,$arr,$deliveries) { /**
* @brief
*
* @param array $sender
* @param array $arr
* @param array $deliveries
* @return array
*/
function process_channel_sync_delivery($sender, $arr, $deliveries) {
/** @FIXME this will sync red structures (channel, pconfig and abook). Eventually we need to make this application agnostic. */ /** @FIXME this will sync red structures (channel, pconfig and abook). Eventually we need to make this application agnostic. */
@ -2979,14 +3074,16 @@ function process_channel_sync_delivery($sender,$arr,$deliveries) {
// now sync the members // now sync the members
if(array_key_exists('collection_members',$arr) && if(array_key_exists('collection_members', $arr)
is_array($arr['collection_members']) && count($arr['collection_members'])) { && is_array($arr['collection_members'])
&& count($arr['collection_members'])) {
// first sort into groups keyed by the group hash // first sort into groups keyed by the group hash
$members = array(); $members = array();
foreach($arr['collection_members'] as $cm) { foreach($arr['collection_members'] as $cm) {
if(! array_key_exists($cm['collection'],$members)) if(! array_key_exists($cm['collection'],$members))
$members[$cm['collection']] = array(); $members[$cm['collection']] = array();
$members[$cm['collection']][] = $cm['member']; $members[$cm['collection']][] = $cm['member'];
} }
@ -3087,8 +3184,15 @@ function process_channel_sync_delivery($sender,$arr,$deliveries) {
return $result; return $result;
} }
// We probably should make rpost discoverable. /**
* @brief Returns path to /rpost
*
* @todo We probably should make rpost discoverable.
*
* @param array $observer
* * \e string \b xchan_url
* @return string
*/
function get_rpost_path($observer) { function get_rpost_path($observer) {
if(! $observer) if(! $observer)
return ''; return '';
@ -3098,7 +3202,6 @@ function get_rpost_path($observer) {
return $parsed['scheme'] . '://' . $parsed['host'] . (($parsed['port']) ? ':' . $parsed['port'] : '') . '/rpost?f='; return $parsed['scheme'] . '://' . $parsed['host'] . (($parsed['port']) ? ':' . $parsed['port'] : '') . '/rpost?f=';
} }
/** /**
* @brief * @brief
* *
@ -3127,7 +3230,6 @@ function import_author_zot($x) {
return false; return false;
} }
/** /**
* @brief Process a message request. * @brief Process a message request.
* *