Correct and extend Doxygen comments.

Correct some documentation errors for Doxygen and add
more comments.
Document some undefined variables with @FIXME.
This commit is contained in:
Klaus Weidenbach 2019-01-18 22:17:10 +01:00
parent 51a7be29f5
commit 13e0151cd2
12 changed files with 351 additions and 273 deletions

View File

@ -2,11 +2,6 @@
namespace Zotlabs\Lib; namespace Zotlabs\Lib;
/**
* @brief lowlevel implementation of Zot6 protocol.
*
*/
use Zotlabs\Zot6\HTTPSig; use Zotlabs\Zot6\HTTPSig;
use Zotlabs\Access\Permissions; use Zotlabs\Access\Permissions;
use Zotlabs\Access\PermissionLimits; use Zotlabs\Access\PermissionLimits;
@ -14,14 +9,17 @@ use Zotlabs\Daemon\Master;
require_once('include/crypto.php'); require_once('include/crypto.php');
/**
* @brief Lowlevel implementation of Zot6 protocol.
*
*/
class Libzot { class Libzot {
/** /**
* @brief Generates a unique string for use as a zot guid. * @brief Generates a unique string for use as a zot guid.
* *
* Generates a unique string for use as a zot guid using our DNS-based url, the * Generates a unique string for use as a zot guid using our DNS-based url,
* channel nickname and some entropy. * the channel nickname and some entropy.
* The entropy ensures uniqueness against re-installs where the same URL and * The entropy ensures uniqueness against re-installs where the same URL and
* nickname are chosen. * nickname are chosen.
* *
@ -32,9 +30,8 @@ class Libzot {
* immediate universe. * immediate universe.
* *
* @param string $channel_nick a unique nickname of controlling entity * @param string $channel_nick a unique nickname of controlling entity
* @returns string * @return string
*/ */
static function new_uid($channel_nick) { static function 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));
@ -52,8 +49,8 @@ class Libzot {
* *
* @param string $guid * @param string $guid
* @param string $pubkey * @param string $pubkey
* @return string
*/ */
static function make_xchan_hash($guid, $pubkey) { static function make_xchan_hash($guid, $pubkey) {
return base64url_encode(hash('whirlpool', $guid . $pubkey, true)); return base64url_encode(hash('whirlpool', $guid . $pubkey, true));
} }
@ -65,10 +62,8 @@ class Libzot {
* should only be used by channels which are defined on this hub. * should only be used by channels which are defined on this hub.
* *
* @param string $hash - xchan_hash * @param string $hash - xchan_hash
* @returns array of hubloc (hub location structures) * @return array of hubloc (hub location structures)
*
*/ */
static function get_hublocs($hash) { static function get_hublocs($hash) {
/* Only search for active hublocs - e.g. those that haven't been marked deleted */ /* Only search for active hublocs - e.g. those that haven't been marked deleted */
@ -92,16 +87,17 @@ class Libzot {
* packet type: one of 'ping', 'pickup', 'purge', 'refresh', 'keychange', 'force_refresh', 'notify', 'auth_check' * packet type: one of 'ping', 'pickup', 'purge', 'refresh', 'keychange', 'force_refresh', 'notify', 'auth_check'
* @param array $recipients * @param array $recipients
* envelope recipients, array of portable_id's; empty for public posts * envelope recipients, array of portable_id's; empty for public posts
* @param string msg * @param string $msg
* optional message * optional message
* @param string $encoding
* optional encoding, default 'activitystreams'
* @param string $remote_key * @param string $remote_key
* optional public site key of target hub used to encrypt entire packet * optional public site key of target hub used to encrypt entire packet
* NOTE: remote_key and encrypted packets are required for 'auth_check' packets, optional for all others * NOTE: remote_key and encrypted packets are required for 'auth_check' packets, optional for all others
* @param string $methods * @param string $methods
* optional comma separated list of encryption methods @ref self::best_algorithm() * optional comma separated list of encryption methods @ref best_algorithm()
* @returns string json encoded zot packet * @returns string json encoded zot packet
*/ */
static function build_packet($channel, $type = 'activity', $recipients = null, $msg = '', $encoding = 'activitystreams', $remote_key = null, $methods = '') { static function build_packet($channel, $type = 'activity', $recipients = null, $msg = '', $encoding = 'activitystreams', $remote_key = null, $methods = '') {
$sig_method = get_config('system','signature_algorithm','sha256'); $sig_method = get_config('system','signature_algorithm','sha256');
@ -146,11 +142,10 @@ class Libzot {
* @brief Choose best encryption function from those available on both sites. * @brief Choose best encryption function from those available on both sites.
* *
* @param string $methods * @param string $methods
* comma separated list of encryption methods * Comma separated list of encryption methods
* @return string first match from our site method preferences crypto_methods() array * @return string first match from our site method preferences crypto_methods() array
* of a method which is common to both sites; or 'aes256cbc' if no matches are found. * of a method which is common to both sites; or 'aes256cbc' if no matches are found.
*/ */
static function best_algorithm($methods) { static function best_algorithm($methods) {
$x = [ $x = [
@ -164,7 +159,6 @@ class Libzot {
* * \e string \b methods - comma separated list of encryption methods * * \e string \b methods - comma separated list of encryption methods
* * \e string \b result - the algorithm to return * * \e string \b result - the algorithm to return
*/ */
call_hooks('zot_best_algorithm', $x); call_hooks('zot_best_algorithm', $x);
if($x['result']) if($x['result'])
@ -190,7 +184,7 @@ class Libzot {
/** /**
* @brief send a zot message * @brief Send a zot message.
* *
* @see z_post_url() * @see z_post_url()
* *
@ -200,18 +194,17 @@ class Libzot {
* @param array $crypto (required if encrypted httpsig, requires hubloc_sitekey and site_crypto elements) * @param array $crypto (required if encrypted httpsig, requires hubloc_sitekey and site_crypto elements)
* @return array see z_post_url() for returned data format * @return array see z_post_url() for returned data format
*/ */
static function zot($url, $data, $channel = null,$crypto = null) { static function zot($url, $data, $channel = null,$crypto = null) {
if($channel) { if($channel) {
$headers = [ $headers = [
'X-Zot-Token' => random_string(), 'X-Zot-Token' => random_string(),
'Digest' => HTTPSig::generate_digest_header($data), 'Digest' => HTTPSig::generate_digest_header($data),
'Content-type' => 'application/x-zot+json', 'Content-type' => 'application/x-zot+json',
'(request-target)' => 'post ' . get_request_string($url) '(request-target)' => 'post ' . get_request_string($url)
]; ];
$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false,'sha512', $h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false,'sha512',
(($crypto) ? [ 'key' => $crypto['hubloc_sitekey'], 'algorithm' => self::best_algorithm($crypto['site_crypto']) ] : false)); (($crypto) ? [ 'key' => $crypto['hubloc_sitekey'], 'algorithm' => self::best_algorithm($crypto['site_crypto']) ] : false));
} }
else { else {
@ -227,7 +220,6 @@ class Libzot {
/** /**
* @brief Refreshes after permission changed or friending, etc. * @brief Refreshes after permission changed or friending, etc.
* *
*
* refresh is typically invoked when somebody has changed permissions of a channel and they are notified * refresh is typically invoked when somebody has changed permissions of a channel and they are notified
* to fetch new permissions via a finger/discovery operation. This may result in a new connection * to fetch new permissions via a finger/discovery operation. This may result in a new connection
* (abook entry) being added to a local channel and it may result in auto-permissions being granted. * (abook entry) being added to a local channel and it may result in auto-permissions being granted.
@ -251,7 +243,6 @@ class Libzot {
* * \b true if successful * * \b true if successful
* * otherwise \b false * * otherwise \b false
*/ */
static function refresh($them, $channel = null, $force = false) { static function refresh($them, $channel = null, $force = false) {
logger('them: ' . print_r($them,true), LOGGER_DATA, LOG_DEBUG); logger('them: ' . print_r($them,true), LOGGER_DATA, LOG_DEBUG);
@ -265,7 +256,7 @@ class Libzot {
} }
else { else {
$r = null; $r = null;
// if they re-installed the server we could end up with the wrong record - pointing to the old install. // if they re-installed the server we could end up with the wrong record - pointing to the old install.
// We'll order by reverse id to try and pick off the newest one first and hopefully end up with the // We'll order by reverse id to try and pick off the newest one first and hopefully end up with the
// correct hubloc. If this doesn't work we may have to re-write this section to try them all. // correct hubloc. If this doesn't work we may have to re-write this section to try them all.
@ -317,6 +308,7 @@ class Libzot {
if(! $hsig_valid) { if(! $hsig_valid) {
logger('http signature not valid: ' . print_r($hsig,true)); logger('http signature not valid: ' . print_r($hsig,true));
/// @FIXME $result is undefined
return $result; return $result;
} }
@ -416,7 +408,7 @@ class Libzot {
if($y) { if($y) {
logger("New introduction received for {$channel['channel_name']}"); logger("New introduction received for {$channel['channel_name']}");
$new_perms = get_all_perms($channel['channel_id'],$x['hash'],false); $new_perms = get_all_perms($channel['channel_id'],$x['hash'],false);
// Send a clone sync packet and a permissions update if permissions have changed // Send a clone sync packet and a permissions update if permissions have changed
$new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 order by abook_created desc limit 1", $new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 order by abook_created desc limit 1",
@ -524,10 +516,14 @@ class Libzot {
return false; return false;
} }
/**
* @brief
*
static function valid_hub($sender,$site_id) { * @param string $sender
* @param string $site_id
* @return null|array
*/
static function valid_hub($sender, $site_id) {
$r = q("select hubloc.*, site.site_crypto from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and hubloc_site_id = '%s' limit 1", $r = q("select hubloc.*, site.site_crypto from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and hubloc_site_id = '%s' limit 1",
dbesc($sender), dbesc($sender),
@ -548,7 +544,6 @@ class Libzot {
} }
return $r[0]; return $r[0];
} }
/** /**
@ -559,21 +554,14 @@ class Libzot {
* 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 associative array which must contain: * @param string $id
* * \e string \b guid => guid of conversant
* * \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_sig => URL signed with conversant's private key
* *
* @return array An associative array with * @return array An associative array with
* * \b success boolean true or false * * \e boolean \b success
* * \b message (optional) error string only if success is false * * \e string \b message (optional, unused) error string only if success is false
*/ */
static function register_hub($id) { static function register_hub($id) {
$id_hash = false;
$valid = false;
$hsig_valid = false; $hsig_valid = false;
$result = [ 'success' => false ]; $result = [ 'success' => false ];
@ -807,7 +795,7 @@ class Libzot {
// If setting for the default profile, unset the profile photo flag from any other photos I own // If setting for the default profile, unset the profile photo flag from any other photos I own
if($is_default_profile) { if($is_default_profile) {
q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d", q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d",
intval(PHOTO_NORMAL), intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE), intval(PHOTO_PROFILE),
dbesc($hash), dbesc($hash),
@ -954,8 +942,8 @@ class Libzot {
* @param string $hub - url of site we just contacted * @param string $hub - url of site we just contacted
* @param array $arr - output of z_post_url() * @param array $arr - output of z_post_url()
* @param array $outq - The queue structure attached to this request * @param array $outq - The queue structure attached to this request
* @return void
*/ */
static function process_response($hub, $arr, $outq) { static function process_response($hub, $arr, $outq) {
logger('remote: ' . print_r($arr,true),LOGGER_DATA); logger('remote: ' . print_r($arr,true),LOGGER_DATA);
@ -986,7 +974,7 @@ class Libzot {
if(! $x['success']) { if(! $x['success']) {
// handle remote validation issues // handle remote validation issues
$b = q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'", $b = q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'",
dbesc(($x['message']) ? $x['message'] : 'unknown delivery error'), dbesc(($x['message']) ? $x['message'] : 'unknown delivery error'),
dbesc(datetime_convert()), dbesc(datetime_convert()),
@ -994,7 +982,7 @@ class Libzot {
); );
} }
if(is_array($x) && array_key_exists('delivery_report',$x) && is_array($x['delivery_report'])) { if(is_array($x) && array_key_exists('delivery_report',$x) && is_array($x['delivery_report'])) {
foreach($x['delivery_report'] as $xx) { foreach($x['delivery_report'] as $xx) {
call_hooks('dreport_process',$xx); call_hooks('dreport_process',$xx);
@ -1083,11 +1071,6 @@ class Libzot {
* *
* @param array $arr * @param array $arr
* 'pickup' structure returned from remote site * 'pickup' structure returned from remote site
* @param string $sender_url
* the url specified by the sender in the initial communication.
* We will verify the sender and url in each returned message structure and
* also verify that all the messages returned match the site url that we are
* currently processing.
* *
* @returns array * @returns array
* Suitable for logging remotely, enumerating the processing results of each message/recipient combination * Suitable for logging remotely, enumerating the processing results of each message/recipient combination
@ -1095,7 +1078,6 @@ class Libzot {
* * [1] => \e string $delivery_status * * [1] => \e string $delivery_status
* * [2] => \e string $address * * [2] => \e string $address
*/ */
static function import($arr) { static function import($arr) {
$env = $arr; $env = $arr;
@ -1117,7 +1099,7 @@ class Libzot {
$has_data = array_key_exists('data',$env) && $env['data']; $has_data = array_key_exists('data',$env) && $env['data'];
$data = (($has_data) ? $env['data'] : false); $data = (($has_data) ? $env['data'] : false);
$AS = null; $AS = null;
if($env['encoding'] === 'activitystreams') { if($env['encoding'] === 'activitystreams') {
@ -1175,7 +1157,6 @@ class Libzot {
$deliveries = self::public_recips($env,$AS); $deliveries = self::public_recips($env,$AS);
} }
$deliveries = array_unique($deliveries); $deliveries = array_unique($deliveries);
@ -1196,7 +1177,7 @@ class Libzot {
$r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", $r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
dbesc($AS->actor['id']) dbesc($AS->actor['id'])
); );
if($r) { if($r) {
$arr['author_xchan'] = $r[0]['hubloc_hash']; $arr['author_xchan'] = $r[0]['hubloc_hash'];
@ -1205,20 +1186,20 @@ class Libzot {
$s = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", $s = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
dbesc($env['sender']) dbesc($env['sender'])
); );
// in individual delivery, change owner if needed // in individual delivery, change owner if needed
if($s) { if($s) {
$arr['owner_xchan'] = $s[0]['hubloc_hash']; $arr['owner_xchan'] = $s[0]['hubloc_hash'];
} }
else { else {
$arr['owner_xchan'] = $env['sender']; $arr['owner_xchan'] = $env['sender'];
} }
if($private) { if($private) {
$arr['item_private'] = true; $arr['item_private'] = true;
} }
// @fixme - spoofable /// @FIXME - spoofable
if($AS->data['hubloc']) { if($AS->data['hubloc']) {
$arr['item_verified'] = true; $arr['item_verified'] = true;
} }
@ -1247,12 +1228,19 @@ class Libzot {
} }
if ($result) { if ($result) {
$return = array_merge($return, $result); $return = array_merge($return, $result);
} }
return $return; return $return;
} }
static function is_top_level($env,$act) { /**
* @brief
*
* @param array $env
* @param object $act
* @return boolean
*/
static function is_top_level($env, $act) {
if($env['encoding'] === 'zot' && array_key_exists('flags',$env) && in_array('thread_parent', $env['flags'])) { if($env['encoding'] === 'zot' && array_key_exists('flags',$env) && in_array('thread_parent', $env['flags'])) {
return true; return true;
} }
@ -1295,9 +1283,9 @@ class Libzot {
* Some of these will be rejected, but this gives us a place to start. * Some of these will be rejected, but this gives us a place to start.
* *
* @param array $msg * @param array $msg
* @return NULL|array * @param object $act
* @return array
*/ */
static function public_recips($msg, $act) { static function public_recips($msg, $act) {
require_once('include/channel.php'); require_once('include/channel.php');
@ -1442,7 +1430,7 @@ class Libzot {
* will normally arrive first via sync delivery, but this isn't guaranteed. * will normally arrive first via sync delivery, but this isn't guaranteed.
* There's a chance the current delivery could take place before the cloned copy arrives * There's a chance the current delivery could take place before the cloned copy arrives
* hence the item could have the wrong ACL and *could* be used in subsequent deliveries or * hence the item could have the wrong ACL and *could* be used in subsequent deliveries or
* access checks. * access checks.
*/ */
if($sender === $channel['channel_portable_id'] && $arr['author_xchan'] === $channel['channel_portable_id'] && $arr['mid'] === $arr['parent_mid']) { if($sender === $channel['channel_portable_id'] && $arr['author_xchan'] === $channel['channel_portable_id'] && $arr['mid'] === $arr['parent_mid']) {
@ -1504,7 +1492,7 @@ class Libzot {
$allowed = true; $allowed = true;
$friendofriend = true; $friendofriend = true;
} }
if (! $allowed) { if (! $allowed) {
logger("permission denied for delivery to channel {$channel['channel_id']} {$channel['channel_address']}"); logger("permission denied for delivery to channel {$channel['channel_id']} {$channel['channel_address']}");
$DR->update('permission denied'); $DR->update('permission denied');
@ -1524,7 +1512,7 @@ class Libzot {
// this is so that permissions mismatches between senders apply to the entire conversation // this is so that permissions mismatches between senders apply to the entire conversation
// As a side effect we will also do a preliminary check that we have the top-level-post, otherwise // As a side effect we will also do a preliminary check that we have the top-level-post, otherwise
// processing it is pointless. // processing it is pointless.
$r = q("select route, id, owner_xchan, item_private from item where mid = '%s' and uid = %d limit 1", $r = q("select route, id, owner_xchan, item_private from item where mid = '%s' and uid = %d limit 1",
dbesc($arr['parent_mid']), dbesc($arr['parent_mid']),
intval($channel['channel_id']) intval($channel['channel_id'])
@ -1553,14 +1541,14 @@ class Libzot {
} }
continue; continue;
} }
if($relay || $friendofriend || (intval($r[0]['item_private']) === 0 && intval($arr['item_private']) === 0)) { if($relay || $friendofriend || (intval($r[0]['item_private']) === 0 && intval($arr['item_private']) === 0)) {
// reset the route in case it travelled a great distance upstream // reset the route in case it travelled a great distance upstream
// use our parent's route so when we go back downstream we'll match // use our parent's route so when we go back downstream we'll match
// with whatever route our parent has. // with whatever route our parent has.
// Also friend-of-friend conversations may have been imported without a route, // Also friend-of-friend conversations may have been imported without a route,
// but we are now getting comments via listener delivery // but we are now getting comments via listener delivery
// and if there is no privacy on this or the parent, we don't care about the route, // and if there is no privacy on this or the parent, we don't care about the route,
// so just set the owner and route accordingly. // so just set the owner and route accordingly.
$arr['route'] = $r[0]['route']; $arr['route'] = $r[0]['route'];
$arr['owner_xchan'] = $r[0]['owner_xchan']; $arr['owner_xchan'] = $r[0]['owner_xchan'];
@ -1614,13 +1602,13 @@ class Libzot {
// remove_community_tag is a no-op if this isn't a community tag activity // remove_community_tag is a no-op if this isn't a community tag activity
self::remove_community_tag($sender,$arr,$channel['channel_id']); self::remove_community_tag($sender,$arr,$channel['channel_id']);
// set these just in case we need to store a fresh copy of the deleted post. // set these just in case we need to store a fresh copy of the deleted post.
// This could happen if the delete got here before the original post did. // This could happen if the delete got here before the original post did.
$arr['aid'] = $channel['channel_account_id']; $arr['aid'] = $channel['channel_account_id'];
$arr['uid'] = $channel['channel_id']; $arr['uid'] = $channel['channel_id'];
$item_id = self::delete_imported_item($sender,$arr,$channel['channel_id'],$relay); $item_id = self::delete_imported_item($sender,$arr,$channel['channel_id'],$relay);
$DR->update(($item_id) ? 'deleted' : 'delete_failed'); $DR->update(($item_id) ? 'deleted' : 'delete_failed');
$result[] = $DR->get(); $result[] = $DR->get();
@ -1716,7 +1704,7 @@ class Libzot {
* * \e array \b item * * \e array \b item
* * \e array \b sender * * \e array \b sender
* * \e array \b channel * * \e array \b channel
*/ */
call_hooks('activity_received', $parr); call_hooks('activity_received', $parr);
// don't add a source route if it's a relay or later recipients will get a route mismatch // don't add a source route if it's a relay or later recipients will get a route mismatch
if(! $relay) if(! $relay)
@ -1783,7 +1771,7 @@ class Libzot {
$r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", $r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
dbesc($AS->actor['id']) dbesc($AS->actor['id'])
); );
if(! $r) { if(! $r) {
$y = import_author_xchan([ 'url' => $AS->actor['id'] ]); $y = import_author_xchan([ 'url' => $AS->actor['id'] ]);
@ -1791,7 +1779,7 @@ class Libzot {
$r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", $r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
dbesc($AS->actor['id']) dbesc($AS->actor['id'])
); );
} }
if(! $r) { if(! $r) {
logger('FOF Activity: no actor'); logger('FOF Activity: no actor');
continue; continue;
@ -1813,7 +1801,7 @@ class Libzot {
$s = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1", $s = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
dbesc($a['signature']['signer']) dbesc($a['signature']['signer'])
); );
if($s) { if($s) {
$arr['owner_xchan'] = $s[0]['hubloc_hash']; $arr['owner_xchan'] = $s[0]['hubloc_hash'];
@ -1822,7 +1810,7 @@ class Libzot {
$arr['owner_xchan'] = $a['signature']['signer']; $arr['owner_xchan'] = $a['signature']['signer'];
} }
// @fixme - spoofable /// @FIXME - spoofable
if($AS->data['hubloc']) { if($AS->data['hubloc']) {
$arr['item_verified'] = true; $arr['item_verified'] = true;
} }
@ -1836,7 +1824,7 @@ class Libzot {
$result = self::process_delivery($arr['owner_xchan'],$arr, [ $channel['channel_portable_id'] ],false,false,true); $result = self::process_delivery($arr['owner_xchan'],$arr, [ $channel['channel_portable_id'] ],false,false,true);
if ($result) { if ($result) {
$ret = array_merge($ret, $result); $ret = array_merge($ret, $result);
} }
} }
return $ret; return $ret;
@ -1853,8 +1841,8 @@ class Libzot {
* * \e int \b obj_type * * \e int \b obj_type
* * \e int \b mid * * \e int \b mid
* @param int $uid * @param int $uid
* @return void
*/ */
static function remove_community_tag($sender, $arr, $uid) { static 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)))
@ -1882,7 +1870,7 @@ class Libzot {
} }
$i = $r[0]; $i = $r[0];
if($i['target']) if($i['target'])
$i['target'] = json_decode($i['target'],true); $i['target'] = json_decode($i['target'],true);
if($i['object']) if($i['object'])
@ -1925,8 +1913,8 @@ class Libzot {
* @param array $orig * @param array $orig
* @param int $uid * @param int $uid
* @param boolean $tag_delivery * @param boolean $tag_delivery
* @return void|array
*/ */
static function update_imported_item($sender, $item, $orig, $uid, $tag_delivery) { static function update_imported_item($sender, $item, $orig, $uid, $tag_delivery) {
// If this is a comment being updated, remove any privacy information // If this is a comment being updated, remove any privacy information
@ -2066,7 +2054,7 @@ class Libzot {
} }
foreach($deliveries as $d) { foreach($deliveries as $d) {
$DR = new DReport(z_root(),$sender,$d,$arr['mid']); $DR = new DReport(z_root(),$sender,$d,$arr['mid']);
$r = q("select * from channel where channel_portable_id = '%s' limit 1", $r = q("select * from channel where channel_portable_id = '%s' limit 1",
@ -2085,7 +2073,7 @@ class Libzot {
if(! perm_is_allowed($channel['channel_id'],$sender,'post_mail')) { if(! perm_is_allowed($channel['channel_id'],$sender,'post_mail')) {
/* /*
* Always allow somebody to reply if you initiated the conversation. It's anti-social * Always allow somebody to reply if you initiated the conversation. It's anti-social
* and a bit rude to send a private message to somebody and block their ability to respond. * and a bit rude to send a private message to somebody and block their ability to respond.
* If you are being harrassed and want to put an end to it, delete the conversation. * If you are being harrassed and want to put an end to it, delete the conversation.
@ -2145,12 +2133,13 @@ class Libzot {
* @brief Processes delivery of profile. * @brief Processes delivery of profile.
* *
* @see import_directory_profile() * @see import_directory_profile()
*
* @param array $sender an associative array * @param array $sender an associative array
* * \e string \b hash a xchan_hash * * \e string \b hash a xchan_hash
* @param array $arr * @param array $arr
* @param array $deliveries (unused) * @param array $deliveries (unused)
* @return void
*/ */
static function process_profile_delivery($sender, $arr, $deliveries) { static function process_profile_delivery($sender, $arr, $deliveries) {
logger('process_profile_delivery', LOGGER_DEBUG); logger('process_profile_delivery', LOGGER_DEBUG);
@ -2171,6 +2160,7 @@ class Libzot {
* * \e string \b hash a xchan_hash * * \e string \b hash a xchan_hash
* @param array $arr * @param array $arr
* @param array $deliveries (unused) deliveries is irrelevant * @param array $deliveries (unused) deliveries is irrelevant
* @return void
*/ */
static function process_location_delivery($sender, $arr, $deliveries) { static function process_location_delivery($sender, $arr, $deliveries) {
@ -2188,7 +2178,7 @@ class Libzot {
$x = Libsync::sync_locations($xchan,$arr,true); $x = Libsync::sync_locations($xchan,$arr,true);
logger('results: ' . print_r($x,true), LOGGER_DEBUG); logger('results: ' . print_r($x,true), LOGGER_DEBUG);
if($x['changed']) { if($x['changed']) {
$guid = random_string() . '@' . App::get_hostname(); //$guid = random_string() . '@' . App::get_hostname();
Libzotdir::update_modtime($sender,$r[0]['xchan_guid'],$arr['locations'][0]['address'],UPDATE_FLAGS_UPDATED); Libzotdir::update_modtime($sender,$r[0]['xchan_guid'],$arr['locations'][0]['address'],UPDATE_FLAGS_UPDATED);
} }
} }
@ -2212,8 +2202,8 @@ class Libzot {
* *
* @param string $sender_hash A channel hash * @param string $sender_hash A channel hash
* @param array $locations * @param array $locations
* @return void
*/ */
static function check_location_move($sender_hash, $locations) { static function check_location_move($sender_hash, $locations) {
if(! $locations) if(! $locations)
@ -2255,7 +2245,6 @@ class Libzot {
} }
/** /**
* @brief Returns an array with all known distinct hubs for this channel. * @brief Returns an array with all known distinct hubs for this channel.
* *
@ -2264,7 +2253,6 @@ class Libzot {
* * \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 associative arrays * @return array an array with associative arrays
*/ */
static function encode_locations($channel) { static function encode_locations($channel) {
$ret = []; $ret = [];
@ -2305,7 +2293,7 @@ class Libzot {
if(! $z['site_id']) { if(! $z['site_id']) {
$z['site_id'] = Libzot::make_xchan_hash($z['url'],$z['sitekey']); $z['site_id'] = Libzot::make_xchan_hash($z['url'],$z['sitekey']);
} }
$ret[] = $z; $ret[] = $z;
} }
} }
@ -2318,10 +2306,8 @@ class Libzot {
* @brief * @brief
* *
* @param array $arr * @param array $arr
* @param string $pubkey
* @return boolean true if updated or inserted * @return boolean true if updated or inserted
*/ */
static function import_site($arr) { static function import_site($arr) {
if( (! is_array($arr)) || (! $arr['url']) || (! $arr['site_sig'])) if( (! is_array($arr)) || (! $arr['url']) || (! $arr['site_sig']))
@ -2600,16 +2586,16 @@ class Libzot {
dbesc($ztarget) dbesc($ztarget)
); );
if($t) { if($t) {
$ztarget_hash = $t[0]['hubloc_hash']; $ztarget_hash = $t[0]['hubloc_hash'];
} }
else { else {
// should probably perform discovery of the requestor (target) but if they actually had // should probably perform discovery of the requestor (target) but if they actually had
// permissions we would know about them and we only want to know who they are to // permissions we would know about them and we only want to know who they are to
// enumerate their specific permissions // enumerate their specific permissions
$ztarget_hash = EMPTY_STR; $ztarget_hash = EMPTY_STR;
} }
} }
@ -2756,7 +2742,7 @@ class Libzot {
$ret['id'] = $e['xchan_guid']; $ret['id'] = $e['xchan_guid'];
$ret['id_sig'] = self::sign($e['xchan_guid'], $e['channel_prvkey']); $ret['id_sig'] = self::sign($e['xchan_guid'], $e['channel_prvkey']);
$ret['primary_location'] = [ $ret['primary_location'] = [
'address' => $e['xchan_addr'], 'address' => $e['xchan_addr'],
'url' => $e['xchan_url'], 'url' => $e['xchan_url'],
'connections_url' => $e['xchan_connurl'], 'connections_url' => $e['xchan_connurl'],
@ -2778,7 +2764,7 @@ class Libzot {
$ret['searchable'] = $searchable; $ret['searchable'] = $searchable;
$ret['adult_content'] = $adult_channel; $ret['adult_content'] = $adult_channel;
$ret['public_forum'] = $public_forum; $ret['public_forum'] = $public_forum;
$ret['comments'] = map_scope(PermissionLimits::Get($e['channel_id'],'post_comments')); $ret['comments'] = map_scope(PermissionLimits::Get($e['channel_id'],'post_comments'));
$ret['mail'] = map_scope(PermissionLimits::Get($e['channel_id'],'post_mail')); $ret['mail'] = map_scope(PermissionLimits::Get($e['channel_id'],'post_mail'));
@ -2836,14 +2822,20 @@ class Libzot {
$ret['locations'] = $x; $ret['locations'] = $x;
$ret['site'] = self::site_info(); $ret['site'] = self::site_info();
/**
* @hooks zotinfo
* Hook to manipulate the zotinfo array before it is returned.
*/
call_hooks('zotinfo', $ret);
call_hooks('zotinfo',$ret); return $ret;
return($ret);
} }
/**
* @brief Get siteinfo.
*
* @return array
*/
static function site_info() { static function site_info() {
$signing_key = get_config('system','prvkey'); $signing_key = get_config('system','prvkey');
@ -2880,7 +2872,7 @@ class Libzot {
if($dirmode != DIRECTORY_MODE_STANDALONE) { if($dirmode != DIRECTORY_MODE_STANDALONE) {
$register_policy = intval(get_config('system','register_policy')); $register_policy = intval(get_config('system','register_policy'));
if($register_policy == REGISTER_CLOSED) if($register_policy == REGISTER_CLOSED)
$ret['site']['register_policy'] = 'closed'; $ret['site']['register_policy'] = 'closed';
if($register_policy == REGISTER_APPROVE) if($register_policy == REGISTER_APPROVE)
@ -2927,18 +2919,16 @@ class Libzot {
} }
return $ret['site']; return $ret['site'];
} }
/** /**
* @brief * @brief
* *
* @param array $hub * @param array $hub
* @param string $sitekey (optional, default empty) * @param string $site_id (optional, default empty)
* *
* @return string hubloc_url * @return string hubloc_url
*/ */
static function update_hub_connected($hub, $site_id = '') { static function update_hub_connected($hub, $site_id = '') {
if ($site_id) { if ($site_id) {
@ -2997,12 +2987,21 @@ class Libzot {
return $hub['hubloc_url']; return $hub['hubloc_url'];
} }
/**
* @brief
*
* @param string $data
* @param string $key
* @param string $alg (optional) default 'sha256'
* @return string
*/
static function sign($data,$key,$alg = 'sha256') { static function sign($data,$key,$alg = 'sha256') {
if(! $key) if(! $key)
return 'no key'; return 'no key';
$sig = ''; $sig = '';
openssl_sign($data,$sig,$key,$alg); openssl_sign($data,$sig,$key,$alg);
return $alg . '.' . base64url_encode($sig); return $alg . '.' . base64url_encode($sig);
} }
@ -3015,24 +3014,27 @@ class Libzot {
if ($key && count($x) === 2) { if ($key && count($x) === 2) {
$alg = $x[0]; $alg = $x[0];
$signature = base64url_decode($x[1]); $signature = base64url_decode($x[1]);
$verify = @openssl_verify($data,$signature,$key,$alg); $verify = @openssl_verify($data,$signature,$key,$alg);
if ($verify === (-1)) { if ($verify === (-1)) {
while ($msg = openssl_error_string()) { while ($msg = openssl_error_string()) {
logger('openssl_verify: ' . $msg,LOGGER_NORMAL,LOG_ERR); logger('openssl_verify: ' . $msg,LOGGER_NORMAL,LOG_ERR);
} }
btlogger('openssl_verify: key: ' . $key, LOGGER_DEBUG, LOG_ERR); btlogger('openssl_verify: key: ' . $key, LOGGER_DEBUG, LOG_ERR);
} }
} }
return(($verify > 0) ? true : false); return(($verify > 0) ? true : false);
} }
/**
* @brief
*
* @return boolean
*/
static function is_zot_request() { static function is_zot_request() {
$x = getBestSupportedMimeType([ 'application/x-zot+json' ]); $x = getBestSupportedMimeType([ 'application/x-zot+json' ]);
return(($x) ? true : false); return(($x) ? true : false);
} }

View File

@ -112,9 +112,11 @@ class PConfig {
* The configuration key to set * The configuration key to set
* @param string $value * @param string $value
* The value to store * The value to store
* @param string $updated (optional)
* The datetime to store
* @return mixed Stored $value or false * @return mixed Stored $value or false
*/ */
static public function Set($uid, $family, $key, $value, $updated=NULL) { static public function Set($uid, $family, $key, $value, $updated = NULL) {
// this catches subtle errors where this function has been called // this catches subtle errors where this function has been called
// with local_channel() when not logged in (which returns false) // with local_channel() when not logged in (which returns false)
@ -239,7 +241,9 @@ class PConfig {
* The category of the configuration value * The category of the configuration value
* @param string $key * @param string $key
* The configuration key to delete * The configuration key to delete
* @return mixed * @param string $updated (optional)
* The datetime to store
* @return boolean
*/ */
static public function Delete($uid, $family, $key, $updated = NULL) { static public function Delete($uid, $family, $key, $updated = NULL) {
@ -283,6 +287,7 @@ class PConfig {
if(! array_key_exists($family, \App::$config[$uid]['transient'])) if(! array_key_exists($family, \App::$config[$uid]['transient']))
\App::$config[$uid]['transient'][$family] = array(); \App::$config[$uid]['transient'][$family] = array();
/// @FIXME $new is undefined, so dead code
if ($new) { if ($new) {
\App::$config[$uid]['transient'][$family]['pcfgdel:'.$key] = $updated; \App::$config[$uid]['transient'][$family]['pcfgdel:'.$key] = $updated;
} }

View File

@ -10,9 +10,13 @@ require_once('include/channel.php');
require_once('include/conversation.php'); require_once('include/conversation.php');
require_once('include/acl_selectors.php'); require_once('include/acl_selectors.php');
/**
* @brief Provides the Cards module.
*
*/
class Cards extends Controller { class Cards extends Controller {
function init() { public function init() {
if(argc() > 1) if(argc() > 1)
$which = argv(1); $which = argv(1);
@ -20,14 +24,15 @@ class Cards extends Controller {
return; return;
profile_load($which); profile_load($which);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
* @see \Zotlabs\Web\Controller::get() * @see \\Zotlabs\\Web\\Controller::get()
*
* @return string Parsed HTML from template 'cards.tpl'
*/ */
function get($update = 0, $load = false) { public function get($update = 0, $load = false) {
if(observer_prohibited(true)) { if(observer_prohibited(true)) {
return login(); return login();
@ -99,7 +104,6 @@ class Cards extends Controller {
} }
if(perm_is_allowed($owner, $ob_hash, 'write_pages')) { if(perm_is_allowed($owner, $ob_hash, 'write_pages')) {
$x = [ $x = [
@ -110,7 +114,7 @@ class Cards extends Controller {
'nickname' => $channel['channel_address'], 'nickname' => $channel['channel_address'],
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] 'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid']
|| $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
'acl' => (($is_owner) ? populate_acl($channel_acl, false, 'acl' => (($is_owner) ? populate_acl($channel_acl, false,
PermissionDescription::fromGlobalPermission('view_pages')) : ''), PermissionDescription::fromGlobalPermission('view_pages')) : ''),
'permissions' => $channel_acl, 'permissions' => $channel_acl,
'showacl' => (($is_owner) ? true : false), 'showacl' => (($is_owner) ? true : false),

View File

@ -29,7 +29,7 @@ class Zot6Handler implements IHandler {
// Implementation of specific methods follows; // Implementation of specific methods follows;
// These generally do a small amout of validation and call Libzot // These generally do a small amout of validation and call Libzot
// to do any heavy lifting // to do any heavy lifting
static function reply_notify($data,$hub) { static function reply_notify($data,$hub) {
@ -40,7 +40,7 @@ class Zot6Handler implements IHandler {
$x = Libzot::fetch($data); $x = Libzot::fetch($data);
$ret['delivery_report'] = $x; $ret['delivery_report'] = $x;
$ret['success'] = true; $ret['success'] = true;
return $ret; return $ret;
@ -58,11 +58,11 @@ class Zot6Handler implements IHandler {
* *
* @param array $sender * @param array $sender
* @param array $recipients * @param array $recipients
* @param array $hub
* *
* @return json_return_and_die() * @return array
*/ */
static function reply_refresh($sender, $recipients, $hub) {
static function reply_refresh($sender, $recipients,$hub) {
$ret = array('success' => false); $ret = array('success' => false);
if($recipients) { if($recipients) {
@ -70,19 +70,18 @@ class Zot6Handler implements IHandler {
// This would be a permissions update, typically for one connection // This would be a permissions update, typically for one connection
foreach ($recipients as $recip) { foreach ($recipients as $recip) {
$r = q("select channel.*,xchan.* from channel $r = q("select channel.*,xchan.* from channel
left join xchan on channel_portable_id = xchan_hash left join xchan on channel_portable_id = xchan_hash
where xchan_hash ='%s' limit 1", where xchan_hash ='%s' limit 1",
dbesc($recip) dbesc($recip)
); );
/// @FIXME $msgtype is undefined
$x = Libzot::refresh( [ 'hubloc_id_url' => $hub['hubloc_id_url'] ], $r[0], (($msgtype === 'force_refresh') ? true : false)); $x = Libzot::refresh( [ 'hubloc_id_url' => $hub['hubloc_id_url'] ], $r[0], (($msgtype === 'force_refresh') ? true : false));
} }
} }
else { else {
// system wide refresh // system wide refresh
/// @FIXME $msgtype is undefined
$x = Libzot::refresh( [ 'hubloc_id_url' => $hub['hubloc_id_url'] ], null, (($msgtype === 'force_refresh') ? true : false)); $x = Libzot::refresh( [ 'hubloc_id_url' => $hub['hubloc_id_url'] ], null, (($msgtype === 'force_refresh') ? true : false));
} }
@ -100,17 +99,16 @@ class Zot6Handler implements IHandler {
* for that packet. We will create a message_list array of the entire conversation starting with * for that packet. We will create a message_list array of the entire conversation starting with
* the missing parent and invoke delivery to the sender of the packet. * the missing parent and invoke delivery to the sender of the packet.
* *
* Zotlabs/Daemon/Deliver.php (for local delivery) and * Zotlabs/Daemon/Deliver.php (for local delivery) and
* mod/post.php???? @fixme (for web delivery) detect the existence of * mod/post.php???? @fixme (for web delivery) detect the existence of
* this 'message_list' at the destination and split it into individual messages which are * this 'message_list' at the destination and split it into individual messages which are
* processed/delivered in order. * processed/delivered in order.
* *
*
* @param array $data * @param array $data
* @param array $hub
* @return array * @return array
*/ */
static function reply_message_request($data, $hub) {
static function reply_message_request($data,$hub) {
$ret = [ 'success' => false ]; $ret = [ 'success' => false ];
$message_id = EMPTY_STR; $message_id = EMPTY_STR;
@ -153,11 +151,10 @@ class Zot6Handler implements IHandler {
/* /*
* fetch the requested conversation * fetch the requested conversation
*/ */
/// @FIXME $sender_hash is undefined
$messages = zot_feed($c[0]['channel_id'],$sender_hash, [ 'message_id' => $data['message_id'], 'encoding' => 'activitystreams' ]); $messages = zot_feed($c[0]['channel_id'],$sender_hash, [ 'message_id' => $data['message_id'], 'encoding' => 'activitystreams' ]);
return (($messages) ? : [] ); return (($messages) ? : [] );
} }
static function rekey_request($sender,$data,$hub) { static function rekey_request($sender,$data,$hub) {
@ -183,7 +180,7 @@ class Zot6Handler implements IHandler {
dbesc($oldhash) dbesc($oldhash)
); );
} }
else else
return $ret; return $ret;
@ -219,10 +216,10 @@ class Zot6Handler implements IHandler {
* *
* @param array $sender * @param array $sender
* @param array $recipients * @param array $recipients
* @param array $hub
* *
* return json_return_and_die() * @return array
*/ */
static function reply_purge($sender, $recipients, $hub) { static function reply_purge($sender, $recipients, $hub) {
$ret = array('success' => false); $ret = array('success' => false);
@ -259,9 +256,4 @@ class Zot6Handler implements IHandler {
return $ret; return $ret;
} }
} }

View File

@ -137,7 +137,7 @@ function z_mime_content_type($filename) {
* @param string $hash (optional) * @param string $hash (optional)
* @param string $filename (optional) * @param string $filename (optional)
* @param string $filetype (optional) * @param string $filetype (optional)
* @return associative array with: * @return array Associative array with:
* * \e boolean \b success * * \e boolean \b success
* * \e int|boolean \b results amount of found results, or false * * \e int|boolean \b results amount of found results, or false
* * \e string \b message with error messages if any * * \e string \b message with error messages if any
@ -176,15 +176,17 @@ function attach_count_files($channel_id, $observer, $hash = '', $filename = '',
/** /**
* @brief Returns a list of files/attachments. * @brief Returns a list of files/attachments.
* *
* @param $channel_id * @param int $channel_id
* @param $observer * @param string $observer
* @param $hash (optional) * @param string $hash (optional)
* @param $filename (optional) * @param string $filename (optional)
* @param $filetype (optional) * @param string $filetype (optional)
* @param $orderby * @param string $orderby (optional)
* @param $start * @param int $start (optional)
* @param $entries * @param int $entries (optional)
* @return associative array with: * @param string $since (optional)
* @param string $until (optional)
* @return array an associative array with:
* * \e boolean \b success * * \e boolean \b success
* * \e array|boolean \b results array with results, or false * * \e array|boolean \b results array with results, or false
* * \e string \b message with error messages if any * * \e string \b message with error messages if any
@ -1428,8 +1430,17 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
if(! $r) { if(! $r) {
attach_drop_photo($channel_id,$resource); attach_drop_photo($channel_id,$resource);
$arr = ['channel_id' => $channel_id, 'resource' => $resource, 'is_photo'=>$is_photo]; $arr = ['channel_id' => $channel_id, 'resource' => $resource, 'is_photo' => $is_photo];
call_hooks("attach_delete",$arr);
/**
* @hooks attach_delete
* Called when deleting an attachment from channel.
* * \e int \b channel_id - the channel_id
* * \e string \b resource
* * \e int \b is_photo
*/
call_hooks('attach_delete', $arr);
return; return;
} }
@ -1488,8 +1499,15 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
intval($channel_id) intval($channel_id)
); );
$arr = ['channel_id' => $channel_id, 'resource' => $resource, 'is_photo'=>$is_photo]; $arr = ['channel_id' => $channel_id, 'resource' => $resource, 'is_photo' => $is_photo];
call_hooks("attach_delete",$arr); /**
* @hooks attach_delete
* Called when deleting an attachment from channel.
* * \e int \b channel_id - the channel_id
* * \e string \b resource
* * \e int \b is_photo
*/
call_hooks('attach_delete', $arr);
file_activity($channel_id, $object, $object['allow_cid'], $object['allow_gid'], $object['deny_cid'], $object['deny_gid'], 'update', true); file_activity($channel_id, $object, $object['allow_cid'], $object['allow_gid'], $object['deny_cid'], $object['deny_gid'], 'update', true);
@ -1868,7 +1886,7 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
* @param int $channel_id * @param int $channel_id
* @param string $hash * @param string $hash
* @param string $url * @param string $url
* @return array An associative array for the specified file. * @return array Associative array for the specified file.
*/ */
function get_file_activity_object($channel_id, $hash, $url) { function get_file_activity_object($channel_id, $hash, $url) {
@ -2110,7 +2128,7 @@ function attach_export_data($channel, $resource_id, $deleted = false) {
if($attach_ptr['is_photo']) { if($attach_ptr['is_photo']) {
// This query could potentially result in a few megabytes of data use. // This query could potentially result in a few megabytes of data use.
$r = q("select * from photo where resource_id = '%s' and uid = %d order by imgscale asc", $r = q("select * from photo where resource_id = '%s' and uid = %d order by imgscale asc",
dbesc($resource_id), dbesc($resource_id),
@ -2352,7 +2370,7 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
$filename = $r[0]['filename']; $filename = $r[0]['filename'];
// don't do duplicate check unless our parent folder has changed. // don't do duplicate check unless our parent folder has changed.
if($r[0]['folder'] !== $new_folder_hash) { if($r[0]['folder'] !== $new_folder_hash) {
@ -2468,7 +2486,7 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
/** /**
* Used to generate a select input box of all your folders * Used to generate a select input box of all your folders
*/ */
@ -2551,10 +2569,10 @@ function attach_syspaths($channel_id,$attach_hash) {
/** /**
* in earlier releases we did not fill in os_path and display_path in the attach DB structure. * in earlier releases we did not fill in os_path and display_path in the attach DB structure.
* (It was not needed or used). Going forward we intend to make use of these fields. * (It was not needed or used). Going forward we intend to make use of these fields.
* A cron task checks for empty values (as older attachments may have arrived at our site * A cron task checks for empty values (as older attachments may have arrived at our site
* in a clone operation) and executes attach_syspaths() to generate these field values and correct * in a clone operation) and executes attach_syspaths() to generate these field values and correct
* the attach table entry. The operation is limited to 100 DB entries at a time so as not to * the attach table entry. The operation is limited to 100 DB entries at a time so as not to
* overload the system in any cron run. Eventually it will catch up with old attach structures * overload the system in any cron run. Eventually it will catch up with old attach structures
* and switch into maintenance mode to correct any that might arrive in clone packets from older * and switch into maintenance mode to correct any that might arrive in clone packets from older
* sites. * sites.

View File

@ -261,13 +261,13 @@ function construct_activity_target($item) {
* @param SimplePie $item * @param SimplePie $item
* @return array $author * @return array $author
*/ */
function get_atom_author($feed, $item) { function get_atom_author($feed, $item) {
$author = []; $author = [];
$found_author = $item->get_author(); $found_author = $item->get_author();
if($found_author) { if($found_author) {
/// @FIXME $rawauthor is undefined here
if($rawauthor) { if($rawauthor) {
if($rawauthor[0]['child'][NAMESPACE_POCO]['displayName'][0]['data']) if($rawauthor[0]['child'][NAMESPACE_POCO]['displayName'][0]['data'])
$author['full_name'] = unxmlify($rawauthor[0]['child'][NAMESPACE_POCO]['displayName'][0]['data']); $author['full_name'] = unxmlify($rawauthor[0]['child'][NAMESPACE_POCO]['displayName'][0]['data']);
@ -398,10 +398,10 @@ function get_atom_author($feed, $item) {
'author' => $author 'author' => $author
]; ];
/** /**
* @hooks parse_atom * @hooks parse_atom_author
* * \e SimplePie \b feed - The original SimplePie feed * * \e SimplePie \b feed - The original SimplePie feed
* * \e SimplePie \b item * * \e SimplePie \b item
* * \e array \b result - the result array that will also get returned * * \e array \b author - the result array that will also get returned
*/ */
call_hooks('parse_atom_author', $arr); call_hooks('parse_atom_author', $arr);
@ -416,10 +416,8 @@ function get_atom_author($feed, $item) {
* *
* @param SimplePie $feed * @param SimplePie $feed
* @param SimplePie $item * @param SimplePie $item
* @param[out] array $author
* @return array Associative array with the parsed item data * @return array Associative array with the parsed item data
*/ */
function get_atom_elements($feed, $item) { function get_atom_elements($feed, $item) {
require_once('include/html2bbcode.php'); require_once('include/html2bbcode.php');
@ -669,10 +667,10 @@ function get_atom_elements($feed, $item) {
$termterm = notags(trim(unxmlify($term))); $termterm = notags(trim(unxmlify($term)));
// Mastodon auto generates an nsfw category tag for any 'content-warning' message. // Mastodon auto generates an nsfw category tag for any 'content-warning' message.
// Most people use CW and use both summary/content as a spoiler and we honour that // Most people use CW and use both summary/content as a spoiler and we honour that
// construct so the post will already be collapsed. The generated tag is almost // construct so the post will already be collapsed. The generated tag is almost
// always wrong and even if it isn't we would already be doing the right thing. // always wrong and even if it isn't we would already be doing the right thing.
if($mastodon && $termterm === 'nsfw' && $summary && $res['body']) if($mastodon && $termterm === 'nsfw' && $summary && $res['body'])
continue; continue;
@ -1336,7 +1334,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
if( ! \Zotlabs\Lib\MessageFilter::evaluate($datarray,get_config('system','pubstream_incl'),get_config('system','pubstream_excl'))) { if( ! \Zotlabs\Lib\MessageFilter::evaluate($datarray,get_config('system','pubstream_incl'),get_config('system','pubstream_excl'))) {
continue; continue;
} }
} }
if(! post_is_importable($datarray, $contact)) if(! post_is_importable($datarray, $contact))
continue; continue;
@ -1492,7 +1490,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
if( ! \Zotlabs\Lib\MessageFilter::evaluate($datarray,get_config('system','pubstream_incl'),get_config('system','pubstream_excl'))) { if( ! \Zotlabs\Lib\MessageFilter::evaluate($datarray,get_config('system','pubstream_incl'),get_config('system','pubstream_excl'))) {
continue; continue;
} }
} }
if(! post_is_importable($datarray, $contact)) if(! post_is_importable($datarray, $contact))
continue; continue;
@ -1900,7 +1898,7 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $
$body = $item['body']; $body = $item['body'];
if($summary) if($summary)
$body = preg_replace('|^(.*?)\[summary\](.*?)\[/summary\](.*?)$|ism','$1$3',$item['body']); $body = preg_replace('|^(.*?)\[summary\](.*?)\[/summary\](.*?)$|ism','$1$3',$item['body']);
if($compat) if($compat)

View File

@ -7,9 +7,10 @@ use \Michelf\MarkdownExtra;
* @brief * @brief
* *
* @param string $path * @param string $path
* @return string|unknown * @param string $suffix (optional) default null
* @return string
*/ */
function get_help_fullpath($path,$suffix=null) { function get_help_fullpath($path, $suffix = null) {
$docroot = (\App::$override_helproot) ? \App::$override_helproot : 'doc/'; $docroot = (\App::$override_helproot) ? \App::$override_helproot : 'doc/';
$docroot = (substr($docroot,-1)!='/') ? $docroot .= '/' : $docroot; $docroot = (substr($docroot,-1)!='/') ? $docroot .= '/' : $docroot;
@ -49,8 +50,8 @@ function get_help_fullpath($path,$suffix=null) {
/** /**
* @brief * @brief
* *
* @param string $tocpath * @param string $tocpath (optional) default false
* @return string|unknown * @return string
*/ */
function get_help_content($tocpath = false) { function get_help_content($tocpath = false) {
@ -171,16 +172,20 @@ function preg_callback_help_include($matches) {
} }
/** /**
* @brief * @brief Determines help language.
* *
* @return boolean|array * If the language was specified in the URL, override the language preference
* of the browser. Default to English if both of these are absent.
*
* @return array Associative array with:
* * \e string \b language - 2-letter ISO 639-1 code ("en")
* * \e boolean \b from_url - true if language from URL overrides browser default
*/ */
function determine_help_language() { function determine_help_language() {
$lang_detect = new Text_LanguageDetect(); $lang_detect = new Text_LanguageDetect();
// Set this mode to recognize language by the short code like "en", "ru", etc. // Set this mode to recognize language by the short code like "en", "ru", etc.
$lang_detect->setNameMode(2); $lang_detect->setNameMode(2);
// If the language was specified in the URL, override the language preference
// of the browser. Default to English if both of these are absent.
if($lang_detect->languageExists(argv(1))) { if($lang_detect->languageExists(argv(1))) {
$lang = argv(1); $lang = argv(1);
$from_url = true; $from_url = true;
@ -211,10 +216,10 @@ function find_doc_file($s) {
} }
/** /**
* @brief * @brief Search in doc files.
* *
* @param string $s * @param string $s The search string to search for
* @return number|mixed|unknown|boolean * @return array
*/ */
function search_doc_files($s) { function search_doc_files($s) {
@ -275,7 +280,6 @@ function doc_rank_sort($s1, $s2) {
* *
* @return string * @return string
*/ */
function load_context_help() { function load_context_help() {
$path = App::$cmd; $path = App::$cmd;
@ -305,7 +309,7 @@ function load_context_help() {
* @brief * @brief
* *
* @param string $s * @param string $s
* @return void|boolean[]|number[]|string[]|unknown[] * @return void|array
*/ */
function store_doc_file($s) { function store_doc_file($s) {

View File

@ -12,6 +12,7 @@ require_once('include/perm_upgrade.php');
* @param array $channel * @param array $channel
* @param int $account_id * @param int $account_id
* @param int $seize * @param int $seize
* @param string $newname (optional)
* @return boolean|array * @return boolean|array
*/ */
function import_channel($channel, $account_id, $seize, $newname = '') { function import_channel($channel, $account_id, $seize, $newname = '') {
@ -650,7 +651,7 @@ function import_items($channel, $items, $sync = false, $relocate = null) {
// preserve conversations you've been involved in from being expired // preserve conversations you've been involved in from being expired
$stored = $item_result['item']; $stored = $item_result['item'];
if((is_array($stored)) && ($stored['id'] != $stored['parent']) if((is_array($stored)) && ($stored['id'] != $stored['parent'])
&& ($stored['author_xchan'] === $channel['channel_hash'])) { && ($stored['author_xchan'] === $channel['channel_hash'])) {
retain_item($stored['item']['parent']); retain_item($stored['item']['parent']);
} }
@ -672,7 +673,7 @@ function import_items($channel, $items, $sync = false, $relocate = null) {
/** /**
* @brief Sync items to channel. * @brief Sync items to channel.
* *
* @see import_items * @see import_items()
* *
* @param array $channel where to import to * @param array $channel where to import to
* @param array $items * @param array $items
@ -1049,7 +1050,7 @@ function import_mail($channel, $mails, $sync = false) {
/** /**
* @brief Synchronise mails. * @brief Synchronise mails.
* *
* @see import_mail * @see import_mail()
* @param array $channel * @param array $channel
* @param array $mails * @param array $mails
*/ */
@ -1337,7 +1338,7 @@ function sync_files($channel, $files) {
if($str) if($str)
$str .= ","; $str .= ",";
$str .= " " . TQUOT . $k . TQUOT . " = '" . (($k === 'content') ? dbescbin($v) : dbesc($v)) . "' "; $str .= " " . TQUOT . $k . TQUOT . " = '" . (($k === 'content') ? dbescbin($v) : dbesc($v)) . "' ";
} }
$r = dbq("update photo set " . $str . " where id = " . intval($exists[0]['id']) ); $r = dbq("update photo set " . $str . " where id = " . intval($exists[0]['id']) );

View File

@ -25,7 +25,7 @@ require_once('include/permissions.php');
* *
* @param array $item * @param array $item
* @param[out] boolean $private_envelope * @param[out] boolean $private_envelope
* @param boolean $include_groups * @param boolean $include_groups
* @return array containing the recipients * @return array containing the recipients
*/ */
function collect_recipients($item, &$private_envelope,$include_groups = true) { function collect_recipients($item, &$private_envelope,$include_groups = true) {
@ -97,9 +97,9 @@ function collect_recipients($item, &$private_envelope,$include_groups = true) {
if(array_key_exists('public_policy',$item) && $item['public_policy'] !== 'self') { if(array_key_exists('public_policy',$item) && $item['public_policy'] !== 'self') {
$hookinfo = [ $hookinfo = [
'recipients' => [], 'recipients' => [],
'item' => $item, 'item' => $item,
'private_envelope' => $private_envelope, 'private_envelope' => $private_envelope,
'include_groups' => $include_groups 'include_groups' => $include_groups
]; ];
@ -410,7 +410,7 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
if(! $arr['mid']) { if(! $arr['mid']) {
$arr['uuid'] = ((x($arr,'uuid')) ? $arr['uuid'] : item_message_id()); $arr['uuid'] = ((x($arr,'uuid')) ? $arr['uuid'] : item_message_id());
} }
$arr['mid'] = ((x($arr,'mid')) ? $arr['mid'] : z_root() . '/item/' . $arr['uuid']); $arr['mid'] = ((x($arr,'mid')) ? $arr['mid'] : z_root() . '/item/' . $arr['uuid']);
$arr['parent_mid'] = ((x($arr,'parent_mid')) ? $arr['parent_mid'] : $arr['mid']); $arr['parent_mid'] = ((x($arr,'parent_mid')) ? $arr['parent_mid'] : $arr['mid']);
@ -2400,15 +2400,15 @@ function item_update_parent_commented($item) {
$update_parent = true; $update_parent = true;
// update the commented timestamp on the parent // update the commented timestamp on the parent
// - unless this is a moderated comment or a potential clone of an older item // - unless this is a moderated comment or a potential clone of an older item
// which we don't wish to bring to the surface. As the queue only holds deliveries // which we don't wish to bring to the surface. As the queue only holds deliveries
// for 3 days, it's suspected of being an older cloned item if the creation time // for 3 days, it's suspected of being an older cloned item if the creation time
//is older than that. //is older than that.
if(intval($item['item_blocked']) === ITEM_MODERATED) if(intval($item['item_blocked']) === ITEM_MODERATED)
$update_parent = false; $update_parent = false;
if($item['created'] < datetime_convert('','','now - 4 days')) if($item['created'] < datetime_convert('','','now - 4 days'))
$update_parent = false; $update_parent = false;
@ -3004,7 +3004,9 @@ function tgroup_check($uid, $item) {
* @param array $channel * @param array $channel
* @param array $item * @param array $item
* @param int $item_id * @param int $item_id
* @param boolean $parent * @param array $parent
* @param boolean $edit (optional) default false
* @return void
*/ */
function start_delivery_chain($channel, $item, $item_id, $parent, $edit = false) { function start_delivery_chain($channel, $item, $item_id, $parent, $edit = false) {
@ -3039,7 +3041,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $edit = false)
} }
// This will change the author to the post owner. Useful for RSS feeds which are to be syndicated // This will change the author to the post owner. Useful for RSS feeds which are to be syndicated
// to federated platforms which can't verify the identity of the author. // to federated platforms which can't verify the identity of the author.
// This MAY cause you to run afoul of copyright law. // This MAY cause you to run afoul of copyright law.
$rewrite_author = intval(get_abconfig($channel['channel_id'],$item['owner_xchan'],'system','rself')); $rewrite_author = intval(get_abconfig($channel['channel_id'],$item['owner_xchan'],'system','rself'));
@ -3552,7 +3554,7 @@ function item_expire($uid,$days,$comment_days = 7) {
if(! $comment_days) if(! $comment_days)
$comment_days = 7; $comment_days = 7;
// $expire_network_only = save your own wall posts // $expire_network_only = save your own wall posts
// and just expire conversations started by others // and just expire conversations started by others
// do not enable this until we can pass bulk delete messages through zot // do not enable this until we can pass bulk delete messages through zot
@ -4892,7 +4894,7 @@ function copy_of_pubitem($channel,$mid) {
dbesc($mid), dbesc($mid),
intval($syschan['channel_id']) intval($syschan['channel_id'])
); );
if($r) { if($r) {
$items = fetch_post_tags($r,true); $items = fetch_post_tags($r,true);
foreach($items as $rv) { foreach($items as $rv) {
@ -4918,5 +4920,5 @@ function copy_of_pubitem($channel,$mid) {
} }
} }
return $result; return $result;
} }

View File

@ -7,13 +7,15 @@
/** /**
* @brief Handle errors in plugin calls * @brief Handle errors in plugin calls.
* *
* @param string $plugin name of the addon * @param string $plugin name of the addon
* @param string $error_text text of error * @param string $notice UI visible text of error
* @param bool $uninstall uninstall plugin * @param string $log technical error message for logging
* @param bool $uninstall (optional) default false
* uninstall plugin on error
*/ */
function handleerrors_plugin($plugin,$notice,$log,$uninstall=false){ function handleerrors_plugin($plugin, $notice, $log, $uninstall = false){
logger("Addons: [" . $plugin . "] Error: ".$log, LOGGER_ERROR); logger("Addons: [" . $plugin . "] Error: ".$log, LOGGER_ERROR);
if ($notice != '') { if ($notice != '') {
notice("[" . $plugin . "] Error: ".$notice, LOGGER_ERROR); notice("[" . $plugin . "] Error: ".$notice, LOGGER_ERROR);
@ -23,7 +25,7 @@ function handleerrors_plugin($plugin,$notice,$log,$uninstall=false){
$idx = array_search($plugin, \App::$plugins); $idx = array_search($plugin, \App::$plugins);
unset(\App::$plugins[$idx]); unset(\App::$plugins[$idx]);
uninstall_plugin($plugin); uninstall_plugin($plugin);
set_config("system","addon", implode(", ",\App::$plugins)); set_config("system", "addon", implode(", ", \App::$plugins));
} }
} }
@ -381,8 +383,6 @@ function unregister_hook($hook, $file, $function) {
* array in their theme_init() and use this to customise the app behaviour. * array in their theme_init() and use this to customise the app behaviour.
* use insert_hook($hookname,$function_name) to do this. * use insert_hook($hookname,$function_name) to do this.
*/ */
function load_hooks() { function load_hooks() {
App::$hooks = []; App::$hooks = [];
@ -1085,10 +1085,11 @@ function get_markup_template($s, $root = '') {
} }
/** /**
* @brief * @brief Test if a folder exists.
* *
* @param string $folder * @param string $folder
* @return boolean|string * @return boolean|string
* False if folder does not exist, or canonicalized absolute pathname
*/ */
function folder_exists($folder) { function folder_exists($folder) {
// Get canonicalized absolute pathname // Get canonicalized absolute pathname

View File

@ -41,12 +41,12 @@ function replace_macros($s, $r) {
$t = App::template_engine(); $t = App::template_engine();
try { try {
$output = $t->replace_macros($arr['template'], $arr['params']); $output = $t->replace_macros($arr['template'], $arr['params']);
} catch (Exception $e) { } catch (Exception $e) {
logger("Unable to render template: ".$e->getMessage()); logger('Unable to render template: ' . $e->getMessage());
$output = "<h3>ERROR: there was an error creating the output.</h3>"; $output = '<h3>ERROR: there was an error creating the output.</h3>';
} }
return $output; return $output;
} }
@ -539,7 +539,14 @@ function paginate(&$a) {
return $o; return $o;
} }
/**
* @brief
*
* @param int $i
* @param string $more
* @param string $less
* @return string Parsed HTML from template 'alt_pager.tpl'
*/
function alt_pager($i, $more = '', $less = '') { function alt_pager($i, $more = '', $less = '') {
if(! $more) if(! $more)
@ -810,7 +817,7 @@ function activity_match($haystack,$needle) {
* and strip the period from any tags which end with one. * and strip the period from any tags which end with one.
* *
* @param string $s * @param string $s
* @return Returns array of tags found, or empty array. * @return array Returns an array of tags found, or empty array.
*/ */
function get_tags($s) { function get_tags($s) {
$ret = array(); $ret = array();
@ -825,7 +832,7 @@ function get_tags($s) {
// ignore anything in [color= ], because it may contain color codes which are mistaken for tags // ignore anything in [color= ], because it may contain color codes which are mistaken for tags
$s = preg_replace('/\[color=(.*?)\]/sm','',$s); $s = preg_replace('/\[color=(.*?)\]/sm','',$s);
// skip anchors in URL // skip anchors in URL
$s = preg_replace('/\[url=(.*?)\]/sm','',$s); $s = preg_replace('/\[url=(.*?)\]/sm','',$s);
@ -900,6 +907,7 @@ function tag_sort_length($a,$b) {
function total_sort($a,$b) { function total_sort($a,$b) {
if($a['total'] == $b['total']) if($a['total'] == $b['total'])
return 0; return 0;
return(($b['total'] > $a['total']) ? 1 : (-1)); return(($b['total'] > $a['total']) ? 1 : (-1));
} }
@ -1004,9 +1012,15 @@ function contact_block() {
'$micropro' => $micropro, '$micropro' => $micropro,
)); ));
$arr = array('contacts' => $r, 'output' => $o); $arr = ['contacts' => $r, 'output' => $o];
/**
* @hooks contact_block_end
* Called at the end of contact_block(), but can not manipulate the output.
* * \e array \b contacts - Result array from database
* * \e string \b output - the generated output
*/
call_hooks('contact_block_end', $arr); call_hooks('contact_block_end', $arr);
return $o; return $o;
} }
@ -1108,16 +1122,20 @@ function linkify($s, $me = false) {
* to a local redirector which uses https and which redirects to the selected content * to a local redirector which uses https and which redirects to the selected content
* *
* @param string $s * @param string $s
* @param int $uid
* @returns string * @returns string
*/ */
function sslify($s) { function sslify($s) {
// Local photo cache // Local photo cache
$str = array( $str = [
'body' => $s, 'body' => $s,
'uid' => local_channel() 'uid' => local_channel()
); ];
/**
* @hooks cache_body_hook
* * \e string \b body The content to parse and also the return value
* * \e int|bool \b uid
*/
call_hooks('cache_body_hook', $str); call_hooks('cache_body_hook', $str);
$s = $str['body']; $s = $str['body'];
@ -1222,7 +1240,11 @@ function get_mood_verbs() {
/** /**
* @brief Function to list all smilies, both internal and from addons. * @brief Function to list all smilies, both internal and from addons.
* *
* @return Returns array with keys 'texts' and 'icons' * @param boolean $default_only (optional) default false
* true will prevent that plugins can add smilies
* @return array Returns an associative array with:
* * \e array \b texts
* * \e array \b icons
*/ */
function list_smilies($default_only = false) { function list_smilies($default_only = false) {
@ -1300,6 +1322,11 @@ function list_smilies($default_only = false) {
if($default_only) if($default_only)
return $params; return $params;
/**
* @hooks smile
* * \e array \b texts - default values and also return value
* * \e array \b icons - default values and also return value
*/
call_hooks('smilie', $params); call_hooks('smilie', $params);
return $params; return $params;
@ -1625,6 +1652,10 @@ function generate_named_map($location) {
function prepare_body(&$item,$attach = false,$opts = false) { function prepare_body(&$item,$attach = false,$opts = false) {
/**
* @hooks prepare_body_init
* * \e array \b item
*/
call_hooks('prepare_body_init', $item); call_hooks('prepare_body_init', $item);
$s = ''; $s = '';
@ -1656,13 +1687,19 @@ function prepare_body(&$item,$attach = false,$opts = false) {
$event = (($item['obj_type'] === ACTIVITY_OBJ_EVENT) ? format_event_obj($item['obj']) : false); $event = (($item['obj_type'] === ACTIVITY_OBJ_EVENT) ? format_event_obj($item['obj']) : false);
$prep_arr = array( $prep_arr = [
'item' => $item, 'item' => $item,
'html' => $event ? $event['content'] : $s, 'html' => $event ? $event['content'] : $s,
'event' => $event['header'], 'event' => $event['header'],
'photo' => $photo 'photo' => $photo
); ];
/**
* @hooks prepare_body
* * \e array \b item
* * \e string \b html - the parsed HTML to return
* * \e string \b event - the event header to return
* * \e string \b photo - the photo to return
*/
call_hooks('prepare_body', $prep_arr); call_hooks('prepare_body', $prep_arr);
$s = $prep_arr['html']; $s = $prep_arr['html'];
@ -2249,19 +2286,24 @@ function ids_to_querystr($arr,$idx = 'id',$quote = false) {
} }
/** /**
* @brief array_elm_to_str($arr,$elm,$delim = ',') extract unique individual elements from an array of arrays and return them as a string separated by a delimiter * @brief Extract unique individual elements from an array of arrays and return
* similar to ids_to_querystr, but allows a different delimiter instead of a db-quote option * them as a string separated by a delimiter.
* empty elements (evaluated after trim()) are ignored. *
* @param $arr array * Similar to ids_to_querystr, but allows a different delimiter instead of a
* @param $elm array key to extract from sub-array * db-quote option empty elements (evaluated after trim()) are ignored.
* @param $delim string default ',' *
* @param $each filter function to apply to each element before evaluation, default is 'trim'. * @see ids_to_querystr()
*
* @param array $arr
* @param string $elm key to extract from sub-array
* @param string $delim (optional) default ','
* @param string $each (optional) default is 'trim'
* Filter function to apply to each element before evaluation.
* @returns string * @returns string
*/ */
function array_elm_to_str($arr, $elm, $delim = ',', $each = 'trim') {
function array_elm_to_str($arr,$elm,$delim = ',',$each = 'trim') {
$tmp = []; $tmp = [];
if($arr && is_array($arr)) { if($arr && is_array($arr)) {
foreach($arr as $x) { foreach($arr as $x) {
if(is_array($x) && array_key_exists($elm,$x)) { if(is_array($x) && array_key_exists($elm,$x)) {
@ -2272,7 +2314,8 @@ function array_elm_to_str($arr,$elm,$delim = ',',$each = 'trim') {
} }
} }
} }
return implode($delim,$tmp);
return implode($delim, $tmp);
} }
function trim_and_unpunify($s) { function trim_and_unpunify($s) {
@ -2496,9 +2539,9 @@ function design_tools() {
} }
/** /**
* @brief Creates website portation tools menu * @brief Creates website portation tools menu.
* *
* @return string * @return string Parsed HTML code from template 'website_portation_tools.tpl'
*/ */
function website_portation_tools() { function website_portation_tools() {
@ -2511,7 +2554,7 @@ function website_portation_tools() {
$sys = true; $sys = true;
} }
return replace_macros(get_markup_template('website_portation_tools.tpl'), array( return replace_macros(get_markup_template('website_portation_tools.tpl'), [
'$title' => t('Import'), '$title' => t('Import'),
'$import_label' => t('Import website...'), '$import_label' => t('Import website...'),
'$import_placeholder' => t('Select folder to import'), '$import_placeholder' => t('Select folder to import'),
@ -2528,7 +2571,7 @@ function website_portation_tools() {
'$cloud_export_desc' => t('/path/to/export/folder'), '$cloud_export_desc' => t('/path/to/export/folder'),
'$cloud_export_hint' => t('Enter a path to a cloud files destination.'), '$cloud_export_hint' => t('Enter a path to a cloud files destination.'),
'$cloud_export_select' => t('Specify folder'), '$cloud_export_select' => t('Specify folder'),
)); ]);
} }
/** /**
@ -2991,9 +3034,9 @@ function item_url_replace($channel,&$item,$old,$new,$oldnick = '') {
json_url_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['target']); json_url_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['target']);
} }
$x = preg_replace("/".preg_quote($old,'/')."\/(search|\w+\/".$channel['channel_address'].")/", $new.'/${1}', $item['body']); $x = preg_replace("/".preg_quote($old,'/')."\/(search|\w+\/".$channel['channel_address'].")/", $new.'/${1}', $item['body']);
if($x) { if($x) {
$item['body'] = $x; $item['body'] = $x;
$item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey'])); $item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey']));
$item['item_verified'] = 1; $item['item_verified'] = 1;
} }
@ -3103,7 +3146,13 @@ function pdl_selector($uid, $current='') {
intval($uid) intval($uid)
); );
$arr = array('channel_id' => $uid, 'current' => $current, 'entries' => $r); $arr = ['channel_id' => $uid, 'current' => $current, 'entries' => $r];
/**
* @hooks pdl_selector
* * \e int \b channel_id
* * \e string \b current
* * \e array \b entries - Result from database query
*/
call_hooks('pdl_selector', $arr); call_hooks('pdl_selector', $arr);
$entries = $arr['entries']; $entries = $arr['entries'];
@ -3178,7 +3227,6 @@ function text_highlight($s, $lang) {
'language' => $lang, 'language' => $lang,
'success' => false 'success' => false
]; ];
/** /**
* @hooks text_highlight * @hooks text_highlight
* * \e string \b text * * \e string \b text
@ -3379,13 +3427,17 @@ function punify($s) {
} }
// Be aware that unpunify will only convert domain names and not pathnames /**
* Be aware that unpunify() will only convert domain names and not pathnames.
*
* @param string $s
* @return string
*/
function unpunify($s) { function unpunify($s) {
require_once('vendor/simplepie/simplepie/idn/idna_convert.class.php'); require_once('vendor/simplepie/simplepie/idn/idna_convert.class.php');
$x = new idna_convert(['encoding' => 'utf8']); $x = new idna_convert(['encoding' => 'utf8']);
return $x->decode($s);
return $x->decode($s);
} }
@ -3521,12 +3573,11 @@ function array_path_exists($str,$arr) {
*/ */
function new_uuid() { function new_uuid() {
try { try {
$hash = Uuid::uuid4()->toString(); $hash = Uuid::uuid4()->toString();
} catch (UnsatisfiedDependencyException $e) { } catch (UnsatisfiedDependencyException $e) {
$hash = random_string(48); $hash = random_string(48);
} }
return $hash; return $hash;
} }

View File

@ -174,7 +174,7 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot
* packet type: one of 'ping', 'pickup', 'purge', 'refresh', 'keychange', 'force_refresh', 'notify', 'auth_check' * packet type: one of 'ping', 'pickup', 'purge', 'refresh', 'keychange', 'force_refresh', 'notify', 'auth_check'
* @param array $recipients * @param array $recipients
* envelope information, array ( 'guid' => string, 'guid_sig' => string ); empty for public posts * envelope information, array ( 'guid' => string, 'guid_sig' => string ); empty for public posts
* @param string msg * @param string $msg
* optional message * optional message
* @param string $remote_key * @param string $remote_key
* optional public site key of target hub used to encrypt entire packet * optional public site key of target hub used to encrypt entire packet
@ -1829,7 +1829,7 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $
else { else {
$arr['item_wall'] = 0; $arr['item_wall'] = 0;
} }
if ((! $tag_delivery) && (! $local_public)) { if ((! $tag_delivery) && (! $local_public)) {
$allowed = (perm_is_allowed($channel['channel_id'],$sender['hash'],$perm)); $allowed = (perm_is_allowed($channel['channel_id'],$sender['hash'],$perm));
@ -1843,7 +1843,7 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $
$allowed = can_comment_on_post($d['hash'],$parent[0]); $allowed = can_comment_on_post($d['hash'],$parent[0]);
} }
} }
if (! $allowed) { if (! $allowed) {
logger("permission denied for delivery to channel {$channel['channel_id']} {$channel['channel_address']}"); logger("permission denied for delivery to channel {$channel['channel_id']} {$channel['channel_address']}");
$DR->update('permission denied'); $DR->update('permission denied');
@ -2330,7 +2330,7 @@ function process_mail_delivery($sender, $arr, $deliveries) {
if(! perm_is_allowed($channel['channel_id'],$sender['hash'],'post_mail')) { if(! perm_is_allowed($channel['channel_id'],$sender['hash'],'post_mail')) {
/* /*
* Always allow somebody to reply if you initiated the conversation. It's anti-social * Always allow somebody to reply if you initiated the conversation. It's anti-social
* and a bit rude to send a private message to somebody and block their ability to respond. * and a bit rude to send a private message to somebody and block their ability to respond.
* If you are being harrassed and want to put an end to it, delete the conversation. * If you are being harrassed and want to put an end to it, delete the conversation.
@ -2358,7 +2358,7 @@ function process_mail_delivery($sender, $arr, $deliveries) {
); );
if($r) { if($r) {
if(intval($arr['mail_recalled'])) { if(intval($arr['mail_recalled'])) {
msg_drop($r[0]['id'], $channel['channel_id'], $r[0]['conv_guid']); msg_drop($r[0]['id'], $channel['channel_id'], $r[0]['conv_guid']);
$DR->update('mail recalled'); $DR->update('mail recalled');
$result[] = $DR->get(); $result[] = $DR->get();
logger('mail_recalled'); logger('mail_recalled');
@ -3247,7 +3247,7 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
$channel = $r[0]; $channel = $r[0];
// don't provide these in the export // don't provide these in the export
unset($channel['channel_active']); unset($channel['channel_active']);
unset($channel['channel_password']); unset($channel['channel_password']);
@ -3616,7 +3616,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
if(array_key_exists('channel_pageflags',$arr['channel']) && intval($arr['channel']['channel_pageflags'])) { if(array_key_exists('channel_pageflags',$arr['channel']) && intval($arr['channel']['channel_pageflags'])) {
// Several pageflags are site-specific and cannot be sync'd. // Several pageflags are site-specific and cannot be sync'd.
// Only allow those bits which are shareable from the remote and then // Only allow those bits which are shareable from the remote and then
// logically OR with the local flags // logically OR with the local flags
$arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] & (PAGE_HIDDEN|PAGE_AUTOCONNECT|PAGE_APPLICATION|PAGE_PREMIUM|PAGE_ADULT); $arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] & (PAGE_HIDDEN|PAGE_AUTOCONNECT|PAGE_APPLICATION|PAGE_PREMIUM|PAGE_ADULT);
@ -4974,9 +4974,9 @@ function zot_reply_pickup($data) {
// It's possible that we have more than 100 messages waiting to be sent. // It's possible that we have more than 100 messages waiting to be sent.
// See if there are any more messages in the queue. // See if there are any more messages in the queue.
$x = q("select * from outq where outq_posturl = '%s' order by outq_created limit 1", $x = q("select * from outq where outq_posturl = '%s' order by outq_created limit 1",
dbesc($data['callback']) dbesc($data['callback'])
); );
// If so, kick off a new delivery notification for the next batch // If so, kick off a new delivery notification for the next batch
if ($x) { if ($x) {
@ -5057,7 +5057,7 @@ function zot_reply_auth_check($data,$encrypted_packet) {
} }
// There should be exactly one recipient, the original auth requestor // There should be exactly one recipient, the original auth requestor
/// @FIXME $recipients is undefined here.
$ret['message'] .= 'recipients ' . print_r($recipients,true) . EOL; $ret['message'] .= 'recipients ' . print_r($recipients,true) . EOL;
if ($data['recipients']) { if ($data['recipients']) {