aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorMario Vavti <mario@mariovavti.com>2016-12-23 10:09:46 +0100
committerMario Vavti <mario@mariovavti.com>2016-12-23 10:09:46 +0100
commit3b9b03cf86979b28e7fa249133176bed84b0105c (patch)
tree336dc8b8b9627e7f4a93e5c35fe3e98555274616 /include
parent2e5a993f880d619aedf3693927e7b3e164fbfcc0 (diff)
parentef39c1e94b5149a3019d417d08dc7c16c8aef9c1 (diff)
downloadvolse-hubzilla-3b9b03cf86979b28e7fa249133176bed84b0105c.tar.gz
volse-hubzilla-3b9b03cf86979b28e7fa249133176bed84b0105c.tar.bz2
volse-hubzilla-3b9b03cf86979b28e7fa249133176bed84b0105c.zip
Merge branch '2.0RC'
Diffstat (limited to 'include')
-rw-r--r--include/Import/Importer.php1
-rw-r--r--include/Import/import_diaspora.php2
-rw-r--r--include/account.php8
-rw-r--r--include/acl_selectors.php73
-rw-r--r--include/api.php2270
-rw-r--r--include/api_zot.php481
-rw-r--r--include/attach.php342
-rw-r--r--include/bb2diaspora.php26
-rw-r--r--include/bbcode.php110
-rw-r--r--include/channel.php302
-rw-r--r--include/config.php28
-rw-r--r--include/connections.php20
-rw-r--r--include/conversation.php104
-rw-r--r--include/crypto.php117
-rw-r--r--include/datetime.php24
-rwxr-xr-xinclude/dba/dba_driver.php119
-rwxr-xr-xinclude/dba/dba_mysql.php2
-rwxr-xr-xinclude/dba/dba_mysqli.php2
-rwxr-xr-xinclude/dba/dba_pdo.php84
-rw-r--r--include/dba/dba_postgres.php3
-rw-r--r--include/dir_fns.php10
-rw-r--r--include/event.php44
-rw-r--r--include/follow.php25
-rw-r--r--include/group.php40
-rw-r--r--include/help.php108
-rw-r--r--include/hubloc.php14
-rw-r--r--include/import.php175
-rwxr-xr-xinclude/items.php364
-rw-r--r--include/language.php58
-rw-r--r--include/menu.php2
-rw-r--r--include/message.php13
-rw-r--r--include/nav.php20
-rw-r--r--include/network.php192
-rwxr-xr-xinclude/oembed.php14
-rw-r--r--include/photo/photo_driver.php104
-rw-r--r--include/photos.php99
-rwxr-xr-xinclude/plugin.php67
-rw-r--r--include/queue_fn.php4
-rw-r--r--include/security.php86
-rw-r--r--include/selectors.php2
-rw-r--r--include/socgraph.php40
-rw-r--r--include/statistics_fns.php2
-rw-r--r--include/taxonomy.php2
-rw-r--r--include/text.php732
-rw-r--r--include/widgets.php159
-rw-r--r--include/wiki.php184
-rw-r--r--include/zid.php232
-rw-r--r--include/zot.php534
48 files changed, 3167 insertions, 4277 deletions
diff --git a/include/Import/Importer.php b/include/Import/Importer.php
index cddfac7b5..1fa677db0 100644
--- a/include/Import/Importer.php
+++ b/include/Import/Importer.php
@@ -5,7 +5,6 @@ namespace Hubzilla\Import;
/**
* @brief Class Import
*
- * @package Hubzilla\Import
*/
class Import {
diff --git a/include/Import/import_diaspora.php b/include/Import/import_diaspora.php
index b664badf1..c6dae0117 100644
--- a/include/Import/import_diaspora.php
+++ b/include/Import/import_diaspora.php
@@ -89,7 +89,7 @@ function import_diaspora($data) {
}
$gender = escape_tags($data['user']['profile']['gender']);
- $about = diaspora2bb($data['user']['profile']['bio']);
+ $about = markdown_to_bb($data['user']['profile']['bio']);
$publish = intval($data['user']['profile']['searchable']);
if($data['user']['profile']['birthday'])
$dob = datetime_convert('UTC','UTC',$data['user']['profile']['birthday'],'Y-m-d');
diff --git a/include/account.php b/include/account.php
index b78c3e56d..5e57d53a8 100644
--- a/include/account.php
+++ b/include/account.php
@@ -74,7 +74,7 @@ function check_account_invite($invite_code) {
if(! $invite_code) {
$result['message'] .= t('An invitation is required.') . EOL;
}
- $r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_code));
+ $r = q("select * from register where hash = '%s' limit 1", dbesc($invite_code));
if(! $r) {
$result['message'] .= t('Invitation could not be verified.') . EOL;
}
@@ -373,7 +373,7 @@ function account_allow($hash) {
$ret = array('success' => false);
- $register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1",
+ $register = q("SELECT * FROM register WHERE hash = '%s' LIMIT 1",
dbesc($hash)
);
@@ -465,7 +465,7 @@ function account_deny($hash) {
intval($register[0]['uid'])
);
- $r = q("DELETE FROM `register` WHERE id = %d",
+ $r = q("DELETE FROM register WHERE id = %d",
dbesc($register[0]['id'])
);
notice( sprintf(t('Registration revoked for %s'), $account[0]['account_email']) . EOL);
@@ -482,7 +482,7 @@ function account_approve($hash) {
// Note: when the password in the register table is 'verify', the uid actually contains the account_id
- $register = q("SELECT * FROM `register` WHERE `hash` = '%s' and password = 'verify' LIMIT 1",
+ $register = q("SELECT * FROM register WHERE hash = '%s' and password = 'verify' LIMIT 1",
dbesc($hash)
);
diff --git a/include/acl_selectors.php b/include/acl_selectors.php
index 63867823f..dcf0fe9a2 100644
--- a/include/acl_selectors.php
+++ b/include/acl_selectors.php
@@ -1,17 +1,24 @@
-<?php /** @file */
+<?php
/**
- *
+ * @file include/acl_selectors.php
+ *
+ * @package acl_selectors
*/
/**
- * @package acl_selectors
+ * @brief
+ *
+ * @param string $selname
+ * @param string $selclass
+ * @param mixed $preselected
+ * @param number $size
+ * @return string
*/
-
-function group_select($selname,$selclass,$preselected = false,$size = 4) {
+function group_select($selname, $selclass, $preselected = false, $size = 4) {
$o = '';
- $o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\" >\r\n";
+ $o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\">\r\n";
$r = q("SELECT * FROM groups WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval(local_channel())
@@ -34,19 +41,17 @@ function group_select($selname,$selclass,$preselected = false,$size = 4) {
$o .= "<option value=\"{$rr['id']}\" $selected title=\"{$rr['name']}\" >$trimmed</option>\r\n";
}
-
+
}
$o .= "</select>\r\n";
call_hooks(App::$module . '_post_' . $selname, $o);
-
return $o;
}
function contact_select($selname, $selclass, $preselected = false, $size = 4, $privmail = false, $celeb = false, $privatenet = false, $tabindex = null) {
-
$o = '';
// When used for private messages, we limit correspondence to mutual DFRN/Friendica friends and the selector
@@ -54,17 +59,17 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
$sql_extra = '';
- $tabindex = ($tabindex > 0 ? "tabindex=\"$tabindex\"" : "");
+ $tabindex = ($tabindex > 0 ? 'tabindex="$tabindex"' : '');
if($privmail)
$o .= "<select name=\"$selname\" id=\"$selclass\" class=\"$selclass\" size=\"$size\" $tabindex >\r\n";
- else
- $o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\" $tabindex >\r\n";
+ else
+ $o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\" $tabindex>\r\n";
$r = q("SELECT abook_id, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash
where abook_self = 0 and abook_channel = %d
$sql_extra
- ORDER BY xchan_name ASC ",
+ ORDER BY xchan_name ASC",
intval(local_channel())
);
@@ -78,15 +83,14 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
if($r) {
foreach($r as $rr) {
if((is_array($preselected)) && in_array($rr['id'], $preselected))
- $selected = " selected=\"selected\" ";
+ $selected = ' selected="selected" ';
else
$selected = '';
- $trimmed = mb_substr($rr['xchan_name'],0,20);
+ $trimmed = mb_substr($rr['xchan_name'], 0, 20);
$o .= "<option value=\"{$rr['abook_id']}\" $selected title=\"{$rr['xchan_name']}|{$rr['xchan_url']}\" >$trimmed</option>\r\n";
}
-
}
$o .= "</select>\r\n";
@@ -98,13 +102,13 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
function fixacl(&$item) {
- $item = str_replace(array('<','>'),array('',''),$item);
+ $item = str_replace(array('<', '>'), array('', ''), $item);
}
/**
* Builds a modal dialog for editing permissions, using acl_selector.tpl as the template.
*
-* @param array $default Optional access control list for the initial state of the dialog.
+* @param array $defaults Optional access control list for the initial state of the dialog.
* @param boolean $show_jotnets Whether plugins for federated networks should be included in the permissions dialog
* @param PermissionDescription $emptyACL_description - An optional description for the permission implied by selecting an empty ACL. Preferably an instance of PermissionDescription.
* @param string $dialog_description Optional message to include at the top of the dialog. E.g. "Warning: Post permissions cannot be changed once sent".
@@ -118,16 +122,15 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti
$allow_cid = $allow_gid = $deny_cid = $deny_gid = false;
$showall_origin = '';
$showall_icon = 'fa-globe';
- $role = get_pconfig(local_channel(),'system','permissions_role');
+ $role = get_pconfig(local_channel(), 'system', 'permissions_role');
if(! $emptyACL_description) {
$showall_caption = t('Visible to your default audience');
- } else if (is_a($emptyACL_description, '\\Zotlabs\\Lib\\PermissionDescription')) {
+ } else if(is_a($emptyACL_description, '\\Zotlabs\\Lib\\PermissionDescription')) {
$showall_caption = $emptyACL_description->get_permission_description();
$showall_origin = (($role === 'custom') ? $emptyACL_description->get_permission_origin_description() : '');
$showall_icon = $emptyACL_description->get_permission_icon();
-
} else {
// For backwards compatibility we still accept a string... for now!
$showall_caption = $emptyACL_description;
@@ -135,7 +138,7 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti
if(is_array($defaults)) {
- $allow_cid = ((strlen($defaults['allow_cid']))
+ $allow_cid = ((strlen($defaults['allow_cid']))
? explode('><', $defaults['allow_cid']) : array() );
$allow_gid = ((strlen($defaults['allow_gid']))
? explode('><', $defaults['allow_gid']) : array() );
@@ -195,9 +198,9 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti
'$select_label' => t('Who can see this?'),
'$custom' => t('Custom selection'),
'$showlimitedDesc' => t('Select "Show" to allow viewing. "Don\'t show" lets you override and limit the scope of "Show".'),
- '$show' => t("Show"),
+ '$show' => t('Show'),
'$hide' => t("Don't show"),
- '$search' => t("Search"),
+ '$search' => t('Search'),
'$allowcid' => json_encode($allow_cid),
'$allowgid' => json_encode($allow_gid),
'$denycid' => json_encode($deny_cid),
@@ -209,20 +212,19 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti
));
return $o;
-
}
/**
-* Returns a string that's suitable for passing as the $dialog_description argument to a
-* populate_acl() call for wall posts or network posts.
-*
-* This string is needed in 3 different files, and our .po translation system currently
-* cannot be used as a string table (because the value is always the key in english) so
-* I've centralized the value here (making this function name the "key") until we have a
-* better way.
-*
-* @return string Description to present to user in modal permissions dialog
-*/
+ * Returns a string that's suitable for passing as the $dialog_description argument to a
+ * populate_acl() call for wall posts or network posts.
+ *
+ * This string is needed in 3 different files, and our .po translation system currently
+ * cannot be used as a string table (because the value is always the key in english) so
+ * I've centralized the value here (making this function name the "key") until we have a
+ * better way.
+ *
+ * @return string Description to present to user in modal permissions dialog
+ */
function get_post_aclDialogDescription() {
// I'm trying to make two points in this description text - warn about finality of wall
@@ -238,4 +240,3 @@ function get_post_aclDialogDescription() {
return sprintf($description, $emphasisOpen, $emphasisClose);
}
-
diff --git a/include/api.php b/include/api.php
index 692baf563..693967696 100644
--- a/include/api.php
+++ b/include/api.php
@@ -10,25 +10,22 @@ require_once('include/photos.php');
require_once('include/items.php');
require_once('include/attach.php');
require_once('include/api_auth.php');
+require_once('include/api_zot.php');
/*
*
- * Hubzilla API. Loosely based on and possibly compatible with Twitter-Like (v1.0) API but all similarities end there.
+ * Hubzilla API.
*
*/
- /**
- ** TWITTER API
- */
-
$API = array();
$called_api = Null;
// All commands which require authentication accept a "channel" parameter
// which is the left hand side of the channel address/nickname.
- // If provided, the desired channel is selected before caarying out the command.
+ // If provided, the desired channel is selected before carrying out the command.
// If not provided, the default channel associated with the account is used.
// If channel selection fails, the API command requiring login will fail.
@@ -49,7 +46,7 @@ require_once('include/api_auth.php');
return false;
}
}
- if ($_SESSION["allow_api"])
+ if ($_SESSION['allow_api'])
return local_channel();
return false;
}
@@ -57,11 +54,11 @@ require_once('include/api_auth.php');
function api_date($str){
//Wed May 23 06:01:13 +0000 2007
- return datetime_convert('UTC', 'UTC', $str, "D M d H:i:s +0000 Y" );
+ return datetime_convert('UTC', 'UTC', $str, 'D M d H:i:s +0000 Y' );
}
- function api_register_func($path, $func, $auth=false) {
+ function api_register_func($path, $func, $auth = false) {
\Zotlabs\Lib\Api_router::register($path,$func,$auth);
}
@@ -90,7 +87,12 @@ require_once('include/api_auth.php');
$info = \Zotlabs\Lib\Api_router::find($p);
- logger('info: ' . $p . ' type: ' . $type . ' ' . print_r($info,true));
+ if(in_array($type, [ 'rss', 'atom', 'as' ])) {
+ // These types no longer supported.
+ $info = false;
+ }
+
+ logger('API info: ' . $p . ' type: ' . $type . ' ' . print_r($info,true), LOGGER_DEBUG,LOG_INFO);
if($info) {
@@ -111,247 +113,73 @@ require_once('include/api_auth.php');
return;
switch($type) {
- case "xml":
- $r = mb_convert_encoding($r, "UTF-8",mb_detect_encoding($r));
- header ("Content-Type: text/xml");
- return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
+ case 'xml':
+ header ('Content-Type: text/xml');
+ return $r;
break;
- case "json":
- header ("Content-Type: application/json");
- if($r) {
- foreach($r as $rv) {
- $json = json_encode($rv);
- }
- }
+ case 'json':
+ header ('Content-Type: application/json');
// Lookup JSONP to understand these lines. They provide cross-domain AJAX ability.
if ($_GET['callback'])
- $json = $_GET['callback'] . '(' . $json . ')' ;
- return $json;
+ $r = $_GET['callback'] . '(' . $r . ')' ;
+ return $r;
break;
- case "rss":
- header ("Content-Type: application/rss+xml");
- return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
- break;
- case "atom":
- header ("Content-Type: application/atom+xml");
- return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
- break;
- case "as":
- if($r) {
- foreach($r as $rv) {
- $json = json_encode($rv);
- }
- }
- return $json;
- break;
-
}
}
- header("HTTP/1.1 404 Not Found");
+ header('HTTP/1.1 404 Not Found');
logger('API call not implemented: ' . App::$query_string . ' - ' . print_r($_REQUEST,true));
$r = '<status><error>not implemented</error></status>';
switch($type){
- case "xml":
- header ("Content-Type: text/xml");
- return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
+ case 'xml':
+ header ('Content-Type: text/xml');
+ return '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $r;
break;
case "json":
- header ("Content-Type: application/json");
+ header ('Content-Type: application/json');
return json_encode(array('error' => 'not implemented'));
break;
case "rss":
- header ("Content-Type: application/rss+xml");
- return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
+ header ('Content-Type: application/rss+xml');
+ return '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $r;
break;
case "atom":
- header ("Content-Type: application/atom+xml");
- return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
+ header ('Content-Type: application/atom+xml');
+ return '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $r;
break;
}
}
/**
- * RSS extra info
- */
-
- function api_rss_extra( $arr, $user_info){
- if (is_null($user_info)) $user_info = api_get_user($a);
- $arr['$user'] = $user_info;
- $arr['$rss'] = array(
- 'alternate' => $user_info['url'],
- 'self' => z_root(). "/". App::$query_string,
- 'base' => z_root(),
- 'updated' => api_date(null),
- 'atom_updated' => datetime_convert('UTC','UTC','now',ATOM_TIME),
- 'language' => $user_info['language'],
- 'logo' => z_root()."/images/rm-64.png",
- );
-
- return $arr;
- }
-
- /**
- * Returns user info array.
+ * load api $templatename for $type and replace $data array
*/
- function api_get_user( $contact_id = null, $contact_xchan = null){
-
- $user = null;
- $extra_query = "";
-
-
- if(! is_null($contact_xchan)) {
- $user = local_channel();
- $extra_query = " and abook_xchan = '" . dbesc($contact_xchan) . "' ";
- }
- else {
- if(!is_null($contact_id)){
- $user=$contact_id;
- $extra_query = " AND abook_id = %d ";
- }
-
- if(is_null($user) && x($_GET, 'user_id')) {
- $user = intval($_GET['user_id']);
- $extra_query = " AND abook_id = %d ";
- }
- if(is_null($user) && x($_GET, 'screen_name')) {
- $user = dbesc($_GET['screen_name']);
- $extra_query = " AND xchan_addr like '%s@%%' ";
- if (api_user()!==false)
- $extra_query .= " AND abook_channel = ".intval(api_user());
- }
- }
-
- if (! $user) {
- if (api_user() === false) {
- api_login($a);
- return false;
- } else {
- $user = local_channel();
- $extra_query = " AND abook_channel = %d AND abook_self = 1 ";
- }
-
- }
-
- logger('api_user: ' . $extra_query . ', user: ' . $user, LOGGER_DATA, LOG_INFO);
-
- // user info
-
- $uinfo = q("SELECT * from abook left join xchan on abook_xchan = xchan_hash
- WHERE 1
- $extra_query",
- $user
- );
-
- if (count($uinfo)==0) {
- return False;
- }
- $following = false;
-
- if(intval($uinfo[0]['abook_self'])) {
- $usr = q("select * from channel where channel_id = %d limit 1",
- intval(api_user())
- );
- $profile = q("select * from profile where uid = %d and `is_default` = 1 limit 1",
- intval(api_user())
- );
-
- $item_normal = item_normal();
-
- // count public wall messages
- $r = q("SELECT COUNT(`id`) as `count` FROM `item`
- WHERE `uid` = %d
- AND item_wall = 1 $item_normal
- AND `allow_cid`='' AND `allow_gid`='' AND `deny_cid`='' AND `deny_gid`=''
- AND item_private = 0 ",
- intval($usr[0]['channel_id'])
- );
- $countitms = $r[0]['count'];
- $following = true;
- }
- else {
- $r = q("SELECT COUNT(`id`) as `count` FROM `item`
- WHERE author_xchan = '%s'
- AND `allow_cid`='' AND `allow_gid`='' AND `deny_cid`='' AND `deny_gid`=''
- AND item_private = 0 ",
- intval($uinfo[0]['xchan_hash'])
- );
- $countitms = $r[0]['count'];
-
- $following = ((get_abconfig($uinfo[0]['abook_channel'],$uinfo[0]['abook_xchan'],'my_perms','view_stream')) ? true : false );
- }
-
+ function api_apply_template($templatename, $type, $data){
- // count friends
- if($usr) {
- $r = q("SELECT COUNT(abook_id) as `count` FROM abook
- WHERE abook_channel = %d AND abook_self = 0 ",
- intval($usr[0]['channel_id'])
- );
- $countfriends = $r[0]['count'];
- $countfollowers = $r[0]['count'];
+ switch($type){
+ case 'xml':
+ if($data) {
+ foreach($data as $k => $v)
+ $ret = arrtoxml(str_replace('$','',$k),$v);
+ }
+ break;
+ case 'json':
+ default:
+ if($data) {
+ foreach($data as $rv) {
+ $ret = json_encode($rv);
+ }
+ }
+ break;
}
- $r = q("SELECT count(`id`) as `count` FROM item where item_starred = 1 and uid = %d " . item_normal(),
- intval($uinfo[0]['channel_id'])
- );
- $starred = $r[0]['count'];
+ return $ret;
+ }
- if(! intval($uinfo[0]['abook_self'])) {
- $countfriends = 0;
- $countfollowers = 0;
- $starred = 0;
- }
-
- $ret = Array(
- 'id' => intval($uinfo[0]['abook_id']),
- 'self' => (intval($uinfo[0]['abook_self']) ? 1 : 0),
- 'uid' => intval($uinfo[0]['abook_channel']),
- 'guid' => $uinfo[0]['xchan_hash'],
- 'name' => (($uinfo[0]['xchan_name']) ? $uinfo[0]['xchan_name'] : substr($uinfo[0]['xchan_addr'],0,strpos($uinfo[0]['xchan_addr'],'@'))),
- 'screen_name' => substr($uinfo[0]['xchan_addr'],0,strpos($uinfo[0]['xchan_addr'],'@')),
- 'location' => ($usr) ? $usr[0]['channel_location'] : '',
- 'profile_image_url' => $uinfo[0]['xchan_photo_l'],
- 'url' => $uinfo[0]['xchan_url'],
- 'contact_url' => z_root() . "/connections/".$uinfo[0]['abook_id'],
- 'protected' => false,
- 'friends_count' => intval($countfriends),
- 'created_at' => api_date($uinfo[0]['abook_created']),
- 'utc_offset' => "+00:00",
- 'time_zone' => 'UTC', //$uinfo[0]['timezone'],
- 'geo_enabled' => false,
- 'statuses_count' => intval($countitms), //#XXX: fix me
- 'lang' => App::$language,
- 'description' => (($profile) ? $profile[0]['pdesc'] : ''),
- 'followers_count' => intval($countfollowers),
- 'favourites_count' => intval($starred),
- 'contributors_enabled' => false,
- 'follow_request_sent' => true,
- 'profile_background_color' => 'cfe8f6',
- 'profile_text_color' => '000000',
- 'profile_link_color' => 'FF8500',
- 'profile_sidebar_fill_color' =>'AD0066',
- 'profile_sidebar_border_color' => 'AD0066',
- 'profile_background_image_url' => '',
- 'profile_background_tile' => false,
- 'profile_use_background_image' => false,
- 'notifications' => false,
- 'following' => $following,
- 'verified' => true // #XXX: fix me
- );
- $x = api_get_status($uinfo[0]['xchan_hash']);
- if($x)
- $ret['status'] = $x;
-// logger('api_get_user: ' . print_r($ret,true));
-
- return $ret;
-
- }
function api_client_register($type) {
@@ -382,1969 +210,6 @@ require_once('include/api_auth.php');
json_return_and_die($ret);
}
- api_register_func('api/client/register','api_client_register', false);
-
-
-
- function api_item_get_user( $item) {
-
- // The author is our direct contact, in a conversation with us.
-
- if($item['author']['abook_id']) {
- return api_get_user($item['author']['abook_id']);
- }
-
- // We don't know this person directly.
-
- $nick = substr($item['author']['xchan_addr'],0,strpos($item['author']['xchan_addr'],'@'));
- $name = $item['author']['xchan_name'];
-
- // Generating a random ID
- if (! $nick)
- $nick = mt_rand(2000000, 2100000);
-
- $ret = array(
- 'id' => $nick,
- 'name' => $name,
- 'screen_name' => $nick,
- 'location' => '', //$uinfo[0]['default-location'],
- 'description' => '',
- 'profile_image_url' => $item['author']['xchan_photo_m'],
- 'url' => $item['author']['xchan_url'],
- 'protected' => false,
- 'followers_count' => 0,
- 'friends_count' => 0,
- 'created_at' => '',
- 'favourites_count' => 0,
- 'utc_offset' => 0, // #XXX: fix me
- 'time_zone' => '', //$uinfo[0]['timezone'],
- 'statuses_count' => 0,
- 'following' => false,
- 'statusnet_blocking' => false,
- 'notifications' => false,
- 'uid' => 0,
- 'contact_url' => 0,
- 'geo_enabled' => false,
- 'lang' => 'en', // #XXX: fix me
- 'contributors_enabled' => false,
- 'follow_request_sent' => false,
- 'profile_background_color' => 'cfe8f6',
- 'profile_text_color' => '000000',
- 'profile_link_color' => 'FF8500',
- 'profile_sidebar_fill_color' =>'AD0066',
- 'profile_sidebar_border_color' => 'AD0066',
- 'profile_background_image_url' => '',
- 'profile_background_tile' => false,
- 'profile_use_background_image' => false,
- 'verified' => true, // #XXX: fix me
- 'followers' => '' // #XXX: fix me
- );
-
- return $ret;
- }
-
-
- /**
- * load api $templatename for $type and replace $data array
- */
- function api_apply_template($templatename, $type, $data){
-
- switch($type){
- case "atom":
- case "rss":
- case "xml":
- $data = array_xmlify($data);
- $tpl = get_markup_template("api_".$templatename."_".$type.".tpl");
- $ret = replace_macros($tpl, $data);
- break;
- case "json":
- default:
- $ret = $data;
- break;
- }
-
- return $ret;
- }
-
-
- /**
- * Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful;
- * returns a 401 status code and an error message if not.
- * http://developer.twitter.com/doc/get/account/verify_credentials
- */
- function api_account_verify_credentials( $type){
- if (api_user()===false) return false;
- $user_info = api_get_user($a);
- return api_apply_template("user", $type, array('$user' => $user_info));
-
- }
- api_register_func('api/account/verify_credentials','api_account_verify_credentials', true);
-
-
- function api_account_logout( $type){
- require_once('include/auth.php');
- App::$session->nuke();
- return api_apply_template("user", $type, array('$user' => null));
-
- }
- api_register_func('api/account/logout','api_account_logout', false);
-
-
-
- /**
- * get data from $_REQUEST ( e.g. $_POST or $_GET )
- */
- function requestdata($k) {
- if(array_key_exists($k,$_REQUEST))
- return $_REQUEST[$k];
- return null;
- }
-
-
- /*
- * Red basic channel export
- */
-
- function api_export_basic( $type) {
- if(api_user() === false) {
- logger('api_export_basic: no user');
- return false;
- }
-
- require_once('include/channel.php');
-
- json_return_and_die(identity_basic_export(api_user(),(($_REQUEST['posts']) ? intval($_REQUEST['posts']) : 0 )));
- }
- api_register_func('api/export/basic','api_export_basic', true);
- api_register_func('api/red/channel/export/basic','api_export_basic', true);
- api_register_func('api/hz/1.0/channel/export/basic','api_export_basic', true);
-
-
- function api_channel_stream( $type) {
- if(api_user() === false) {
- logger('api_channel_stream: no user');
- return false;
- }
-
- if($_SERVER['REQUEST_METHOD'] == 'POST') {
- json_return_and_die(post_activity_item($_REQUEST));
- }
- else {
- // fetch stream
-
- }
- }
- api_register_func('api/red/channel/stream','api_channel_stream', true);
- api_register_func('api/hz/1.0/channel/stream','api_channel_stream', true);
-
- function api_attach_list($type) {
- logger('api_user: ' . api_user());
- json_return_and_die(attach_list_files(api_user(),get_observer_hash(),'','','','created asc'));
- }
- api_register_func('api/red/files','api_attach_list', true);
- api_register_func('api/hz/1.0/files','api_attach_list', true);
-
-
-
-
-
- function api_file_meta($type) {
- if (api_user()===false) return false;
- if(! $_REQUEST['file_id']) return false;
- $r = q("select * from attach where uid = %d and hash = '%s' limit 1",
- intval(api_user()),
- dbesc($_REQUEST['file_id'])
- );
- if($r) {
- unset($r[0]['content']);
- $ret = array('attach' => $r[0]);
- json_return_and_die($ret);
- }
- killme();
- }
-
- api_register_func('api/red/filemeta', 'api_file_meta', true);
- api_register_func('api/hz/1.0/filemeta', 'api_file_meta', true);
-
-
- function api_file_data($type) {
- if (api_user()===false) return false;
- if(! $_REQUEST['file_id']) return false;
- $start = (($_REQUEST['start']) ? intval($_REQUEST['start']) : 0);
- $length = (($_REQUEST['length']) ? intval($_REQUEST['length']) : 0);
-
- $r = q("select * from attach where uid = %d and hash = '%s' limit 1",
- intval(api_user()),
- dbesc($_REQUEST['file_id'])
- );
- if($r) {
- $ptr = $r[0];
- if($length === 0)
- $length = intval($ptr['filesize']);
-
- if($ptr['is_dir'])
- $ptr['content'] = '';
- elseif(! intval($r[0]['os_storage'])) {
- $ptr['start'] = $start;
- $x = substr(dbunescbin($ptr['content'],$start,$length));
- $ptr['length'] = strlen($x);
- $ptr['content'] = base64_encode($x);
- }
- else {
- $fp = fopen(dbunescbin($ptr['content']),'r');
- if($fp) {
- $seek = fseek($fp,$start,SEEK_SET);
- $x = fread($fp,$length);
- $ptr['start'] = $start;
- $ptr['length'] = strlen($x);
- $ptr['content'] = base64_encode($x);
- }
- }
-
- $ret = array('attach' => $ptr);
- json_return_and_die($ret);
- }
- killme();
- }
-
- api_register_func('api/red/filedata', 'api_file_data', true);
- api_register_func('api/hz/1.0/filedata', 'api_file_data', true);
-
-
-
- function api_file_detail($type) {
- if (api_user()===false) return false;
- if(! $_REQUEST['file_id']) return false;
- $r = q("select * from attach where uid = %d and hash = '%s' limit 1",
- intval(api_user()),
- dbesc($_REQUEST['file_id'])
- );
- if($r) {
- if($r[0]['is_dir'])
- $r[0]['content'] = '';
- elseif(intval($r[0]['os_storage']))
- $r[0]['content'] = base64_encode(file_get_contents(dbunescbin($r[0]['content'])));
- else
- $r[0]['content'] = base64_encode(dbunescbin($r[0]['content']));
-
- $ret = array('attach' => $r[0]);
- json_return_and_die($ret);
- }
- killme();
- }
-
- api_register_func('api/red/file', 'api_file_detail', true);
- api_register_func('api/hz/1.0/file', 'api_file_detail', true);
-
-
- function api_albums($type) {
- json_return_and_die(photos_albums_list(App::get_channel(),App::get_observer()));
- }
- api_register_func('api/red/albums','api_albums', true);
- api_register_func('api/hz/1.0/albums','api_albums', true);
-
- function api_photos($type) {
- $album = $_REQUEST['album'];
- json_return_and_die(photos_list_photos(App::get_channel(),App::get_observer(),$album));
- }
- api_register_func('api/red/photos','api_photos', true);
- api_register_func('api/hz/1.0/photos','api_photos', true);
-
- function api_photo_detail($type) {
- if (api_user()===false) return false;
- if(! $_REQUEST['photo_id']) return false;
- $scale = ((array_key_exists('scale',$_REQUEST)) ? intval($_REQUEST['scale']) : 0);
- $r = q("select * from photo where uid = %d and resource_id = '%s' and imgscale = %d limit 1",
- intval(local_channel()),
- dbesc($_REQUEST['photo_id']),
- intval($scale)
- );
- if($r) {
- $data = dbunescbin($r[0]['content']);
- if(array_key_exists('os_storage',$r[0]) && intval($r[0]['os_storage']))
- $data = file_get_contents($data);
- $r[0]['content'] = base64_encode($data);
- $ret = array('photo' => $r[0]);
- $i = q("select id from item where uid = %d and resource_type = 'photo' and resource_id = '%s' limit 1",
- intval(local_channel()),
- dbesc($_REQUEST['photo_id'])
- );
- if($i) {
- $ii = q("select * from item where parent = %d order by id",
- intval($i[0]['id'])
- );
- if($ii) {
- xchan_query($ii,true,0);
- $ii = fetch_post_tags($ii,true);
- if($ii) {
- $ret['item'] = array();
- foreach($ii as $iii)
- $ret['item'][] = encode_item($iii,true);
- }
- }
- }
-
- json_return_and_die($ret);
- }
- killme();
- }
-
- api_register_func('api/red/photo', 'api_photo_detail', true);
- api_register_func('api/hz/1.0/photo', 'api_photo_detail', true);
-
-
- function api_group_members($type) {
- if(api_user() === false)
- return false;
-
- if($_REQUEST['group_id']) {
- $r = q("select * from groups where uid = %d and id = %d limit 1",
- intval(api_user()),
- intval($_REQUEST['group_id'])
- );
- if($r) {
- $x = q("select * from group_member left join xchan on group_member.xchan = xchan.xchan_hash
- left join abook on abook_xchan = xchan_hash where gid = %d",
- intval($_REQUEST['group_id'])
- );
- json_return_and_die($x);
- }
- }
- }
-
- api_register_func('api/red/group_members','api_group_members', true);
- api_register_func('api/hz/1.0/group_members','api_group_members', true);
-
-
-
-
- function api_group($type) {
- if(api_user() === false)
- return false;
-
- $r = q("select * from groups where uid = %d",
- intval(api_user())
- );
- json_return_and_die($r);
- }
- api_register_func('api/red/group','api_group', true);
- api_register_func('api/hz/1.0/group','api_group', true);
-
-
- function api_red_xchan($type) {
- logger('api_xchan');
-
- if(api_user() === false)
- return false;
- logger('api_xchan');
- require_once('include/hubloc.php');
-
- if($_SERVER['REQUEST_METHOD'] === 'POST') {
- $r = xchan_store($_REQUEST);
- }
- $r = xchan_fetch($_REQUEST);
- json_return_and_die($r);
- };
-
- api_register_func('api/red/xchan','api_red_xchan',true);
- api_register_func('api/hz/1.0/xchan','api_red_xchan',true);
-
-
- function api_statuses_mediap( $type) {
- if (api_user() === false) {
- logger('api_statuses_update: no user');
- return false;
- }
- $user_info = api_get_user($a);
-
-// logger('status_with_media: ' . print_r($_REQUEST,true), LOGGER_DEBUG);
-
- $_REQUEST['type'] = 'wall';
- $_REQUEST['profile_uid'] = api_user();
- $_REQUEST['api_source'] = true;
-
- $txt = requestdata('status');
-
- require_once('library/HTMLPurifier.auto.php');
- require_once('include/html2bbcode.php');
-
- if((strpos($txt,'<') !== false) || (strpos($txt,'>') !== false)) {
- $txt = html2bb_video($txt);
- $config = HTMLPurifier_Config::createDefault();
- $config->set('Cache.DefinitionImpl', null);
- $purifier = new HTMLPurifier($config);
- $txt = $purifier->purify($txt);
- }
- $txt = html2bbcode($txt);
-
- App::$argv[1] = $user_info['screen_name'];
-
- $_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
- $_FILES['userfile'] = $_FILES['media'];
-
- $mod = new Zotlabs\Module\Wall_attach();
- $mod->post();
-
-
- $_REQUEST['body']=$txt."\n\n".$posted;
-
- $mod = new Zotlabs\Module\Item();
- $mod->post();
-
- // this should output the last post (the one we just posted).
- return api_status_show($type);
- }
- api_register_func('api/statuses/mediap','api_statuses_mediap', true);
-
- function api_statuses_update( $type) {
- if (api_user() === false) {
- logger('api_statuses_update: no user');
- return false;
- }
-
- logger('api_statuses_update: REQUEST ' . print_r($_REQUEST,true));
- logger('api_statuses_update: FILES ' . print_r($_FILES,true));
-
-
- // set this so that the item_post() function is quiet and doesn't redirect or emit json
-
- $_REQUEST['api_source'] = true;
-
-
- $user_info = api_get_user($a);
-
- // convert $_POST array items to the form we use for web posts.
-
- // logger('api_post: ' . print_r($_POST,true));
-
- if(requestdata('htmlstatus')) {
- require_once('library/HTMLPurifier.auto.php');
- require_once('include/html2bbcode.php');
-
- $txt = requestdata('htmlstatus');
-
- if((strpos($txt,'<') !== false) || (strpos($txt,'>') !== false)) {
-
- $txt = html2bb_video($txt);
-
- $config = HTMLPurifier_Config::createDefault();
- $config->set('Cache.DefinitionImpl', null);
-
-
- $purifier = new HTMLPurifier($config);
- $txt = $purifier->purify($txt);
-
- }
-
- $_REQUEST['body'] = html2bbcode($txt);
-
- }
- else
- $_REQUEST['body'] = requestdata('status');
-
- $parent = requestdata('in_reply_to_status_id');
-
- if(ctype_digit($parent))
- $_REQUEST['parent'] = $parent;
- else
- $_REQUEST['parent_mid'] = $parent;
-
- if($_REQUEST['namespace'] && $parent) {
- $x = q("select iid from iconfig where cat = 'system' and k = '%s' and v = '%s' limit 1",
- dbesc($_REQUEST['namespace']),
- dbesc($parent)
- );
- if($x) {
- $_REQUEST['parent'] = $x[0]['iid'];
- }
- }
-
- if(requestdata('lat') && requestdata('long'))
- $_REQUEST['coord'] = sprintf("%s %s",requestdata('lat'),requestdata('long'));
-
- $_REQUEST['profile_uid'] = api_user();
-
- if($parent)
- $_REQUEST['type'] = 'net-comment';
- else {
- $_REQUEST['type'] = 'wall';
-
- if(x($_FILES,'media')) {
- if(is_array($_FILES['media']['name'])) {
- $num_uploads = count($_FILES['media']['name']);
- for($x = 0; $x < $num_uploads; $x ++) {
- $_FILES['userfile'] = array();
- $_FILES['userfile']['name'] = $_FILES['media']['name'][$x];
- $_FILES['userfile']['type'] = $_FILES['media']['type'][$x];
- $_FILES['userfile']['tmp_name'] = $_FILES['media']['tmp_name'][$x];
- $_FILES['userfile']['error'] = $_FILES['media']['error'][$x];
- $_FILES['userfile']['size'] = $_FILES['media']['size'][$x];
-
- // upload each image if we have any
- $_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
- $mod = new Zotlabs\Module\Wall_attach();
- App::$data['api_info'] = $user_info;
- $media = $mod->post();
-
- if(strlen($media)>0)
- $_REQUEST['body'] .= "\n\n" . $media;
- }
- }
- else {
- // AndStatus doesn't present media as an array
- $_FILES['userfile'] = $_FILES['media'];
- // upload each image if we have any
- $_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
- $mod = new Zotlabs\Module\Wall_attach();
- App::$data['api_info'] = $user_info;
- $media = $mod->post();
-
- if(strlen($media)>0)
- $_REQUEST['body'] .= "\n\n" . $media;
- }
- }
- }
-
- // call out normal post function
-
- $mod = new Zotlabs\Module\Item();
- $mod->post();
-
- // this should output the last post (the one we just posted).
- return api_status_show($type);
- }
- api_register_func('api/statuses/update_with_media','api_statuses_update', true);
- api_register_func('api/statuses/update','api_statuses_update', true);
-
-
- function red_item_new( $type) {
-
- if (api_user() === false) {
- logger('api_red_item_new: no user');
- return false;
- }
-
- logger('api_red_item_new: REQUEST ' . print_r($_REQUEST,true));
- logger('api_red_item_new: FILES ' . print_r($_FILES,true));
-
-
- // set this so that the item_post() function is quiet and doesn't redirect or emit json
-
- $_REQUEST['api_source'] = true;
- $_REQUEST['profile_uid'] = api_user();
-
- if(x($_FILES,'media')) {
- $_FILES['userfile'] = $_FILES['media'];
- // upload the image if we have one
- $_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
- $mod = new Zotlabs\Module\Wall_upload();
- $media = $mod->post();
- if(strlen($media)>0)
- $_REQUEST['body'] .= "\n\n".$media;
- }
-
- $mod = new Zotlabs\Module\Item();
- $x = $mod->post();
- json_return_and_die($x);
- }
-
- api_register_func('api/red/item/new','red_item_new', true);
- api_register_func('api/hz/1.0/item/new','red_item_new', true);
-
-
- function red_item( $type) {
-
- if (api_user() === false) {
- logger('api_red_item_full: no user');
- return false;
- }
-
- if($_REQUEST['mid']) {
- $arr = array('mid' => $_REQUEST['mid']);
- }
- elseif($_REQUEST['item_id']) {
- $arr = array('item_id' => $_REQUEST['item_id']);
- }
- else
- json_return_and_die(array());
-
- $arr['start'] = 0;
- $arr['records'] = 999999;
- $arr['item_type'] = '*';
-
- $i = items_fetch($arr,App::get_channel(),get_observer_hash());
-
- if(! $i)
- json_return_and_die(array());
-
- $ret = array();
- $tmp = array();
- foreach($i as $ii) {
- $tmp[] = encode_item($ii,true);
- }
- $ret['item'] = $tmp;
-
- json_return_and_die($ret);
- }
-
- api_register_func('api/red/item/full','red_item', true);
- api_register_func('api/hz/1.0/item/full','red_item', true);
-
-
-
- function api_get_status($xchan_hash) {
- require_once('include/security.php');
-
- $item_normal = item_normal();
-
- $lastwall = q("SELECT * from item where
- item_private = 0 $item_normal
- and author_xchan = '%s'
- and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = ''
- and verb = '%s'
- order by created desc limit 1",
- dbesc($xchan_hash),
- dbesc(ACTIVITY_POST)
- );
-
- if($lastwall){
- $lastwall = $lastwall[0];
-
- $in_reply_to_status_id = '';
- $in_reply_to_user_id = '';
- $in_reply_to_screen_name = '';
-
- if($lastwall['author_xchan'] != $lastwall['owner_xchan']) {
- $w = q("select * from abook left join xchan on abook_xchan = xchan_hash where
- xchan_hash = '%s' limit 1",
- dbesc($lastwall['owner_xchan'])
- );
- if($w) {
- $in_reply_to_user_id = $w[0]['abook_id'];
- $in_reply_to_screen_name = substr($w[0]['xchan_addr'],0,strpos($w[0]['xchan_addr'],'@'));
- }
- }
-
- if ($lastwall['parent']!=$lastwall['id']) {
- $in_reply_to_status_id=$lastwall['thr_parent'];
- if(! $in_reply_to_user_id) {
- $in_reply_to_user_id = $user_info['id'];
- $in_reply_to_screen_name = $user_info['screen_name'];
- }
- }
- unobscure($lastwall);
- $status_info = array(
- 'text' => html2plain(prepare_text($lastwall['body'],$lastwall['mimetype']), 0),
- 'truncated' => false,
- 'created_at' => api_date($lastwall['created']),
- 'in_reply_to_status_id' => $in_reply_to_status_id,
- 'source' => (($lastwall['app']) ? $lastwall['app'] : 'web'),
- 'id' => ($lastwall['id']),
- 'in_reply_to_user_id' => $in_reply_to_user_id,
- 'in_reply_to_screen_name' => $in_reply_to_screen_name,
- 'geo' => '',
- 'favorited' => false,
- 'coordinates' => $lastwall['coord'],
- 'place' => $lastwall['location'],
- 'contributors' => ''
- );
-
- }
-
- return $status_info;
- }
-
- function api_status_show( $type){
- $user_info = api_get_user($a);
-
- // get last public message
-
- require_once('include/security.php');
- $item_normal = item_normal();
-
- $lastwall = q("SELECT * from item where
- item_private = 0 $item_normal
- and author_xchan = '%s'
- and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = ''
- and verb = '%s'
- order by created desc limit 1",
- dbesc($user_info['guid']),
- dbesc(ACTIVITY_POST)
- );
-
- if($lastwall){
- $lastwall = $lastwall[0];
-
- $in_reply_to_status_id = '';
- $in_reply_to_user_id = '';
- $in_reply_to_screen_name = '';
-
- if($lastwall['author_xchan'] != $lastwall['owner_xchan']) {
- $w = q("select * from abook left join xchan on abook_xchan = xchan_hash where
- xchan_hash = '%s' limit 1",
- dbesc($lastwall['owner_xchan'])
- );
- if($w) {
- $in_reply_to_user_id = $w[0]['abook_id'];
- $in_reply_to_screen_name = substr($w[0]['xchan_addr'],0,strpos($w[0]['xchan_addr'],'@'));
- }
- }
-
- if ($lastwall['parent']!=$lastwall['id']) {
- $in_reply_to_status_id=$lastwall['thr_parent'];
- if(! $in_reply_to_user_id) {
- $in_reply_to_user_id = $user_info['id'];
- $in_reply_to_screen_name = $user_info['screen_name'];
- }
- }
- unobscure($lastwall);
- $status_info = array(
- 'text' => html2plain(prepare_text($lastwall['body'],$lastwall['mimetype']), 0),
- 'truncated' => false,
- 'created_at' => api_date($lastwall['created']),
- 'in_reply_to_status_id' => $in_reply_to_status_id,
- 'source' => (($lastwall['app']) ? $lastwall['app'] : 'web'),
- 'id' => ($lastwall['id']),
- 'in_reply_to_user_id' => $in_reply_to_user_id,
- 'in_reply_to_screen_name' => $in_reply_to_screen_name,
- 'geo' => '',
- 'favorited' => false,
- 'coordinates' => $lastwall['coord'],
- 'place' => $lastwall['location'],
- 'contributors' => ''
- );
- $status_info['user'] = $user_info;
- if(array_key_exists('status',$status_info['user']))
- unset($status_info['user']['status']);
- }
-
- return api_apply_template("status", $type, array('$status' => $status_info));
-
- }
-
-
- /**
- * Returns extended information of a given user, specified by ID or screen name as per the required id parameter.
- * The author's most recent status will be returned inline.
- * http://developer.twitter.com/doc/get/users/show
- */
-
-// FIXME - this is essentially the same as api_status_show except for the template formatting at the end. Consolidate.
-
-
- function api_users_show( $type){
- $user_info = api_get_user($a);
-
- require_once('include/security.php');
- $item_normal = item_normal();
-
- $lastwall = q("SELECT * from item where 1
- and item_private != 0 $item_normal
- and author_xchan = '%s'
- and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = ''
- and verb = '%s'
- order by created desc limit 1",
- dbesc($user_info['guid']),
- dbesc(ACTIVITY_POST)
- );
-
- if($lastwall){
- $lastwall = $lastwall[0];
-
- $in_reply_to_status_id = '';
- $in_reply_to_user_id = '';
- $in_reply_to_screen_name = '';
-
- if($lastwall['author_xchan'] != $lastwall['owner_xchan']) {
- $w = q("select * from abook left join xchan on abook_xchan = xchan_hash where
- xchan_hash = '%s' limit 1",
- dbesc($lastwall['owner_xchan'])
- );
- if($w) {
- $in_reply_to_user_id = $w[0]['abook_id'];
- $in_reply_to_screen_name = substr($w[0]['xchan_addr'],0,strpos($w[0]['xchan_addr'],'@'));
- }
- }
-
- if ($lastwall['parent']!=$lastwall['id']) {
- $in_reply_to_status_id=$lastwall['thr_parent'];
- if(! $in_reply_to_user_id) {
- $in_reply_to_user_id = $user_info['id'];
- $in_reply_to_screen_name = $user_info['screen_name'];
- }
- }
- unobscure($lastwall);
- $user_info['status'] = array(
- 'text' => html2plain(prepare_text($lastwall['body'],$lastwall['mimetype']), 0),
- 'truncated' => false,
- 'created_at' => api_date($lastwall['created']),
- 'in_reply_to_status_id' => $in_reply_to_status_id,
- 'source' => (($lastwall['app']) ? $lastwall['app'] : 'web'),
- 'id' => (($w) ? $w[0]['abook_id'] : $user_info['id']),
- 'in_reply_to_user_id' => $in_reply_to_user_id,
- 'in_reply_to_screen_name' => $in_reply_to_screen_name,
- 'geo' => '',
- 'favorited' => false,
- 'coordinates' => $lastwall['coord'],
- 'place' => $lastwall['location'],
- 'contributors' => ''
- );
-
- }
- return api_apply_template("user", $type, array('$user' => $user_info));
-
- }
- api_register_func('api/users/show','api_users_show');
-
- /**
- *
- * http://developer.twitter.com/doc/get/statuses/home_timeline
- *
- * TODO: Optional parameters
- * TODO: Add reply info
- */
-
- function api_statuses_home_timeline( $type){
- if (api_user() === false)
- return false;
-
- $user_info = api_get_user($a);
- // get last network messages
-
-
- // params
- $count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
- $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
- if($page < 0)
- $page = 0;
- $since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
- $max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0);
- $exclude_replies = (x($_REQUEST,'exclude_replies')?1:0);
- //$since_id = 0;//$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
-
- $start = $page*$count;
-
- //$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
-
- $sql_extra = '';
- if ($max_id > 0)
- $sql_extra .= ' AND `item`.`id` <= '.intval($max_id);
- if ($exclude_replies > 0)
- $sql_extra .= ' AND `item`.`parent` = `item`.`id`';
-
- if (api_user() != $user_info['uid']) {
- $observer = App::get_observer();
- require_once('include/permissions.php');
- if(! perm_is_allowed($user_info['uid'],(($observer) ? $observer['xchan_hash'] : ''),'view_stream'))
- return '';
- $sql_extra .= " and item_private = 0 ";
- }
-
- $item_normal = item_normal();
-
- $r = q("SELECT * from item WHERE uid = %d $item_normal
- $sql_extra
- AND id > %d
- ORDER BY received DESC LIMIT %d ,%d ",
- intval($user_info['uid']),
- intval($since_id),
- intval($start),
- intval($count)
- );
-
- xchan_query($r,true);
-
- $ret = api_format_items($r,$user_info);
-
- // We aren't going to try to figure out at the item, group, and page
- // level which items you've seen and which you haven't. If you're looking
- // at the network timeline just mark everything seen.
-
- if (api_user() == $user_info['uid']) {
- $r = q("UPDATE item SET item_unseen = 0 WHERE item_unseen = 1 and uid = %d",
- intval($user_info['uid'])
- );
- }
-
-
- $data = array('$statuses' => $ret);
- switch($type){
- case "atom":
- case "rss":
- $data = api_rss_extra( $data, $user_info);
- break;
- case "as":
- $as = api_format_as( $ret, $user_info);
- $as['title'] = App::$config['sitename']." Home Timeline";
- $as['link']['url'] = z_root()."/".$user_info["screen_name"]."/all";
- return($as);
- break;
- }
-
- return api_apply_template("timeline", $type, $data);
- }
- api_register_func('api/statuses/home_timeline','api_statuses_home_timeline', true);
- api_register_func('api/statuses/friends_timeline','api_statuses_home_timeline', true);
-
- function api_statuses_public_timeline( $type){
- if (api_user()===false) return false;
-
- $user_info = api_get_user($a);
-
- $sys = get_sys_channel();
-
- // params
- $count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
- $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
- if ($page<0) $page=0;
- $since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
- $max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0);
- //$since_id = 0;//$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
-
- $start = $page*$count;
-
- //$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
-
- if ($max_id > 0)
- $sql_extra = 'AND `item`.`id` <= '.intval($max_id);
- require_once('include/security.php');
- $item_normal = item_normal();
-
- $r = q("select * from item where allow_cid = '' and allow_gid = ''
- and deny_cid = '' and deny_gid = ''
- and item_private = 0
- $item_normal
- and uid = " . $sys['channel_id'] . "
- $sql_extra
- AND id > %d group by mid
- order by received desc LIMIT %d OFFSET %d ",
- intval($since_id),
- intval($count),
- intval($start)
- );
-
- xchan_query($r,true);
-
- $ret = api_format_items($r,$user_info);
-
-
- $data = array('$statuses' => $ret);
- switch($type){
- case "atom":
- case "rss":
- $data = api_rss_extra( $data, $user_info);
- break;
- case "as":
- $as = api_format_as( $ret, $user_info);
- $as['title'] = App::$config['sitename']. " " . t('Public Timeline');
- $as['link']['url'] = z_root()."/";
- return($as);
- break;
- }
-
- return api_apply_template("timeline", $type, $data);
- }
- api_register_func('api/statuses/public_timeline','api_statuses_public_timeline', true);
-
- /**
- *
-
- */
- function api_statuses_show( $type){
- if (api_user()===false) return false;
-
- $user_info = api_get_user($a);
-
- // params
- $id = intval(argv(3));
- if(! $id)
- $id = $_REQUEST['id'];
-
- logger('API: api_statuses_show: '.$id);
-
- //$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
- $conversation = (x($_REQUEST,'conversation')?1:0);
-
- $sql_extra = '';
- if ($conversation)
- $sql_extra .= " AND `item`.`parent` = %d ORDER BY `received` ASC ";
- else
- $sql_extra .= " AND `item`.`id` = %d";
-
- $item_normal = item_normal();
- $r = q("select * from item where true $item_normal $sql_extra",
- intval($id)
- );
-
- xchan_query($r,true);
-
- $ret = api_format_items($r,$user_info);
-
-
- if ($conversation) {
- $data = array('$statuses' => $ret);
- return api_apply_template("timeline", $type, $data);
- } else {
- $data = array('$status' => $ret[0]);
- /*switch($type){
- case "atom":
- case "rss":
- $data = api_rss_extra( $data, $user_info);
- }*/
- return api_apply_template("status", $type, $data);
- }
- }
- api_register_func('api/statuses/show','api_statuses_show', true);
-
-
- /**
- *
- */
- function api_statuses_repeat( $type){
- if (api_user()===false) return false;
-
- $user_info = api_get_user($a);
-
- // params
- $id = intval(argv(3));
-
- logger('API: api_statuses_repeat: '.$id);
-
- //$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
-
- $observer = App::get_observer();
-
- $item_normal = item_normal();
-
- $r = q("SELECT * from item where and id = %d $item_normal limit 1",
- intval($id)
- );
-
- if(perm_is_allowed($r[0]['uid'],$observer['xchan_hash'],'view_stream')) {
- if ($r[0]['body'] != "") {
- $_REQUEST['body'] = html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8')."[zrl=".$r[0]['reply_url']."]".$r[0]['reply_author']."[/zrl] \n".$r[0]['body'];
- $_REQUEST['profile_uid'] = api_user();
- $_REQUEST['type'] = 'wall';
- $_REQUEST['api_source'] = true;
- $mod = new Zotlabs\Module\Item();
- $mod->post();
- }
- }
- else
- return false;
-
- if ($type == 'xml')
- $ok = "true";
- else
- $ok = "ok";
-
- return api_apply_template('test', $type, array('$ok' => $ok));
- }
- api_register_func('api/statuses/retweet','api_statuses_repeat', true);
-
- /**
- *
- */
-
- function api_statuses_destroy( $type){
- if (api_user()===false) return false;
-
- $user_info = api_get_user($a);
-
- // params
- $id = intval(argv(3));
- if($id) {
- // first prove that we own the item
-
- $r = q("select * from item where id = %d and uid = %d limit 1",
- intval($id),
- intval($user_info['uid'])
- );
- if(! $r)
- return false;
- }
- else {
- if($_REQUEST['namespace'] && $_REQUEST['remote_id']) {
- $r = q("select * from iconfig left join item on iconfig.iid = item.id
- where cat = 'system' and k = '%s' and v = '%s' and item.uid = %d limit 1",
- dbesc($_REQUEST['namespace']),
- dbesc($_REQUEST['remote_id']),
- intval($user_info['uid'])
- );
- if(! $r)
- return false;
- $id = $r[0]['iid'];
- }
- if($_REQUEST['namespace'] && $_REQUEST['comment_id']) {
- $r = q("select * from iconfig left join item on item.id = iconfig.iid where cat = 'system' and k = '%s' and v = '%s' and uid = %d and item.id != item.parent limit 1",
- dbesc($_REQUEST['namespace']),
- dbesc($_REQUEST['comment_id']),
- intval($user_info['uid'])
- );
- if(! $r)
- return false;
- $id = $r[0]['iid'];
- }
- }
- if(! $id)
- return false;
-
- logger('API: api_statuses_destroy: '.$id);
- require_once('include/items.php');
- drop_item($id, false);
-
-
- if ($type == 'xml')
- $ok = "true";
- else
- $ok = "ok";
-
- return api_apply_template('test', $type, array('$ok' => $ok));
- }
- api_register_func('api/statuses/destroy','api_statuses_destroy', true);
-
- /**
- *
- * http://developer.twitter.com/doc/get/statuses/mentions
- *
- */
-
-
- function api_statuses_mentions( $type){
- if (api_user()===false) return false;
-
- $user_info = api_get_user($a);
- // get last network messages
-
-
- // params
- $count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
- $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
- if ($page<0) $page=0;
- $since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
- $max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0);
- //$since_id = 0;//$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
-
- $start = $page*$count;
-
- //$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
-
- $myurl = z_root() . '/channel/'. App::$user['nickname'];
- $myurl = substr($myurl,strpos($myurl,'://')+3);
- $myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
- $diasp_url = str_replace('/channel/','/u/',$myurl);
-
- $sql_extra .= " AND item_mentionsme = 1 ";
- if ($max_id > 0)
- $sql_extra .= " AND item.id <= " . intval($max_id) . " ";
-
- require_once('include/security.php');
- $item_normal = item_normal();
-
- $r = q("select * from item where uid = " . intval(api_user()) . "
- $item_normal $sql_extra
- AND id > %d group by mid
- order by received desc LIMIT %d OFFSET %d ",
- intval($since_id),
- intval($count),
- intval($start)
- );
-
- xchan_query($r,true);
-
-
- $ret = api_format_items($r,$user_info);
-
-
- $data = array('$statuses' => $ret);
- switch($type){
- case "atom":
- case "rss":
- $data = api_rss_extra( $data, $user_info);
- break;
- case "as":
- $as = api_format_as( $ret, $user_info);
- $as["title"] = App::$config['sitename']." Mentions";
- $as['link']['url'] = z_root()."/";
- return($as);
- break;
- }
-
- return api_apply_template("timeline", $type, $data);
- }
- api_register_func('api/statuses/mentions','api_statuses_mentions', true);
- // FIXME?? I don't think mentions and replies are congruent in this case
- api_register_func('api/statuses/replies','api_statuses_mentions', true);
-
-
- function api_statuses_user_timeline( $type){
- if (api_user()===false) return false;
-
- $user_info = api_get_user($a);
- // get last network messages
-
-
- logger("api_statuses_user_timeline: api_user: ". api_user() .
- "\nuser_info: ".print_r($user_info, true) .
- "\n_REQUEST: ".print_r($_REQUEST, true),
- LOGGER_DEBUG);
-
- // params
- $count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
- $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
- if ($page<0) $page=0;
- $since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
- $exclude_replies = (x($_REQUEST,'exclude_replies')?1:0);
- //$since_id = 0;//$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
-
- $start = $page*$count;
-
- $sql_extra = '';
- if ($user_info['self']==1) $sql_extra .= " AND `item`.`wall` = 1 ";
-
-//FIXME - this isn't yet implemented
- if ($exclude_replies > 0) $sql_extra .= ' AND `item`.`parent` = `item`.`id`';
-
-// $r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
-// `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
-// `contact`.`network`, `contact`.`thumb`, `contact`.`dfrn_id`, `contact`.`self`,
-// `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
-// FROM `item`, `contact`
-// WHERE `item`.`uid` = %d
-// AND `item`.`contact-id` = %d
-// AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
-// AND `contact`.`id` = `item`.`contact-id`
-// AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
-// $sql_extra
-// AND `item`.`id`>%d
-// ORDER BY `item`.`received` DESC LIMIT %d ,%d ",
-// intval(api_user()),
-// intval($user_info['id']),
-// intval($since_id),
-// intval($start), intval($count)
-// );
-
- $arr = array(
- 'uid' => api_user(),
- 'since_id' => $since_id,
- 'start' => $start,
- 'records' => $count);
-
- if ($user_info['self']==1)
- $arr['wall'] = 1;
- else
- $arr['cid'] = $user_info['id'];
-
-
- $r = items_fetch($arr,App::get_channel(),get_observer_hash());
-
- $ret = api_format_items($r,$user_info);
-
-
- $data = array('$statuses' => $ret);
- switch($type){
- case "atom":
- case "rss":
- $data = api_rss_extra( $data, $user_info);
- }
-
- return api_apply_template("timeline", $type, $data);
- }
-
- api_register_func('api/statuses/user_timeline','api_statuses_user_timeline', true);
-
-
-
- /**
- * Star/unstar an item
- * param: id : id of the item
- *
- * api v1 : https://web.archive.org/web/20131019055350/https://dev.twitter.com/docs/api/1/post/favorites/create/%3Aid
- */
- function api_favorites_create_destroy( $type){
-
- logger('favorites_create_destroy');
-
- if (api_user()===false)
- return false;
-
- $action = str_replace(".".$type,"",argv(2));
- if (argc() > 3) {
- $itemid = intval(argv(3));
- } else {
- $itemid = intval($_REQUEST['id']);
- }
-
- $item = q("SELECT * FROM item WHERE id = %d AND uid = %d",
- intval($itemid),
- intval(api_user())
- );
-
- if (! $item)
- return false;
-
- switch($action){
- case "create":
- $flags = $item[0]['item_starred'] = 1;
- break;
- case "destroy":
- $flags = $item[0]['item_starred'] = 0;
- break;
- default:
- return false;
- }
-
- $r = q("UPDATE item SET item_starred = %d where id = %d and uid = %d",
- intval($flags),
- intval($itemid),
- intval(api_user())
- );
- if(! $r)
- return false;
-
- $item = q("SELECT * FROM item WHERE id = %d AND uid = %d",
- intval($itemid),
- intval(api_user())
- );
-
- xchan_query($item,true);
-
-
- $user_info = api_get_user($a);
- $rets = api_format_items($item,$user_info);
- $ret = $rets[0];
-
- $data = array('$status' => $ret);
- switch($type){
- case "atom":
- case "rss":
- $data = api_rss_extra( $data, $user_info);
- }
-
- return api_apply_template("status", $type, $data);
- }
-
- api_register_func('api/favorites/create', 'api_favorites_create_destroy', true);
- api_register_func('api/favorites/destroy', 'api_favorites_create_destroy', true);
-
-
-
- function api_favorites( $type){
- if (api_user()===false)
- return false;
-
- $user_info = api_get_user($a);
-
- // params
- $count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
- $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
- if($page < 0)
- $page = 0;
- $since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
- $max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0);
- $exclude_replies = (x($_REQUEST,'exclude_replies')?1:0);
-
- $start = $page*$count;
-
- //$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
-
- $sql_extra = '';
- if ($max_id > 0)
- $sql_extra .= ' AND `item`.`id` <= '.intval($max_id);
- if ($exclude_replies > 0)
- $sql_extra .= ' AND `item`.`parent` = `item`.`id`';
-
- if (api_user() != $user_info['uid']) {
- $observer = App::get_observer();
- require_once('include/permissions.php');
- if(! perm_is_allowed($user_info['uid'],(($observer) ? $observer['xchan_hash'] : ''),'view_stream'))
- return '';
- $sql_extra .= " and item_private = 0 ";
- }
-
- $item_normal = item_normal();
-
- $r = q("SELECT * from item WHERE uid = %d $item_normal
- and item_starred = 1 $sql_extra
- AND id > %d
- ORDER BY received DESC LIMIT %d ,%d ",
- intval($user_info['uid']),
- intval($since_id),
- intval($start),
- intval($count)
- );
-
- xchan_query($r,true);
-
- $ret = api_format_items($r,$user_info);
-
- $data = array('$statuses' => $ret);
- switch($type){
- case "atom":
- case "rss":
- $data = api_rss_extra( $data, $user_info);
- break;
- case "as":
- $as = api_format_as( $ret, $user_info);
- $as['title'] = App::$config['sitename']." Home Timeline";
- $as['link']['url'] = z_root()."/".$user_info["screen_name"]."/all";
- return($as);
- break;
- }
-
- return api_apply_template("timeline", $type, $data);
-
- }
-
- api_register_func('api/favorites','api_favorites', true);
-
-
-
-
- function api_format_as( $ret, $user_info) {
-
- $as = array();
- $as['title'] = App::$config['sitename']." Public Timeline";
- $items = array();
- foreach ($ret as $item) {
- $singleitem["actor"]["displayName"] = $item["user"]["name"];
- $singleitem["actor"]["id"] = $item["user"]["contact_url"];
- $avatar[0]["url"] = $item["user"]["profile_image_url"];
- $avatar[0]["rel"] = "avatar";
- $avatar[0]["type"] = "";
- $avatar[0]["width"] = 96;
- $avatar[0]["height"] = 96;
- $avatar[1]["url"] = $item["user"]["profile_image_url"];
- $avatar[1]["rel"] = "avatar";
- $avatar[1]["type"] = "";
- $avatar[1]["width"] = 48;
- $avatar[1]["height"] = 48;
- $avatar[2]["url"] = $item["user"]["profile_image_url"];
- $avatar[2]["rel"] = "avatar";
- $avatar[2]["type"] = "";
- $avatar[2]["width"] = 24;
- $avatar[2]["height"] = 24;
- $singleitem["actor"]["avatarLinks"] = $avatar;
-
- $singleitem["actor"]["image"]["url"] = $item["user"]["profile_image_url"];
- $singleitem["actor"]["image"]["rel"] = "avatar";
- $singleitem["actor"]["image"]["type"] = "";
- $singleitem["actor"]["image"]["width"] = 96;
- $singleitem["actor"]["image"]["height"] = 96;
- $singleitem["actor"]["type"] = "person";
- $singleitem["actor"]["url"] = $item["person"]["contact_url"];
- $singleitem["actor"]["statusnet:profile_info"]["local_id"] = $item["user"]["id"];
- $singleitem["actor"]["statusnet:profile_info"]["following"] = $item["user"]["following"] ? "true" : "false";
- $singleitem["actor"]["statusnet:profile_info"]["blocking"] = "false";
- $singleitem["actor"]["contact"]["preferredUsername"] = $item["user"]["screen_name"];
- $singleitem["actor"]["contact"]["displayName"] = $item["user"]["name"];
- $singleitem["actor"]["contact"]["addresses"] = "";
-
- $singleitem["body"] = $item["text"];
- $singleitem["object"]["displayName"] = $item["text"];
- $singleitem["object"]["id"] = $item["url"];
- $singleitem["object"]["type"] = "note";
- $singleitem["object"]["url"] = $item["url"];
- //$singleitem["context"] =;
- $singleitem["postedTime"] = date("c", strtotime($item["published"]));
- $singleitem["provider"]["objectType"] = "service";
- $singleitem["provider"]["displayName"] = "Test";
- $singleitem["provider"]["url"] = "http://test.tld";
- $singleitem["title"] = $item["text"];
- $singleitem["verb"] = "post";
- $singleitem["statusnet:notice_info"]["local_id"] = $item["id"];
- $singleitem["statusnet:notice_info"]["source"] = $item["source"];
- $singleitem["statusnet:notice_info"]["favorite"] = "false";
- $singleitem["statusnet:notice_info"]["repeated"] = "false";
- //$singleitem["original"] = $item;
- $items[] = $singleitem;
- }
- $as['items'] = $items;
- $as['link']['url'] = z_root()."/".$user_info["screen_name"]."/all";
- $as['link']['rel'] = "alternate";
- $as['link']['type'] = "text/html";
- return($as);
- }
-
- function api_format_message($item, $recipient, $sender) {
- // standard meta information
- $ret = array(
- 'id' => $item['id'],
- 'created_at' => api_date($item['created']),
- 'sender_id' => $sender['id'] ,
- 'sender_screen_name' => $sender['screen_name'],
- 'sender' => $sender,
- 'recipient_id' => $recipient['id'],
- 'recipient_screen_name' => $recipient['screen_name'],
- 'recipient' => $recipient,
- );
- unobscure_mail($item);
- //don't send title to regular StatusNET requests to avoid confusing these apps
- if (x($_GET, 'getText')) {
- $ret['title'] = $item['title'] ;
- if ($_GET["getText"] == "html") {
- $ret['text'] = prepare_text($item['body'],$item['mimetype']);
- }
- elseif ($_GET["getText"] == "plain") {
- $ret['text'] = html2plain(prepare_text($item['body'],$item['mimetype']), 0);
- }
- }
- else {
- $ret['text'] = $item['title']."\n".html2plain(prepare_text($item['body'],$item['mimetype']), 0);
- }
- if (isset($_GET["getUserObjects"]) && $_GET["getUserObjects"] == "false") {
- unset($ret['sender']);
- unset($ret['recipient']);
- }
-
- return $ret;
- }
-
- function api_format_items($r,$user_info) {
-
- //logger('api_format_items: ' . print_r($r,true));
-
- //logger('api_format_items: ' . print_r($user_info,true));
-
- $ret = array();
-
- $x = array('items' => $r,'api_user' => api_user(),'user_info' => $user_info);
- call_hooks('api_format_items',$x);
- $r = $x['items'];
-
- if(! $r)
- return $ret;
-
- foreach($r as $item) {
-
- localize_item($item);
-
- $status_user = (($item['author_xchan']==$user_info['guid'])?$user_info: api_item_get_user($item));
- if(array_key_exists('status',$status_user))
- unset($status_user['status']);
-
- if($item['parent'] != $item['id']) {
- $r = q("select id from item where parent= %d and id < %d order by id desc limit 1",
- intval($item['parent']),
- intval($item['id'])
- );
- if ($r)
- $in_reply_to_status_id = $r[0]['id'];
- else
- $in_reply_to_status_id = $item['parent'];
-
- xchan_query($r,true);
-
- $in_reply_to_screen_name = $r[0]['author']['xchan_name'];
- $in_reply_to_user_id = $r[0]['author']['abook_id'];
-
- } else {
- $in_reply_to_screen_name = '';
- $in_reply_to_user_id = 0;
- $in_reply_to_status_id = 0;
- }
- unobscure($item);
- // Workaround for ostatus messages where the title is identically to the body
- $statusbody = trim(html2plain(prepare_text($item['body'],$item['mimetype']), 0));
- $statustitle = trim($item['title']);
-
- if (($statustitle != '') and (strpos($statusbody, $statustitle) !== false))
- $statustext = trim($statusbody);
- else
- $statustext = trim($statustitle."\n\n".$statusbody);
-
-
- $status = array(
- 'text' => $statustext,
- 'truncated' => False,
- 'created_at' => api_date($item['created']),
- 'in_reply_to_status_id' => $in_reply_to_status_id,
- 'source' => (($item['app']) ? $item['app'] : 'web'),
- 'id' => intval($item['id']),
- 'in_reply_to_user_id' => $in_reply_to_user_id,
- 'in_reply_to_screen_name' => $in_reply_to_screen_name,
- 'geo' => '',
- 'favorited' => (intval($item['item_starred']) ? true : false),
- 'user' => $status_user ,
- 'statusnet_html' => trim(prepare_text($item['body'],$item['mimetype'])),
-
- 'statusnet_conversation_id' => $item['parent'],
- );
-
- // Seesmic doesn't like the following content
- if ($_SERVER['HTTP_USER_AGENT'] != 'Seesmic') {
- $status2 = array(
- 'updated' => api_date($item['edited']),
- 'published' => api_date($item['created']),
- 'message_id' => $item['mid'],
- 'url' => $item['plink'],
- 'coordinates' => $item['coord'],
- 'place' => $item['location'],
- 'contributors' => '',
- 'annotations' => '',
- 'entities' => '',
- 'objecttype' => (($item['obj_type']) ? $item['obj_type'] : ACTIVITY_OBJ_NOTE),
- 'verb' => (($item['verb']) ? $item['verb'] : ACTIVITY_POST),
- 'self' => z_root()."/api/statuses/show/".$item['id'].".".$type,
- 'edit' => z_root()."/api/statuses/show/".$item['id'].".".$type,
- );
-
- $status = array_merge($status, $status2);
- }
-
- $ret[]=$status;
- };
- return $ret;
- }
-
-
- function api_account_rate_limit_status($type) {
-
- $hash = array(
- 'reset_time_in_seconds' => strtotime('now + 1 hour'),
- 'remaining_hits' => (string) 150,
- 'hourly_limit' => (string) 150,
- 'reset_time' => datetime_convert('UTC','UTC','now + 1 hour',ATOM_TIME),
- );
- if ($type == "xml")
- $hash['resettime_in_seconds'] = $hash['reset_time_in_seconds'];
-
- return api_apply_template('ratelimit', $type, array('$hash' => $hash));
-
- }
- api_register_func('api/account/rate_limit_status','api_account_rate_limit_status',true);
-
- function api_help_test($type) {
-
- if ($type == 'xml')
- $ok = "true";
- else
- $ok = "ok";
-
- return api_apply_template('test', $type, array('$ok' => $ok));
-
- }
- api_register_func('api/help/test','api_help_test',false);
-
- /**
- * https://dev.twitter.com/docs/api/1/get/statuses/friends
- * This function is deprecated by Twitter
- * returns: json, xml
- **/
- function api_statuses_f( $type, $qtype) {
- if (api_user()===false) return false;
- $user_info = api_get_user($a);
-
-
- // friends and followers only for self
- if ($user_info['self']==0){
- return false;
- }
-
- if (x($_GET,'cursor') && $_GET['cursor']=='undefined'){
- /* this is to stop Hotot to load friends multiple times
- * I'm not sure if I'm missing return something or
- * is a bug in hotot. Workaround, meantime
- */
-
- /*$ret=Array();
- return array('$users' => $ret);*/
- return false;
- }
-
-// @fixme - update for hubzilla extensible perms using abconfig or find a better way to do it
- // For Red, the closest thing we can do to figure out if you're friends is if both of you are sending each other your streams.
- // This won't work if either of you send your stream to everybody on the network
- if($qtype == 'friends')
- $sql_extra = sprintf(" AND ( abook_their_perms & %d )>0 and ( abook_my_perms & %d )>0 ", intval(PERMS_W_STREAM), intval(PERMS_W_STREAM));
- if($qtype == 'followers')
- $sql_extra = sprintf(" AND ( abook_my_perms & %d )>0 and not ( abook_their_perms & %d )>0 ", intval(PERMS_W_STREAM), intval(PERMS_W_STREAM));
-
- $r = q("SELECT abook_id FROM abook where abook_self = 0 and abook_channel = %d $sql_extra",
- intval(api_user())
- );
-
- $ret = array();
- foreach($r as $cid){
- $ret[] = api_get_user( $cid['abook_id']);
- }
-
-
- return array('$users' => $ret);
-
- }
- function api_statuses_friends( $type){
- $data = api_statuses_f($type,"friends");
- if ($data===false) return false;
- return api_apply_template("friends", $type, $data);
- }
- function api_statuses_followers( $type){
- $data = api_statuses_f($type,"followers");
- if ($data===false) return false;
- return api_apply_template("friends", $type, $data);
- }
- api_register_func('api/statuses/friends','api_statuses_friends',true);
- api_register_func('api/statuses/followers','api_statuses_followers',true);
-
-
-
-
-
-
- function api_statusnet_config($type) {
-
- load_config('system');
-
- $name = get_config('system','sitename');
- $server = App::get_hostname();
- $logo = z_root() . '/images/rm-64.png';
- $email = get_config('system','admin_email');
- $closed = ((get_config('system','register_policy') == REGISTER_CLOSED) ? 'true' : 'false');
- $private = ((get_config('system','block_public')) ? 'true' : 'false');
- $textlimit = (string) ((get_config('system','max_import_size')) ? get_config('system','max_import_size') : 200000);
- if(get_config('system','api_import_size'))
- $texlimit = string(get_config('system','api_import_size'));
- $ssl = ((get_config('system','have_ssl')) ? 'true' : 'false');
- $sslserver = (($ssl === 'true') ? str_replace('http:','https:',z_root()) : '');
-
- $config = array(
- 'site' => array('name' => $name,'server' => $server, 'theme' => 'default', 'path' => '',
- 'logo' => $logo, 'fancy' => 'true', 'language' => 'en', 'email' => $email, 'broughtby' => '',
- 'broughtbyurl' => '', 'timezone' => 'UTC', 'closed' => $closed, 'inviteonly' => 'false',
- 'private' => $private, 'textlimit' => $textlimit, 'sslserver' => $sslserver, 'ssl' => $ssl,
- 'shorturllength' => '30',
- 'hubzilla' => array(
- 'PLATFORM_NAME' => Zotlabs\Lib\System::get_platform_name(),
- 'STD_VERSION' => Zotlabs\Lib\System::get_project_version(),
- 'ZOT_REVISION' => ZOT_REVISION,
- 'DB_UPDATE_VERSION' => Zotlabs\Lib\System::get_update_version()
- )
- ));
-
- return api_apply_template('config', $type, array('$config' => $config));
-
- }
- api_register_func('api/statusnet/config','api_statusnet_config',false);
- api_register_func('api/friendica/config','api_statusnet_config',false);
- api_register_func('api/red/config','api_statusnet_config',false);
- api_register_func('api/hz/1.0/config','api_statusnet_config',false);
-
- function api_statusnet_version($type) {
-
- // liar
-
- if($type === 'xml') {
- header("Content-type: application/xml");
- echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" . '<version>0.9.7</version>' . "\r\n";
- killme();
- }
- elseif($type === 'json') {
- header("Content-type: application/json");
- echo '"0.9.7"';
- killme();
- }
- }
- api_register_func('api/statusnet/version','api_statusnet_version',false);
-
-
- function api_friendica_version($type) {
-
- if($type === 'xml') {
- header("Content-type: application/xml");
- echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" . '<version>' . Zotlabs\Lib\System::get_project_version() . '</version>' . "\r\n";
- killme();
- }
- elseif($type === 'json') {
- header("Content-type: application/json");
- echo '"' . Zotlabs\Lib\System::get_project_version() . '"';
- killme();
- }
- }
- api_register_func('api/friendica/version','api_friendica_version',false);
- api_register_func('api/red/version','api_friendica_version',false);
- api_register_func('api/hz/1.0/version','api_friendica_version',false);
-
-
- function api_ff_ids($type,$qtype) {
- if(! api_user())
- return false;
-
-
- // For Red, the closest thing we can do to figure out if you're friends is if both of you are sending each other your streams.
- // This won't work if either of you send your stream to everybody on the network
-
- if($qtype == 'friends')
- $sql_extra = sprintf(" AND ( abook_their_perms & %d )>0 and ( abook_my_perms & %d )>0 ", intval(PERMS_W_STREAM), intval(PERMS_W_STREAM));
- if($qtype == 'followers')
- $sql_extra = sprintf(" AND ( abook_my_perms & %d )>0 and not ( abook_their_perms & %d )>0 ", intval(PERMS_W_STREAM), intval(PERMS_W_STREAM));
-
- $r = q("SELECT abook_id FROM abook where abook_self = 0 and abook_channel = %d $sql_extra",
- intval(api_user())
- );
-
- if(is_array($r)) {
- if($type === 'xml') {
- header("Content-type: application/xml");
- echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" . '<ids>' . "\r\n";
- foreach($r as $rr)
- echo '<id>' . $rr['abook_id'] . '</id>' . "\r\n";
- echo '</ids>' . "\r\n";
- killme();
- }
- elseif($type === 'json') {
- $ret = array();
- header("Content-type: application/json");
- foreach($r as $rr) $ret[] = $rr['abook_id'];
- echo json_encode($ret);
- killme();
- }
- }
- }
-
- function api_friends_ids($type) {
- api_ff_ids($type,'friends');
- }
- function api_followers_ids($type) {
- api_ff_ids($type,'followers');
- }
- api_register_func('api/friends/ids','api_friends_ids',true);
- api_register_func('api/followers/ids','api_followers_ids',true);
-
-
- function api_direct_messages_new( $type) {
- if (api_user()===false) return false;
-
- if (!x($_POST, "text") || !x($_POST,"screen_name")) return;
-
- $sender = api_get_user($a);
-
- require_once("include/message.php");
-
- // in a decentralised world the screen name is ambiguous
-
- $r = q("SELECT `abook_id` FROM `abook` left join xchan on abook_xchan = xchan_hash WHERE `abook_channel`=%d and xchan_addr like '%s'",
- intval(api_user()),
- dbesc($_POST['screen_name'] . '@%')
- );
-
- $recipient = api_get_user( $r[0]['abook_id']);
- $replyto = '';
- $sub = '';
- if (x($_REQUEST,'replyto')) {
- $r = q('SELECT `parent_mid`, `title` FROM `mail` WHERE `uid`=%d AND `id`=%d',
- intval(api_user()),
- intval($_REQUEST['replyto']));
- $replyto = $r[0]['parent_mid'];
- $sub = $r[0]['title'];
- }
- else {
- if (x($_REQUEST,'title')) {
- $sub = $_REQUEST['title'];
- }
- else {
- $sub = ((strlen($_POST['text'])>10)?substr($_POST['text'],0,10)."...":$_POST['text']);
- }
- }
-
- $id = send_message(api_user(),$recipient['guid'], $_POST['text'], $sub, $replyto);
-
- if ($id>-1) {
- $r = q("SELECT * FROM `mail` WHERE id=%d", intval($id));
- $ret = api_format_message($r[0], $recipient, $sender);
-
- } else {
- $ret = array("error"=>$id);
- }
-
- $data = Array('$messages'=>$ret);
-
- switch($type){
- case "atom":
- case "rss":
- $data = api_rss_extra( $data, $user_info);
- }
-
- return api_apply_template("direct_messages", $type, $data);
-
- }
- api_register_func('api/direct_messages/new','api_direct_messages_new',true);
-
- function api_direct_messages_box( $type, $box) {
- if (api_user()===false) return false;
-
- $user_info = api_get_user($a);
-
- // params
- $count = (x($_GET,'count')?$_GET['count']:20);
- $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
- if ($page<0) $page=0;
-
- $start = $page*$count;
- $channel = App::get_channel();
-
- $profile_url = z_root() . '/channel/' . $channel['channel_address'];
- if ($box=="sentbox") {
- $sql_extra = "`from_xchan`='".dbesc( $channel['channel_hash'] )."'";
- }
- elseif ($box=="conversation") {
- $sql_extra = "`parent_mid`='".dbesc( $_GET["uri"] ) ."'";
- }
- elseif ($box=="all") {
- $sql_extra = "true";
- }
- elseif ($box=="inbox") {
- $sql_extra = "`from_xchan`!='".dbesc( $channel['channel_hash'] )."'";
- }
-
- $r = q("SELECT * FROM `mail` WHERE channel_id = %d AND $sql_extra ORDER BY created DESC LIMIT %d OFFSET %d",
- intval(api_user()),
- intval($count), intval($start)
- );
-
- $ret = Array();
- if($r) {
- foreach($r as $item) {
- if ($item['from_xchan'] == $channel['channel_hash']) {
- $sender = $user_info;
- $recipient = api_get_user( null, $item['to_xchan']);
- }
- else {
- $sender = api_get_user( null, $item['from_xchan']);
- $recipient = $user_info;
- }
-
- $ret[]=api_format_message($item, $recipient, $sender);
- }
- }
-
-
- $data = array('$messages' => $ret);
- switch($type){
- case "atom":
- case "rss":
- $data = api_rss_extra( $data, $user_info);
- }
-
- return api_apply_template("direct_messages", $type, $data);
-
- }
-
- function api_direct_messages_sentbox( $type){
- return api_direct_messages_box( $type, "sentbox");
- }
- function api_direct_messages_inbox( $type){
- return api_direct_messages_box( $type, "inbox");
- }
- function api_direct_messages_all( $type){
- return api_direct_messages_box( $type, "all");
- }
- function api_direct_messages_conversation( $type){
- return api_direct_messages_box( $type, "conversation");
- }
- api_register_func('api/direct_messages/conversation','api_direct_messages_conversation',true);
- api_register_func('api/direct_messages/all','api_direct_messages_all',true);
- api_register_func('api/direct_messages/sent','api_direct_messages_sentbox',true);
- api_register_func('api/direct_messages','api_direct_messages_inbox',true);
function api_oauth_request_token( $type){
@@ -2355,7 +220,7 @@ require_once('include/api_auth.php');
$r = $oauth->fetch_request_token($req);
}catch(Exception $e){
logger('oauth_exception: ' . print_r($e->getMessage(),true));
- echo "error=". OAuth1Util::urlencode_rfc3986($e->getMessage());
+ echo 'error=' . OAuth1Util::urlencode_rfc3986($e->getMessage());
killme();
}
echo $r;
@@ -2365,42 +230,15 @@ require_once('include/api_auth.php');
function api_oauth_access_token( $type){
try{
$oauth = new ZotOAuth1();
- $req = OAuth1Request::from_request();
- $r = $oauth->fetch_access_token($req);
- }catch(Exception $e){
- echo "error=". OAuth1Util::urlencode_rfc3986($e->getMessage()); killme();
+ $req = OAuth1Request::from_request();
+ $r = $oauth->fetch_access_token($req);
+ }
+ catch(Exception $e) {
+ echo 'error=' . OAuth1Util::urlencode_rfc3986($e->getMessage());
+ killme();
}
echo $r;
killme();
}
- api_register_func('api/oauth/request_token', 'api_oauth_request_token', false);
- api_register_func('api/oauth/access_token', 'api_oauth_access_token', false);
-
-
-/*
-Not implemented by now:
-statuses/retweets_of_me
-friendships/create
-friendships/destroy
-friendships/exists
-friendships/show
-account/update_location
-account/update_profile_background_image
-account/update_profile_image
-blocks/create
-blocks/destroy
-
-Not implemented in status.net:
-statuses/retweeted_to_me
-statuses/retweeted_by_me
-direct_messages/destroy
-account/end_session
-account/update_delivery_device
-notifications/follow
-notifications/leave
-blocks/exists
-blocks/blocking
-lists
-*/
diff --git a/include/api_zot.php b/include/api_zot.php
new file mode 100644
index 000000000..d1979c3ae
--- /dev/null
+++ b/include/api_zot.php
@@ -0,0 +1,481 @@
+<?php
+
+ function zot_api_init() {
+ api_register_func('api/export/basic','api_export_basic', true);
+ api_register_func('api/red/channel/export/basic','api_export_basic', true);
+ api_register_func('api/z/1.0/channel/export/basic','api_export_basic', true);
+ api_register_func('api/red/channel/stream','api_channel_stream', true);
+ api_register_func('api/z/1.0/channel/stream','api_channel_stream', true);
+ api_register_func('api/red/files','api_attach_list', true);
+ api_register_func('api/z/1.0/files','api_attach_list', true);
+ api_register_func('api/red/filemeta', 'api_file_meta', true);
+ api_register_func('api/z/1.0/filemeta', 'api_file_meta', true);
+ api_register_func('api/red/filedata', 'api_file_data', true);
+ api_register_func('api/z/1.0/filedata', 'api_file_data', true);
+ api_register_func('api/red/file/export', 'api_file_export', true);
+ api_register_func('api/z/1.0/file/export', 'api_file_export', true);
+ api_register_func('api/red/file', 'api_file_detail', true);
+ api_register_func('api/z/1.0/file', 'api_file_detail', true);
+ api_register_func('api/red/albums','api_albums', true);
+ api_register_func('api/z/1.0/albums','api_albums', true);
+ api_register_func('api/red/photos','api_photos', true);
+ api_register_func('api/z/1.0/photos','api_photos', true);
+ api_register_func('api/red/photo', 'api_photo_detail', true);
+ api_register_func('api/z/1.0/photo', 'api_photo_detail', true);
+ api_register_func('api/red/group_members','api_group_members', true);
+ api_register_func('api/z/1.0/group_members','api_group_members', true);
+ api_register_func('api/red/group','api_group', true);
+ api_register_func('api/z/1.0/group','api_group', true);
+ api_register_func('api/red/xchan','api_red_xchan',true);
+ api_register_func('api/z/1.0/xchan','api_red_xchan',true);
+ api_register_func('api/red/item/update','zot_item_update', true);
+ api_register_func('api/z/1.0/item/update','zot_item_update', true);
+ api_register_func('api/red/item/full','red_item', true);
+ api_register_func('api/z/1.0/item/full','red_item', true);
+
+ api_register_func('api/z/1.0/network/stream','api_network_stream', true);
+ api_register_func('api/z/1.0/abook','api_zot_abook_xchan',true);
+ api_register_func('api/z/1.0/abconfig','api_zot_abconfig',true);
+ api_register_func('api/z/1.0/perm_allowed','api_zot_perm_allowed',true);
+
+ return;
+ }
+
+
+ /*
+ * Red basic channel export
+ */
+
+ function api_export_basic($type) {
+ if(api_user() === false) {
+ logger('api_export_basic: no user');
+ return false;
+ }
+
+ json_return_and_die(identity_basic_export(api_user(),(($_REQUEST['posts']) ? intval($_REQUEST['posts']) : 0 )));
+ }
+
+
+ function api_network_stream($type) {
+ if(api_user() === false) {
+ logger('api_channel_stream: no user');
+ return false;
+ }
+
+ $channel = channelx_by_n(api_user());
+ if(! $channel)
+ return false;
+
+
+ if($_SERVER['REQUEST_METHOD'] == 'POST') {
+ // json_return_and_die(post_activity_item($_REQUEST));
+ }
+ else {
+ $mindate = (($_REQUEST['mindate']) ? datetime_convert('UTC','UTC',$_REQUEST['mindate']) : '');
+ if(! $mindate)
+ $mindate = datetime_convert('UTC','UTC', 'now - 14 days');
+
+ $arr = $_REQUEST;
+ $ret = [];
+ $i = items_fetch($arr,App::get_channel(),get_observer_hash());
+ if($i) {
+ foreach($i as $iv) {
+ $ret[] = encode_item($iv);
+ }
+ }
+
+ json_return_and_die($ret);
+ }
+ }
+
+
+
+
+
+
+ function api_channel_stream($type) {
+ if(api_user() === false) {
+ logger('api_channel_stream: no user');
+ return false;
+ }
+
+ $channel = channelx_by_n(api_user());
+ if(! $channel)
+ return false;
+
+
+ if($_SERVER['REQUEST_METHOD'] == 'POST') {
+ json_return_and_die(post_activity_item($_REQUEST));
+ }
+ else {
+ $mindate = (($_REQUEST['mindate']) ? datetime_convert('UTC','UTC',$_REQUEST['mindate']) : '');
+ if(! $mindate)
+ $mindate = datetime_convert('UTC','UTC', 'now - 14 days');
+
+ json_return_and_die(zot_feed($channel['channel_id'],$channel['channel_hash'],[ 'mindate' => $mindate ]));
+ }
+ }
+
+ function api_attach_list($type) {
+ if(api_user() === false)
+ return false;
+
+ logger('api_user: ' . api_user());
+ $hash = ((array_key_exists('filehash',$_REQUEST)) ? $_REQUEST['filehash'] : '');
+ $filename = ((array_key_exists('filename',$_REQUEST)) ? $_REQUEST['filename'] : '');
+ $filetype = ((array_key_exists('filetype',$_REQUEST)) ? $_REQUEST['filetype'] : '');
+ $start = ((array_key_exists('start',$_REQUEST)) ? intval($_REQUEST['start']) : 0);
+ $records = ((array_key_exists('records',$_REQUEST)) ? intval($_REQUEST['records']) : 0);
+
+ $x = attach_list_files(api_user(),get_observer_hash(),$hash,$filename,$filetype,'created asc',$start,$records);
+ if($start || $records) {
+ $x['start'] = $start;
+ $x['records'] = count($x['results']);
+ }
+
+ json_return_and_die($x);
+ }
+
+
+ function api_file_meta($type) {
+ if(api_user() === false)
+ return false;
+ if(! $_REQUEST['file_id']) return false;
+ $r = q("select * from attach where uid = %d and hash = '%s' limit 1",
+ intval(api_user()),
+ dbesc($_REQUEST['file_id'])
+ );
+ if($r) {
+ unset($r[0]['content']);
+ $ret = array('attach' => $r[0]);
+ json_return_and_die($ret);
+ }
+ killme();
+ }
+
+
+
+ function api_file_data($type) {
+ if(api_user() === false)
+ return false;
+ if(! $_REQUEST['file_id']) return false;
+ $start = (($_REQUEST['start']) ? intval($_REQUEST['start']) : 0);
+ $length = (($_REQUEST['length']) ? intval($_REQUEST['length']) : 0);
+
+ $r = q("select * from attach where uid = %d and hash like '%s' limit 1",
+ intval(api_user()),
+ dbesc($_REQUEST['file_id'] . '%')
+ );
+ if($r) {
+ $ptr = $r[0];
+ if($length === 0)
+ $length = intval($ptr['filesize']);
+
+ if($ptr['is_dir'])
+ $ptr['content'] = '';
+ elseif(! intval($r[0]['os_storage'])) {
+ $ptr['start'] = $start;
+ $x = substr(dbunescbin($ptr['content']),$start,$length);
+ $ptr['length'] = strlen($x);
+ $ptr['content'] = base64_encode($x);
+ }
+ else {
+ $fp = fopen(dbunescbin($ptr['content']),'r');
+ if($fp) {
+ $seek = fseek($fp,$start,SEEK_SET);
+ $x = fread($fp,$length);
+ $ptr['start'] = $start;
+ $ptr['length'] = strlen($x);
+ $ptr['content'] = base64_encode($x);
+ }
+ }
+
+ $ret = array('attach' => $ptr);
+ json_return_and_die($ret);
+ }
+ killme();
+ }
+
+
+ function api_file_export($type) {
+ if(api_user() === false)
+ return false;
+ if(! $_REQUEST['file_id'])
+ return false;
+
+ $ret = attach_export_data(api_user(),$_REQUEST['file_id']);
+ if($ret) {
+ json_return_and_die($ret);
+ }
+ killme();
+ }
+
+
+ function api_file_detail($type) {
+ if(api_user() === false)
+ return false;
+ if(! $_REQUEST['file_id']) return false;
+ $r = q("select * from attach where uid = %d and hash = '%s' limit 1",
+ intval(api_user()),
+ dbesc($_REQUEST['file_id'])
+ );
+ if($r) {
+ if($r[0]['is_dir'])
+ $r[0]['content'] = '';
+ elseif(intval($r[0]['os_storage']))
+ $r[0]['content'] = base64_encode(file_get_contents(dbunescbin($r[0]['content'])));
+ else
+ $r[0]['content'] = base64_encode(dbunescbin($r[0]['content']));
+
+ $ret = array('attach' => $r[0]);
+ json_return_and_die($ret);
+ }
+ killme();
+ }
+
+
+
+ function api_albums($type) {
+ if(api_user() === false)
+ return false;
+ json_return_and_die(photos_albums_list(App::get_channel(),App::get_observer()));
+ }
+
+ function api_photos($type) {
+ if(api_user() === false)
+ return false;
+ $album = $_REQUEST['album'];
+ json_return_and_die(photos_list_photos(App::get_channel(),App::get_observer(),$album));
+ }
+
+ function api_photo_detail($type) {
+ if(api_user() === false)
+ return false;
+ if(! $_REQUEST['photo_id']) return false;
+ $scale = ((array_key_exists('scale',$_REQUEST)) ? intval($_REQUEST['scale']) : 0);
+ $r = q("select * from photo where uid = %d and resource_id = '%s' and imgscale = %d limit 1",
+ intval(local_channel()),
+ dbesc($_REQUEST['photo_id']),
+ intval($scale)
+ );
+ if($r) {
+ $data = dbunescbin($r[0]['content']);
+ if(array_key_exists('os_storage',$r[0]) && intval($r[0]['os_storage']))
+ $data = file_get_contents($data);
+ $r[0]['content'] = base64_encode($data);
+ $ret = array('photo' => $r[0]);
+ $i = q("select id from item where uid = %d and resource_type = 'photo' and resource_id = '%s' limit 1",
+ intval(local_channel()),
+ dbesc($_REQUEST['photo_id'])
+ );
+ if($i) {
+ $ii = q("select * from item where parent = %d order by id",
+ intval($i[0]['id'])
+ );
+ if($ii) {
+ xchan_query($ii,true,0);
+ $ii = fetch_post_tags($ii,true);
+ if($ii) {
+ $ret['item'] = array();
+ foreach($ii as $iii)
+ $ret['item'][] = encode_item($iii,true);
+ }
+ }
+ }
+
+ json_return_and_die($ret);
+ }
+ killme();
+ }
+
+ function api_group_members($type) {
+ if(api_user() === false)
+ return false;
+
+ $r = null;
+
+ if($_REQUEST['group_id']) {
+ $r = q("select * from groups where uid = %d and id = %d limit 1",
+ intval(api_user()),
+ intval($_REQUEST['group_id'])
+ );
+ }
+ elseif($_REQUEST['group_name']) {
+ $r = q("select * from groups where uid = %d and gname = '%s' limit 1",
+ intval(api_user()),
+ dbesc($_REQUEST['group_name'])
+ );
+ }
+
+ if($r) {
+ $x = q("select * from group_member left join abook on abook_xchan = xchan and abook_channel = group_member.uid left join xchan on group_member.xchan = xchan.xchan_hash
+ where gid = %d",
+ intval($r[0]['id'])
+ );
+ json_return_and_die($x);
+ }
+
+ }
+
+ function api_group($type) {
+ if(api_user() === false)
+ return false;
+
+ $r = q("select * from groups where uid = %d",
+ intval(api_user())
+ );
+ json_return_and_die($r);
+ }
+
+
+ function api_red_xchan($type) {
+ if(api_user() === false)
+ return false;
+ logger('api_xchan');
+ require_once('include/hubloc.php');
+
+ if($_SERVER['REQUEST_METHOD'] === 'POST') {
+ // $r = xchan_store($_REQUEST);
+ }
+ $r = xchan_fetch($_REQUEST);
+ json_return_and_die($r);
+ };
+
+ function api_zot_abook_xchan($type) {
+ logger('api_abook_xchan');
+
+ if(api_user() === false)
+ return false;
+
+ $sql_extra = ((array_key_exists('abook_id',$_REQUEST) && intval($_REQUEST['abook_id'])) ? ' and abook_id = ' . intval($_REQUEST['abook_id']) . ' ' : '');
+ if($_SERVER['REQUEST_METHOD'] === 'POST') {
+ // update
+ }
+ $r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d $sql_extra ",
+ intval(api_user())
+ );
+
+ json_return_and_die($r);
+ };
+
+ function api_zot_abconfig($type) {
+
+ if(api_user() === false)
+ return false;
+
+ $sql_extra = ((array_key_exists('abook_id',$_REQUEST) && intval($_REQUEST['abook_id'])) ? ' and abook_id = ' . intval($_REQUEST['abook_id']) . ' ' : '');
+ if($_SERVER['REQUEST_METHOD'] === 'POST') {
+ // update
+ }
+ $r = q("select abconfig.* from abconfig left join abook on abook_xchan = abconfig.xchan and abook_channel = abconfig.chan where abconfig.chan = %d $sql_extra ",
+ intval(api_user())
+ );
+
+ json_return_and_die($r);
+
+ }
+
+ function api_zot_perm_allowed($type) {
+ if(api_user() === false)
+ return false;
+
+ $perm = ((array_key_exists('perm',$_REQUEST)) ? $_REQUEST['perm'] : '');
+
+ if(array_key_exists('abook_id',$_REQUEST) && intval($_REQUEST['abook_id'])) {
+ $r = q("select abook_xchan as hash from abook where abook_id = %d and abook_channel = %d limit 1",
+ intval($_REQUEST['abook_id']),
+ intval(api_user())
+ );
+ }
+ else {
+ $r = xchan_fetch($_REQUEST);
+ }
+
+ $x = false;
+
+ if($r) {
+ if($perm)
+ $x = [ [ 'perm' => $perm, 'allowed' => perm_is_allowed(api_user(), $r[0]['hash'], $perm)] ];
+ else {
+ $x = [];
+ $p = get_all_perms(api_user(),$r[0]['hash']);
+ if($p) {
+ foreach($p as $k => $v)
+ $x[] = [ 'perm' => $k, 'allowed' => $v ];
+ }
+ }
+ }
+
+ json_return_and_die($x);
+
+ }
+
+ function zot_item_update($type) {
+
+ if (api_user() === false) {
+ logger('api_red_item_store: no user');
+ return false;
+ }
+
+ logger('api_red_item_store: REQUEST ' . print_r($_REQUEST,true));
+ logger('api_red_item_store: FILES ' . print_r($_FILES,true));
+
+
+ // set this so that the item_post() function is quiet and doesn't redirect or emit json
+
+ $_REQUEST['api_source'] = true;
+ $_REQUEST['profile_uid'] = api_user();
+
+ if(x($_FILES,'media')) {
+ $_FILES['userfile'] = $_FILES['media'];
+ // upload the image if we have one
+ $mod = new Zotlabs\Module\Wall_attach();
+ $media = $mod->post();
+ if($media)
+ $_REQUEST['body'] .= "\n\n" . $media;
+ }
+
+ $mod = new Zotlabs\Module\Item();
+ $x = $mod->post();
+ json_return_and_die($x);
+ }
+
+
+
+ function red_item($type) {
+
+ if (api_user() === false) {
+ logger('api_red_item_full: no user');
+ return false;
+ }
+
+ if($_REQUEST['mid']) {
+ $arr = array('mid' => $_REQUEST['mid']);
+ }
+ elseif($_REQUEST['item_id']) {
+ $arr = array('item_id' => $_REQUEST['item_id']);
+ }
+ else
+ json_return_and_die(array());
+
+ $arr['start'] = 0;
+ $arr['records'] = 999999;
+ $arr['item_type'] = '*';
+
+ $i = items_fetch($arr,App::get_channel(),get_observer_hash());
+
+ if(! $i)
+ json_return_and_die(array());
+
+ $ret = array();
+ $tmp = array();
+ foreach($i as $ii) {
+ $tmp[] = encode_item($ii,true);
+ }
+ $ret['item'] = $tmp;
+
+ json_return_and_die($ret);
+ }
+
+
+
diff --git a/include/attach.php b/include/attach.php
index b5c334d3e..ba2f60a90 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -159,7 +159,6 @@ function attach_count_files($channel_id, $observer, $hash = '', $filename = '',
intval($channel_id)
);
-
$ret['success'] = ((is_array($r)) ? true : false);
$ret['results'] = ((is_array($r)) ? count($r) : false);
@@ -198,13 +197,13 @@ function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $
$sql_extra .= protect_sprintf(" and hash = '" . dbesc($hash) . "' ");
if($filename)
- $sql_extra .= protect_sprintf(" and filename like '@" . dbesc($filename) . "@' ");
+ $sql_extra .= protect_sprintf(" and filename like '%" . dbesc($filename) . "%' ");
if($filetype)
- $sql_extra .= protect_sprintf(" and filetype like '@" . dbesc($filetype) . "@' ");
+ $sql_extra .= protect_sprintf(" and filetype like '%" . dbesc($filetype) . "%' ");
if($entries)
- $limit = " limit " . intval($start) . ", " . intval(entries) . " ";
+ $limit = " limit " . intval($start) . ", " . intval($entries) . " ";
// Retrieve all columns except 'data'
@@ -226,7 +225,8 @@ function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $
* This could exhaust memory so most useful only when immediately sending the data.
*
* @param string $hash
- * @param int $rev Revision
+ * @param string $observer_hash
+ * @param int $rev (optional) Revision default 0
* @return array
*/
function attach_by_hash($hash, $observer_hash, $rev = 0) {
@@ -285,7 +285,7 @@ function attach_by_hash($hash, $observer_hash, $rev = 0) {
function attach_can_view_folder($uid,$ob_hash,$folder_hash) {
$sql_extra = permissions_sql($uid,$ob_hash);
- $hash = $folder_hash;
+ $hash = $folder_hash;
$result = false;
do {
@@ -295,9 +295,10 @@ function attach_can_view_folder($uid,$ob_hash,$folder_hash) {
);
if(! $r)
return false;
+
$hash = $r[0]['folder'];
- }
- while($hash);
+ } while($hash);
+
return true;
}
@@ -308,8 +309,9 @@ function attach_can_view_folder($uid,$ob_hash,$folder_hash) {
* Returns the entire attach structure excluding data.
*
* @see attach_by_hash()
- * @param $hash
- * @param $rev revision default 0
+ * @param string $hash
+ * @param string $observer_hash
+ * @param int $rev (optional) revision default 0
* @return associative array with everything except data
* * \e boolean \b success boolean true or false
* * \e string \b message (optional) only when success is false
@@ -335,12 +337,12 @@ function attach_by_hash_nodata($hash, $observer_hash, $rev = 0) {
return $ret;
}
- if(! perm_is_allowed($r[0]['uid'],$observer_hash,'view_storage')) {
+ if(! perm_is_allowed($r[0]['uid'], $observer_hash, 'view_storage')) {
$ret['message'] = t('Permission denied.');
return $ret;
}
- $sql_extra = permissions_sql($r[0]['uid'],$observer_hash);
+ $sql_extra = permissions_sql($r[0]['uid'], $observer_hash);
// Now we'll see if we can access the attachment
@@ -355,14 +357,13 @@ function attach_by_hash_nodata($hash, $observer_hash, $rev = 0) {
}
if($r[0]['folder']) {
- $x = attach_can_view_folder($r[0]['uid'],$observer_hash,$r[0]['folder']);
+ $x = attach_can_view_folder($r[0]['uid'], $observer_hash, $r[0]['folder']);
if(! $x) {
$ret['message'] = t('Permission denied.');
return $ret;
}
}
-
$ret['success'] = true;
$ret['data'] = $r[0];
@@ -378,25 +379,18 @@ function attach_by_hash_nodata($hash, $observer_hash, $rev = 0) {
* @note Requires an input field \e userfile and does not accept multiple files
* in one request.
*
- * @param array $channel channel array of owner
- * @param string $observer_hash hash of current observer
- * @param string $options (optional) one of update, replace, revision
- * @param array $arr (optional) associative array
- */
-
-/**
- * A lot going on in this function, and some of it is old cruft and some is new cruft
+ * @note A lot going on in this function, and some of it is old cruft and some is new cruft
* and the entire thing probably needs to be refactored. It started out just storing
- * files, before we had DAV. It was made extensible to do extra stuff like edit an
+ * files, before we had DAV. It was made extensible to do extra stuff like edit an
* existing file or optionally store a separate revision using $options to choose between different
* storage models. Along the way we moved from
- * DB data storage to file system storage.
- * Then DAV came along and used different upload methods depending on whether the
- * file was stored as a DAV directory object or updated as a file object. One of these
+ * DB data storage to file system storage.
+ * Then DAV came along and used different upload methods depending on whether the
+ * file was stored as a DAV directory object or updated as a file object. One of these
* is essentially an update and the other is basically an upload, but doesn't use the traditional PHP
- * upload workflow.
+ * upload workflow.
* Then came hubzilla and we tried to merge photo functionality with the file storage. Most of
- * that integration occurs within this function.
+ * that integration occurs within this function.
* This required overlap with the old photo_upload stuff and photo albums were
* completely different concepts from directories which needed to be reconciled somehow.
* The old revision stuff is kind of orphaned currently. There's new revision stuff for photos
@@ -404,13 +398,18 @@ function attach_by_hash_nodata($hash, $observer_hash, $rev = 0) {
* That's where it sits currently. I repeat it needs to be refactored, and this note is here
* for future explorers and those who may be doing that work to understand where it came
* from and got to be the monstrosity of tangled unrelated code that it currently is.
+ *
+ * @param array $channel channel array of owner
+ * @param string $observer_hash hash of current observer
+ * @param string $options (optional) one of update, replace, revision
+ * @param array $arr (optional) associative array
+ * @return void|array
*/
-
function attach_store($channel, $observer_hash, $options = '', $arr = null) {
require_once('include/photos.php');
- call_hooks('photo_upload_begin',$arr);
+ call_hooks('photo_upload_begin', $arr);
$ret = array('success' => false);
$channel_id = $channel['channel_id'];
@@ -441,7 +440,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
return $ret;
}
- $str_group_allow = perms2str($arr['group_allow']);
+ $str_group_allow = perms2str($arr['group_allow']);
$str_contact_allow = perms2str($arr['contact_allow']);
$str_group_deny = perms2str($arr['group_deny']);
$str_contact_deny = perms2str($arr['contact_deny']);
@@ -458,7 +457,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$remove_when_processed = true;
- if($options === 'import') {
+ if($options === 'import') {
$src = $arr['src'];
$filename = $arr['filename'];
$filesize = @filesize($src);
@@ -485,17 +484,15 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
elseif($options !== 'update') {
$f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => '');
- call_hooks('photo_upload_file',$f);
+ call_hooks('photo_upload_file',$f);
call_hooks('attach_upload_file',$f);
- if (x($f,'src') && x($f,'filesize')) {
- $src = $f['src'];
- $filename = $f['filename'];
- $filesize = $f['filesize'];
- $type = $f['type'];
-
- } else {
-
+ if (x($f,'src') && x($f,'filesize')) {
+ $src = $f['src'];
+ $filename = $f['filename'];
+ $filesize = $f['filesize'];
+ $type = $f['type'];
+ } else {
if(! x($_FILES,'userfile')) {
$ret['message'] = t('No source file.');
return $ret;
@@ -543,12 +540,10 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$hash = $x[0]['hash'];
}
-
-
$def_extension = '';
$is_photo = 0;
$gis = @getimagesize($src);
- logger('getimagesize: ' . print_r($gis,true), LOGGER_DATA);
+ logger('getimagesize: ' . print_r($gis,true), LOGGER_DATA);
if(($gis) && ($gis[2] === IMAGETYPE_GIF || $gis[2] === IMAGETYPE_JPEG || $gis[2] === IMAGETYPE_PNG)) {
$is_photo = 1;
if($gis[2] === IMAGETYPE_GIF)
@@ -557,7 +552,6 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$def_extension = '.jpg';
if($gis[2] === IMAGETYPE_PNG)
$def_extension = '.png';
-
}
$pathname = '';
@@ -607,7 +601,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
}
else {
$folder_hash = ((($arr) && array_key_exists('folder',$arr)) ? $arr['folder'] : '');
- }
+ }
if((! $options) || ($options === 'import')) {
@@ -654,8 +648,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
}
if($found)
$x++;
- }
- while($found);
+ } while($found);
$filename = $basename . '(' . $x . ')' . $ext;
}
else
@@ -702,7 +695,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
if($folder_hash) {
$curr = find_folder_hash_by_attach_hash($channel_id,$folder_hash,true);
- if($curr)
+ if($curr)
$os_relpath .= $curr . '/';
$os_relpath .= $folder_hash . '/';
}
@@ -711,6 +704,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
// not yet used
$os_path = '';
+ $display_path = '';
if($src)
@file_put_contents($os_basepath . $os_relpath,@file_get_contents($src));
@@ -726,23 +720,24 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$edited = $created;
if($options === 'replace') {
- $r = q("update attach set filename = '%s', filetype = '%s', folder = '%s', filesize = %d, os_storage = %d, is_photo = %d, content = '%s', edited = '%s', os_path = '%s' where id = %d and uid = %d",
+ $r = q("update attach set filename = '%s', filetype = '%s', folder = '%s', filesize = %d, os_storage = %d, is_photo = %d, content = '%s', edited = '%s', os_path = '%s', display_path = '%s' where id = %d and uid = %d",
dbesc($filename),
dbesc($mimetype),
dbesc($folder_hash),
intval($filesize),
intval(1),
intval($is_photo),
- dbesc($os_basepath . $os_relpath),
+ dbescbin($os_basepath . $os_relpath),
dbesc($created),
dbesc($os_path),
+ dbesc($display_path),
intval($existing_id),
intval($channel_id)
);
}
elseif($options === 'revise') {
- $r = q("insert into attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, content, created, edited, os_path, allow_cid, allow_gid, deny_cid, deny_gid )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
+ $r = q("insert into attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, content, created, edited, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
intval($x[0]['aid']),
intval($channel_id),
dbesc($x[0]['hash']),
@@ -754,10 +749,11 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
intval($x[0]['revision'] + 1),
intval(1),
intval($is_photo),
- dbesc($os_basepath . $os_relpath),
+ dbescbin($os_basepath . $os_relpath),
dbesc($created),
dbesc($created),
dbesc($os_path),
+ dbesc($display_path),
dbesc($x[0]['allow_cid']),
dbesc($x[0]['allow_gid']),
dbesc($x[0]['deny_cid']),
@@ -766,7 +762,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
}
elseif($options === 'update') {
$r = q("update attach set filename = '%s', filetype = '%s', folder = '%s', edited = '%s', os_storage = %d, is_photo = %d, os_path = '%s',
- allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where id = %d and uid = %d",
+ display_path = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where id = %d and uid = %d",
dbesc((array_key_exists('filename',$arr)) ? $arr['filename'] : $x[0]['filename']),
dbesc((array_key_exists('filetype',$arr)) ? $arr['filetype'] : $x[0]['filetype']),
dbesc(($folder_hash) ? $folder_hash : $x[0]['folder']),
@@ -774,6 +770,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
dbesc((array_key_exists('os_storage',$arr)) ? $arr['os_storage'] : $x[0]['os_storage']),
dbesc((array_key_exists('is_photo',$arr)) ? $arr['is_photo'] : $x[0]['is_photo']),
dbesc((array_key_exists('os_path',$arr)) ? $arr['os_path'] : $x[0]['os_path']),
+ dbesc((array_key_exists('display_path',$arr)) ? $arr['display_path'] : $x[0]['display_path']),
dbesc((array_key_exists('allow_cid',$arr)) ? $arr['allow_cid'] : $x[0]['allow_cid']),
dbesc((array_key_exists('allow_gid',$arr)) ? $arr['allow_gid'] : $x[0]['allow_gid']),
dbesc((array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : $x[0]['deny_cid']),
@@ -784,8 +781,8 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
}
else {
- $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, content, created, edited, os_path, allow_cid, allow_gid,deny_cid, deny_gid )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
+ $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, content, created, edited, os_path, display_path, allow_cid, allow_gid,deny_cid, deny_gid )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
intval($channel['channel_account_id']),
intval($channel_id),
dbesc($hash),
@@ -797,10 +794,11 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
intval(0),
intval(1),
intval($is_photo),
- dbesc($os_basepath . $os_relpath),
+ dbescbin($os_basepath . $os_relpath),
dbesc($created),
dbesc($created),
dbesc($os_path),
+ dbesc($display_path),
dbesc(($arr && array_key_exists('allow_cid',$arr)) ? $arr['allow_cid'] : $str_contact_allow),
dbesc(($arr && array_key_exists('allow_gid',$arr)) ? $arr['allow_gid'] : $str_group_allow),
dbesc(($arr && array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : $str_contact_deny),
@@ -869,7 +867,6 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
return $ret;
}
-
$ret['success'] = true;
$ret['data'] = $r[0];
if(! $is_photo) {
@@ -880,7 +877,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
if($dosync) {
$sync = attach_export_data($channel,$hash);
- if($sync)
+ if($sync)
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
}
@@ -998,7 +995,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
intval($channel['channel_id'])
);
if($r) {
- if(array_key_exists('force',$arr) && intval($arr['force'])
+ if(array_key_exists('force',$arr) && intval($arr['force'])
&& (intval($r[0]['is_dir']))) {
$ret['success'] = true;
$r = q("select * from attach where id = %d limit 1",
@@ -1046,8 +1043,12 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
$created = datetime_convert();
- $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_dir, content, created, edited, allow_cid, allow_gid, deny_cid, deny_gid )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
+ // not yet used
+ $os_path = '';
+ $display_path = '';
+
+ $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_dir, content, created, edited, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
intval($channel['channel_account_id']),
intval($channel_id),
dbesc($arr['hash']),
@@ -1059,9 +1060,11 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
dbesc($arr['folder']),
intval(1),
intval(1),
- dbesc($path),
+ dbescbin($path),
dbesc($created),
dbesc($created),
+ dbesc($os_path),
+ dbesc($display_path),
dbesc(($arr && array_key_exists('allow_cid',$arr)) ? $arr['allow_cid'] : $channel['channel_allow_cid']),
dbesc(($arr && array_key_exists('allow_gid',$arr)) ? $arr['allow_gid'] : $channel['channel_allow_gid']),
dbesc(($arr && array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : $channel['channel_deny_cid']),
@@ -1150,7 +1153,7 @@ function attach_mkdirp($channel, $observer_hash, $arr = null) {
if(! $p)
continue;
$arx = array(
- 'filename' => $p,
+ 'filename' => $p,
'folder' => $current_parent,
'force' => 1
);
@@ -1163,7 +1166,7 @@ function attach_mkdirp($channel, $observer_hash, $arr = null) {
if(array_key_exists('deny_gid',$arr))
$arx['deny_gid'] = $arr['deny_gid'];
- $x = attach_mkdir($channel, $observer_hash, $arx);
+ $x = attach_mkdir($channel, $observer_hash, $arx);
if($x['success']) {
$current_parent = $x['data']['hash'];
}
@@ -1177,26 +1180,22 @@ function attach_mkdirp($channel, $observer_hash, $arr = null) {
$ret['data'] = $x['data'];
}
- return $ret;
-
+ return $ret;
}
-
-
-
-
/**
* @brief Changes permissions of a file.
*
- * @param int $channel_id
+ * @param int $channel_id The id of the channel
* @param array $resource
* @param string $allow_cid
* @param string $allow_gid
* @param string $deny_cid
* @param string $deny_gid
* @param boolean $recurse (optional) default false
+ * @param boolean $sync (optional) default false
*/
function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $recurse = false, $sync = false) {
@@ -1248,7 +1247,7 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi
if($sync) {
$data = attach_export_data($channel,$resource);
- if($data)
+ if($data)
build_sync_packet($channel['channel_id'],array('file' => array($data)));
}
}
@@ -1263,6 +1262,7 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi
* The id of the channel
* @param string $resource
* The hash to delete
+ * @param int $is_photo (optional) default 0
* @return void
*/
function attach_delete($channel_id, $resource, $is_photo = 0) {
@@ -1306,6 +1306,7 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
);
if($y) {
+ $y[0]['content'] = dbunescbin($y[0]['content']);
if(strpos($y[0]['content'],'store') === false)
$f = 'store/' . $channel_address . '/' . $y[0]['content'];
else
@@ -1337,7 +1338,7 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
dbesc($resource)
);
}
-
+
// update the parent folder's lastmodified timestamp
$e = q("UPDATE attach SET edited = '%s' WHERE hash = '%s' AND uid = %d",
dbesc(datetime_convert()),
@@ -1425,6 +1426,7 @@ function get_parent_cloudpath($channel_id, $channel_name, $attachHash) {
$parentFullPath = $parentName . '/' . $parentFullPath;
}
} while ($parentHash);
+
$parentFullPath = z_root() . '/cloud/' . $channel_name . '/' . $parentFullPath;
return $parentFullPath;
@@ -1437,11 +1439,14 @@ function get_parent_cloudpath($channel_id, $channel_name, $attachHash) {
* The id of the channel
* @param string $attachHash
* The hash of the attachment
+ * @param boolean $recurse
+ * (optional) default false
* @return string
*/
function find_folder_hash_by_attach_hash($channel_id, $attachHash, $recurse = false) {
-logger('attach_hash: ' . $attachHash);
+ logger('attach_hash: ' . $attachHash);
+
$r = q("SELECT folder FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1",
intval($channel_id),
dbesc($attachHash)
@@ -1449,10 +1454,11 @@ logger('attach_hash: ' . $attachHash);
$hash = '';
if($r && $r[0]['folder']) {
if($recurse)
- $hash = find_folder_hash_by_attach_hash($channel_id,$r[0]['folder'],true) . '/' . $r[0]['folder'];
+ $hash = find_folder_hash_by_attach_hash($channel_id,$r[0]['folder'],true) . '/' . $r[0]['folder'];
else
$hash = $r[0]['folder'];
}
+
return $hash;
}
@@ -1569,13 +1575,13 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
$arr = array();
$arr['aid'] = get_account_id();
$arr['uid'] = $channel_id;
- $arr['item_wall'] = 1;
+ $arr['item_wall'] = 1;
$arr['item_origin'] = 1;
$arr['item_unseen'] = 1;
$arr['author_xchan'] = $poster['xchan_hash'];
$arr['owner_xchan'] = $poster['xchan_hash'];
$arr['title'] = '';
- $arr['item_hidden'] = 1;
+ $arr['item_notshown'] = 1;
$arr['obj_type'] = $objtype;
$arr['resource_id'] = $object['hash'];
$arr['resource_type'] = 'attach';
@@ -1732,11 +1738,11 @@ function get_file_activity_object($channel_id, $hash, $cloudpath) {
/**
* @brief Returns array of channels which have recursive permission for a file
*
- * @param $arr_allow_cid
- * @param $arr_allow_gid
- * @param $arr_deny_cid
- * @param $arr_deny_gid
- * @param $folder_hash
+ * @param array $arr_allow_cid
+ * @param array $arr_allow_gid
+ * @param array $arr_deny_cid
+ * @param array $arr_deny_gid
+ * @param string $folder_hash
*/
function recursive_activity_recipients($arr_allow_cid, $arr_allow_gid, $arr_deny_cid, $arr_deny_gid, $folder_hash) {
@@ -1907,7 +1913,7 @@ function attach_export_data($channel, $resource_id, $deleted = false) {
);
if($r) {
for($x = 0; $x < count($r); $x ++) {
- $r[$x]['content'] = base64_encode($r[$x]['content']);
+ $r[$x]['content'] = base64_encode(dbunescbin($r[$x]['content']));
}
$ret['photo'] = $r;
}
@@ -1931,50 +1937,53 @@ function attach_export_data($channel, $resource_id, $deleted = false) {
}
return $ret;
-
}
-/* strip off 'store/nickname/' from the provided path */
-
+/**
+ * @brief Strip off 'store/nickname/' from the provided path
+ *
+ * @param string $s
+ * @return string
+ */
function get_attach_binname($s) {
$p = $s;
- if(strpos($s,'store/') === 0) {
- $p = substr($s,6);
- $p = substr($p,strpos($p,'/')+1);
+ if(strpos($s, 'store/') === 0) {
+ $p = substr($s, 6);
+ $p = substr($p, strpos($p, '/')+1);
}
+
return $p;
}
function get_dirpath_by_cloudpath($channel, $path) {
-
- // Warning: Do not edit the following line. The first symbol is UTF-8 &#65312;
- $path = str_replace('@','@',notags(trim($path)));
+
+ $path = notags(trim($path));
$h = @parse_url($path);
if(! $h || !x($h, 'path')) {
return null;
}
- if(substr($h['path'],-1,1) === '/') {
- $h['path'] = substr($h['path'],0,-1);
+ if(substr($h['path'], -1, 1) === '/') {
+ $h['path'] = substr($h['path'], 0, -1);
}
if(substr($h['path'],0,1) === '/') {
- $h['path'] = substr($h['path'],1);
+ $h['path'] = substr($h['path'], 1);
}
$folders = explode('/', $h['path']);
$f = array_shift($folders);
-
+
$nick = $channel['channel_address'];
//check to see if the absolute path was provided (/cloud/channelname/path/to/folder)
- if($f === 'cloud' ) {
+ if($f === 'cloud' ) {
$g = array_shift($folders);
if( $g !== $nick) {
// if nick does not follow "cloud", then the top level folder must be called "cloud"
- // and the given path must be relative to "/cloud/channelname/".
+ // and the given path must be relative to "/cloud/channelname/".
$folders = array_unshift(array_unshift($folders, $g), $f);
- }
+ }
} else {
array_unshift($folders, $f);
}
@@ -1998,8 +2007,6 @@ function get_dirpath_by_cloudpath($channel, $path) {
} else {
return $clouddir . $subdir;
}
-
-
}
function get_filename_by_cloudname($cloudname, $channel, $storepath) {
@@ -2013,66 +2020,74 @@ function get_filename_by_cloudname($cloudname, $channel, $storepath) {
return null;
}
-
-// recursively copy a directory into cloud files
-function copy_folder_to_cloudfiles($channel, $observer_hash, $srcpath, $cloudpath)
-{
- if (!is_dir($srcpath) || !is_readable($srcpath)) {
- logger('Error reading source path: ' . $srcpath, LOGGER_NORMAL);
+/**
+ * @brief recursively copy a directory into cloud files
+ *
+ * @param array $channel
+ * @param string $observer_hash
+ * @param string $srcpath
+ * @param string $cloudpath
+ * @return boolean
+ */
+function copy_folder_to_cloudfiles($channel, $observer_hash, $srcpath, $cloudpath) {
+ if (!is_dir($srcpath) || !is_readable($srcpath)) {
+ logger('Error reading source path: ' . $srcpath, LOGGER_NORMAL);
+ return false;
+ }
+ $nodes = array_diff(scandir($srcpath), array('.', '..'));
+ foreach ($nodes as $node) {
+ $clouddir = $cloudpath . '/' . $node; // Sub-folder in cloud files destination
+ $nodepath = $srcpath . '/' . $node; // Sub-folder in source path
+ if(is_dir($nodepath)) {
+ $x = attach_mkdirp($channel, $observer_hash, array('pathname' => $clouddir));
+ if(!$x['success']) {
+ logger('Error creating cloud path: ' . $clouddir, LOGGER_NORMAL);
return false;
+ }
+ // Recursively call this function where the source and destination are the subfolders
+ $success = copy_folder_to_cloudfiles($channel, $observer_hash, $nodepath, $clouddir);
+ if(!$success) {
+ logger('Error copying contents of folder: ' . $nodepath, LOGGER_NORMAL);
+ return false;
+ }
+ } elseif(is_file($nodepath) && is_readable($nodepath)) {
+ $x = attach_store($channel, $observer_hash, 'import', array(
+ 'directory' => $cloudpath,
+ 'src' => $nodepath,
+ 'filename' => $node,
+ 'filesize' => @filesize($nodepath),
+ 'preserve_original' => true
+ ));
+ if(!$x['success']) {
+ logger('Error copying file: ' . $nodepath, LOGGER_NORMAL);
+ logger('Return value: ' . json_encode($x), LOGGER_NORMAL);
+ return false;
+ }
+ } else {
+ logger('Error scanning source path', LOGGER_NORMAL);
+ return false;
}
- $nodes = array_diff(scandir($srcpath), array('.', '..'));
- foreach ($nodes as $node) {
- $clouddir = $cloudpath . '/' . $node; // Sub-folder in cloud files destination
- $nodepath = $srcpath . '/' . $node; // Sub-folder in source path
- if(is_dir($nodepath)) {
- $x = attach_mkdirp($channel, $observer_hash, array('pathname' => $clouddir));
- if(!$x['success']) {
- logger('Error creating cloud path: ' . $clouddir, LOGGER_NORMAL);
- return false;
- }
- // Recursively call this function where the source and destination are the subfolders
- $success = copy_folder_to_cloudfiles($channel, $observer_hash, $nodepath, $clouddir);
- if(!$success) {
- logger('Error copying contents of folder: ' . $nodepath, LOGGER_NORMAL);
- return false;
- }
- } elseif (is_file($nodepath) && is_readable($nodepath)) {
- $x = attach_store($channel, $observer_hash, 'import',
- array(
- 'directory' => $cloudpath,
- 'src' => $nodepath,
- 'filename' => $node,
- 'filesize' => @filesize($nodepath),
- 'preserve_original' => true)
- );
- if(!$x['success']) {
- logger('Error copying file: ' . $nodepath , LOGGER_NORMAL);
- logger('Return value: ' . json_encode($x), LOGGER_NORMAL);
- return false;
- }
- } else {
- logger('Error scanning source path', LOGGER_NORMAL);
- return false;
- }
- }
+ }
- return true;
+ return true;
}
/**
- * attach_move()
* This function performs an in place directory-to-directory move of a stored attachment or photo.
* The data is physically moved in the store/nickname storage location and the paths adjusted
* in the attach structure (and if applicable the photo table). The new 'album name' is recorded
* for photos and will show up immediately there.
* This takes a channel_id, attach.hash of the file to move (this is the same as a photo resource_id), and
* the attach.hash of the new parent folder, which must already exist. If $new_folder_hash is blank or empty,
- * the file is relocated to the root of the channel's storage area.
+ * the file is relocated to the root of the channel's storage area.
*
* @fixme: this operation is currently not synced to clones !!
+ *
+ * @param int $channel_id
+ * @param int $resource_id
+ * @param string $new_folder_hash
+ * @return void|boolean
*/
-
-function attach_move($channel_id,$resource_id,$new_folder_hash) {
+function attach_move($channel_id, $resource_id, $new_folder_hash) {
$c = channelx_by_n($channel_id);
if(! $c)
@@ -2085,8 +2100,8 @@ function attach_move($channel_id,$resource_id,$new_folder_hash) {
if(! $r)
return false;
- $oldstorepath = $r[0]['content'];
-
+ $oldstorepath = dbunescbin($r[0]['content']);
+
if($new_folder_hash) {
$n = q("select * from attach where hash = '%s' and uid = %d limit 1",
dbesc($new_folder_hash),
@@ -2094,8 +2109,9 @@ function attach_move($channel_id,$resource_id,$new_folder_hash) {
);
if(! $n)
return;
+
$newdirname = $n[0]['filename'];
- $newstorepath = $n[0]['content'] . '/' . $resource_id;
+ $newstorepath = dbunescbin($n[0]['content']) . '/' . $resource_id;
}
else {
$newstorepath = 'store/' . $c['channel_address'] . '/' . $resource_id;
@@ -2115,7 +2131,7 @@ function attach_move($channel_id,$resource_id,$new_folder_hash) {
if($s) {
$overwrite = get_pconfig($channel_id,'system','overwrite_dup_files');
if($overwrite) {
- // @fixme
+ /// @fixme
return;
}
else {
@@ -2128,6 +2144,10 @@ function attach_move($channel_id,$resource_id,$new_folder_hash) {
$ext = '';
}
+ $matches = false;
+ if(preg_match('/(.*?)\([0-9]{1,}\)$/',$basename,$matches))
+ $basename = $matches[1];
+
$v = q("select filename from attach where ( filename = '%s' OR filename like '%s' ) and folder = '%s' ",
dbesc($basename . $ext),
dbesc($basename . '(%)' . $ext),
@@ -2147,7 +2167,7 @@ function attach_move($channel_id,$resource_id,$new_folder_hash) {
}
if($found)
$x++;
- }
+ }
while($found);
$filename = $basename . '(' . $x . ')' . $ext;
}
@@ -2157,7 +2177,7 @@ function attach_move($channel_id,$resource_id,$new_folder_hash) {
}
$t = q("update attach set content = '%s', folder = '%s', filename = '%s' where id = %d",
- dbesc($newstorepath),
+ dbescbin($newstorepath),
dbesc($new_folder_hash),
dbesc($filename),
intval($r[0]['id'])
@@ -2172,14 +2192,13 @@ function attach_move($channel_id,$resource_id,$new_folder_hash) {
);
$t = q("update photo set content = '%s' where resource_id = '%s' and uid = %d and imgscale = 0",
- dbesc($newstorepath),
+ dbescbin($newstorepath),
dbesc($resource_id),
intval($channel_id)
);
}
return true;
-
}
@@ -2191,7 +2210,7 @@ function attach_folder_select_list($channel_id) {
$out = [];
$out[''] = '/';
-
+
if($r) {
foreach($r as $rv) {
$x = attach_folder_rpaths($r,$rv);
@@ -2199,6 +2218,7 @@ function attach_folder_select_list($channel_id) {
$out[$x[0]] = $x[1];
}
}
+
return $out;
}
@@ -2223,11 +2243,11 @@ function attach_folder_rpaths($all_folders,$that_folder) {
break;
}
}
- if(! $found)
+ if(! $found)
$error = true;
}
while((! $found) && (! $error) && ($parent_hash != ''));
}
- return (($error) ? false : [ $current_hash , $path ]);
-} \ No newline at end of file
+ return (($error) ? false : [ $current_hash , $path ]);
+}
diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php
index d3f88e17c..87a8551ae 100644
--- a/include/bb2diaspora.php
+++ b/include/bb2diaspora.php
@@ -123,13 +123,16 @@ function diaspora_mention_callback($matches) {
* @param boolean $use_zrl default false
* @return string
*/
-function diaspora2bb($s, $use_zrl = false) {
+function markdown_to_bb($s, $use_zrl = false) {
$s = str_replace("&#xD;","\r",$s);
$s = str_replace("&#xD;\n&gt;","",$s);
$s = html_entity_decode($s,ENT_COMPAT,'UTF-8');
+ // if empty link text replace with the url
+ $s = preg_replace("/\[\]\((.*?)\)/ism",'[$1]($1)',$s);
+
// first try plustags
$s = preg_replace_callback('/\@\{(.+?)\; (.+?)\@(.+?)\}\+/','diaspora_mention_callback',$s);
@@ -155,23 +158,20 @@ function diaspora2bb($s, $use_zrl = false) {
// Convert everything that looks like a link to a link
if($use_zrl) {
$s = str_replace(array('[img','/img]'),array('[zmg','/zmg]'),$s);
- $s = preg_replace("/([^\]\=]|^)(https?\:\/\/)([a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1[zrl=$2$3]$2$3[/zrl]',$s);
+ $s = preg_replace("/([^\]\=]|^)(https?\:\/\/)([a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\(\)]+)/ism", '$1[zrl=$2$3]$2$3[/zrl]',$s);
}
else {
- $s = preg_replace("/([^\]\=]|^)(https?\:\/\/)([a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1[url=$2$3]$2$3[/url]',$s);
+ $s = preg_replace("/([^\]\=]|^)(https?\:\/\/)([a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\(\)]+)/ism", '$1[url=$2$3]$2$3[/url]',$s);
}
- //$s = preg_replace("/([^\]\=]|^)(https?\:\/\/)(vimeo|youtu|www\.youtube|soundcloud)([a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1[url=$2$3$4]$2$3$4[/url]',$s);
- $s = bb_tag_preg_replace("/\[url\=?(.*?)\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/url\]/ism",'[embed]https://www.youtube.com/watch?v=$2[/embed]','url',$s);
- $s = bb_tag_preg_replace("/\[url\=https?:\/\/www.youtube.com\/watch\?v\=(.*?)\].*?\[\/url\]/ism",'[embed]https://www.youtube.com/watch?v=$1[/embed]','url',$s);
- $s = bb_tag_preg_replace("/\[url\=?(.*?)\]https?:\/ \/vimeo.com\/([0-9]+)(.*?)\[\/url\]/ism",'[embed]https://vimeo.com/$2[/embed]','url',$s);
- $s = bb_tag_preg_replace("/\[url\=https?:\/\/vimeo.com\/([0-9]+)\](.*?)\[\/url\]/ism",'[embed]https://vimeo.com/$1[/embed]','url',$s);
// remove duplicate adjacent code tags
$s = preg_replace("/(\[code\])+(.*?)(\[\/code\])+/ism","[code]$2[/code]", $s);
// Don't show link to full picture (until it is fixed)
$s = scale_external_images($s, false);
+ call_hooks('markdown_to_bb',$s);
+
return $s;
}
@@ -324,7 +324,7 @@ function bb2diaspora_itemwallwall(&$item,$uplink = false) {
}
-function bb2diaspora_itembody($item, $force_update = false, $have_channel = false, $uplink) {
+function bb2diaspora_itembody($item, $force_update = false, $have_channel = false, $uplink = false) {
if(! get_iconfig($item,'diaspora','fields')) {
@@ -430,6 +430,12 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
$Text = preg_replace_callback('/\@\!?\[([zu])rl\=(\w+.*?)\](\w+.*?)\[\/([zu])rl\]/i', 'bb2dmention_callback', $Text);
+ // strip map tags, as the rendering is performed in bbcode() and the resulting output
+ // is not compatible with Diaspora (at least in the case of openstreetmap and probably
+ // due to the inclusion of an html iframe)
+
+ $Text = preg_replace("/\[map\=(.*?)\]/ism", '$1', $Text);
+ $Text = preg_replace("/\[map\](.*?)\[\/map\]/ism", '$1', $Text);
// Converting images with size parameters to simple images. Markdown doesn't know it.
$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text);
@@ -452,6 +458,8 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
$md = new Markdownify(false, false, false);
$Text = $md->parseString($Text);
+
+
// It also adds backslashes to our attempt at getting around the html entity preservation for some weird reason.
$Text = str_replace(array('&\\_lt\\_;','&\\_gt\\_;','&\\_amp\\_;'),array('&lt;','&gt;','&amp;'),$Text);
diff --git a/include/bbcode.php b/include/bbcode.php
index a82b658b1..32354aeda 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -403,6 +403,15 @@ function bb_definitionList_unescapeBraces($match) {
return '<dt>' . str_replace('\]', ']', $match[1]) . '</dt>';
}
+
+function bb_checklist($match) {
+ $str = $match[1];
+ $str = str_replace("[]", "<li><input type=\"checkbox\" disabled=\"disabled\">", $str);
+ $str = str_replace("[x]", "<li><input type=\"checkbox\" checked=\"checked\" disabled=\"disabled\">", $str);
+ return '<ul class="checklist" style="list-style-type: none;">' . $str . '</ul>';
+}
+
+
/**
* @brief Sanitize style properties from BBCode to HTML.
*
@@ -503,10 +512,10 @@ function bb_code($match) {
}
function bb_highlight($match) {
- if(in_array(strtolower($match[1]),['php','css','mysql','sql','abap','diff','html','perl','ruby',
+ $lang = ((in_array(strtolower($match[1]),['php','css','mysql','sql','abap','diff','html','perl','ruby',
'vbscript','avrc','dtd','java','xml','cpp','python','javascript','js','json','sh']))
- return text_highlight($match[2],strtolower($match[1]));
- return $match[0];
+ ? strtolower($match[1]) : 'php' );
+ return text_highlight($match[2],$lang);
}
function bb_fixtable_lf($match) {
@@ -520,7 +529,49 @@ function bb_fixtable_lf($match) {
}
+function parseIdentityAwareHTML($Text) {
+
+ // process [observer] tags before we do anything else because we might
+ // be stripping away stuff that then doesn't need to be worked on anymore
+
+ $observer = App::get_observer();
+ if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) {
+ if ($observer) {
+ $Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text);
+ $Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text);
+ $Text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $Text);
+ } else {
+ $Text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $Text);
+ $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text);
+ $Text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $Text);
+ }
+ }
+ // replace [observer.baseurl]
+ if ($observer) {
+ $s1 = '<span class="bb_observer" title="' . t('Different viewers will see this text differently') . '">';
+ $s2 = '</span>';
+ $obsBaseURL = $observer['xchan_connurl'];
+ $obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL);
+ $Text = str_replace('[observer.baseurl]', $obsBaseURL, $Text);
+ $Text = str_replace('[observer.url]',$observer['xchan_url'], $Text);
+ $Text = str_replace('[observer.name]',$s1 . $observer['xchan_name'] . $s2, $Text);
+ $Text = str_replace('[observer.address]',$s1 . $observer['xchan_addr'] . $s2, $Text);
+ $Text = str_replace('[observer.webname]', substr($observer['xchan_addr'],0,strpos($observer['xchan_addr'],'@')), $Text);
+ $Text = str_replace('[observer.photo]',$s1 . '[zmg]'.$observer['xchan_photo_l'].'[/zmg]' . $s2, $Text);
+ } else {
+ $Text = str_replace('[observer.baseurl]', '', $Text);
+ $Text = str_replace('[observer.url]','', $Text);
+ $Text = str_replace('[observer.name]','', $Text);
+ $Text = str_replace('[observer.address]','', $Text);
+ $Text = str_replace('[observer.webname]','',$Text);
+ $Text = str_replace('[observer.photo]','', $Text);
+ }
+
+ $Text = str_replace(array('[baseurl]','[sitename]'),array(z_root(),get_config('system','sitename')),$Text);
+
+ return $Text;
+}
// BBcode 2 HTML was written by WAY2WEB.net
// extended to work with Mistpark/Friendica/Redmatrix/Hubzilla - Mike Macgirvin
@@ -550,7 +601,6 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
// process [observer] tags before we do anything else because we might
// be stripping away stuff that then doesn't need to be worked on anymore
-
if($cache)
$observer = false;
else
@@ -653,7 +703,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
// Perform URL Search
- $urlchars = '[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,\@]';
+ $urlchars = '[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,\@\(\)]';
if (strpos($Text,'http') !== false) {
if($tryoembed) {
@@ -737,6 +787,12 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
if (strpos($Text,'[/color]') !== false) {
$Text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])ism", "<span style=\"color: $1;\">$2</span>", $Text);
}
+ // Check for colored text
+ if (strpos($Text,'[/hl]') !== false) {
+ $Text = preg_replace("(\[hl\](.*?)\[\/hl\])ism", "<span style=\"background-color: yellow;\">$1</span>", $Text);
+ $Text = preg_replace("(\[hl=(.*?)\](.*?)\[\/hl\])ism", "<span style=\"background-color: $1;\">$2</span>", $Text);
+ }
+
// Check for sized text
// [size=50] --> font-size: 50px (with the unit).
if (strpos($Text,'[/size]') !== false) {
@@ -768,12 +824,14 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$Text = preg_replace("(\[h6\](.*?)\[\/h6\])ism",'<h6>$1</h6>',$Text);
}
// Check for table of content without params
- if (strpos($Text,'[toc]') !== false) {
- $Text = preg_replace("/\[toc\]/ism",'<ul id="toc"></ul>',$Text);
+ while(strpos($Text,'[toc]') !== false) {
+ $toc_id = 'toc-' . random_string(10);
+ $Text = preg_replace("/\[toc\]/ism", '<ul id="' . $toc_id . '" class="toc" data-toc=".section-content-wrapper"></ul><script>$("#' . $toc_id . '").toc();</script>', $Text, 1);
}
// Check for table of content with params
- if (strpos($Text,'[toc') !== false) {
- $Text = preg_replace("/\[toc([^\]]+?)\]/ism",'<ul$1></ul>',$Text);
+ while(strpos($Text,'[toc') !== false) {
+ $toc_id = 'toc-' . random_string(10);
+ $Text = preg_replace("/\[toc([^\]]+?)\]/ism", '<ul id="' . $toc_id . '" class="toc"$1></ul><script>$("#' . $toc_id . '").toc();</script>', $Text, 1);
}
// Check for centered text
if (strpos($Text,'[/center]') !== false) {
@@ -784,15 +842,15 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$Text = preg_replace("(\[footer\](.*?)\[\/footer\])ism", "<div class=\"wall-item-footer\">$1</div>", $Text);
}
// Check for list text
+
+ $Text = preg_replace("/<br \/>\[\*\]/ism",'[*]',$Text);
+
$Text = str_replace("[*]", "<li>", $Text);
- $Text = str_replace("[]", "<li><input type=\"checkbox\" disabled=\"disabled\">", $Text);
- $Text = str_replace("[x]", "<li><input type=\"checkbox\" checked=\"checked\" disabled=\"disabled\">", $Text);
// handle nested lists
$endlessloop = 0;
while ((((strpos($Text, "[/list]") !== false) && (strpos($Text, "[list") !== false)) ||
- ((strpos($Text, "[/checklist]") !== false) && (strpos($Text, "[checklist]") !== false)) ||
((strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false)) ||
((strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false)) ||
((strpos($Text, "[/dl]") !== false) && (strpos($Text, "[dl") !== false)) ||
@@ -804,9 +862,9 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$Text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '<ul class="listupperroman" style="list-style-type: upper-roman;">$2</ul>', $Text);
$Text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '<ul class="listloweralpha" style="list-style-type: lower-alpha;">$2</ul>', $Text);
$Text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '<ul class="listupperalpha" style="list-style-type: upper-alpha;">$2</ul>', $Text);
- $Text = preg_replace("/\[checklist\](.*?)\[\/checklist\]/ism", '<ul class="checklist" style="list-style-type: none;">$1</ul>', $Text);
$Text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>', $Text);
$Text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>', $Text);
+ $Text = preg_replace("/\[\/li\]<br \/>\[li\]/ism",'[/li][li]',$Text);
$Text = preg_replace("/\[li\](.*?)\[\/li\]/ism", '<li>$1</li>', $Text);
// [dl] tags have an optional [dl terms="bi"] form where bold/italic/underline/mono/large
@@ -815,7 +873,13 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
// "[dl" <optional-whitespace> <optional-termStyles> "]" <matchGroup2> "[/dl]"
// where optional-termStyles are: "terms=" <optional-quote> <matchGroup1> <optional-quote>
$Text = preg_replace_callback('/\[dl[[:space:]]*(?:terms=(?:&quot;|")?([a-zA-Z]+)(?:&quot;|")?)?\](.*?)\[\/dl\]/ism', 'bb_definitionList', $Text);
+
}
+
+ if (strpos($Text,'[checklist]') !== false) {
+ $Text = preg_replace_callback("/\[checklist\](.*?)\[\/checklist\]/ism", 'bb_checklist', $Text);
+ }
+
if (strpos($Text,'[th]') !== false) {
$Text = preg_replace("/\[th\](.*?)\[\/th\]/sm", '<th>$1</th>', $Text);
}
@@ -1003,15 +1067,15 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$Text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '<a class="zid" href="$1" target="_blank" >$1</a>', $Text);
}
- if ($tryoembed){
- if (strpos($Text,'[/iframe]') !== false) {
- $Text = preg_replace_callback("/\[iframe\](.*?)\[\/iframe\]/ism", 'bb_iframe', $Text);
- }
- } else {
- if (strpos($Text,'[/iframe]') !== false) {
- $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<a href="$1" target="_blank" >$1</a>', $Text);
- }
- }
+// if ($tryoembed){
+// if (strpos($Text,'[/iframe]') !== false) {
+// $Text = preg_replace_callback("/\[iframe\](.*?)\[\/iframe\]/ism", 'bb_iframe', $Text);
+// }
+// } else {
+// if (strpos($Text,'[/iframe]') !== false) {
+// $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<a href="$1" target="_blank" >$1</a>', $Text);
+// }
+// }
// oembed tag
$Text = oembed_bbcode2html($Text);
@@ -1024,7 +1088,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
// Summary (e.g. title) is required, earlier revisions only required description (in addition to
// start which is always required). Allow desc with a missing summary for compatibility.
- if ((x($ev,'desc') || x($ev,'summary')) && x($ev,'start')) {
+ if ((x($ev,'desc') || x($ev,'summary')) && x($ev,'dtstart')) {
$sub = format_event_html($ev);
diff --git a/include/channel.php b/include/channel.php
index 88e59830f..4fc873402 100644
--- a/include/channel.php
+++ b/include/channel.php
@@ -162,7 +162,7 @@ function channel_total() {
* Also creates the related xchan, hubloc, profile, and "self" abook records,
* and an empty "Friends" group/collection for the new channel.
*
- * @param array $arr assoziative array with:
+ * @param array $arr associative array with:
* * \e string \b name full name of channel
* * \e string \b nickname "email/url-compliant" nickname
* * \e int \b account_id to attach with this channel
@@ -182,7 +182,7 @@ function create_identity($arr) {
return $ret;
}
$ret = identity_check_service_class($arr['account_id']);
- if (!$ret['success']) {
+ if (!$ret['success']) {
return $ret;
}
// save this for auto_friending
@@ -236,13 +236,13 @@ function create_identity($arr) {
$publish = intval($role_permissions['directory_publish']);
$primary = true;
-
+
if(array_key_exists('primary', $arr))
$primary = intval($arr['primary']);
$expire = 0;
- $r = q("insert into channel ( channel_account_id, channel_primary,
+ $r = q("insert into channel ( channel_account_id, channel_primary,
channel_name, channel_address, channel_guid, channel_guid_sig,
channel_hash, channel_prvkey, channel_pubkey, channel_pageflags, channel_system, channel_expire_days, channel_timezone )
values ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s' ) ",
@@ -262,7 +262,7 @@ function create_identity($arr) {
dbesc(App::$timezone)
);
- $r = q("select * from channel where channel_account_id = %d
+ $r = q("select * from channel where channel_account_id = %d
and channel_guid = '%s' limit 1",
intval($arr['account_id']),
dbesc($guid)
@@ -291,7 +291,7 @@ function create_identity($arr) {
// Create a verified hub location pointing to this site.
- $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary,
+ $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary,
hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network )
values ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )",
dbesc($guid),
@@ -392,11 +392,11 @@ function create_identity($arr) {
intval($newuid)
);
}
- }
+ }
}
- // Create a group with yourself as a member. This allows somebody to use it
- // right away as a default group for new contacts.
+ // Create a group with yourself as a member. This allows somebody to use it
+ // right away as a default group for new contacts.
require_once('include/group.php');
group_add($newuid, t('Friends'));
@@ -422,7 +422,7 @@ function create_identity($arr) {
set_pconfig($ret['channel']['channel_id'],'system','photo_path', '%Y-%m');
set_pconfig($ret['channel']['channel_id'],'system','attach_path','%Y-%m');
}
-
+
// auto-follow any of the hub's pre-configured channel choices.
// Only do this if it's the first channel for this account;
// otherwise it could get annoying. Don't make this list too big
@@ -494,7 +494,7 @@ function identity_basic_export($channel_id, $items = false) {
$ret = array();
- // use constants here as otherwise we will have no idea if we can import from a site
+ // use constants here as otherwise we will have no idea if we can import from a site
// with a non-standard platform and version.
$ret['compatibility'] = array('project' => PLATFORM_NAME, 'version' => STD_VERSION, 'database' => DB_UPDATE_VERSION, 'server_role' => Zotlabs\Lib\System::get_server_role());
@@ -503,7 +503,7 @@ function identity_basic_export($channel_id, $items = false) {
);
if($r) {
translate_channel_perms_outbound($r[0]);
- $ret['channel'] = $r[0];
+ $ret['channel'] = $r[0];
$ret['relocate'] = [ 'channel_address' => $r[0]['channel_address'], 'url' => z_root()];
}
@@ -526,7 +526,7 @@ function identity_basic_export($channel_id, $items = false) {
if($abconfig)
$ret['abook'][$x]['abconfig'] = $abconfig;
translate_abook_perms_outbound($ret['abook'][$x]);
- }
+ }
stringify_array_elms($xchans);
}
@@ -534,13 +534,13 @@ function identity_basic_export($channel_id, $items = false) {
$r = q("select * from xchan where xchan_hash in ( " . implode(',',$xchans) . " ) ");
if($r)
$ret['xchan'] = $r;
-
+
$r = q("select * from hubloc where hubloc_hash in ( " . implode(',',$xchans) . " ) ");
if($r)
$ret['hubloc'] = $r;
}
- $r = q("select * from `groups` where uid = %d ",
+ $r = q("select * from groups where uid = %d ",
intval($channel_id)
);
@@ -578,7 +578,6 @@ function identity_basic_export($channel_id, $items = false) {
if($r)
$ret['term'] = $r;
-
// add psuedo-column obj_baseurl to aid in relocations
$r = q("select obj.*, '%s' as obj_baseurl from obj where obj_channel = %d",
@@ -608,7 +607,6 @@ function identity_basic_export($channel_id, $items = false) {
if($r)
$ret['chatroom'] = $r;
-
$r = q("select * from event where uid = %d",
intval($channel_id)
);
@@ -625,7 +623,7 @@ function identity_basic_export($channel_id, $items = false) {
foreach($r as $rr)
$ret['event_item'][] = encode_item($rr,true);
}
-
+
$x = menu_list($channel_id);
if($x) {
$ret['menu'] = array();
@@ -636,12 +634,10 @@ function identity_basic_export($channel_id, $items = false) {
}
}
-
$addon = array('channel_id' => $channel_id,'data' => $ret);
call_hooks('identity_basic_export',$addon);
$ret = $addon['data'];
-
if(! $items)
return $ret;
@@ -659,11 +655,10 @@ function identity_basic_export($channel_id, $items = false) {
if($r) {
for($x = 0; $x < count($r); $x ++) {
$r[$x]['subject'] = base64url_decode(str_rot47($r[$x]['subject']));
- }
+ }
$ret['conv'] = $r;
}
-
$r = q("select * from mail where mail.uid = %d",
intval($channel_id)
);
@@ -680,15 +675,15 @@ function identity_basic_export($channel_id, $items = false) {
/** @warning this may run into memory limits on smaller systems */
- /** export three months of posts. If you want to export and import all posts you have to start with
- * the first year and export/import them in ascending order.
+ /** export three months of posts. If you want to export and import all posts you have to start with
+ * the first year and export/import them in ascending order.
*
* Don't export linked resource items. we'll have to pull those out separately.
*/
$r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created > %s - INTERVAL %s and resource_type = '' order by created",
intval($channel_id),
- db_utcnow(),
+ db_utcnow(),
db_quoteinterval('3 MONTH')
);
if($r) {
@@ -730,7 +725,7 @@ function identity_export_year($channel_id,$year,$month = 0) {
$r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created < '%s' and resource_type = '' order by created",
intval(ITEM_TYPE_POST),
intval($channel_id),
- dbesc($mindate),
+ dbesc($mindate),
dbesc($maxdate)
);
@@ -745,16 +740,24 @@ function identity_export_year($channel_id,$year,$month = 0) {
return $ret;
}
-// export items within an arbitrary date range. Date/time is in UTC.
-
-function channel_export_items($channel_id,$start,$finish) {
+/**
+ * @brief Export items within an arbitrary date range.
+ *
+ * Date/time is in UTC.
+ *
+ * @param int $channel_id The channel ID
+ * @param string $start
+ * @param string $finish
+ * @return array
+ */
+function channel_export_items($channel_id, $start, $finish) {
if(! $start)
return array();
else
- $start = datetime_convert('UTC','UTC',$start);
+ $start = datetime_convert('UTC', 'UTC', $start);
- $finish = datetime_convert('UTC','UTC',(($finish) ? $finish : 'now'));
+ $finish = datetime_convert('UTC', 'UTC', (($finish) ? $finish : 'now'));
if($finish < $start)
return array();
@@ -768,16 +771,16 @@ function channel_export_items($channel_id,$start,$finish) {
$r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created < '%s' and resource_type = '' order by created",
intval(ITEM_TYPE_POST),
intval($channel_id),
- dbesc($start),
+ dbesc($start),
dbesc($finish)
);
if($r) {
$ret['item'] = array();
xchan_query($r);
- $r = fetch_post_tags($r,true);
+ $r = fetch_post_tags($r, true);
foreach($r as $rr)
- $ret['item'][] = encode_item($rr,true);
+ $ret['item'][] = encode_item($rr, true);
}
return $ret;
@@ -792,7 +795,7 @@ function channel_export_items($channel_id,$start,$finish) {
*
* Permissions of the current observer are checked. If a restricted profile is available
* to the current observer, that will be loaded instead of the channel default profile.
- *
+ *
* The channel owner can set $profile to a valid profile_guid to preview that profile.
*
* The channel default theme is also selected for use, unless over-riden elsewhere.
@@ -866,7 +869,6 @@ function profile_load($nickname, $profile = '') {
intval($p[0]['profile_uid'])
);
if($q) {
-
$extra_fields = array();
require_once('include/channel.php');
@@ -903,7 +905,7 @@ function profile_load($nickname, $profile = '') {
// fetch user tags if this isn't the default profile
if(! $p[0]['is_default']) {
- $x = q("select `keywords` from `profile` where uid = %d and `is_default` = 1 limit 1",
+ $x = q("select keywords from profile where uid = %d and is_default = 1 limit 1",
intval($p[0]['profile_uid'])
);
if($x && $can_view_profile)
@@ -985,7 +987,6 @@ function profile_edit_menu($uid) {
}
return $ret;
-
}
/**
@@ -997,6 +998,7 @@ function profile_edit_menu($uid) {
* @param array $profile
* @param int $block
* @param boolean $show_connect
+ * @param mixed $zcard
*
* @return HTML string suitable for sidebar inclusion
* Exceptions: Returns empty string if passed $profile is wrong type or not populated
@@ -1032,7 +1034,7 @@ function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = fa
$connect_url = rconnect_url($profile['uid'],get_observer_hash());
$connect = (($connect_url) ? t('Connect') : '');
- if($connect_url)
+ if($connect_url)
$connect_url = sprintf($connect_url,urlencode(channel_reddress($profile)));
// premium channel - over-ride
@@ -1066,19 +1068,26 @@ function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = fa
? trim(substr($profile['channel_name'],0,strpos($profile['channel_name'],' '))) : $profile['channel_name']);
$lastname = (($firstname === $profile['channel_name']) ? '' : trim(substr($profile['channel_name'],strlen($firstname))));
- $diaspora = array(
- 'podloc' => z_root(),
- 'guid' => $profile['channel_guid'] . str_replace('.','',App::get_hostname()),
- 'pubkey' => pemtorsa($profile['channel_pubkey']),
- 'searchable' => (($block) ? 'false' : 'true'),
- 'nickname' => $profile['channel_address'],
- 'fullname' => $profile['channel_name'],
- 'firstname' => $firstname,
- 'lastname' => $lastname,
- 'photo300' => z_root() . '/photo/profile/300/' . $profile['uid'] . '.jpg',
- 'photo100' => z_root() . '/photo/profile/100/' . $profile['uid'] . '.jpg',
- 'photo50' => z_root() . '/photo/profile/50/' . $profile['uid'] . '.jpg',
- );
+ // @fixme move this to the diaspora plugin itself
+
+ if(plugin_is_installed('diaspora')) {
+ $diaspora = array(
+ 'podloc' => z_root(),
+ 'guid' => $profile['channel_guid'] . str_replace('.','',App::get_hostname()),
+ 'pubkey' => pemtorsa($profile['channel_pubkey']),
+ 'searchable' => (($block) ? 'false' : 'true'),
+ 'nickname' => $profile['channel_address'],
+ 'fullname' => $profile['channel_name'],
+ 'firstname' => $firstname,
+ 'lastname' => $lastname,
+ 'photo300' => z_root() . '/photo/profile/300/' . $profile['uid'] . '.jpg',
+ 'photo100' => z_root() . '/photo/profile/100/' . $profile['uid'] . '.jpg',
+ 'photo50' => z_root() . '/photo/profile/50/' . $profile['uid'] . '.jpg',
+ );
+ }
+ else
+ $diaspora = '';
+
$contact_block = contact_block();
@@ -1124,7 +1133,7 @@ function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = fa
'$editmenu' => profile_edit_menu($profile['uid'])
));
- $arr = array('profile' => &$profile, 'entry' => &$o);
+ $arr = array('profile' => $profile, 'entry' => $o);
call_hooks('profile_sidebar', $arr);
@@ -1156,7 +1165,6 @@ function advanced_profile(&$a) {
}
-
$tpl = get_markup_template('profile_advanced.tpl');
$profile = array();
@@ -1191,12 +1199,12 @@ function advanced_profile(&$a) {
if((substr(App::$profile['dob'],5,2) === '00') || (substr(App::$profile['dob'],8,2) === '00'))
$val = substr(App::$profile['dob'],0,4);
-
+
$year_bd_format = t('j F, Y');
$short_bd_format = t('j F');
if(! $val) {
- $val = ((intval(App::$profile['dob']))
+ $val = ((intval(App::$profile['dob']))
? day_translate(datetime_convert('UTC','UTC',App::$profile['dob'] . ' 00:00 +00:00',$year_bd_format))
: day_translate(datetime_convert('UTC','UTC','2001-' . substr(App::$profile['dob'],5) . ' 00:00 +00:00',$short_bd_format)));
}
@@ -1241,7 +1249,7 @@ function advanced_profile(&$a) {
if($txt = prepare_text(App::$profile['channels'])) $profile['channels'] = array( t('My other channels:'), $txt);
if($txt = prepare_text(App::$profile['music'])) $profile['music'] = array( t('Musical interests:'), $txt);
-
+
if($txt = prepare_text(App::$profile['book'])) $profile['book'] = array( t('Books, literature:'), $txt);
if($txt = prepare_text(App::$profile['tv'])) $profile['tv'] = array( t('Television:'), $txt);
@@ -1249,7 +1257,7 @@ function advanced_profile(&$a) {
if($txt = prepare_text(App::$profile['film'])) $profile['film'] = array( t('Film/dance/culture/entertainment:'), $txt);
if($txt = prepare_text(App::$profile['romance'])) $profile['romance'] = array( t('Love/Romance:'), $txt);
-
+
if($txt = prepare_text(App::$profile['employment'])) $profile['employment'] = array( t('Work/employment:'), $txt);
if($txt = prepare_text(App::$profile['education'])) $profile['education'] = array( t('School/education:'), $txt );
@@ -1268,7 +1276,7 @@ function advanced_profile(&$a) {
$things = get_things(App::$profile['profile_guid'],App::$profile['profile_uid']);
-// logger('mod_profile: things: ' . print_r($things,true), LOGGER_DATA);
+// logger('mod_profile: things: ' . print_r($things,true), LOGGER_DATA);
return replace_macros($tpl, array(
'$title' => t('Profile'),
@@ -1363,64 +1371,11 @@ function zat_init() {
-/**
- * @brief Adds a zid parameter to a url.
- *
- * @param string $s
- * The url to accept the zid
- * @param boolean $address
- * $address to use instead of session environment
- * @return string
- *
- * @hooks 'zid'
- * string url - url to accept zid
- * string zid - urlencoded zid
- * string result - the return string we calculated, change it if you want to return something else
- */
-function zid($s,$address = '') {
- if (! strlen($s) || strpos($s,'zid='))
- return $s;
-
- $m = parse_url($s);
- $fragment = ((array_key_exists('fragment',$m) && $m['fragment']) ? $m['fragment'] : false);
- if($fragment !== false)
- $s = str_replace('#' . $fragment,'',$s);
-
- $has_params = ((strpos($s,'?')) ? true : false);
- $num_slashes = substr_count($s, '/');
- if (! $has_params)
- $has_params = ((strpos($s, '&')) ? true : false);
-
- $achar = strpos($s,'?') ? '&' : '?';
-
- $mine = get_my_url();
- $myaddr = (($address) ? $address : get_my_address());
-
- /** @FIXME checking against our own channel url is no longer reliable. We may have a lot
- * of urls attached to out channel. Should probably match against our site, since we
- * will not need to remote authenticate on our own site anyway.
- */
-
- if ($mine && $myaddr && (! link_compare($mine,$s)))
- $zurl = $s . (($num_slashes >= 3) ? '' : '/') . $achar . 'zid=' . urlencode($myaddr);
- else
- $zurl = $s;
-
- // put fragment at the end
-
- if($fragment)
- $zurl .= '#' . $fragment;
-
- $arr = array('url' => $s, 'zid' => urlencode($myaddr), 'result' => $zurl);
- call_hooks('zid', $arr);
-
- return $arr['result'];
-}
// Used from within PCSS themes to set theme parameters. If there's a
// puid request variable, that is the "page owner" and normally their theme
-// settings take precedence; unless a local user sets the "always_my_theme"
-// system pconfig, which means they don't want to see anybody else's theme
+// settings take precedence; unless a local user sets the "always_my_theme"
+// system pconfig, which means they don't want to see anybody else's theme
// settings except their own while on this site.
function get_theme_uid() {
@@ -1523,25 +1478,18 @@ function remote_online_status($webbie) {
}
-function get_channel_by_nick($nick) {
- $r = q("select * from channel where channel_address = '%s' limit 1",
- dbesc($nick)
- );
- return(($r) ? $r[0] : false);
-
-}
-
/**
* @brief
*
* @return string
*/
+
function identity_selector() {
- if (local_channel()) {
+ if(local_channel()) {
$r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel.channel_account_id = %d and channel_removed = 0 order by channel_name ",
intval(get_account_id())
);
- if (count($r) > 1) {
+ if($r && count($r) > 1) {
//$account = App::get_account();
$o = replace_macros(get_markup_template('channel_id_select.tpl'), array(
'$channels' => $r,
@@ -1612,7 +1560,7 @@ function get_profile_fields_advanced($filter = 0) {
* The channel to disable notifications for
* @returns int
* Current notification flag value. Send this to notifications_on() to restore the channel settings when finished
- * with the activity requiring notifications_off();
+ * with the activity requiring notifications_off();
*/
function notifications_off($channel_id) {
$r = q("select channel_notifyflags from channel where channel_id = %d limit 1",
@@ -1626,18 +1574,18 @@ function notifications_off($channel_id) {
}
-function notifications_on($channel_id,$value) {
+function notifications_on($channel_id, $value) {
$x = q("update channel set channel_notifyflags = %d where channel_id = %d",
intval($value),
intval($channel_id)
);
+
return $x;
}
function get_channel_default_perms($uid) {
-
$ret = [];
$r = q("select abook_xchan from abook where abook_channel = %d and abook_self = 1 limit 1",
@@ -1659,7 +1607,6 @@ function get_channel_default_perms($uid) {
function profiles_build_sync($channel_id) {
-
$r = q("select * from profile where uid = %d",
intval($channel_id)
);
@@ -1706,7 +1653,6 @@ function auto_channel_create($account_id) {
$arr['nickname'] = check_webbie(array($arr['nickname'], $arr['nickname'] . mt_rand(1000,9999)));
return create_identity($arr);
-
}
function get_cover_photo($channel_id,$format = 'bbcode', $res = PHOTO_RES_COVER_1200) {
@@ -1741,18 +1687,24 @@ function get_cover_photo($channel_id,$format = 'bbcode', $res = PHOTO_RES_COVER_
break;
}
- return $output;
-
+ return $output;
}
-function get_zcard($channel,$observer_hash = '',$args = array()) {
+/**
+ * @brief
+ *
+ * @param array $channel
+ * @param string $observer_hash
+ * @param array $args
+ * @return string
+ */
+function get_zcard($channel, $observer_hash = '', $args = array()) {
logger('get_zcard');
$maxwidth = (($args['width']) ? intval($args['width']) : 0);
$maxheight = (($args['height']) ? intval($args['height']) : 0);
-
if(($maxwidth > 1200) || ($maxwidth < 1))
$maxwidth = 1200;
@@ -1760,25 +1712,22 @@ function get_zcard($channel,$observer_hash = '',$args = array()) {
$width = 425;
$size = 'hz_small';
$cover_size = PHOTO_RES_COVER_425;
- $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']);
- }
- elseif($maxwidth <= 900) {
+ $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']);
+ } elseif($maxwidth <= 900) {
$width = 900;
$size = 'hz_medium';
$cover_size = PHOTO_RES_COVER_850;
- $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']);
- }
- elseif($maxwidth <= 1200) {
+ $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']);
+ } elseif($maxwidth <= 1200) {
$width = 1200;
$size = 'hz_large';
$cover_size = PHOTO_RES_COVER_1200;
- $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']);
+ $pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']);
}
// $scale = (float) $maxwidth / $width;
// $translate = intval(($scale / 1.0) * 100);
-
$channel['channel_addr'] = channel_reddress($channel);
$zcard = array('chan' => $channel);
@@ -1791,12 +1740,11 @@ function get_zcard($channel,$observer_hash = '',$args = array()) {
if($r) {
$cover = $r[0];
$cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['imgscale'];
- }
- else {
+ } else {
$cover = $pphoto;
}
-
- $o .= replace_macros(get_markup_template('zcard.tpl'),array(
+
+ $o .= replace_macros(get_markup_template('zcard.tpl'), array(
'$maxwidth' => $maxwidth,
'$scale' => $scale,
'$translate' => $translate,
@@ -1804,21 +1752,19 @@ function get_zcard($channel,$observer_hash = '',$args = array()) {
'$cover' => $cover,
'$pphoto' => $pphoto,
'$zcard' => $zcard
- ));
-
+ ));
+
return $o;
-
}
-function get_zcard_embed($channel,$observer_hash = '',$args = array()) {
+function get_zcard_embed($channel, $observer_hash = '', $args = array()) {
logger('get_zcard_embed');
$maxwidth = (($args['width']) ? intval($args['width']) : 0);
$maxheight = (($args['height']) ? intval($args['height']) : 0);
-
if(($maxwidth > 1200) || ($maxwidth < 1))
$maxwidth = 1200;
@@ -1853,11 +1799,10 @@ function get_zcard_embed($channel,$observer_hash = '',$args = array()) {
if($r) {
$cover = $r[0];
$cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['imgscale'];
- }
- else {
+ } else {
$cover = $pphoto;
}
-
+
$o .= replace_macros(get_markup_template('zcard_embed.tpl'),array(
'$maxwidth' => $maxwidth,
'$scale' => $scale,
@@ -1866,36 +1811,73 @@ function get_zcard_embed($channel,$observer_hash = '',$args = array()) {
'$cover' => $cover,
'$pphoto' => $pphoto,
'$zcard' => $zcard
- ));
-
+ ));
+
return $o;
-
}
-
+/**
+ * @brief
+ *
+ * @param string $nick
+ * @return mixed
+ */
function channelx_by_nick($nick) {
$r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_address = '%s' and channel_removed = 0 LIMIT 1",
dbesc($nick)
);
+
return(($r) ? $r[0] : false);
}
+/**
+ * @brief
+ *
+ * @param string $hash
+ * @return mixed
+ */
function channelx_by_hash($hash) {
- $r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_hash = '%s' and channel_removed = 0 LIMIT 1",
+ $r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_hash = '%s' and channel_removed = 0 LIMIT 1",
dbesc($hash)
);
+
return(($r) ? $r[0] : false);
}
+/**
+ * @brief
+ *
+ * @param int $id
+ * @return mixed
+ */
function channelx_by_n($id) {
- $r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_id = %d and channel_removed = 0 LIMIT 1",
+ $r = q("SELECT * FROM channel left join xchan on channel_hash = xchan_hash WHERE channel_id = %d and channel_removed = 0 LIMIT 1",
dbesc($id)
);
+
return(($r) ? $r[0] : false);
}
+/**
+ * @brief
+ *
+ * @param string $channel
+ * @return string
+ */
function channel_reddress($channel) {
- if(! ($channel && array_key_exists('channel_address',$channel)))
+ if(! ($channel && array_key_exists('channel_address', $channel)))
return '';
+
return strtolower($channel['channel_address'] . '@' . App::get_hostname());
+}
+
+
+function channel_manual_conv_update($channel_id) {
+
+ $x = get_pconfig($channel_id, 'system','manual_conversation_update');
+ if($x === false)
+ $x = get_config('system','manual_conversation_update');
+
+ return intval($x);
+
} \ No newline at end of file
diff --git a/include/config.php b/include/config.php
index 8c0469392..0b0e639ab 100644
--- a/include/config.php
+++ b/include/config.php
@@ -1,5 +1,4 @@
<?php
-
/**
* @file include/config.php
* @brief Arbitrary configuration storage.
@@ -7,7 +6,6 @@
* Arrays get stored as serialized strings.
* Booleans are stored as integer 0/1.
*
-
* - <b>config</b> is used for hub specific configurations. It overrides the
* configurations from .htconfig file. The storage is of size TEXT.
* - <b>pconfig</b> is used for channel specific configurations and takes a
@@ -26,7 +24,7 @@
* - get_config() and set_config() can also be done through the command line tool
* @ref util/config.md "util/config"
* - get_pconfig() and set_pconfig() can also be done through the command line tool
- * @ref util/pconfig.md "util/pconfig" and takes a channel_id as first argument.
+ * @ref util/pconfig.md "util/pconfig" and takes a channel_id as first argument.
*
*/
@@ -37,8 +35,8 @@ function load_config($family) {
Zlib\Config::Load($family);
}
-function get_config($family, $key) {
- return Zlib\Config::Get($family,$key);
+function get_config($family, $key, $default = false) {
+ return Zlib\Config::Get($family,$key,$default);
}
function set_config($family, $key, $value) {
@@ -53,8 +51,8 @@ function load_pconfig($uid) {
Zlib\PConfig::Load($uid);
}
-function get_pconfig($uid, $family, $key, $instore = false) {
- return Zlib\PConfig::Get($uid,$family,$key,$instore = false);
+function get_pconfig($uid, $family, $key, $default = false) {
+ return Zlib\PConfig::Get($uid,$family,$key,$default);
}
function set_pconfig($uid, $family, $key, $value) {
@@ -69,8 +67,8 @@ function load_xconfig($xchan) {
Zlib\XConfig::Load($xchan);
}
-function get_xconfig($xchan, $family, $key) {
- return Zlib\XConfig::Get($xchan,$family,$key);
+function get_xconfig($xchan, $family, $key, $default = false) {
+ return Zlib\XConfig::Get($xchan,$family,$key, $default);
}
function set_xconfig($xchan, $family, $key, $value) {
@@ -85,8 +83,8 @@ function load_aconfig($account_id) {
Zlib\AConfig::Load($account_id);
}
-function get_aconfig($account_id, $family, $key) {
- return Zlib\AConfig::Get($account_id, $family, $key);
+function get_aconfig($account_id, $family, $key, $default = false) {
+ return Zlib\AConfig::Get($account_id, $family, $key, $default);
}
function set_aconfig($account_id, $family, $key, $value) {
@@ -101,8 +99,8 @@ function load_abconfig($chan, $xhash, $family = '') {
return Zlib\AbConfig::Load($chan,$xhash,$family);
}
-function get_abconfig($chan,$xhash,$family,$key) {
- return Zlib\AbConfig::Get($chan,$xhash,$family,$key);
+function get_abconfig($chan,$xhash,$family,$key, $default = false) {
+ return Zlib\AbConfig::Get($chan,$xhash,$family,$key, $default);
}
function set_abconfig($chan,$xhash,$family,$key,$value) {
@@ -117,8 +115,8 @@ function load_iconfig(&$item) {
Zlib\IConfig::Load($item);
}
-function get_iconfig(&$item, $family, $key) {
- return Zlib\IConfig::Get($item, $family, $key);
+function get_iconfig(&$item, $family, $key, $default = false) {
+ return Zlib\IConfig::Get($item, $family, $key, $default);
}
function set_iconfig(&$item, $family, $key, $value, $sharing = false) {
diff --git a/include/connections.php b/include/connections.php
index 017117dda..b08d046b3 100644
--- a/include/connections.php
+++ b/include/connections.php
@@ -297,16 +297,16 @@ function channel_remove($channel_id, $local = true, $unset_session=false) {
}
- q("DELETE FROM `groups` WHERE `uid` = %d", intval($channel_id));
- q("DELETE FROM `group_member` WHERE `uid` = %d", intval($channel_id));
- q("DELETE FROM `event` WHERE `uid` = %d", intval($channel_id));
- q("DELETE FROM `item` WHERE `uid` = %d", intval($channel_id));
- q("DELETE FROM `mail` WHERE `channel_id` = %d", intval($channel_id));
- q("DELETE FROM `notify` WHERE `uid` = %d", intval($channel_id));
- q("DELETE FROM `photo` WHERE `uid` = %d", intval($channel_id));
- q("DELETE FROM `attach` WHERE `uid` = %d", intval($channel_id));
- q("DELETE FROM `profile` WHERE `uid` = %d", intval($channel_id));
- q("DELETE FROM `pconfig` WHERE `uid` = %d", intval($channel_id));
+ q("DELETE FROM groups WHERE uid = %d", intval($channel_id));
+ q("DELETE FROM group_member WHERE uid = %d", intval($channel_id));
+ q("DELETE FROM event WHERE uid = %d", intval($channel_id));
+ q("DELETE FROM item WHERE uid = %d", intval($channel_id));
+ q("DELETE FROM mail WHERE channel_id = %d", intval($channel_id));
+ q("DELETE FROM notify WHERE uid = %d", intval($channel_id));
+ q("DELETE FROM photo WHERE uid = %d", intval($channel_id));
+ q("DELETE FROM attach WHERE uid = %d", intval($channel_id));
+ q("DELETE FROM profile WHERE uid = %d", intval($channel_id));
+ q("DELETE FROM pconfig WHERE uid = %d", intval($channel_id));
// @FIXME At this stage we need to remove the file resources located under /store/$nickname
diff --git a/include/conversation.php b/include/conversation.php
index 287dd4983..d367c27a6 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -146,7 +146,7 @@ function localize_item(&$item){
case ACTIVITY_OBJ_NOTE:
default:
$post_type = t('status');
- if($obj['mid'] != $obj['parent_mid'])
+ if($obj['id'] != $obj['parent'])
$post_type = t('comment');
break;
}
@@ -269,8 +269,8 @@ function localize_item(&$item){
// (and update to json storage)
if (activity_match($item['verb'],ACTIVITY_TAG)) {
- $r = q("SELECT * from `item`,`contact` WHERE
- `item`.`contact-id`=`contact`.`id` AND `item`.`mid`='%s';",
+ $r = q("SELECT * from item,contact WHERE
+ item.contact-id=contact.id AND item.mid='%s';",
dbesc($item['parent_mid']));
if(count($r)==0) return;
$obj=$r[0];
@@ -363,7 +363,7 @@ function localize_item(&$item){
if(intval($item['item_obscured'])
&& strlen($item['body']) && (! strpos($item['body'],'data'))) {
- $item['body'] = json_encode(crypto_encapsulate($item['body'],get_config('system','pubkey')));
+ $item['body'] = z_obscure($item['body']);
}
}
@@ -405,8 +405,6 @@ function count_descendants($item) {
function visible_activity($item) {
$hidden_activities = [ ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_AGREE, ACTIVITY_DISAGREE, ACTIVITY_ABSTAIN, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE ];
- $post_types = [ ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_COMMENT, basename(ACTIVITY_OBJ_NOTE), basename(ACTIVITY_OBJ_COMMENT)];
-
if(intval($item['item_notshown']))
return false;
@@ -416,14 +414,32 @@ function visible_activity($item) {
}
}
+ if(is_edit_activity($item))
+ return false;
+
+ return true;
+}
+
+/**
+ * @brief Check if a given activity is an edit activity
+ *
+ *
+ * @param array $item
+ * @return boolean
+ */
+
+function is_edit_activity($item) {
+
+ $post_types = [ ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_COMMENT, basename(ACTIVITY_OBJ_NOTE), basename(ACTIVITY_OBJ_COMMENT)];
+
// In order to share edits with networks which have no concept of editing, we'll create
// separate activities to indicate the edit. Our network will not require them, since our
// edits are automatically applied and the activity indicated.
if(($item['verb'] === ACTIVITY_UPDATE) && (in_array($item['obj_type'],$post_types)))
- return false;
+ return true;
- return true;
+ return false;
}
/**
@@ -457,22 +473,6 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
if (local_channel())
load_pconfig(local_channel(),'');
- $arr_blocked = null;
-
- if (local_channel())
- $str_blocked = get_pconfig(local_channel(),'system','blocked');
- if (! local_channel() && ($mode == 'network')) {
- $sys = get_sys_channel();
- $id = $sys['channel_id'];
- $str_blocked = get_pconfig($id,'system','blocked');
- }
-
- if ($str_blocked) {
- $arr_blocked = explode(',',$str_blocked);
- for ($x = 0; $x < count($arr_blocked); $x ++)
- $arr_blocked[$x] = trim($arr_blocked[$x]);
- }
-
$profile_owner = 0;
$page_writeable = false;
$live_update_div = '';
@@ -599,17 +599,13 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
foreach($items as $item) {
- if($arr_blocked) {
- $blocked = false;
- foreach($arr_blocked as $b) {
- if(($b) && (($item['author_xchan'] == $b) || ($item['owner_xchan'] == $b))) {
- $blocked = true;
- break;
- }
- }
- if($blocked)
- continue;
- }
+ $x = [ 'mode' => $mode, 'item' => $item ];
+ call_hooks('stream_item',$x);
+
+ if($x['item']['blocked'])
+ continue;
+
+ $item = $x['item'];
$threadsid++;
@@ -771,28 +767,14 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
// Check for any blocked authors
- if($arr_blocked) {
- $blocked = false;
- foreach($arr_blocked as $b) {
- if(($b) && ($item['author_xchan'] == $b)) {
- $blocked = true;
- break;
- }
- }
- if($blocked)
- continue;
- }
- // Check all the kids too
+ $x = [ 'mode' => $mode, 'item' => $item ];
+ call_hooks('stream_item',$x);
+
+ if($x['item']['blocked'])
+ continue;
- if($arr_blocked && $item['children']) {
- for($d = 0; $d < count($item['children']); $d ++) {
- foreach($arr_blocked as $b) {
- if(($b) && ($item['children'][$d]['author_xchan'] == $b))
- $item['children'][$d]['author_blocked'] = true;
- }
- }
- }
+ $item = $x['item'];
builtin_activity_puller($item, $conv_responses);
@@ -1296,7 +1278,8 @@ function status_editor($a, $x, $popup = false) {
'$expiryModalOK' => t('OK'),
'$expiryModalCANCEL' => t('Cancel'),
'$expanded' => ((x($x, 'expanded')) ? $x['expanded'] : false),
- '$bbcode' => ((x($x, 'bbcode')) ? $x['bbcode'] : false)
+ '$bbcode' => ((x($x, 'bbcode')) ? $x['bbcode'] : false),
+ '$parent' => ((array_key_exists('parent',$x) && $x['parent']) ? $x['parent'] : 0)
));
if ($popup === true) {
@@ -1536,7 +1519,11 @@ function network_tabs() {
// tabs
$tabs = array();
- if(! get_config('system','disable_discover_tab')) {
+ $d = get_config('system','disable_discover_tab');
+ if($d === false)
+ $d = 1;
+
+ if(! $d) {
$tabs[] = array(
'label' => t('Discover'),
'url' => z_root() . '/' . $cmd . '?f=&fh=1' ,
@@ -1628,7 +1615,6 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
$uid = ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : local_channel());
$account_id = ((App::$profile['profile_uid']) ? App::$profile['channel_account_id'] : App::$channel['channel_account_id']);
-
if($uid == local_channel()) {
$cal_link = '';
}
@@ -1732,7 +1718,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
if(feature_enabled($uid,'wiki') && (get_account_techlevel($account_id) > 3)) {
$tabs[] = array(
- 'label' => t('Wiki'),
+ 'label' => t('Wikis'),
'url' => z_root() . '/wiki/' . $nickname,
'sel' => ((argv(0) == 'wiki') ? 'active' : ''),
'title' => t('Wiki'),
diff --git a/include/crypto.php b/include/crypto.php
index bc798d919..f75390985 100644
--- a/include/crypto.php
+++ b/include/crypto.php
@@ -48,27 +48,122 @@ function pkcs5_unpad($text)
function AES256CBC_encrypt($data,$key,$iv) {
return openssl_encrypt($data,'aes-256-cbc',str_pad($key,32,"\0"),OPENSSL_RAW_DATA,str_pad($iv,16,"\0"));
-
}
function AES256CBC_decrypt($data,$key,$iv) {
return openssl_decrypt($data,'aes-256-cbc',str_pad($key,32,"\0"),OPENSSL_RAW_DATA,str_pad($iv,16,"\0"));
+}
+
+function AES128CBC_encrypt($data,$key,$iv) {
+ $key = substr($key,0,16);
+ $iv = substr($iv,0,16);
+ return openssl_encrypt($data,'aes-128-cbc',str_pad($key,16,"\0"),OPENSSL_RAW_DATA,str_pad($iv,16,"\0"));
+}
+
+function AES128CBC_decrypt($data,$key,$iv) {
+ $key = substr($key,0,16);
+ $iv = substr($iv,0,16);
+ return openssl_decrypt($data,'aes-128-cbc',str_pad($key,16,"\0"),OPENSSL_RAW_DATA,str_pad($iv,16,"\0"));
+}
+
+function STD_encrypt($data,$key,$iv) {
+ $key = substr($key,0,32);
+ $iv = substr($iv,0,16);
+ return openssl_encrypt($data,'aes-256-cbc',str_pad($key,32,"\0"),OPENSSL_RAW_DATA,str_pad($iv,16,"\0"));
+}
+
+function STD_decrypt($data,$key,$iv) {
+ $key = substr($key,0,32);
+ $iv = substr($iv,0,16);
+ return openssl_decrypt($data,'aes-256-cbc',str_pad($key,32,"\0"),OPENSSL_RAW_DATA,str_pad($iv,16,"\0"));
+}
+function CAST5CBC_encrypt($data,$key,$iv) {
+ $key = substr($key,0,16);
+ $iv = substr($iv,0,8);
+ return openssl_encrypt($data,'cast5-cbc',str_pad($key,16,"\0"),OPENSSL_RAW_DATA,str_pad($iv,8,"\0"));
+}
+
+function CAST5CBC_decrypt($data,$key,$iv) {
+ $key = substr($key,0,16);
+ $iv = substr($iv,0,8);
+ return openssl_decrypt($data,'cast5-cbc',str_pad($key,16,"\0"),OPENSSL_RAW_DATA,str_pad($iv,8,"\0"));
}
function crypto_encapsulate($data,$pubkey,$alg='aes256cbc') {
+ $fn = strtoupper($alg) . '_encrypt';
+
if($alg === 'aes256cbc')
return aes_encapsulate($data,$pubkey);
+ return other_encapsulate($data,$pubkey,$alg);
+
+}
+
+function other_encapsulate($data,$pubkey,$alg) {
+ if(! $pubkey)
+ logger('no key. data: ' . $data);
+
+ $fn = strtoupper($alg) . '_encrypt';
+ if(function_exists($fn)) {
+
+ // A bit hesitant to use openssl_random_pseudo_bytes() as we know
+ // it has been historically targeted by US agencies for 'weakening'.
+ // It is still arguably better than trying to come up with an
+ // alternative cryptographically secure random generator.
+ // There is little point in using the optional second arg to flag the
+ // assurance of security since it is meaningless if the source algorithms
+ // have been compromised. Also none of this matters if RSA has been
+ // compromised by state actors and evidence is mounting that this has
+ // already happened.
+
+ $key = openssl_random_pseudo_bytes(256);
+ $iv = openssl_random_pseudo_bytes(256);
+ $result['data'] = base64url_encode($fn($data,$key,$iv),true);
+ // log the offending call so we can track it down
+ if(! openssl_public_encrypt($key,$k,$pubkey)) {
+ $x = debug_backtrace();
+ logger('RSA failed. ' . print_r($x[0],true));
+ }
+
+ $result['alg'] = $alg;
+ $result['key'] = base64url_encode($k,true);
+ openssl_public_encrypt($iv,$i,$pubkey);
+ $result['iv'] = base64url_encode($i,true);
+ return $result;
+ }
+ else {
+ $x = [ 'data' => $data, 'pubkey' => $pubkey, 'alg' => $alg, 'result' => $data ];
+ call_hooks('other_encapsulate', $x);
+ return $x['result'];
+ }
+}
+
+function crypto_methods() {
+
+ if(\Zotlabs\Lib\System::get_server_role() !== 'pro')
+ return [ 'aes256cbc' ];
+
+ // 'std' is the new project standard which is aes256cbc but transmits/receives 256-byte key and iv.
+ // aes256cbc is provided for compatibility with earlier zot implementations which assume 32-byte key and 16-byte iv.
+ // other_encapsulate() now produces these longer keys/ivs by default so that it is difficult to guess a
+ // particular implementation or choice of underlying implementations based on the key/iv length.
+ // The actual methods are responsible for deriving the actual key/iv from the provided parameters;
+ // possibly by truncation or segmentation - though many other methods could be used.
+
+ $r = [ 'std', 'aes256cbc', 'aes128cbc', 'cast5cbc' ];
+ call_hooks('crypto_methods',$r);
+ return $r;
+
}
function aes_encapsulate($data,$pubkey) {
if(! $pubkey)
logger('aes_encapsulate: no key. data: ' . $data);
- $key = random_string(32,RANDOM_STRING_TEXT);
- $iv = random_string(16,RANDOM_STRING_TEXT);
+ $key = openssl_random_pseudo_bytes(32);
+ $iv = openssl_random_pseudo_bytes(16);
$result['data'] = base64url_encode(AES256CBC_encrypt($data,$key,$iv),true);
// log the offending call so we can track it down
if(! openssl_public_encrypt($key,$k,$pubkey)) {
@@ -89,6 +184,22 @@ function crypto_unencapsulate($data,$prvkey) {
if($alg === 'aes256cbc')
return aes_unencapsulate($data,$prvkey);
+ return other_unencapsulate($data,$prvkey,$alg);
+
+}
+
+function other_unencapsulate($data,$prvkey,$alg) {
+ $fn = strtoupper($alg) . '_decrypt';
+ if(function_exists($fn)) {
+ openssl_private_decrypt(base64url_decode($data['key']),$k,$prvkey);
+ openssl_private_decrypt(base64url_decode($data['iv']),$i,$prvkey);
+ return $fn(base64url_decode($data['data']),$k,$i);
+ }
+ else {
+ $x = [ 'data' => $data, 'prvkey' => $prvkey, 'alg' => $alg, 'result' => $data ];
+ call_hooks('other_unencapsulate',$x);
+ return $x['result'];
+ }
}
diff --git a/include/datetime.php b/include/datetime.php
index cd08ab367..85e87848b 100644
--- a/include/datetime.php
+++ b/include/datetime.php
@@ -92,8 +92,8 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d
// Slight hackish adjustment so that 'zero' datetime actually returns what is intended
// otherwise we end up with -0001-11-30 ...
- // add 32 days so that we at least get year 00, and then hack around the fact that
- // months and days always start with 1.
+ // add 32 days so that we at least get year 00, and then hack around the fact that
+ // months and days always start with 1.
// if(substr($s,0,10) == '0000-00-00') {
// $d = new DateTime($s . ' + 32 days', new DateTimeZone('UTC'));
@@ -195,7 +195,7 @@ function timesel($format, $h, $m, $id='timepicker') {
/**
* @brief Returns a datetime selector.
*
- * @param $format
+ * @param string $format
* format string, e.g. 'ymd' or 'mdy'. Not currently supported
* @param $min
* unix timestamp of minimum date
@@ -203,6 +203,7 @@ function timesel($format, $h, $m, $id='timepicker') {
* unix timestap of maximum date
* @param $default
* unix timestamp of default date
+ * @param string $label
* @param string $id
* id and name of datetimepicker (defaults to "datetimepicker")
* @param boolean $pickdate
@@ -214,8 +215,9 @@ function timesel($format, $h, $m, $id='timepicker') {
* @param $maxfrom
* set maximum date from picker with id $maxfrom (none by default)
* @param boolean $required default false
+ * @param int $first_day (optional) default 0
* @return string Parsed HTML output.
- *
+ *
* @todo Once browser support is better this could probably be replaced with
* native HTML5 date picker.
*/
@@ -239,10 +241,10 @@ function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicke
if(!$picktime) $pickers .= ',timepicker: false, closeOnDateSelect:true';
$extra_js = '';
- if($minfrom != '')
+ if($minfrom != '')
$extra_js .= "\$('#id_$minfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({minDate: currentDateTime})}})";
- if($maxfrom != '')
+ if($maxfrom != '')
$extra_js .= "\$('#id_$maxfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({maxDate: currentDateTime})}})";
$readable_format = $dateformat;
@@ -276,7 +278,7 @@ function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicke
*/
function relative_date($posted_date, $format = null) {
- $localtime = datetime_convert('UTC', date_default_timezone_get(), $posted_date);
+ $localtime = datetime_convert('UTC', date_default_timezone_get(), $posted_date);
$abs = strtotime($localtime);
@@ -340,7 +342,7 @@ function plural_dates($k,$n) {
return;
}
}
-
+
@@ -512,7 +514,7 @@ function cal($y = 0, $m = 0, $links = false, $class='') {
/**
* @brief Return the next birthday, converted from the owner's timezone to UTC.
- *
+ *
* This makes it globally portable.
* If the provided birthday lacks a month and or day, return an empty string.
* A missing year is acceptable.
@@ -554,7 +556,7 @@ function update_birthdays() {
require_once('include/event.php');
require_once('include/permissions.php');
- $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
+ $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_dob > %s + interval %s and abook_dob < %s + interval %s",
db_utcnow(), db_quoteinterval('7 day'),
db_utcnow(), db_quoteinterval('14 day')
@@ -572,7 +574,7 @@ function update_birthdays() {
$ev['dtend'] = datetime_convert('UTC', 'UTC', $rr['abook_dob'] . ' + 1 day ');
$ev['adjust'] = intval(feature_enabled($rr['abook_channel'],'smart_birthdays'));
$ev['summary'] = sprintf( t('%1$s\'s birthday'), $rr['xchan_name']);
- $ev['description'] = sprintf( t('Happy Birthday %1$s'),
+ $ev['description'] = sprintf( t('Happy Birthday %1$s'),
'[zrl=' . $rr['xchan_url'] . ']' . $rr['xchan_name'] . '[/zrl]') ;
$ev['etype'] = 'birthday';
diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php
index 852dc16af..81a3bd590 100755
--- a/include/dba/dba_driver.php
+++ b/include/dba/dba_driver.php
@@ -12,66 +12,78 @@ class DBA {
static public $dba = null;
static public $dbtype = null;
+ static public $scheme = 'mysql';
static public $logging = false;
+ static public $install_script = 'install/schema_mysql.sql';
+ static public $null_date = '0001-01-01 00:00:00';
+ static public $utc_now = 'UTC_TIMESTAMP()';
+ static public $tquot = "`";
+
+
+
/**
* @brief Returns the database driver object.
*
- * If available it will use PHP's mysqli otherwise mysql driver.
- *
- * @param string $server DB server name
+ * @param string $server DB server name (or PDO dsn - e.g. mysqli:foobar.com;)
* @param string $port DB port
* @param string $user DB username
* @param string $pass DB password
* @param string $db database name
* @param string $dbtype 0 for mysql, 1 for postgres
* @param bool $install Defaults to false
- * @return null|dba_driver A database driver object (dba_mysql|dba_mysqli) or null if no driver found.
+ * @return null|dba_driver A database driver object (dba_pdo) or null if no driver found.
*/
- static public function dba_factory($server, $port,$user,$pass,$db,$dbtype,$install = false) {
+ static public function dba_factory($server,$port,$user,$pass,$db,$dbtype,$install = false) {
self::$dba = null;
self::$dbtype = intval($dbtype);
- $set_port = $port;
+
if(self::$dbtype == DBTYPE_POSTGRES) {
- require_once('include/dba/dba_postgres.php');
- if(is_null($port)) $set_port = 5432;
- self::$dba = new dba_postgres($server, $set_port, $user, $pass, $db, $install);
+ if(!($port))
+ $port = 5432;
+
+ self::$install_script = 'install/schema_postgres.sql';
+ self::$utc_now = "now() at time zone 'UTC'";
+ self::$tquot = '"';
+ self::$scheme = 'pgsql';
+
}
else {
-// Highly experimental at the present time.
-// require_once('include/dba/dba_pdo.php');
-// self::$dba = new dba_pdo($server, $set_port,$user,$pass,$db,$install);
-// }
+ // attempt to use the pdo driver compiled-in mysqli socket
+ // if using 'localhost' with no port configured.
+ // If this is wrong you'll need to set the socket path specifically
+ // using a server name of 'mysql:unix_socket=/socket/path', setting /socket/path
+ // as needed for your platform
- if(class_exists('mysqli')) {
- if (is_null($port)) $set_port = ini_get("mysqli.default_port");
- require_once('include/dba/dba_mysqli.php');
- self::$dba = new dba_mysqli($server, $set_port,$user,$pass,$db,$install);
- }
+ if((!($port)) && ($server !== 'localhost'))
+ $port = 3306;
}
- // Until we have a proper PDO driver, store the DB connection parameters for
- // plugins/addons which use PDO natively (such as cdav). This is wasteful as
- // it opens a separate connection to the DB, but saves a lot of effort re-writing
- // third-party interfaces that are working and well tested.
-
-
+ require_once('include/dba/dba_pdo.php');
+ self::$dba = new dba_pdo($server,self::$scheme,$port,$user,$pass,$db,$install);
+
if(is_object(self::$dba) && self::$dba->connected) {
- if($server === 'localhost')
- $port = $set_port;
- $dns = ((self::$dbtype == DBTYPE_POSTGRES) ? 'postgres' : 'mysql')
- . ':host=' . $server . (is_null($port) ? '' : ';port=' . $port)
- . ';dbname=' . $db;
- self::$dba->pdo_set(array($dns,$user,$pass));
+
+ if(strpbrk($server,':;')) {
+ $dsn = $server;
+ }
+ else {
+ $dsn = self::$scheme . ':host=' . $server . (intval($port) ? '' : ';port=' . $port);
+ }
+ $dsn .= ';dbname=' . $db;
+
+
+ self::$dba->pdo_set(array($dsn,$user,$pass));
}
- define('NULL_DATE', self::$dba->get_null_date());
+ define('NULL_DATE', self::$null_date);
define('ACTIVE_DBTYPE', self::$dbtype);
+ define('TQUOT', self::$tquot);
return self::$dba;
}
@@ -85,11 +97,8 @@ class DBA {
*/
abstract class dba_driver {
// legacy behavior
- const INSTALL_SCRIPT='install/schema_mysql.sql';
- const NULL_DATE = '0001-01-01 00:00:00';
- const UTC_NOW = 'UTC_TIMESTAMP()';
- protected $db;
+ public $db;
protected $pdo = array();
public $debug = 0;
@@ -108,7 +117,7 @@ abstract class dba_driver {
* @param string $db database name
* @return bool
*/
- abstract function connect($server, $port, $user, $pass, $db);
+ abstract function connect($server, $scheme, $port, $user, $pass, $db);
/**
* @brief Perform a DB query with the SQL statement $sql.
@@ -142,34 +151,39 @@ abstract class dba_driver {
*/
abstract function getdriver();
- function __construct($server, $port, $user,$pass,$db,$install = false) {
- if(($install) && (! $this->install($server, $port, $user, $pass, $db))) {
+ function __construct($server, $scheme, $port, $user,$pass,$db,$install = false) {
+ if(($install) && (! $this->install($server, $scheme, $port, $user, $pass, $db))) {
return;
}
- $this->connect($server, $port, $user, $pass, $db);
+ $this->connect($server, $scheme, $port, $user, $pass, $db);
}
function get_null_date() {
- return static::NULL_DATE;
+ return \DBA::$null_date;
}
function get_install_script() {
- return static::INSTALL_SCRIPT;
+ return \DBA::$install_script;
+ }
+
+ function get_table_quote() {
+ return \DBA::$tquot;
}
+
function utcnow() {
- return static::UTC_NOW;
+ return \DBA::$utc_now;
}
- function install($server,$user,$pass,$db) {
+ function install($server,$scheme,$port,$user,$pass,$db) {
if (!(strlen($server) && strlen($user))){
$this->connected = false;
$this->db = null;
return false;
}
- if(strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1')) {
- if((! dns_get_record($server, DNS_A + DNS_CNAME + DNS_PTR)) && (! filter_var($server, FILTER_VALIDATE_IP))) {
+ if(strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1') && (! strpbrk($server,':;'))) {
+ if(! z_dns_check($server)) {
$this->error = sprintf( t('Cannot locate DNS info for database server \'%s\''), $server);
$this->connected = false;
$this->db = null;
@@ -313,7 +327,7 @@ function db_concat($fld, $sep) {
* queries return true if the command was successful or false if it wasn't.
*
* Example:
- * $r = q("SELECT * FROM `%s` WHERE `uid` = %d",
+ * $r = q("SELECT * FROM %s WHERE `uid` = %d",
* 'user', 1);
*
* @param string $sql The SQL query to execute
@@ -384,9 +398,22 @@ function dbesc_array_cb(&$item, $key) {
function dbesc_array(&$arr) {
+ $bogus_key = false;
if(is_array($arr) && count($arr)) {
+ $matches = false;
+ foreach($arr as $k => $v) {
+ if(preg_match('/([^a-zA-Z0-9\-\_\.])/',$k,$matches)) {
+ logger('bogus key: ' . $k);
+ $bogus_key = true;
+ }
+ }
array_walk($arr,'dbesc_array_cb');
+ if($bogus_key) {
+ $arr['BOGUS.KEY'] = 1;
+ return false;
+ }
}
+ return true;
}
function db_getfunc($f) {
diff --git a/include/dba/dba_mysql.php b/include/dba/dba_mysql.php
index 3cadad6dc..8b51cf578 100755
--- a/include/dba/dba_mysql.php
+++ b/include/dba/dba_mysql.php
@@ -5,7 +5,7 @@ require_once('include/dba/dba_driver.php');
class dba_mysql extends dba_driver {
- function connect($server, $port, $user,$pass,$db) {
+ function connect($server, $scheme, $port, $user,$pass,$db) {
$this->db = mysql_connect($server.":".$port,$user,$pass);
if($this->db && mysql_select_db($db,$this->db)) {
$this->connected = true;
diff --git a/include/dba/dba_mysqli.php b/include/dba/dba_mysqli.php
index afd2aa642..165c8e969 100755
--- a/include/dba/dba_mysqli.php
+++ b/include/dba/dba_mysqli.php
@@ -4,7 +4,7 @@ require_once('include/dba/dba_driver.php');
class dba_mysqli extends dba_driver {
- function connect($server,$port,$user,$pass,$db) {
+ function connect($server,$scheme,$port,$user,$pass,$db) {
if($port)
$this->db = new mysqli($server,$user,$pass,$db, $port);
else
diff --git a/include/dba/dba_pdo.php b/include/dba/dba_pdo.php
index 7255a2b66..f76e6cdd7 100755
--- a/include/dba/dba_pdo.php
+++ b/include/dba/dba_pdo.php
@@ -7,16 +7,21 @@ class dba_pdo extends dba_driver {
public $driver_dbtype = null;
- function connect($server,$port,$user,$pass,$db) {
+ function connect($server,$scheme,$port,$user,$pass,$db) {
- $this->driver_dbtype = 'mysql'; // (($dbtype == DBTYPE_POSTGRES) ? 'postgres' : 'mysql');
- $dns = $this->driver_dbtype
- . ':host=' . $server . (is_null($port) ? '' : ';port=' . $port)
- . ';dbname=' . $db;
+ $this->driver_dbtype = $scheme;
+ if(strpbrk($server,':;')) {
+ $dsn = $server;
+ }
+ else {
+ $dsn = $this->driver_dbtype . ':host=' . $server . (intval($port) ? '' : ';port=' . $port);
+ }
+
+ $dsn .= ';dbname=' . $db;
try {
- $this->db = new PDO($dns,$user,$pass);
+ $this->db = new PDO($dsn,$user,$pass);
$this->db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
@@ -27,6 +32,9 @@ class dba_pdo extends dba_driver {
return false;
}
+ if($this->driver_dbtype === 'pgsql')
+ $this->q("SET standard_conforming_strings = 'off'; SET backslash_quote = 'on';");
+
$this->connected = true;
return true;
@@ -36,17 +44,23 @@ class dba_pdo extends dba_driver {
if((! $this->db) || (! $this->connected))
return false;
+ if($this->driver_dbtype === 'pgsql') {
+ if(substr(rtrim($sql),-1,1) !== ';') {
+ $sql .= ';';
+ }
+ }
+
$this->error = '';
$select = ((stripos($sql,'select') === 0) ? true : false);
try {
- $result = $this->db->query($sql);
+ $result = $this->db->query($sql, PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$this->error = $e->getMessage();
if($this->error) {
- db_logger('dba_mysqli: ERROR: ' . printable($sql) . "\n" . $this->error, LOGGER_NORMAL, LOG_ERR);
+ db_logger('dba_pdo: ERROR: ' . printable($sql) . "\n" . $this->error, LOGGER_NORMAL, LOG_ERR);
if(file_exists('dbfail.out')) {
file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . "\n" . $this->error . "\n", FILE_APPEND);
}
@@ -55,13 +69,13 @@ class dba_pdo extends dba_driver {
if(!($select)) {
if($this->debug) {
- db_logger('dba_mysqli: DEBUG: ' . printable($sql) . ' returns ' . (($result) ? 'true' : 'false'), LOGGER_NORMAL,(($result) ? LOG_INFO : LOG_ERR));
+ db_logger('dba_pdo: DEBUG: ' . printable($sql) . ' returns ' . (($result) ? 'true' : 'false'), LOGGER_NORMAL,(($result) ? LOG_INFO : LOG_ERR));
}
return $result;
}
if($this->debug) {
- db_logger('dba_mysqli: DEBUG: ' . printable($sql) . ' returned ' . count($result) . ' results.', LOGGER_NORMAL, LOG_INFO);
+ db_logger('dba_pdo: DEBUG: ' . printable($sql) . ' returned ' . count($result) . ' results.', LOGGER_NORMAL, LOG_INFO);
}
$r = array();
@@ -73,7 +87,7 @@ class dba_pdo extends dba_driver {
db_logger('dba_pdo: ' . printable(print_r($r,true)), LOGGER_NORMAL, LOG_INFO);
}
}
- return $r;
+ return (($this->error) ? false : $r);
}
function escape($str) {
@@ -88,6 +102,54 @@ class dba_pdo extends dba_driver {
$this->connected = false;
}
+ function concat($fld,$sep) {
+ if($this->driver_dbtype === 'pgsql') {
+ return 'string_agg(' . $fld . ',\'' . $sep . '\')';
+ }
+ else {
+ return 'GROUP_CONCAT(DISTINCT ' . $fld . ' SEPARATOR \'' . $sep . '\')';
+ }
+ }
+
+ function quote_interval($txt) {
+ if($this->driver_dbtype === 'pgsql') {
+ return "'$txt'";
+ }
+ else {
+ return $txt;
+ }
+ }
+
+ // These two functions assume that postgres standard_conforming_strings is set to off;
+ // which we perform during DB open.
+
+ function escapebin($str) {
+ if($this->driver_dbtype === 'pgsql') {
+ return "\\\\x" . bin2hex($str);
+ }
+ else {
+ return $this->escape($str);
+ }
+ }
+
+ function unescapebin($str) {
+ if($this->driver_dbtype === 'pgsql' && (! is_null($str))) {
+ $x = '';
+ while(! feof($str)) {
+ $x .= fread($str,8192);
+ }
+ if(substr($x,0,2) === '\\x') {
+ $x = hex2bin(substr($x,2));
+ }
+ return $x;
+
+ }
+ else {
+ return $str;
+ }
+ }
+
+
function getdriver() {
return 'pdo';
}
diff --git a/include/dba/dba_postgres.php b/include/dba/dba_postgres.php
index 03b29d703..560d8da60 100644
--- a/include/dba/dba_postgres.php
+++ b/include/dba/dba_postgres.php
@@ -7,8 +7,9 @@ class dba_postgres extends dba_driver {
const INSTALL_SCRIPT='install/schema_postgres.sql';
const NULL_DATE = '0001-01-01 00:00:00';
const UTC_NOW = "now() at time zone 'UTC'";
+ const TQUOT = '"';
- function connect($server,$port,$user,$pass,$db) {
+ function connect($server,$scheme,$port,$user,$pass,$db) {
if(!$port) $port = 5432;
$connstr = 'host=' . $server . ' port='.$port . ' user=' . $user . ' password=' . $pass . ' dbname='. $db;
$this->db = pg_connect($connstr);
diff --git a/include/dir_fns.php b/include/dir_fns.php
index 03cc2706a..3922730fc 100644
--- a/include/dir_fns.php
+++ b/include/dir_fns.php
@@ -192,17 +192,19 @@ function sync_directories($dirmode) {
'site_update' => NULL_DATE,
'site_directory' => DIRECTORY_FALLBACK_MASTER . '/dirsearch',
'site_realm' => DIRECTORY_REALM,
- 'site_valid' => 1
+ 'site_valid' => 1,
+ 'site_crypto' => 'aes256cbc'
);
- $x = q("insert into site ( site_url, site_flags, site_update, site_directory, site_realm, site_valid )
- values ( '%s', %d, '%s', '%s', '%s', %d ) ",
+ $x = q("insert into site ( site_url, site_flags, site_update, site_directory, site_realm, site_valid, site_crypto )
+ values ( '%s', %d, '%s', '%s', '%s', %d, '%s' ) ",
dbesc($r[0]['site_url']),
intval($r[0]['site_flags']),
dbesc($r[0]['site_update']),
dbesc($r[0]['site_directory']),
dbesc($r[0]['site_realm']),
- intval($r[0]['site_valid'])
+ intval($r[0]['site_valid']),
+ dbesc($r[0]['site_crypto'])
);
$r = q("select * from site where site_flags in (%d, %d) and site_url != '%s' and site_type = %d ",
diff --git a/include/event.php b/include/event.php
index 153654120..cbee2b759 100644
--- a/include/event.php
+++ b/include/event.php
@@ -362,28 +362,28 @@ function event_store_event($arr) {
// The event changed. Update it.
- $r = q("UPDATE `event` SET
- `edited` = '%s',
- `dtstart` = '%s',
- `dtend` = '%s',
- `summary` = '%s',
- `description` = '%s',
- `location` = '%s',
- `etype` = '%s',
- `adjust` = %d,
- `nofinish` = %d,
- `event_status` = '%s',
- `event_status_date` = '%s',
- `event_percent` = %d,
- `event_repeat` = '%s',
- `event_sequence` = %d,
- `event_priority` = %d,
- `event_vdata` = '%s',
- `allow_cid` = '%s',
- `allow_gid` = '%s',
- `deny_cid` = '%s',
- `deny_gid` = '%s'
- WHERE `id` = %d AND `uid` = %d",
+ $r = q("UPDATE event SET
+ edited = '%s',
+ dtstart = '%s',
+ dtend = '%s',
+ summary = '%s',
+ description = '%s',
+ location = '%s',
+ etype = '%s',
+ adjust = %d,
+ nofinish = %d,
+ event_status = '%s',
+ event_status_date = '%s',
+ event_percent = %d,
+ event_repeat = '%s',
+ event_sequence = %d,
+ event_priority = %d,
+ event_vdata = '%s',
+ allow_cid = '%s',
+ allow_gid = '%s',
+ deny_cid = '%s',
+ deny_gid = '%s'
+ WHERE id = %d AND uid = %d",
dbesc($arr['edited']),
dbesc($arr['dtstart']),
diff --git a/include/follow.php b/include/follow.php
index 5f63687f8..fa198e402 100644
--- a/include/follow.php
+++ b/include/follow.php
@@ -211,7 +211,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
return $result;
}
- $r = q("select abook_xchan, abook_instance from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
+ $r = q("select abook_id, abook_xchan, abook_pending, abook_instance from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($xchan_hash),
intval($uid)
);
@@ -237,7 +237,28 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
$x = q("update abook set abook_instance = '%s' where abook_id = %d",
dbesc($abook_instance),
intval($r[0]['abook_id'])
- );
+ );
+
+ if(intval($r[0]['abook_pending'])) {
+
+ $abook_my_perms = get_channel_default_perms($uid);
+ $role = get_pconfig($uid,'system','permissions_role');
+ if($role) {
+ $x = \Zotlabs\Access\PermissionRoles::role_perms($role);
+ if($x['perms_connect']) {
+ $abook_my_perms = $x['perms_connect'];
+ }
+ }
+
+ $filled_perms = \Zotlabs\Access\Permissions::FilledPerms($abook_my_perms);
+ foreach($filled_perms as $k => $v) {
+ set_abconfig($uid,$r[0]['abook_xchan'],'my_perms',$k,$v);
+ }
+
+ $x = q("update abook set abook_pending = 0 where abook_id = %d",
+ intval($r[0]['abook_id'])
+ );
+ }
}
else {
$closeness = get_pconfig($uid,'system','new_abook_closeness');
diff --git a/include/group.php b/include/group.php
index 10853ff6b..38d9d190f 100644
--- a/include/group.php
+++ b/include/group.php
@@ -14,11 +14,11 @@ function group_add($uid,$name,$public = 0) {
// access lists. What we're doing here is reviving the dead group, but old content which
// was restricted to this group may now be seen by the new group members.
- $z = q("SELECT * FROM `groups` WHERE `id` = %d LIMIT 1",
+ $z = q("SELECT * FROM groups WHERE id = %d LIMIT 1",
intval($r)
);
if(($z) && $z[0]['deleted']) {
- /*$r = q("UPDATE `groups` SET `deleted` = 0 WHERE `uid` = %d AND `gname` = '%s' LIMIT 1",
+ /*$r = q("UPDATE groups SET deleted = 0 WHERE uid = %d AND gname = '%s'",
intval($uid),
dbesc($name)
);*/
@@ -32,13 +32,13 @@ function group_add($uid,$name,$public = 0) {
$dups = false;
$hash = random_string() . $name;
- $r = q("SELECT id FROM `groups` WHERE hash = '%s' LIMIT 1", dbesc($hash));
+ $r = q("SELECT id FROM groups WHERE hash = '%s' LIMIT 1", dbesc($hash));
if($r)
$dups = true;
} while($dups == true);
- $r = q("INSERT INTO `groups` ( hash, uid, visible, gname )
+ $r = q("INSERT INTO groups ( hash, uid, visible, gname )
VALUES( '%s', %d, %d, '%s' ) ",
dbesc($hash),
intval($uid),
@@ -57,7 +57,7 @@ function group_add($uid,$name,$public = 0) {
function group_rmv($uid,$name) {
$ret = false;
if(x($uid) && x($name)) {
- $r = q("SELECT id, hash FROM `groups` WHERE `uid` = %d AND `gname` = '%s' LIMIT 1",
+ $r = q("SELECT id, hash FROM groups WHERE uid = %d AND gname = '%s' LIMIT 1",
intval($uid),
dbesc($name)
);
@@ -102,13 +102,13 @@ function group_rmv($uid,$name) {
}
// remove all members
- $r = q("DELETE FROM `group_member` WHERE `uid` = %d AND `gid` = %d ",
+ $r = q("DELETE FROM group_member WHERE uid = %d AND gid = %d ",
intval($uid),
intval($group_id)
);
// remove group
- $r = q("UPDATE `groups` SET `deleted` = 1 WHERE `uid` = %d AND `gname` = '%s'",
+ $r = q("UPDATE groups SET deleted = 1 WHERE uid = %d AND gname = '%s'",
intval($uid),
dbesc($name)
);
@@ -125,7 +125,7 @@ function group_rmv($uid,$name) {
function group_byname($uid,$name) {
if((! $uid) || (! strlen($name)))
return false;
- $r = q("SELECT * FROM `groups` WHERE `uid` = %d AND `gname` = '%s' LIMIT 1",
+ $r = q("SELECT * FROM groups WHERE uid = %d AND gname = '%s' LIMIT 1",
intval($uid),
dbesc($name)
);
@@ -138,7 +138,7 @@ function group_byname($uid,$name) {
function group_rec_byhash($uid,$hash) {
if((! $uid) || (! strlen($hash)))
return false;
- $r = q("SELECT * FROM `groups` WHERE `uid` = %d AND `hash` = '%s' LIMIT 1",
+ $r = q("SELECT * FROM groups WHERE uid = %d AND hash = '%s' LIMIT 1",
intval($uid),
dbesc($hash)
);
@@ -153,7 +153,7 @@ function group_rmv_member($uid,$name,$member) {
return false;
if(! ( $uid && $gid && $member))
return false;
- $r = q("DELETE FROM `group_member` WHERE `uid` = %d AND `gid` = %d AND xchan = '%s' ",
+ $r = q("DELETE FROM group_member WHERE uid = %d AND gid = %d AND xchan = '%s' ",
intval($uid),
intval($gid),
dbesc($member)
@@ -173,7 +173,7 @@ function group_add_member($uid,$name,$member,$gid = 0) {
if((! $gid) || (! $uid) || (! $member))
return false;
- $r = q("SELECT * FROM `group_member` WHERE `uid` = %d AND `gid` = %d AND `xchan` = '%s' LIMIT 1",
+ $r = q("SELECT * FROM group_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1",
intval($uid),
intval($gid),
dbesc($member)
@@ -183,7 +183,7 @@ function group_add_member($uid,$name,$member,$gid = 0) {
// we indicate success because the group member was in fact created
// -- It was just created at another time
if(! $r)
- $r = q("INSERT INTO `group_member` (`uid`, `gid`, `xchan`)
+ $r = q("INSERT INTO group_member (uid, gid, xchan)
VALUES( %d, %d, '%s' ) ",
intval($uid),
intval($gid),
@@ -198,9 +198,9 @@ function group_add_member($uid,$name,$member,$gid = 0) {
function group_get_members($gid) {
$ret = array();
if(intval($gid)) {
- $r = q("SELECT * FROM `group_member`
- LEFT JOIN abook ON abook_xchan = `group_member`.`xchan` left join xchan on xchan_hash = abook_xchan
- WHERE `gid` = %d AND abook_channel = %d and `group_member`.`uid` = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ",
+ $r = q("SELECT * FROM group_member
+ LEFT JOIN abook ON abook_xchan = group_member.xchan left join xchan on xchan_hash = abook_xchan
+ WHERE gid = %d AND abook_channel = %d and group_member.uid = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ",
intval($gid),
intval(local_channel()),
intval(local_channel())
@@ -232,7 +232,7 @@ function mini_group_select($uid,$group = '') {
$grps = array();
$o = '';
- $r = q("SELECT * FROM `groups` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `gname` ASC",
+ $r = q("SELECT * FROM groups WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval($uid)
);
$grps[] = array('name' => '', 'hash' => '0', 'selected' => '');
@@ -271,7 +271,7 @@ function group_side($every="connections",$each="group",$edit = false, $group_id
);
- $r = q("SELECT * FROM `groups` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `gname` ASC",
+ $r = q("SELECT * FROM groups WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval($_SESSION['uid'])
);
$member_of = array();
@@ -328,7 +328,7 @@ function expand_groups($a) {
$groups = implode(',', $x);
if($groups)
- $r = q("SELECT xchan FROM group_member WHERE gid IN ( select id from `groups` where hash in ( $groups ))");
+ $r = q("SELECT xchan FROM group_member WHERE gid IN ( select id from groups where hash in ( $groups ))");
$ret = array();
if($r)
@@ -340,7 +340,7 @@ function expand_groups($a) {
function member_of($c) {
- $r = q("SELECT `groups`.`gname`, `groups`.`id` FROM `groups` LEFT JOIN `group_member` ON `group_member`.`gid` = `groups`.`id` WHERE `group_member`.`xchan` = '%s' AND `groups`.`deleted` = 0 ORDER BY `groups`.`gname` ASC ",
+ $r = q("SELECT groups.gname, groups.id FROM groups LEFT JOIN group_member ON group_member.gid = groups.id WHERE group_member.xchan = '%s' AND groups.deleted = 0 ORDER BY groups.gname ASC ",
dbesc($c)
);
@@ -350,7 +350,7 @@ function member_of($c) {
function groups_containing($uid,$c) {
- $r = q("SELECT `gid` FROM `group_member` WHERE `uid` = %d AND `group_member`.`xchan` = '%s' ",
+ $r = q("SELECT gid FROM group_member WHERE uid = %d AND group_member.xchan = '%s' ",
intval($uid),
dbesc($c)
);
diff --git a/include/help.php b/include/help.php
index 3081ae41f..03d01d1a1 100644
--- a/include/help.php
+++ b/include/help.php
@@ -1,15 +1,21 @@
<?php
+/**
+ * @brief
+ *
+ * @param string $tocpath
+ * @return string|unknown
+ */
function get_help_content($tocpath = false) {
-
+
global $lang;
-
+
$doctype = 'markdown';
-
+
$text = '';
$path = (($tocpath !== false) ? $tocpath : '');
-
+
if($tocpath === false && argc() > 1) {
$path = '';
for($x = 1; $x < argc(); $x ++) {
@@ -25,7 +31,7 @@ function get_help_content($tocpath = false) {
\App::$page['title'] = t('Help:') . ' ' . ucwords(str_replace('-',' ',notags($title)));
$text = load_doc_file('doc/' . $path . '.md');
-
+
if(! $text) {
$text = load_doc_file('doc/' . $path . '.bb');
if($text)
@@ -49,20 +55,21 @@ function get_help_content($tocpath = false) {
if(! $text) {
$doctype = 'bbcode';
$text = load_doc_file('doc/main.bb');
+ goaway('/help/about/about_hubzilla');
\App::$page['title'] = t('Help');
}
-
+
if(! $text) {
header($_SERVER["SERVER_PROTOCOL"] . ' 404 ' . t('Not Found'));
$tpl = get_markup_template("404.tpl");
return replace_macros($tpl, array(
- '$message' => t('Page not found.' )
+ '$message' => t('Page not found.')
));
}
}
-
+
if($doctype === 'html')
- $content = $text;
+ $content = parseIdentityAwareHTML($text);
if($doctype === 'markdown') {
require_once('library/markdown.php');
# escape #include tags
@@ -74,30 +81,30 @@ function get_help_content($tocpath = false) {
require_once('include/bbcode.php');
$content = bbcode($text);
// bbcode retargets external content to new windows. This content is internal.
- $content = str_replace(' target="_blank"','',$content);
- }
-
+ $content = str_replace(' target="_blank"', '', $content);
+ }
+
$content = preg_replace_callback("/#include (.*?)\;/ism", 'preg_callback_help_include', $content);
+
return translate_projectname($content);
-
}
function preg_callback_help_include($matches) {
-
+
if($matches[1]) {
$include = str_replace($matches[0],load_doc_file($matches[1]),$matches[0]);
if(preg_match('/\.bb$/', $matches[1]) || preg_match('/\.txt$/', $matches[1])) {
require_once('include/bbcode.php');
$include = bbcode($include);
- $include = str_replace(' target="_blank"','',$include);
- }
+ $include = str_replace(' target="_blank"','',$include);
+ }
elseif(preg_match('/\.md$/', $matches[1])) {
require_once('library/markdown.php');
$include = Markdown($include);
}
return $include;
}
-
+
}
@@ -110,10 +117,10 @@ function load_doc_file($s) {
$d = dirname($s);
$c = find_doc_file("$d/$lang/$b");
- if($c)
+ if($c)
return $c;
$c = find_doc_file($s);
- if($c)
+ if($c)
return $c;
return '';
}
@@ -125,6 +132,12 @@ function find_doc_file($s) {
return '';
}
+/**
+ * @brief
+ *
+ * @param string $s
+ * @return number|mixed|unknown|boolean
+ */
function search_doc_files($s) {
$itemspage = get_pconfig(local_channel(),'system','itemspage');
@@ -133,21 +146,21 @@ function search_doc_files($s) {
$regexop = db_getfunc('REGEXP');
- $r = q("select iconfig.v, item.* from item left join iconfig on item.id = iconfig.iid
+ $r = q("select iconfig.v, item.* from item left join iconfig on item.id = iconfig.iid
where iconfig.cat = 'system' and iconfig.k = 'docfile' and
body $regexop '%s' and item_type = %d $pager_sql",
dbesc($s),
intval(ITEM_TYPE_DOC)
);
-
- $r = fetch_post_tags($r,true);
+
+ $r = fetch_post_tags($r, true);
for($x = 0; $x < count($r); $x ++) {
$position = stripos($r[$x]['body'], $s);
$dislen = 300;
$start = $position-floor($dislen/2);
if ( $start < 0) {
- $start = 0;
+ $start = 0;
}
$r[$x]['text'] = substr($r[$x]['body'], $start, $dislen);
@@ -159,43 +172,50 @@ function search_doc_files($s) {
}
}
}
- if(stristr($r[$x]['v'],$s))
+ if(stristr($r[$x]['v'], $s))
$r[$x]['rank'] ++;
- $r[$x]['rank'] += substr_count(strtolower($r[$x]['text']),strtolower($s));
+ $r[$x]['rank'] += substr_count(strtolower($r[$x]['text']), strtolower($s));
// bias the results to the observer's native language
if($r[$x]['lang'] === \App::$language)
$r[$x]['rank'] = $r[$x]['rank'] + 10;
}
usort($r,'doc_rank_sort');
+
return $r;
}
-function doc_rank_sort($s1,$s2) {
+function doc_rank_sort($s1, $s2) {
if($s1['rank'] == $s2['rank'])
return 0;
+
return (($s1['rank'] < $s2['rank']) ? 1 : (-1));
}
-
+/**
+ * @brief
+ *
+ * @return string
+ */
function load_context_help() {
-
+
$path = App::$cmd;
$args = App::$argv;
$lang = App::$language;
-
+
if(! isset($lang) || !is_dir('doc/context/' . $lang . '/')) {
- $lang = 'en';
- }
+ $lang = 'en';
+ }
while($path) {
$context_help = load_doc_file('doc/context/' . $lang . '/' . $path . '/help.html');
- if(!$context_help) {
- // Fallback to English if the translation is absent
- $context_help = load_doc_file('doc/context/en/' . $path . '/help.html');
- }
+ if(!$context_help) {
+ // Fallback to English if the translation is absent
+ $context_help = load_doc_file('doc/context/en/' . $path . '/help.html');
+ }
if($context_help)
break;
+
array_pop($args);
$path = implode($args,'/');
}
@@ -203,7 +223,12 @@ function load_context_help() {
return $context_help;
}
-
+/**
+ * @brief
+ *
+ * @param string $s
+ * @return void|boolean[]|number[]|string[]|unknown[]
+ */
function store_doc_file($s) {
if(is_dir($s))
@@ -215,10 +240,9 @@ function store_doc_file($s) {
$item['aid'] = 0;
$item['uid'] = $sys['channel_id'];
-
- if(strpos($s,'.md'))
+ if(strpos($s, '.md'))
$mimetype = 'text/markdown';
- elseif(strpos($s,'.html'))
+ elseif(strpos($s, '.html'))
$mimetype = 'text/html';
else
$mimetype = 'text/bbcode';
@@ -227,12 +251,12 @@ function store_doc_file($s) {
$item['body'] = html2plain(prepare_text(file_get_contents($s),$mimetype, true));
$item['mimetype'] = 'text/plain';
-
+
$item['plink'] = z_root() . '/' . str_replace('doc','help',$s);
$item['owner_xchan'] = $item['author_xchan'] = $sys['channel_hash'];
$item['item_type'] = ITEM_TYPE_DOC;
- $r = q("select item.* from item left join iconfig on item.id = iconfig.iid
+ $r = q("select item.* from item left join iconfig on item.id = iconfig.iid
where iconfig.cat = 'system' and iconfig.k = 'docfile' and
iconfig.v = '%s' and item_type = %d limit 1",
dbesc($s),
@@ -252,6 +276,4 @@ function store_doc_file($s) {
}
return $x;
-
}
-
diff --git a/include/hubloc.php b/include/hubloc.php
index 397646449..17f921f67 100644
--- a/include/hubloc.php
+++ b/include/hubloc.php
@@ -1,19 +1,5 @@
<?php /** @file */
-function is_matrix_url($url) {
- $m = @parse_url($url);
- if($m['host']) {
- $r = q("select hubloc_url from hubloc where hubloc_host = '%s' limit 1",
- dbesc($m['host'])
- );
- if($r)
- return true;
- }
- return false;
-}
-
-
-
function prune_hub_reinstalls() {
$r = q("select site_url from site where site_type = %d",
diff --git a/include/import.php b/include/import.php
index 479e45cc2..0d8398acb 100644
--- a/include/import.php
+++ b/include/import.php
@@ -82,14 +82,7 @@ function import_channel($channel, $account_id, $seize) {
}
if($clean) {
- dbesc_array($clean);
-
- $r = dbq("INSERT INTO channel (`"
- . implode("`, `", array_keys($clean))
- . "`) VALUES ('"
- . implode("', '", array_values($clean))
- . "')"
- );
+ create_table_from_array('channel',$clean);
}
if(! $r) {
@@ -131,12 +124,7 @@ function import_config($channel,$configs) {
foreach($configs as $config) {
unset($config['id']);
$config['uid'] = $channel['channel_id'];
- dbesc_array($config);
- $r = dbq("INSERT INTO pconfig (`"
- . implode("`, `", array_keys($config))
- . "`) VALUES ('"
- . implode("', '", array_values($config))
- . "')" );
+ create_table_from_array('pconfig',$config);
}
load_pconfig($channel['channel_id']);
}
@@ -161,14 +149,7 @@ function import_profiles($channel,$profiles) {
$profile['photo'] = z_root() . '/photo/profile/l/' . $channel['channel_id'];
$profile['thumb'] = z_root() . '/photo/profile/m/' . $channel['channel_id'];
-
- dbesc_array($profile);
- $r = dbq("INSERT INTO profile (`"
- . implode("`, `", array_keys($profile))
- . "`) VALUES ('"
- . implode("', '", array_values($profile))
- . "')"
- );
+ create_table_from_array('profile',$profile);
}
}
}
@@ -203,14 +184,7 @@ function import_hublocs($channel,$hublocs,$seize) {
if(! zot_gethub($arr)) {
unset($hubloc['hubloc_id']);
- dbesc_array($hubloc);
-
- $r = dbq("INSERT INTO hubloc (`"
- . implode("`, `", array_keys($hubloc))
- . "`) VALUES ('"
- . implode("', '", array_values($hubloc))
- . "')"
- );
+ create_table_from_array('hubloc',$hubloc);
}
}
}
@@ -242,14 +216,7 @@ function import_objs($channel,$objs) {
$obj['obj_imgurl'] = $x[0];
}
- dbesc_array($obj);
-
- $r = dbq("INSERT INTO obj (`"
- . implode("`, `", array_keys($obj))
- . "`) VALUES ('"
- . implode("', '", array_values($obj))
- . "')"
- );
+ create_table_from_array('obj',$obj);
}
}
}
@@ -260,7 +227,7 @@ function sync_objs($channel,$objs) {
foreach($objs as $obj) {
if(array_key_exists('obj_deleted',$obj) && $obj['obj_deleted'] && $obj['obj_obj']) {
- q("delete from obj where obj_obj = '%s' and obj_channel = %d limit 1",
+ q("delete from obj where obj_obj = '%s' and obj_channel = %d",
dbesc($obj['obj_obj']),
intval($channel['channel_id'])
);
@@ -304,7 +271,7 @@ function sync_objs($channel,$objs) {
if($exists) {
unset($obj['obj_obj']);
foreach($obj as $k => $v) {
- $r = q("UPDATE obj SET `%s` = '%s' WHERE obj_obj = '%s' AND obj_channel = %d",
+ $r = q("UPDATE obj SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE obj_obj = '%s' AND obj_channel = %d",
dbesc($k),
dbesc($v),
dbesc($hash),
@@ -313,15 +280,7 @@ function sync_objs($channel,$objs) {
}
}
else {
-
- dbesc_array($obj);
-
- $r = dbq("INSERT INTO obj (`"
- . implode("`, `", array_keys($obj))
- . "`) VALUES ('"
- . implode("', '", array_values($obj))
- . "')"
- );
+ create_table_from_array('obj',$obj);
}
}
}
@@ -351,13 +310,7 @@ function import_apps($channel,$apps) {
$hash = $app['app_id'];
- dbesc_array($app);
- $r = dbq("INSERT INTO app (`"
- . implode("`, `", array_keys($app))
- . "`) VALUES ('"
- . implode("', '", array_values($app))
- . "')"
- );
+ create_table_from_array('app',$app);
if($term) {
$x = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
@@ -398,7 +351,7 @@ function sync_apps($channel,$apps) {
}
if(array_key_exists('app_deleted',$app) && $app['app_deleted'] && $app['app_id']) {
- q("delete from app where app_id = '%s' and app_channel = %d limit 1",
+ q("delete from app where app_id = '%s' and app_channel = %d",
dbesc($app['app_id']),
intval($channel['channel_id'])
);
@@ -451,7 +404,7 @@ function sync_apps($channel,$apps) {
if($exists) {
unset($app['app_id']);
foreach($app as $k => $v) {
- $r = q("UPDATE app SET `%s` = '%s' WHERE app_id = '%s' AND app_channel = %d",
+ $r = q("UPDATE app SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE app_id = '%s' AND app_channel = %d",
dbesc($k),
dbesc($v),
dbesc($hash),
@@ -460,15 +413,10 @@ function sync_apps($channel,$apps) {
}
}
else {
- dbesc_array($app);
- $r = dbq("INSERT INTO app (`"
- . implode("`, `", array_keys($app))
- . "`) VALUES ('"
- . implode("', '", array_values($app))
- . "')"
- );
+ create_table_from_array('app',$app);
+
if($term) {
- $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1",
+ $x = q("select * from app where app_id = '%s' and app_channel = %d",
dbesc($hash),
intval($channel['channel_id'])
);
@@ -502,13 +450,7 @@ function import_chatrooms($channel,$chatrooms) {
$chatroom['cr_aid'] = $channel['channel_account_id'];
$chatroom['cr_uid'] = $channel['channel_id'];
- dbesc_array($chatroom);
- $r = dbq("INSERT INTO chatroom (`"
- . implode("`, `", array_keys($chatroom))
- . "`) VALUES ('"
- . implode("', '", array_values($chatroom))
- . "')"
- );
+ create_table_from_array('chatroom',$chatroom);
}
}
}
@@ -524,7 +466,7 @@ function sync_chatrooms($channel,$chatrooms) {
continue;
if(array_key_exists('cr_deleted',$chatroom) && $chatroom['cr_deleted']) {
- q("delete from chatroom where cr_name = '%s' and cr_uid = %d limit 1",
+ q("delete from chatroom where cr_name = '%s' and cr_uid = %d",
dbesc($chatroom['cr_name']),
intval($channel['channel_id'])
);
@@ -559,7 +501,7 @@ function sync_chatrooms($channel,$chatrooms) {
if($exists) {
foreach($chatroom as $k => $v) {
- $r = q("UPDATE chatroom SET `%s` = '%s' WHERE cr_name = '%s' AND cr_uid = %d",
+ $r = q("UPDATE chatroom SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE cr_name = '%s' AND cr_uid = %d",
dbesc($k),
dbesc($v),
dbesc($name),
@@ -568,13 +510,7 @@ function sync_chatrooms($channel,$chatrooms) {
}
}
else {
- dbesc_array($chatroom);
- $r = dbq("INSERT INTO chatroom (`"
- . implode("`, `", array_keys($chatroom))
- . "`) VALUES ('"
- . implode("', '", array_values($chatroom))
- . "')"
- );
+ create_table_from_array('chatroom',$chatroom);
}
}
}
@@ -684,13 +620,7 @@ function import_events($channel,$events) {
convert_oldfields($event,'type','etype');
convert_oldfields($event,'ignore','dismissed');
- dbesc_array($event);
- $r = dbq("INSERT INTO event (`"
- . implode("`, `", array_keys($event))
- . "`) VALUES ('"
- . implode("', '", array_values($event))
- . "')"
- );
+ create_table_from_array('event',$event);
}
}
}
@@ -705,7 +635,7 @@ function sync_events($channel,$events) {
continue;
if($event['event_deleted']) {
- $r = q("delete from event where event_hash = '%s' and uid = %d limit 1",
+ $r = q("delete from event where event_hash = '%s' and uid = %d",
dbesc($event['event_hash']),
intval($channel['channel_id'])
);
@@ -736,7 +666,7 @@ function sync_events($channel,$events) {
if($exists) {
foreach($event as $k => $v) {
- $r = q("UPDATE event SET `%s` = '%s' WHERE event_hash = '%s' AND uid = %d",
+ $r = q("UPDATE event SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE event_hash = '%s' AND uid = %d",
dbesc($k),
dbesc($v),
dbesc($event['event_hash']),
@@ -745,13 +675,7 @@ function sync_events($channel,$events) {
}
}
else {
- dbesc_array($event);
- $r = dbq("INSERT INTO event (`"
- . implode("`, `", array_keys($event))
- . "`) VALUES ('"
- . implode("', '", array_values($event))
- . "')"
- );
+ create_table_from_array('event',$event);
}
}
}
@@ -927,12 +851,7 @@ function import_likes($channel,$likes) {
if($r)
continue;
- dbesc_array($like);
- $r = dbq("INSERT INTO likes (`"
- . implode("`, `", array_keys($like))
- . "`) VALUES ('"
- . implode("', '", array_values($like))
- . "')" );
+ create_table_from_array('likes',$like);
}
}
}
@@ -941,7 +860,7 @@ function import_conv($channel,$convs) {
if($channel && $convs) {
foreach($convs as $conv) {
if($conv['deleted']) {
- q("delete from conv where guid = '%s' and uid = %d limit 1",
+ q("delete from conv where guid = '%s' and uid = %d",
dbesc($conv['guid']),
intval($channel['channel_id'])
);
@@ -959,13 +878,7 @@ function import_conv($channel,$convs) {
);
if($r)
continue;
-
- dbesc_array($conv);
- $r = dbq("INSERT INTO conv (`"
- . implode("`, `", array_keys($conv))
- . "`) VALUES ('"
- . implode("', '", array_values($conv))
- . "')" );
+ create_table_from_array('conv',$conv);
}
}
}
@@ -976,14 +889,14 @@ function import_mail($channel,$mails,$sync = false) {
if($channel && $mails) {
foreach($mails as $mail) {
if(array_key_exists('flags',$mail) && in_array('deleted',$mail['flags'])) {
- q("delete from mail where mid = '%s' and uid = %d limit 1",
+ q("delete from mail where mid = '%s' and uid = %d",
dbesc($mail['message_id']),
intval($channel['channel_id'])
);
continue;
}
if(array_key_exists('flags',$mail) && in_array('recalled',$mail['flags'])) {
- q("update mail set mail_recalled = 1 where mid = '%s' and uid = %d limit 1",
+ q("update mail set mail_recalled = 1 where mid = '%s' and uid = %d",
dbesc($mail['message_id']),
intval($channel['channel_id'])
);
@@ -1110,25 +1023,22 @@ function sync_files($channel,$files) {
if(!isset($att['os_path']))
$att['os_path'] = '';
- dbesc_array($att);
if($attach_exists) {
logger('sync_files attach exists: ' . print_r($att,true), LOGGER_DEBUG);
+ if(! dbesc_array($att))
+ continue;
$str = '';
- foreach($att as $k => $v) {
- if($str)
- $str .= ",";
- $str .= " `" . $k . "` = '" . $v . "' ";
- }
- $r = dbq("update `attach` set " . $str . " where id = " . intval($attach_id) );
+ foreach($att as $k => $v) {
+ if($str)
+ $str .= ",";
+ $str .= " " . TQUOT . $k . TQUOT . " = '" . $v . "' ";
+ }
+ $r = dbq("update attach set " . $str . " where id = " . intval($attach_id) );
}
else {
logger('sync_files attach does not exists: ' . print_r($att,true), LOGGER_DEBUG);
- $r = dbq("INSERT INTO attach (`"
- . implode("`, `", array_keys($att))
- . "`) VALUES ('"
- . implode("', '", array_values($att))
- . "')" );
+ create_table_from_array('attach',$att);
}
@@ -1229,23 +1139,20 @@ function sync_files($channel,$files) {
intval($channel['channel_id'])
);
- dbesc_array($p);
if($exists) {
+ if(! dbesc_array($p))
+ continue;
$str = '';
foreach($p as $k => $v) {
if($str)
$str .= ",";
- $str .= " `" . $k . "` = '" . $v . "' ";
+ $str .= " " . TQUOT . $k . TQUOT . " = '" . $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']) );
}
else {
- $r = dbq("INSERT INTO photo (`"
- . implode("`, `", array_keys($p))
- . "`) VALUES ('"
- . implode("', '", array_values($p))
- . "')" );
+ create_attach_from_array('photo',$p);
}
}
}
diff --git a/include/items.php b/include/items.php
index c62d53c3e..9bd256d58 100755
--- a/include/items.php
+++ b/include/items.php
@@ -3,9 +3,6 @@
* @file include/items.php
*/
-// uncertain if this line is needed and why
-use Sabre\HTTP\URLUtil;
-
use Zotlabs\Lib as Zlib;
require_once('include/bbcode.php');
@@ -66,6 +63,7 @@ function collect_recipients($item, &$private_envelope) {
if($recipients && $deny)
$recipients = array_diff($recipients,$deny);
+
$private_envelope = true;
}
else {
@@ -116,7 +114,7 @@ function collect_recipients($item, &$private_envelope) {
// Add the authors of any posts in this thread, if they are known to us.
// This is specifically designed to forward wall-to-wall posts to the original author,
- // in case they aren't a connection but have permission to write on our wall.
+ // in case they aren't a connection but have permission to write on our wall.
// This is important for issue tracker channels. It should be a no-op for most channels.
// Whether or not they will accept the delivery is not determined here, but should
// be taken into account by zot:process_delivery()
@@ -131,7 +129,6 @@ function collect_recipients($item, &$private_envelope) {
}
}
}
-
}
@@ -173,19 +170,19 @@ function comments_are_now_closed($item) {
}
function item_normal() {
- return " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0
- and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
+ return " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0
+ and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
and item.item_blocked = 0 ";
}
/**
* @brief
- *
- * This is a compatibility function primarily for plugins, because
+ *
+ * This is a compatibility function primarily for plugins, because
* in earlier DB schemas this was a much simpler single integer compare
*
+ * @param array $item
*/
-
function is_item_normal($item) {
if(intval($item['item_hidden']) || intval($item['item_type']) || intval($item['item_deleted'])
@@ -193,8 +190,7 @@ function is_item_normal($item) {
|| intval($item['item_blocked']))
return false;
- return true;
-
+ return true;
}
/**
@@ -236,7 +232,7 @@ function can_comment_on_post($observer_xchan, $item) {
case 'public':
// We don't really allow or support public comments yet, but anonymous
// folks won't ever reach this point (as $observer_xchan will be empty).
- // This means the viewer has an xchan and we can identify them.
+ // This means the viewer has an xchan and we can identify them.
return true;
break;
case 'any connections':
@@ -295,78 +291,6 @@ function add_source_route($iid, $hash) {
/**
- * @brief preg_match function when fixing 'naked' links in mod item.php.
- *
- * Check if we've got a hubloc for the site and use a zrl if we do, a url if we don't.
- * Remove any existing zid= param which may have been pasted by mistake - and will have
- * the author's credentials. zid's are dynamic and can't really be passed around like
- * that.
- *
- * @param array $matches
- * @return string
- */
-function red_zrl_callback($matches) {
- require_once('include/hubloc.php');
- $zrl = is_matrix_url($matches[2]);
-
- $t = strip_zids($matches[2]);
- if($t !== $matches[2]) {
- $zrl = true;
- $matches[2] = $t;
- }
-
- if($matches[1] === '#^')
- $matches[1] = '';
- if($zrl)
- return $matches[1] . '#^[zrl=' . $matches[2] . ']' . $matches[2] . '[/zrl]';
-
- return $matches[1] . '#^[url=' . $matches[2] . ']' . $matches[2] . '[/url]';
-}
-
-/**
- * If we've got a url or zrl tag with a naked url somewhere in the link text,
- * escape it with quotes unless the naked url is a linked photo.
- *
- * @param array $matches
- * @return string
- */
-function red_escape_zrl_callback($matches) {
-
- // Uncertain why the url/zrl forms weren't picked up by the non-greedy regex.
-
- if((strpos($matches[3], 'zmg') !== false) || (strpos($matches[3], 'img') !== false) || (strpos($matches[3],'zrl') !== false) || (strpos($matches[3],'url') !== false))
- return $matches[0];
-
- return '[' . $matches[1] . 'rl' . $matches[2] . ']' . $matches[3] . '"' . $matches[4] . '"' . $matches[5] . '[/' . $matches[6] . 'rl]';
-}
-
-function red_escape_codeblock($m) {
- return '[$b64' . $m[2] . base64_encode($m[1]) . '[/' . $m[2] . ']';
-}
-
-function red_unescape_codeblock($m) {
- return '[' . $m[2] . base64_decode($m[1]) . '[/' . $m[2] . ']';
-}
-
-
-function red_zrlify_img_callback($matches) {
- require_once('include/hubloc.php');
- $zrl = is_matrix_url($matches[2]);
-
- $t = strip_zids($matches[2]);
- if($t !== $matches[2]) {
- $zrl = true;
- $matches[2] = $t;
- }
-
- if($zrl)
- return '[zmg' . $matches[1] . ']' . $matches[2] . '[/zmg]';
-
- return $matches[0];
-}
-
-
-/**
* @brief Post an activity.
*
* In its simplest form one needs only to set $arr['body'] to post a note to the logged in channel's wall.
@@ -481,7 +405,7 @@ function validate_item_elements($message,$arr) {
if(! array_key_exists('created',$arr))
$result['message'] = 'missing created, possible author/owner lookup failure';
- if((! $arr['mid']) || (! $arr['parent_mid']))
+ if((! $arr['mid']) || (! $arr['parent_mid']))
$result['message'] = 'missing message-id or parent message-id';
if(array_key_exists('flags',$message) && in_array('relay',$message['flags']) && $arr['mid'] === $arr['parent_mid'])
@@ -495,10 +419,6 @@ function validate_item_elements($message,$arr) {
}
-
-
-
-
/**
* @brief Limit lenght on imported system messages.
*
@@ -652,7 +572,6 @@ function get_item_elements($x,$allow_code = false) {
if(mb_strlen($arr['title']) > 255)
$arr['title'] = mb_substr($arr['title'],0,255);
-
$arr['app'] = (($x['app']) ? htmlspecialchars($x['app'], ENT_COMPAT,'UTF-8',false) : '');
$arr['route'] = (($x['route']) ? htmlspecialchars($x['route'], ENT_COMPAT,'UTF-8',false) : '');
$arr['mid'] = (($x['message_id']) ? htmlspecialchars($x['message_id'], ENT_COMPAT,'UTF-8',false) : '');
@@ -714,7 +633,7 @@ function get_item_elements($x,$allow_code = false) {
// hub and verify that they are legit - or else we're going to toss the post. We only need to do this
// once, and after that your hub knows them. Sure some info is in the post, but it's only a transit identifier
// and not enough info to be able to look you up from your hash - which is the only thing stored with the post.
-
+
$xchan_hash = import_author_xchan($x['author']);
if($xchan_hash)
$arr['author_xchan'] = $xchan_hash;
@@ -1057,7 +976,6 @@ function encode_item($item,$mirror = false) {
$x['item_blocked'] = $item['item_blocked'];
}
-
$x['message_id'] = $item['mid'];
$x['message_top'] = $item['parent_mid'];
$x['message_parent'] = $item['thr_parent'];
@@ -1078,9 +996,9 @@ function encode_item($item,$mirror = false) {
$x['longlat'] = $item['coord'];
$x['signature'] = $item['sig'];
$x['route'] = $item['route'];
-
$x['owner'] = encode_item_xchan($item['owner']);
$x['author'] = encode_item_xchan($item['author']);
+
if($item['obj'])
$x['object'] = json_decode($item['obj'],true);
if($item['target'])
@@ -1237,7 +1155,7 @@ function decode_item_meta($meta) {
$ret[] = array('cat' => escape_tags($m['family']),'k' => escape_tags($m['key']),'v' => $m['value'],'sharing' => $m['sharing']);
}
}
- return $ret;
+ return $ret;
}
/**
@@ -1530,6 +1448,8 @@ function get_profile_elements($x) {
*
* @param array $arr
* @param boolean $allow_exec (optional) default false
+ * @param boolean $deliver (optional) default true
+ *
* @return array
* * \e boolean \b success
* * \e int \b item_id
@@ -1543,6 +1463,11 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
$ret = array('success' => false, 'item_id' => 0);
+ if(array_key_exists('cancel',$arr) && $arr['cancel']) {
+ logger('cancelled by plugin');
+ return $ret;
+ }
+
if(! $arr['uid']) {
logger('item_store: no uid');
$ret['message'] = 'No uid.';
@@ -1662,7 +1587,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
// otherwise, just preserve the original timestamp.
$arr['received'] = ((x($arr,'received') !== false) ? datetime_convert('UTC','UTC',$arr['received']) : datetime_convert());
- $arr['changed'] = ((x($arr,'changed') !== false) ? datetime_convert('UTC','UTC',$arr['changed']) : datetime_convert());
+ $arr['changed'] = ((x($arr,'changed') !== false) ? datetime_convert('UTC','UTC',$arr['changed']) : datetime_convert());
}
$arr['location'] = ((x($arr,'location')) ? notags(trim($arr['location'])) : '');
@@ -1681,7 +1606,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
$arr['public_policy'] = ((x($arr,'public_policy')) ? notags(trim($arr['public_policy'])) : '' );
$arr['comment_policy'] = ((x($arr,'comment_policy')) ? notags(trim($arr['comment_policy'])) : 'contacts' );
-
+
if(! array_key_exists('item_unseen',$arr))
$arr['item_unseen'] = 1;
@@ -1717,7 +1642,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
// find the parent and snarf the item id and ACL's
// and anything else we need to inherit
- $r = q("SELECT * FROM `item` WHERE `mid` = '%s' AND `uid` = %d ORDER BY `id` ASC LIMIT 1",
+ $r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d ORDER BY id ASC LIMIT 1",
dbesc($arr['parent_mid']),
intval($arr['uid'])
);
@@ -1749,8 +1674,8 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
if($r[0]['mid'] != $r[0]['parent_mid']) {
$arr['parent_mid'] = $r[0]['parent_mid'];
- $z = q("SELECT * FROM `item` WHERE `mid` = '%s' AND `parent_mid` = '%s' AND `uid` = %d
- ORDER BY `id` ASC LIMIT 1",
+ $z = q("SELECT * FROM item WHERE mid = '%s' AND parent_mid = '%s' AND uid = %d
+ ORDER BY id ASC LIMIT 1",
dbesc($r[0]['parent_mid']),
dbesc($r[0]['parent_mid']),
intval($arr['uid'])
@@ -1801,7 +1726,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
if($parent_deleted)
$arr['item_deleted'] = 1;
- $r = q("SELECT `id` FROM `item` WHERE `mid` = '%s' AND `uid` = %d LIMIT 1",
+ $r = q("SELECT id FROM item WHERE mid = '%s' AND uid = %d LIMIT 1",
dbesc($arr['mid']),
intval($arr['uid'])
);
@@ -1853,17 +1778,12 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
logger('item_store: ' . print_r($arr,true), LOGGER_DATA);
- dbesc_array($arr);
- $r = dbq("INSERT INTO `item` (`"
- . implode("`, `", array_keys($arr))
- . "`) VALUES ('"
- . implode("', '", array_values($arr))
- . "')" );
+ create_table_from_array('item',$arr);
// find the item we just created
- $r = q("SELECT * FROM `item` WHERE `mid` = '%s' AND `uid` = %d ORDER BY `id` ASC ",
+ $r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d ORDER BY id ASC ",
$arr['mid'], // already dbesc'd
intval($arr['uid'])
);
@@ -1880,7 +1800,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
}
if(count($r) > 1) {
logger('item_store: duplicated post occurred. Removing duplicates.');
- q("DELETE FROM `item` WHERE `mid` = '%s' AND `uid` = %d AND `id` != %d ",
+ q("DELETE FROM item WHERE mid = '%s' AND uid = %d AND id != %d ",
$arr['mid'],
intval($arr['uid']),
intval($current_post)
@@ -1893,6 +1813,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
$x = q("update item set parent = id where id = %d",
intval($r[0]['id'])
);
+ $arr['parent'] = $r[0]['id'];
}
@@ -1926,18 +1847,22 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
call_hooks('post_remote_end',$arr);
- // update the commented timestamp on the parent
+ // update the commented timestamp on the parent - unless this is potentially a clone of an older item
+ // 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 is older than that.
- $z = q("select max(created) as commented from item where parent_mid = '%s' and uid = %d and item_delayed = 0 ",
- dbesc($arr['parent_mid']),
- intval($arr['uid'])
- );
+ if($arr['created'] > datetime_convert('','','now - 4 days')) {
+ $z = q("select max(created) as commented from item where parent_mid = '%s' and uid = %d and item_delayed = 0 ",
+ dbesc($arr['parent_mid']),
+ intval($arr['uid'])
+ );
- q("UPDATE item set commented = '%s', changed = '%s' WHERE id = %d",
- dbesc(($z) ? $z[0]['commented'] : (datetime_convert())),
- dbesc(datetime_convert()),
- intval($parent_id)
- );
+ q("UPDATE item set commented = '%s', changed = '%s' WHERE id = %d",
+ dbesc(($z) ? $z[0]['commented'] : (datetime_convert())),
+ dbesc(datetime_convert()),
+ intval($parent_id)
+ );
+ }
// If _creating_ a deleted item, don't propagate it further or send out notifications.
@@ -1966,6 +1891,12 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
$allow_exec = $d['allow_exec'];
$ret = array('success' => false, 'item_id' => 0);
+
+ if(array_key_exists('cancel',$arr) && $arr['cancel']) {
+ logger('cancelled by plugin');
+ return $ret;
+ }
+
if(! intval($arr['uid'])) {
logger('item_store_update: no uid');
$ret['message'] = 'no uid.';
@@ -2072,20 +2003,8 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
$arr['commented'] = $orig[0]['commented'];
- if($deliver) {
- $arr['received'] = datetime_convert();
- $arr['changed'] = datetime_convert();
- }
- else {
-
- // When deliver flag is false, we are *probably* performing an import or bulk migration.
- // If one updates the changed timestamp it will be made available to zotfeed and delivery
- // will still take place through backdoor methods. Since these fields are rarely used
- // otherwise, just preserve the original timestamp.
-
- $arr['received'] = $orig[0]['received'];
- $arr['changed'] = $orig[0]['changed'];
- }
+ $arr['received'] = $orig[0]['received'];
+ $arr['changed'] = $orig[0]['changed'];
$arr['route'] = ((array_key_exists('route',$arr)) ? trim($arr['route']) : $orig[0]['route']);
$arr['diaspora_meta'] = ((x($arr,'diaspora_meta')) ? $arr['diaspora_meta'] : $orig[0]['diaspora_meta']);
@@ -2166,7 +2085,10 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
}
- dbesc_array($arr);
+ if(! dbesc_array($arr)) {
+ $ret['message'] = 'DB array malformed';
+ return $ret;
+ }
logger('item_store_update: ' . print_r($arr,true), LOGGER_DATA);
@@ -2174,10 +2096,10 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
foreach($arr as $k => $v) {
if($str)
$str .= ",";
- $str .= " `" . $k . "` = '" . $v . "' ";
+ $str .= " " . TQUOT . $k . TQUOT . " = '" . $v . "' ";
}
- $r = dbq("update `item` set " . $str . " where id = " . $orig_post_id );
+ $r = dbq("update item set " . $str . " where id = " . $orig_post_id );
if($r)
logger('item_store_update: updated item ' . $orig_post_id, LOGGER_DEBUG);
@@ -2336,10 +2258,10 @@ function send_status_notifications($post_id,$item) {
// check for an unfollow thread activity - we should probably decode the obj and check the id
// but it will be extremely rare for this to be wrong.
- if(($xx['verb'] === ACTIVITY_UNFOLLOW)
- && ($xx['obj_type'] === ACTIVITY_OBJ_NOTE || $xx['obj_type'] === ACTIVITY_OBJ_PHOTO)
+ if(($xx['verb'] === ACTIVITY_UNFOLLOW)
+ && ($xx['obj_type'] === ACTIVITY_OBJ_NOTE || $xx['obj_type'] === ACTIVITY_OBJ_PHOTO)
&& ($xx['parent'] != $xx['id']))
- $unfollowed = true;
+ $unfollowed = true;
}
if($xx['id'] == $xx['parent']) {
$parent = $xx['parent'];
@@ -2562,7 +2484,7 @@ function tag_deliver($uid, $item_id) {
if($mention) {
logger('tag_deliver: mention found for ' . $u[0]['channel_name']);
-
+
$r = q("update item set item_mentionsme = 1 where id = %d",
intval($item_id)
);
@@ -2851,7 +2773,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent) {
$title = $item['title'];
$body = $item['body'];
- $r = q("update item set item_uplink = %d, item_nocomment = %d, item_obscured = %d, item_flags = %d, owner_xchan = '%s', allow_cid = '%s', allow_gid = '%s',
+ $r = q("update item set item_uplink = %d, item_nocomment = %d, item_obscured = %d, item_flags = %d, owner_xchan = '%s', allow_cid = '%s', allow_gid = '%s',
deny_cid = '%s', deny_gid = '%s', item_private = %d, public_policy = '%s', comment_policy = '%s', title = '%s', body = '%s', item_wall = %d, item_origin = %d where id = %d",
intval($item_uplink),
intval($item_nocomment),
@@ -3066,7 +2988,7 @@ function mail_store($arr) {
$arr['parent_mid'] = $arr['mid'];
}
- $r = q("SELECT `id` FROM mail WHERE `mid` = '%s' AND channel_id = %d LIMIT 1",
+ $r = q("SELECT id FROM mail WHERE mid = '%s' AND channel_id = %d LIMIT 1",
dbesc($arr['mid']),
intval($arr['channel_id'])
);
@@ -3088,19 +3010,13 @@ function mail_store($arr) {
return 0;
}
- dbesc_array($arr);
-
logger('mail_store: ' . print_r($arr,true), LOGGER_DATA);
- $r = dbq("INSERT INTO mail (`"
- . implode("`, `", array_keys($arr))
- . "`) VALUES ('"
- . implode("', '", array_values($arr))
- . "')" );
+ create_table_from_array('mail', $arr);
// find the item we just created
- $r = q("SELECT `id` FROM mail WHERE `mid` = '%s' AND `channel_id` = %d ORDER BY `id` ASC ",
+ $r = q("SELECT id FROM mail WHERE mid = '%s' AND channel_id = %d ORDER BY id ASC ",
$arr['mid'], // already dbesc'd
intval($arr['channel_id'])
);
@@ -3116,7 +3032,7 @@ function mail_store($arr) {
}
if(count($r) > 1) {
logger('mail_store: duplicated post occurred. Removing duplicates.');
- q("DELETE FROM mail WHERE `mid` = '%s' AND `channel_id` = %d AND `id` != %d ",
+ q("DELETE FROM mail WHERE mid = '%s' AND channel_id = %d AND id != %d ",
$arr['mid'],
intval($arr['channel_id']),
intval($current_post)
@@ -3168,7 +3084,7 @@ function fix_private_photos($s, $uid, $item = null, $cid = 0) {
if($x) {
$res = substr($i,$x+1);
$i = substr($i,0,$x);
- $r = q("SELECT * FROM `photo` WHERE `resource_id` = '%s' AND `imgscale` = %d AND `uid` = %d",
+ $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND imgscale = %d AND uid = %d",
dbesc($i),
intval($res),
intval($uid)
@@ -3352,7 +3268,7 @@ function item_expire($uid,$days) {
AND item_starred = 0
$sql_extra $item_normal LIMIT $expire_limit ",
intval($uid),
- db_utcnow(),
+ db_utcnow(),
db_quoteinterval(intval($days).' DAY')
);
@@ -3745,7 +3661,7 @@ function fetch_post_tags($items,$link = false) {
);
$imeta = q("select * from iconfig where iid in ( %s )",
dbesc($tag_finder_str)
- );
+ );
}
@@ -3878,13 +3794,13 @@ function zot_feed($uid,$observer_hash,$arr) {
unset($r[$x]);
}
}
-
+
$parents_str = ids_to_querystr($r,'parent');
$sys_query = ((is_sys_channel($uid)) ? $sql_extra : '');
$item_normal = item_normal();
- $items = q("SELECT `item`.*, `item`.`id` AS `item_id` FROM `item`
- WHERE `item`.`parent` IN ( %s ) $item_normal $sys_query ",
+ $items = q("SELECT item.*, item.id AS item_id FROM item
+ WHERE item.parent IN ( %s ) $item_normal $sys_query ",
dbesc($parents_str)
);
}
@@ -3942,9 +3858,9 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
if($arr['mid'])
$sql_options .= " and parent_mid = '" . dbesc($arr['mid']) . "' ";
-
+
$sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE item_thread_top = 1 $sql_options $item_normal ) ";
-
+
if($arr['since_id'])
$sql_extra .= " and item.id > " . $since_id . " ";
@@ -3952,7 +3868,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
$sql_extra .= protect_sprintf(term_query('item', $arr['cat'], TERM_CATEGORY));
if($arr['gid'] && $uid) {
- $r = q("SELECT * FROM `groups` WHERE id = %d AND uid = %d LIMIT 1",
+ $r = q("SELECT * FROM groups WHERE id = %d AND uid = %d LIMIT 1",
intval($arr['group']),
intval($uid)
);
@@ -4056,8 +3972,8 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
$sql_nets .= "( abook.abook_closeness >= " . intval($arr['cmin']) . " ";
$sql_nets .= " AND abook.abook_closeness <= " . intval($arr['cmax']) . " ) ";
- /** @fixme dead code, $cmax is undefined */
- if ($cmax == 99)
+
+ if ($arr['cmax'] == 99)
$sql_nets .= " OR abook.abook_closeness IS NULL ) ";
}
}
@@ -4192,25 +4108,21 @@ function webpage_to_namespace($webpage) {
function update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remote_id,$mid) {
- $page_type = '';
-
if(! $post_id)
return;
-
- if($webpage == ITEM_TYPE_WEBPAGE)
- $page_type = 'WEBPAGE';
- elseif($webpage == ITEM_TYPE_BLOCK)
- $page_type = 'BUILDBLOCK';
- elseif($webpage == ITEM_TYPE_PDL)
- $page_type = 'PDL';
- elseif($webpage == ITEM_TYPE_DOC)
- $page_type = 'docfile';
- elseif($namespace && $remote_id) {
+
+ $page_type = webpage_to_namespace($webpage);
+
+ if($page_type == 'unknown' && $namespace && $remote_id) {
$page_type = $namespace;
$pagetitle = $remote_id;
}
+ else {
+ $page_type = '';
+ }
if($page_type) {
+
// store page info as an alternate message_id so we can access it via
// https://sitename/page/$channelname/$pagetitle
// if no pagetitle was given or it couldn't be transliterated into a url, use the first
@@ -4347,7 +4259,7 @@ function send_profile_photo_activity($channel,$photo,$profile) {
$ptext = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']' . t('profile photo') . '[/zrl]';
- $ltext = '[zrl=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . '[zmg=150x150]' . z_root() . '/photo/' . $photo['resource_id'] . '-4[/zmg][/zrl]';
+ $ltext = '[zrl=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . '[zmg=150x150]' . z_root() . '/photo/' . $photo['resource_id'] . '-4[/zmg][/zrl]';
$arr['body'] = sprintf($t,$channel['channel_name'],$ptext) . "\n\n" . $ltext;
@@ -4389,11 +4301,11 @@ function sync_an_item($channel_id,$item_id) {
function fix_attached_photo_permissions($uid,$xchan_hash,$body,
$str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny) {
-
+
if(get_pconfig($uid,'system','force_public_uploads')) {
$str_contact_allow = $str_group_allow = $str_contact_deny = $str_group_deny = '';
}
-
+
$match = null;
// match img and zmg image links
if(preg_match_all("/\[[zi]mg(.*?)\](.*?)\[\/[zi]mg\]/",$body,$match)) {
@@ -4410,7 +4322,7 @@ function fix_attached_photo_permissions($uid,$xchan_hash,$body,
if(! strlen($image_uri))
continue;
$srch = '<' . $xchan_hash . '>';
-
+
$r = q("select folder from attach where hash = '%s' and uid = %d limit 1",
dbesc($image_uri),
intval($uid)
@@ -4427,15 +4339,15 @@ function fix_attached_photo_permissions($uid,$xchan_hash,$body,
$str_group_deny = $f[0]['deny_gid'];
}
}
-
- $r = q("SELECT id FROM photo
+
+ $r = q("SELECT id FROM photo
WHERE allow_cid = '%s' AND allow_gid = '' AND deny_cid = '' AND deny_gid = ''
AND resource_id = '%s' AND uid = %d LIMIT 1",
dbesc($srch),
dbesc($image_uri),
intval($uid)
);
-
+
if($r) {
$r = q("UPDATE photo SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s'
WHERE resource_id = '%s' AND uid = %d ",
@@ -4446,9 +4358,9 @@ function fix_attached_photo_permissions($uid,$xchan_hash,$body,
dbesc($image_uri),
intval($uid)
);
-
+
// also update the linked item (which is probably invisible)
-
+
$r = q("select id from item
WHERE allow_cid = '%s' AND allow_gid = '' AND deny_cid = '' AND deny_gid = ''
AND resource_id = '%s' and resource_type = 'photo' AND uid = %d LIMIT 1",
@@ -4458,7 +4370,7 @@ function fix_attached_photo_permissions($uid,$xchan_hash,$body,
);
if($r) {
$private = (($str_contact_allow || $str_group_allow || $str_contact_deny || $str_group_deny) ? true : false);
-
+
$r = q("UPDATE item SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d
WHERE id = %d AND uid = %d",
dbesc($str_contact_allow),
@@ -4484,23 +4396,23 @@ function fix_attached_photo_permissions($uid,$xchan_hash,$body,
intval($r[0]['id']),
intval($uid)
);
- }
+ }
}
}
}
}
}
-
-
+
+
function fix_attached_file_permissions($channel,$observer_hash,$body,
$str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny) {
-
+
if(get_pconfig($channel['channel_id'],'system','force_public_uploads')) {
$str_contact_allow = $str_group_allow = $str_contact_deny = $str_group_deny = '';
}
-
+
$match = false;
-
+
if(preg_match_all("/\[attachment\](.*?)\[\/attachment\]/",$body,$match)) {
$attaches = $match[1];
if($attaches) {
@@ -4519,3 +4431,75 @@ function fix_attached_file_permissions($channel,$observer_hash,$body,
}
}
}
+
+
+function item_create_edit_activity($post) {
+
+ if((! $post) || (! $post['item']) || ($post['item']['item_type'] != ITEM_TYPE_POST))
+ return;
+
+ $update_item = $post['item'];
+
+ $new_item = $update_item;
+
+ $author = q("select * from xchan where xchan_hash = '%s' limit 1",
+ dbesc($new_item['author_xchan'])
+ );
+ if($author)
+ $item_author = $author[0];
+
+
+ $new_item['id'] = 0;
+ $new_item['parent'] = 0;
+ $new_item['mid'] = item_message_id();
+
+ $new_item['body'] = sprintf( t('[Edited %s]'), (($update_item['item_thread_top']) ? t('Post','edit_activity') : t('Comment','edit_activity')));
+
+ $new_item['body'] .= "\n\n";
+ $new_item['body'] .= $update_item['body'];
+
+ $new_item['sig'] = '';
+
+ $new_item['verb'] = ACTIVITY_UPDATE;
+ $new_item['item_thread_top'] = 0;
+ $new_item['created'] = $new_item['edited'] = datetime_convert();
+
+ $new_item['obj'] = json_encode(array(
+ 'type' => (($update_item['item_thread_top']) ? ACTIVITY_OBJ_NOTE : ACTIVITY_OBJ_COMMENT),
+ 'id' => $update_item['mid'],
+ 'parent' => $update_item['parent_mid'],
+ 'link' => array(array('rel' => 'alternate','type' => 'text/html', 'href' => $update_item['plink'])),
+ 'title' => $update_item['title'],
+ 'content' => $update_item['body'],
+ 'created' => $update_item['created'],
+ 'edited' => $update_item['edited'],
+ 'author' => array(
+ 'name' => $item_author['xchan_name'],
+ 'address' => $item_author['xchan_addr'],
+ 'guid' => $item_author['xchan_guid'],
+ 'guid_sig' => $item_author['xchan_guid_sig'],
+ 'link' => array(
+ array('rel' => 'alternate', 'type' => 'text/html', 'href' => $item_author['xchan_url']),
+ array('rel' => 'photo', 'type' => $item_author['xchan_photo_mimetype'], 'href' => $item_author['xchan_photo_m'])),
+ ),
+ ));
+
+
+
+ $x = post_activity_item($new_item);
+
+ $post_id = $x['id'];
+ if($post_id) {
+ $r = q("select * from item where id = %d",
+ intval($post_id)
+ );
+ if($r) {
+ xchan_query($r);
+ $sync_item = fetch_post_tags($r);
+ build_sync_packet($new_item['uid'],array('item' => array(encode_item($sync_item[0],true))));
+ }
+ }
+
+ \Zotlabs\Daemon\Master::Summon(array('Notifier', 'edit_activity', $post_id));
+
+}
diff --git a/include/language.php b/include/language.php
index 96d3e48a9..efe9397fb 100644
--- a/include/language.php
+++ b/include/language.php
@@ -327,3 +327,61 @@ function get_language_name($s, $l = null) {
return $language->getName();
}
+
+
+
+function language_list() {
+
+ $langs = glob('view/*/hstrings.php');
+
+ $lang_options = array();
+ $selected = "";
+
+ if(is_array($langs) && count($langs)) {
+ if(! in_array('view/en/hstrings.php',$langs))
+ $langs[] = 'view/en/';
+ asort($langs);
+ foreach($langs as $l) {
+ $ll = substr($l,5);
+ $ll = substr($ll,0,strrpos($ll,'/'));
+ $lang_options[$ll] = get_language_name($ll, $ll) . " ($ll)";
+ }
+ }
+ return $lang_options;
+}
+
+function lang_selector() {
+
+ $langs = glob('view/*/hstrings.php');
+
+ $lang_options = array();
+ $selected = "";
+
+ if(is_array($langs) && count($langs)) {
+ $langs[] = '';
+ if(! in_array('view/en/hstrings.php',$langs))
+ $langs[] = 'view/en/';
+ asort($langs);
+ foreach($langs as $l) {
+ if($l == '') {
+ $lang_options[""] = t('default');
+ continue;
+ }
+ $ll = substr($l,5);
+ $ll = substr($ll,0,strrpos($ll,'/'));
+ $selected = (($ll === App::$language && (x($_SESSION, 'language'))) ? $ll : $selected);
+ $lang_options[$ll] = get_language_name($ll, $ll) . " ($ll)";
+ }
+ }
+
+ $tpl = get_markup_template('lang_selector.tpl');
+
+ $o = replace_macros($tpl, array(
+ '$title' => t('Select an alternate language'),
+ '$langs' => array($lang_options, $selected),
+
+ ));
+
+ return $o;
+}
+
diff --git a/include/menu.php b/include/menu.php
index 3b0180d37..b54ff7f9e 100644
--- a/include/menu.php
+++ b/include/menu.php
@@ -284,7 +284,7 @@ function menu_delete_id($menu_id, $uid) {
intval($menu_id),
intval($uid)
);
- return q("delete from menu where menu_id = %d and menu_channel_id = %d limit 1",
+ return q("delete from menu where menu_id = %d and menu_channel_id = %d",
intval($menu_id),
intval($uid)
);
diff --git a/include/message.php b/include/message.php
index 748689206..7cbea3c6b 100644
--- a/include/message.php
+++ b/include/message.php
@@ -187,10 +187,10 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
if($body)
$body = str_rot47(base64url_encode($body));
+ $sig = ''; // placeholder
-
- $r = q("INSERT INTO mail ( account_id, conv_guid, mail_obscured, channel_id, from_xchan, to_xchan, title, body, attach, mid, parent_mid, created, expires, mail_isreply )
- VALUES ( %d, '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d )",
+ $r = q("INSERT INTO mail ( account_id, conv_guid, mail_obscured, channel_id, from_xchan, to_xchan, title, body, sig, attach, mid, parent_mid, created, expires, mail_isreply )
+ VALUES ( %d, '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d )",
intval($channel['channel_account_id']),
dbesc($conv_guid),
intval(1),
@@ -199,6 +199,7 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
dbesc($recipient),
dbesc($subject),
dbesc($body),
+ dbesc($sig),
dbesc($jattach),
dbesc($mid),
dbesc($replyto),
@@ -392,7 +393,7 @@ function private_messages_fetch_message($channel_id, $messageitem_id, $updatesee
if($updateseen) {
- $r = q("UPDATE `mail` SET mail_seen = 1 where mail_seen = 0 and id = %d AND channel_id = %d",
+ $r = q("UPDATE mail SET mail_seen = 1 where mail_seen = 0 and id = %d AND channel_id = %d",
dbesc($messageitem_id),
intval($channel_id)
);
@@ -436,7 +437,7 @@ function private_messages_drop($channel_id, $messageitem_id, $drop_conversation
intval($channel_id)
);
if($z) {
- q("delete from conv where guid = '%s' and uid = %d limit 1",
+ q("delete from conv where guid = '%s' and uid = %d",
dbesc($x[0]['conv_guid']),
intval($channel_id)
);
@@ -516,7 +517,7 @@ function private_messages_fetch_conversation($channel_id, $messageitem_id, $upda
if($updateseen) {
- $r = q("UPDATE `mail` SET mail_seen = 1 where mail_seen = 0 and parent_mid = '%s' AND channel_id = %d",
+ $r = q("UPDATE mail SET mail_seen = 1 where mail_seen = 0 and parent_mid = '%s' AND channel_id = %d",
dbesc($r[0]['parent_mid']),
intval($channel_id)
);
diff --git a/include/nav.php b/include/nav.php
index c2a058457..2762e2a14 100644
--- a/include/nav.php
+++ b/include/nav.php
@@ -108,7 +108,7 @@ EOT;
if(feature_enabled($channel['channel_id'],'webpages') && (! $basic))
$nav['usermenu'][] = Array('webpages/' . $channel['channel_address'],t('Webpages'),"",t('Your webpages'),'webpages_nav_btn');
if(feature_enabled($channel['channel_id'],'wiki') && (! $basic))
- $nav['usermenu'][] = Array('wiki/' . $channel['channel_address'],t('Wiki'),"",t('Your wiki'),'wiki_nav_btn');
+ $nav['usermenu'][] = Array('wiki/' . $channel['channel_address'],t('Wikis'),"",t('Your wikis'),'wiki_nav_btn');
}
else {
if(! get_account_id()) {
@@ -127,26 +127,24 @@ EOT;
);
}
- if($observer) {
- $nav['lock'] = array('logout','','lock',
- sprintf( t('%s - click to logout'), $observer['xchan_addr']));
- }
elseif(! $_SESSION['authenticated']) {
$nav['loginmenu'][] = Array('rmagic',t('Remote authentication'),'',t('Click to authenticate to your home hub'),'rmagic_nav_btn');
}
- /**
- * "Home" should also take you home from an authenticated remote profile connection
- */
-
$homelink = get_my_url();
if(! $homelink) {
$observer = App::get_observer();
$homelink = (($observer) ? $observer['xchan_url'] : '');
}
- if(! local_channel())
- $nav['home'] = array($homelink, t('Home'), "", t('Home Page'),'home_nav_btn');
+ if(! local_channel()) {
+ $nav['rusermenu'] = array(
+ $homelink,
+ t('Get me home'),
+ 'logout',
+ t('Log me out of this site')
+ );
+ }
if(((get_config('system','register_policy') == REGISTER_OPEN) || (get_config('system','register_policy') == REGISTER_APPROVE)) && (! $_SESSION['authenticated']))
$nav['register'] = array('register',t('Register'), "", t('Create an account'),'register_nav_btn');
diff --git a/include/network.php b/include/network.php
index 7851f8976..451ce12a1 100644
--- a/include/network.php
+++ b/include/network.php
@@ -30,12 +30,12 @@ function get_capath() {
* * \b filep => stream resource to write body to. header and body are not returned when using this option.
* * \b custom => custom request method: e.g. 'PUT', 'DELETE'
* * \b cookiejar => cookie file (write)
- * * \B cookiefile => cookie file (read)
+ * * \b cookiefile => cookie file (read)
*
* @return array an associative array with:
* * \e int \b return_code => HTTP return code or 0 if timeout or failure
* * \e boolean \b success => boolean true (if HTTP 2xx result) or false
- * * \e string \b header => HTTP headers
+ * * \e string \b header => HTTP headers
* * \e string \b body => fetched content
*/
function z_fetch_url($url, $binary = false, $redirects = 0, $opts = array()) {
@@ -43,7 +43,7 @@ function z_fetch_url($url, $binary = false, $redirects = 0, $opts = array()) {
$ret = array('return_code' => 0, 'success' => false, 'header' => "", 'body' => "");
$ch = @curl_init($url);
- if(($redirects > 8) || (! $ch))
+ if(($redirects > 8) || (! $ch))
return $ret;
@curl_setopt($ch, CURLOPT_HEADER, true);
@@ -59,12 +59,12 @@ function z_fetch_url($url, $binary = false, $redirects = 0, $opts = array()) {
if(x($opts,'filep')) {
@curl_setopt($ch, CURLOPT_FILE, $opts['filep']);
- @curl_setopt($ch, CURLOPT_HEADER, $false);
+ @curl_setopt($ch, CURLOPT_HEADER, false);
}
if(x($opts,'upload'))
@curl_setopt($ch, CURLOPT_UPLOAD, $opts['upload']);
-
+
if(x($opts,'infile'))
@curl_setopt($ch, CURLOPT_INFILE, $opts['infile']);
@@ -87,7 +87,7 @@ function z_fetch_url($url, $binary = false, $redirects = 0, $opts = array()) {
@curl_setopt($ch, CURLOPT_TIMEOUT, $opts['timeout']);
}
else {
- $curl_time = intval(get_config('system','curl_timeout'));
+ $curl_time = intval(@get_config('system','curl_timeout'));
@curl_setopt($ch, CURLOPT_TIMEOUT, (($curl_time !== false) ? $curl_time : 60));
}
@@ -104,10 +104,10 @@ function z_fetch_url($url, $binary = false, $redirects = 0, $opts = array()) {
if(x($opts,'cookie'))
@curl_setopt($ch, CURLOPT_COOKIE, $opts['cookie']);
- @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,
+ @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,
((x($opts,'novalidate') && intval($opts['novalidate'])) ? false : true));
- $prx = get_config('system','proxy');
+ $prx = @get_config('system','proxy');
if(strlen($prx)) {
@curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
@curl_setopt($ch, CURLOPT_PROXY, $prx);
@@ -179,10 +179,10 @@ function z_fetch_url($url, $binary = false, $redirects = 0, $opts = array()) {
* @param string $url
* URL to post
* @param mixed $params
- * The full data to post in a HTTP "POST" operation. This parameter can
- * either be passed as a urlencoded string like 'para1=val1&para2=val2&...'
- * or as an array with the field name as key and field data as value. If value
- * is an array, the Content-Type header will be set to multipart/form-data.
+ * The full data to post in a HTTP "POST" operation. This parameter can
+ * either be passed as a urlencoded string like 'para1=val1&para2=val2&...'
+ * or as an array with the field name as key and field data as value. If value
+ * is an array, the Content-Type header will be set to multipart/form-data.
* @param int $redirects = 0
* internal use, recursion counter
* @param array $opts (optional parameters)
@@ -209,7 +209,7 @@ function z_post_url($url,$params, $redirects = 0, $opts = array()) {
$ret = array('return_code' => 0, 'success' => false, 'header' => "", 'body' => "");
$ch = curl_init($url);
- if(($redirects > 8) || (! $ch))
+ if(($redirects > 8) || (! $ch))
return $ret;
@curl_setopt($ch, CURLOPT_HEADER, true);
@@ -226,13 +226,13 @@ function z_post_url($url,$params, $redirects = 0, $opts = array()) {
if(x($opts,'filep')) {
@curl_setopt($ch, CURLOPT_FILE, $opts['filep']);
- @curl_setopt($ch, CURLOPT_HEADER, $false);
+ @curl_setopt($ch, CURLOPT_HEADER, false);
}
if(x($opts,'headers')) {
@curl_setopt($ch, CURLOPT_HTTPHEADER, $opts['headers']);
}
-
+
if(x($opts,'nobody'))
@curl_setopt($ch, CURLOPT_NOBODY, $opts['nobody']);
@@ -246,7 +246,7 @@ function z_post_url($url,$params, $redirects = 0, $opts = array()) {
@curl_setopt($ch, CURLOPT_TIMEOUT, $opts['timeout']);
}
else {
- $curl_time = intval(get_config('system','curl_timeout'));
+ $curl_time = intval(@get_config('system','curl_timeout'));
@curl_setopt($ch, CURLOPT_TIMEOUT, (($curl_time !== false) ? $curl_time : 60));
}
@@ -265,7 +265,7 @@ function z_post_url($url,$params, $redirects = 0, $opts = array()) {
if(x($opts,'cookie'))
@curl_setopt($ch, CURLOPT_COOKIE, $opts['cookie']);
- @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,
+ @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,
((x($opts,'novalidate') && intval($opts['novalidate'])) ? false : true));
$prx = get_config('system','proxy');
@@ -379,8 +379,8 @@ function json_return_and_die($x, $content_type = 'application/json') {
// Generic XML return
-// Outputs a basic dfrn XML status structure to STDOUT, with a <status> variable
-// of $st and an optional text <message> of $message and terminates the current process.
+// Outputs a basic dfrn XML status structure to STDOUT, with a <status> variable
+// of $st and an optional text <message> of $message and terminates the current process.
function xml_status($st, $message = '') {
@@ -399,7 +399,7 @@ function xml_status($st, $message = '') {
/**
- * @brief Send HTTP status header
+ * @brief Send HTTP status header
*
* @param int $val
* integer HTTP status result value
@@ -413,7 +413,7 @@ function http_status($val, $msg = '') {
if ($val >= 200 && $val < 300)
$msg = (($msg) ? $msg : 'OK');
- logger('http_status_exit ' . $val . ' ' . $msg);
+ logger('http_status_exit ' . $val . ' ' . $msg);
header($_SERVER['SERVER_PROTOCOL'] . ' ' . $val . ' ' . $msg);
}
@@ -480,21 +480,46 @@ function convert_xml_element_to_array($xml_element, &$recursion_depth=0) {
}
}
+
+
+function z_dns_check($h,$check_mx = 0) {
+
+ // dns_get_record() has issues on some platforms
+ // so allow somebody to ignore it completely
+ // Use config values from memory as this can be called during setup
+ // before a database or even any config structure exists.
+
+ if(is_array(\App::$config) && array_key_exists('system',\App::$config)
+ && is_array(\App::$config['system'])
+ && array_key_exists('do_not_check_dns',\App::$config['system'])
+ && \App::$config['system']['do_not_check_dns'])
+ return true;
+
+
+ //$opts = DNS_A + DNS_CNAME + DNS_PTR;
+ //if($check_mx)
+ // $opts += DNS_MX;
+ // Specific record type flags are unreliable on FreeBSD and Mac,
+ // so now we'll ignore these and just check for the existence of any DNS record.
+ return((@dns_get_record($h) || filter_var($h, FILTER_VALIDATE_IP)) ? true : false);
+
+}
+
// Take a URL from the wild, prepend http:// if necessary
// and check DNS to see if it's real (or check if is a valid IP address)
// return true if it's OK, false if something is wrong with it
function validate_url(&$url) {
-
+
// no naked subdomains (allow localhost for tests)
if(strpos($url,'.') === false && strpos($url,'/localhost/') === false)
return false;
if(substr($url,0,4) != 'http')
$url = 'http://' . $url;
$h = @parse_url($url);
-
- if(($h) && (@dns_get_record($h['host'], DNS_A + DNS_CNAME + DNS_PTR) || filter_var($h['host'], FILTER_VALIDATE_IP) )) {
+
+ if(($h) && z_dns_check($h['host'])) {
return true;
}
return false;
@@ -512,7 +537,7 @@ function validate_email($addr) {
return false;
$h = substr($addr,strpos($addr,'@') + 1);
- if(($h) && (@dns_get_record($h, DNS_A + DNS_CNAME + DNS_PTR + DNS_MX) || filter_var($h, FILTER_VALIDATE_IP) )) {
+ if(($h) && z_dns_check($h,true)) {
return true;
}
return false;
@@ -552,7 +577,7 @@ function allowed_url($url) {
foreach($allowed as $a) {
$pat = strtolower(trim($a));
if(($fnmatch && fnmatch($pat,$host)) || ($pat == $host)) {
- $found = true;
+ $found = true;
break;
}
}
@@ -575,14 +600,14 @@ function allowed_email($email) {
$str_allowed = get_config('system','allowed_email');
$str_not_allowed = get_config('system','not_allowed_email');
-
+
if(! $str_allowed && ! $str_not_allowed)
return true;
$return = false;
- $found_allowed = false;
+ $found_allowed = false;
$found_not_allowed = false;
-
+
$fnmatch = function_exists('fnmatch');
$allowed = explode(',',$str_allowed);
@@ -591,7 +616,7 @@ function allowed_email($email) {
foreach($allowed as $a) {
$pat = strtolower(trim($a));
if(($fnmatch && fnmatch($pat,$email)) || ($pat == $domain)) {
- $found_allowed = true;
+ $found_allowed = true;
break;
}
}
@@ -603,16 +628,16 @@ function allowed_email($email) {
foreach($not_allowed as $na) {
$pat = strtolower(trim($na));
if(($fnmatch && fnmatch($pat,$email)) || ($pat == $domain)) {
- $found_not_allowed = true;
+ $found_not_allowed = true;
break;
}
}
- }
-
+ }
+
if ($found_allowed) {
- $return = true;
+ $return = true;
} elseif (!$str_allowed && !$found_not_allowed) {
- $return = true;
+ $return = true;
}
return $return;
}
@@ -652,7 +677,7 @@ function scale_external_images($s, $include_link = true, $scale_replace = false)
foreach($matches as $mtch) {
logger('scale_external_image: ' . $mtch[2] . ' ' . $mtch[3]);
-
+
if(substr($mtch[1],0,1) == '=') {
$owidth = intval(substr($mtch[2],1));
if(intval($owidth) > 0 && intval($owidth) < 1024)
@@ -686,7 +711,7 @@ function scale_external_images($s, $include_link = true, $scale_replace = false)
$type = guess_image_type($mtch[3],$i['header']);
if(strpos($type,'image') === false)
continue;
-
+
if($i['success']) {
$ph = photo_factory($i['body'], $type);
if($ph->is_valid()) {
@@ -700,7 +725,7 @@ function scale_external_images($s, $include_link = true, $scale_replace = false)
$new_height = $ph->getHeight();
logger('scale_external_images: ' . $orig_width . '->' . $new_width . 'w ' . $orig_height . '->' . $new_height . 'h' . ' match: ' . $mtch[0], LOGGER_DEBUG);
$s = str_replace($mtch[0],'[' . $tag . '=' . $new_width . 'x' . $new_height. ']' . $scaled . '[/' . $tag . ']'
- . "\n" . (($include_link)
+ . "\n" . (($include_link)
? '[zrl=' . $mtch[2] . ']' . t('view full size') . '[/zrl]' . "\n"
: ''),$s);
logger('scale_external_images: new string: ' . $s, LOGGER_DEBUG);
@@ -728,7 +753,7 @@ function scale_external_images($s, $include_link = true, $scale_replace = false)
* Return: The parsed XML in an array form. Use print_r() to see the resulting array structure.
* Examples: $array = xml2array(file_get_contents('feed.xml'));
* $array = xml2array(file_get_contents('feed.xml', true, 1, 'attribute'));
- */
+ */
function xml2array($contents, $namespaces = true, $get_attributes=1, $priority = 'attribute') {
if(!$contents) return array();
@@ -752,7 +777,7 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority =
return array();
}
- xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
+ xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
// http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
@@ -786,7 +811,7 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority =
$result = array();
$attributes_data = array();
-
+
if(isset($value)) {
if($priority == 'tag') $result = $value;
else $result['value'] = $value; // Put the value in a assoc array if we are in the 'Attribute' mode
@@ -802,7 +827,7 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority =
// See tag status and do the needed.
if($namespaces && strpos($tag,':')) {
- $namespc = substr($tag,0,strrpos($tag,':'));
+ $namespc = substr($tag,0,strrpos($tag,':'));
$tag = strtolower(substr($tag,strlen($namespc)+1));
$result['@namespace'] = $namespc;
}
@@ -825,7 +850,7 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority =
} else { // This section will make the value an array if multiple tags with the same name appear together
$current[$tag] = array($current[$tag],$result); // This will combine the existing item and the new item together to make an array
$repeated_tag_index[$tag.'_'.$level] = 2;
-
+
if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
$current[$tag]['0_attr'] = $current[$tag.'_attr'];
unset($current[$tag.'_attr']);
@@ -848,7 +873,7 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority =
// ...push the new element into that array.
$current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
-
+
if($priority == 'tag' and $get_attributes and $attributes_data) {
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
}
@@ -859,11 +884,11 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority =
$repeated_tag_index[$tag.'_'.$level] = 1;
if($priority == 'tag' and $get_attributes) {
if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
-
+
$current[$tag]['0_attr'] = $current[$tag.'_attr'];
unset($current[$tag.'_attr']);
}
-
+
if($attributes_data) {
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
}
@@ -876,9 +901,9 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority =
$current = &$parent[$level-1];
}
}
-
+
return($xml_array);
-}
+}
function email_header_encode($in_str, $charset = 'UTF-8') {
@@ -1128,7 +1153,7 @@ function discover_by_webbie($webbie) {
$diaspora = false;
$gnusoc = false;
$dfrn = false;
-
+
$has_salmon = false;
$salmon_key = false;
$atom_feed = false;
@@ -1144,7 +1169,7 @@ function discover_by_webbie($webbie) {
if(array_key_exists('rel',$link)) {
// If we discover zot - don't search further; grab the info and get out of
- // here.
+ // here.
if($link['rel'] === PROTOCOL_ZOT) {
logger('discover_by_webbie: zot found for ' . $webbie, LOGGER_DEBUG);
@@ -1204,11 +1229,11 @@ function discover_by_webbie($webbie) {
$pubkey = '';
if(is_array($x)) {
- if(array_key_exists('address',$x))
+ if(array_key_exists('address',$x))
$address = $x['address'];
- if(array_key_exists('location',$x))
+ if(array_key_exists('location',$x))
$location = $x['location'];
- if(array_key_exists('nickname',$x))
+ if(array_key_exists('nickname',$x))
$nickname = $x['nickname'];
}
@@ -1216,16 +1241,16 @@ function discover_by_webbie($webbie) {
$probe_old = true;
- if((! $dfrn) && (! $has_salmon))
+ if((! $dfrn) && (! $has_salmon))
$probe_old = true;
if($probe_old) {
- $y = old_webfinger($webbie);
+ $y = old_webfinger($webbie);
if($y) {
logger('old_webfinger: ' . print_r($x,true));
foreach($y as $link) {
if($link['@attributes']['rel'] === NAMESPACE_DFRN)
- $dfrn = unamp($link['@attributes']['href']);
+ $dfrn = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === 'salmon')
$notify = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === NAMESPACE_FEED)
@@ -1344,7 +1369,7 @@ function discover_by_webbie($webbie) {
if($vcard['fn'])
$fullname = $vcard['fn'];
if($vcard['photo'] && (strpos($vcard['photo'],'http') !== 0))
- $vcard['photo'] = $diaspora_base . '/' . $vcard['photo'];
+ $vcard['photo'] = $diaspora_base . '/' . $vcard['photo'];
if(($vcard['public_key']) && (! $pubkey)) {
$diaspora_key = $vcard['public_key'];
if(strstr($diaspora_key,'RSA '))
@@ -1358,7 +1383,7 @@ function discover_by_webbie($webbie) {
if(($vcard['uid']) && (! $diaspora_guid))
$diaspora_guid = $vcard['uid'];
if(($vcard['url']) && (! $diaspora_base))
- $diaspora_base = $vcard['url'];
+ $diaspora_base = $vcard['url'];
@@ -1372,7 +1397,7 @@ function discover_by_webbie($webbie) {
if(($profile) && (! $location))
$location = $profile;
- if($location) {
+ if($location) {
$m = parse_url($location);
$base = $m['scheme'] . '://' . $m['host'];
$host = $m['host'];
@@ -1407,12 +1432,12 @@ function discover_by_webbie($webbie) {
// if we have everything we need, let's create the records
- if($network && $address && $fullname && $pubkey && $location) {
+ if($network && $address && $fullname && $pubkey && $location) {
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($address)
);
if($r) {
- $r = q("update xchan set xchan_name = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s' limit 1",
+ $r = q("update xchan set xchan_name = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s'",
dbesc($fullname),
dbesc($network),
dbesc(datetime_convert()),
@@ -1493,7 +1518,7 @@ function webfinger_rfc7033($webbie,$zot = false) {
// We could have a number of URL aliases and webbies
// make an executive decision about the most likely "best" of each
// by comparing against some examples from known networks we're likely to encounter.
- // Otherwise we have to store every alias that we may ever encounter and
+ // Otherwise we have to store every alias that we may ever encounter and
// validate every URL we ever find against every possible alias
// @fixme pump.io is going to be a real bugger since it doesn't return subject or aliases
@@ -1564,7 +1589,7 @@ function match_webfinger_location($s,$h) {
return $s;
return '';
}
-
+
@@ -1935,7 +1960,7 @@ function format_and_send_email($sender,$xchan,$item) {
));
$sender_name = t('Administrator');
-
+
$hostname = App::get_hostname();
if(strpos($hostname,':'))
$hostname = substr($hostname,0,strpos($hostname,':'));
@@ -1964,7 +1989,7 @@ function do_delivery($deliveries) {
if(! (is_array($deliveries) && count($deliveries)))
return;
- $interval = ((get_config('system','delivery_interval') !== false)
+ $interval = ((get_config('system','delivery_interval') !== false)
? intval(get_config('system','delivery_interval')) : 2 );
$deliveries_per_process = intval(get_config('system','delivery_batch_count'));
@@ -1993,7 +2018,7 @@ function do_delivery($deliveries) {
if($deliver)
Zotlabs\Daemon\Master::Summon(array('Deliver',$deliver));
-
+
}
@@ -2002,7 +2027,7 @@ function get_site_info() {
$register_policy = Array('REGISTER_CLOSED', 'REGISTER_APPROVE', 'REGISTER_OPEN');
$directory_mode = Array('DIRECTORY_MODE_NORMAL', 'DIRECTORY_MODE_PRIMARY', 'DIRECTORY_MODE_SECONDARY', 256 => 'DIRECTORY_MODE_STANDALONE');
-
+
$sql_extra = '';
$r = q("select * from channel left join account on account_id = channel_account_id where ( account_roles & 4096 )>0 and account_default_channel = channel_id");
@@ -2053,7 +2078,7 @@ function get_site_info() {
else {
$version = $commit = '';
}
-
+
//Statistics
$channels_total_stat = intval(get_config('system','channels_total_stat'));
$channels_active_halfyear_stat = intval(get_config('system','channels_active_halfyear_stat'));
@@ -2073,7 +2098,7 @@ function get_site_info() {
}
-
+
$data = Array(
'version' => $version,
'version_tag' => $tag,
@@ -2190,7 +2215,7 @@ function deliverable_singleton($channel_id,$xchan) {
function get_repository_version($branch = 'master') {
$path = "https://raw.githubusercontent.com/redmatrix/hubzilla/$branch/boot.php";
-
+
$x = z_fetch_url($path);
if($x['success']) {
$y = preg_match('/define(.*?)STD_VERSION(.*?)([0-9.].*)\'/',$x['body'],$matches);
@@ -2199,7 +2224,7 @@ function get_repository_version($branch = 'master') {
}
return '?.?';
-}
+}
function network_to_name($s) {
@@ -2266,11 +2291,11 @@ function z_mail($params) {
call_hooks('email_send', $params);
if($params['sent']) {
- logger('notification: z_mail returns ' . $params['result'], LOGGER_DEBUG);
+ logger('notification: z_mail returns ' . (($params['result']) ? 'success' : 'failure'), LOGGER_DEBUG);
return $params['result'];
}
- $fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8');
+ $fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8');
$messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8');
$messageHeader =
@@ -2285,6 +2310,25 @@ function z_mail($params) {
$params['textVersion'],
$messageHeader // message headers
);
- logger('notification: z_mail returns ' . $res, LOGGER_DEBUG);
+ logger('notification: z_mail returns ' . (($res) ? 'success' : 'failure'), LOGGER_DEBUG);
return $res;
}
+
+// discover the best API path available for redmatrix/hubzilla servers
+
+function probe_api_path($host) {
+
+ $schemes = ['https', 'http' ];
+ $paths = ['/api/z/1.0/version', '/api/red/version' ];
+
+ foreach($schemes as $scheme) {
+ foreach($paths as $path) {
+ $curpath = $scheme . '://' . $host . $path;
+ $x = z_fetch_url($curpath);
+ if($x['success'] && ! strlen($x['body'],'not implemented'))
+ return str_replace('version','',$curpath);
+ }
+ }
+
+ return '';
+}
diff --git a/include/oembed.php b/include/oembed.php
index 1780e7046..eb7b76437 100755
--- a/include/oembed.php
+++ b/include/oembed.php
@@ -137,10 +137,6 @@ function oembed_fetch_url($embedurl){
if($action !== 'block') {
$txt = Zlib\Cache::get('[' . App::$videowidth . '] ' . $embedurl);
-
- if(strstr($txt,'youtu') && strstr(z_root(),'https:')) {
- $txt = str_replace('http:','https:',$txt);
- }
}
if(is_null($txt)) {
@@ -272,13 +268,7 @@ function oembed_format_object($j){
$th=120; $tw = $th*$tr;
$tpl=get_markup_template('oembed_video.tpl');
- if(strstr($embedurl,'youtu') && strstr(z_root(),'https:')) {
- $embedurl = str_replace('http:','https:',$embedurl);
- $j['thumbnail_url'] = str_replace('http:','https:', $j['thumbnail_url']);
- $jhtml = str_replace('http:','https:', $jhtml);
- $j['html'] = str_replace('http:','https:', $j['html']);
-
- }
+
$ret.=replace_macros($tpl, array(
'$baseurl' => z_root(),
'$embedurl'=>$embedurl,
@@ -348,7 +338,7 @@ function oembed_iframe($src,$width,$height) {
// Make sure any children are sandboxed within their own iframe.
- return '<iframe ' . $scroll . 'height="' . $height . '" width="' . $width . '" src="' . $s . '" frameborder="no" >'
+ return '<iframe ' . $scroll . 'height="' . $height . '" width="' . $width . '" src="' . $s . '" allowfullscreen frameborder="no" >'
. t('Embedded content') . '</iframe>';
}
diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php
index 9b6d38cc1..af4fd0a30 100644
--- a/include/photo/photo_driver.php
+++ b/include/photo/photo_driver.php
@@ -340,31 +340,31 @@ abstract class photo_driver {
intval($p['imgscale'])
);
if($x) {
- $r = q("UPDATE `photo` set
- `aid` = %d,
- `uid` = %d,
- `xchan` = '%s',
- `resource_id` = '%s',
- `created` = '%s',
- `edited` = '%s',
- `filename` = '%s',
- `mimetype` = '%s',
- `album` = '%s',
- `height` = %d,
- `width` = %d,
- `content` = '%s',
- `os_storage` = %d,
- `filesize` = %d,
- `imgscale` = %d,
- `photo_usage` = %d,
- `title` = '%s',
- `description` = '%s',
- `os_path` = '%s',
- `display_path` = '%s',
- `allow_cid` = '%s',
- `allow_gid` = '%s',
- `deny_cid` = '%s',
- `deny_gid` = '%s'
+ $r = q("UPDATE photo set
+ aid = %d,
+ uid = %d,
+ xchan = '%s',
+ resource_id = '%s',
+ created = '%s',
+ edited = '%s',
+ filename = '%s',
+ mimetype = '%s',
+ album = '%s',
+ height = %d,
+ width = %d,
+ content = '%s',
+ os_storage = %d,
+ filesize = %d,
+ imgscale = %d,
+ photo_usage = %d,
+ title = '%s',
+ description = '%s',
+ os_path = '%s',
+ display_path = '%s',
+ allow_cid = '%s',
+ allow_gid = '%s',
+ deny_cid = '%s',
+ deny_gid = '%s'
where id = %d",
intval($p['aid']),
@@ -378,7 +378,7 @@ abstract class photo_driver {
dbesc($p['album']),
intval($this->getHeight()),
intval($this->getWidth()),
- (intval($p['os_storage']) ? dbesc($p['os_path']) : dbescbin($this->imageString())),
+ (intval($p['os_storage']) ? dbescbin($p['os_path']) : dbescbin($this->imageString())),
intval($p['os_storage']),
intval(strlen($this->imageString())),
intval($p['imgscale']),
@@ -395,8 +395,8 @@ abstract class photo_driver {
);
}
else {
- $r = q("INSERT INTO `photo`
- ( `aid`, `uid`, `xchan`, `resource_id`, `created`, `edited`, `filename`, mimetype, `album`, `height`, `width`, `content`, `os_storage`, `filesize`, `imgscale`, `photo_usage`, `title`, `description`, `os_path`, `display_path`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` )
+ $r = q("INSERT INTO photo
+ ( aid, uid, xchan, resource_id, created, edited, filename, mimetype, album, height, width, content, os_storage, filesize, imgscale, photo_usage, title, description, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid )
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )",
intval($p['aid']),
intval($p['uid']),
@@ -409,7 +409,7 @@ abstract class photo_driver {
dbesc($p['album']),
intval($this->getHeight()),
intval($this->getWidth()),
- (intval($p['os_storage']) ? dbesc($p['os_path']) : dbescbin($this->imageString())),
+ (intval($p['os_storage']) ? dbescbin($p['os_path']) : dbescbin($this->imageString())),
intval($p['os_storage']),
intval(strlen($this->imageString())),
intval($p['imgscale']),
@@ -432,33 +432,33 @@ abstract class photo_driver {
public function store($aid, $uid, $xchan, $rid, $filename, $album, $scale, $usage = PHOTO_NORMAL, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') {
- $x = q("select id from photo where `resource_id` = '%s' and uid = %d and `xchan` = '%s' and `imgscale` = %d limit 1",
+ $x = q("select id from photo where resource_id = '%s' and uid = %d and xchan = '%s' and imgscale = %d limit 1",
dbesc($rid),
intval($uid),
dbesc($xchan),
intval($scale)
);
if(count($x)) {
- $r = q("UPDATE `photo`
- set `aid` = %d,
- `uid` = %d,
- `xchan` = '%s',
- `resource_id` = '%s',
- `created` = '%s',
- `edited` = '%s',
- `filename` = '%s',
- `mimetype` = '%s',
- `album` = '%s',
- `height` = %d,
- `width` = %d,
- `content` = '%s',
- `filesize` = %d,
- `imgscale` = %d,
- `photo_usage` = %d,
- `allow_cid` = '%s',
- `allow_gid` = '%s',
- `deny_cid` = '%s',
- `deny_gid` = '%s'
+ $r = q("UPDATE photo
+ set aid = %d,
+ uid = %d,
+ xchan = '%s',
+ resource_id = '%s',
+ created = '%s',
+ edited = '%s',
+ filename = '%s',
+ mimetype = '%s',
+ album = '%s',
+ height = %d,
+ width = %d,
+ content = '%s',
+ filesize = %d,
+ imgscale = %d,
+ photo_usage = %d,
+ allow_cid = '%s',
+ allow_gid = '%s',
+ deny_cid = '%s',
+ deny_gid = '%s'
where id = %d",
intval($aid),
@@ -484,8 +484,8 @@ abstract class photo_driver {
);
}
else {
- $r = q("INSERT INTO `photo`
- ( `aid`, `uid`, `xchan`, `resource_id`, `created`, `edited`, `filename`, mimetype, `album`, `height`, `width`, `content`, `filesize`, `imgscale`, `photo_usage`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` )
+ $r = q("INSERT INTO photo
+ ( aid, uid, xchan, resource_id, created, edited, filename, mimetype, album, height, width, content, filesize, imgscale, photo_usage, allow_cid, allow_gid, deny_cid, deny_gid )
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s' )",
intval($aid),
intval($uid),
diff --git a/include/photos.php b/include/photos.php
index a3018816c..5e4d755e3 100644
--- a/include/photos.php
+++ b/include/photos.php
@@ -28,7 +28,8 @@ function photo_upload($channel, $observer, $args) {
return $ret;
}
-// call_hooks('photo_upload_begin', $args);
+
+//call_hooks('photo_upload_begin', $args);
/*
* Determine the album to use
@@ -45,7 +46,7 @@ function photo_upload($channel, $observer, $args) {
if(array_key_exists('deliver',$args))
$deliver = intval($args['deliver']);
- // Set to default channel permissions. If the parent directory (album) has permissions set,
+ // Set to default channel permissions. If the parent directory (album) has permissions set,
// use those instead. If we have specific permissions supplied, they take precedence over
// all other settings. 'allow_cid' being passed from an external source takes priority over channel settings.
// ...messy... needs re-factoring once the photos/files integration stabilises
@@ -55,9 +56,9 @@ function photo_upload($channel, $observer, $args) {
$acl->set($args['directory']);
if(array_key_exists('allow_cid',$args))
$acl->set($args);
- if( (array_key_exists('group_allow',$args))
- || (array_key_exists('contact_allow',$args))
- || (array_key_exists('group_deny',$args))
+ if( (array_key_exists('group_allow',$args))
+ || (array_key_exists('contact_allow',$args))
+ || (array_key_exists('group_deny',$args))
|| (array_key_exists('contact_deny',$args))) {
$acl->set_from_array($args);
}
@@ -103,7 +104,7 @@ function photo_upload($channel, $observer, $args) {
$type = $_FILES['userfile']['type'];
}
- if (! $type)
+ if (! $type)
$type=guess_image_type($filename);
logger('photo_upload: received file: ' . $filename . ' as ' . $src . ' ('. $type . ') ' . $filesize . ' bytes', LOGGER_DEBUG);
@@ -176,7 +177,7 @@ function photo_upload($channel, $observer, $args) {
$errors = false;
$p = array('aid' => $account_id, 'uid' => $channel_id, 'xchan' => $visitor, 'resource_id' => $photo_hash,
- 'filename' => $filename, 'album' => $album, 'imgscale' => 0, 'photo_usage' => PHOTO_NORMAL,
+ 'filename' => $filename, 'album' => $album, 'imgscale' => 0, 'photo_usage' => PHOTO_NORMAL,
'allow_cid' => $ac['allow_cid'], 'allow_gid' => $ac['allow_gid'],
'deny_cid' => $ac['deny_cid'], 'deny_gid' => $ac['deny_gid'],
'os_storage' => $os_storage, 'os_path' => $args['os_path']
@@ -220,8 +221,8 @@ function photo_upload($channel, $observer, $args) {
);
if(! $r1)
$errors = true;
-
- if(($width > 640 || $height > 640) && (! $errors))
+
+ if(($width > 640 || $height > 640) && (! $errors))
$ph->scaleImage(640);
$p['imgscale'] = 2;
@@ -236,7 +237,7 @@ function photo_upload($channel, $observer, $args) {
if(! $r2)
$errors = true;
- if(($width > 320 || $height > 320) && (! $errors))
+ if(($width > 320 || $height > 320) && (! $errors))
$ph->scaleImage(320);
$p['imgscale'] = 3;
@@ -304,8 +305,8 @@ function photo_upload($channel, $observer, $args) {
$summary = (($args['body']) ? $args['body'] : '') . '[footer]' . $activity_format . '[/footer]';
- $obj_body = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']'
- . $tag . z_root() . "/photo/{$photo_hash}-{$scale}." . $ph->getExt() . '[/zmg]'
+ $obj_body = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']'
+ . $tag . z_root() . "/photo/{$photo_hash}-{$scale}." . $ph->getExt() . '[/zmg]'
. '[/zrl]';
// Create item object
@@ -361,7 +362,7 @@ function photo_upload($channel, $observer, $args) {
$item['uid'] = $channel['channel_id'];
item_store_update($item,false,$deliver);
continue;
- }
+ }
}
else {
$item['aid'] = $channel['channel_account_id'];
@@ -381,7 +382,7 @@ function photo_upload($channel, $observer, $args) {
$arr['aid'] = $account_id;
$arr['uid'] = $channel_id;
$arr['mid'] = $mid;
- $arr['parent_mid'] = $mid;
+ $arr['parent_mid'] = $mid;
$arr['item_hidden'] = $item_hidden;
$arr['resource_type'] = 'photo';
$arr['resource_id'] = $photo_hash;
@@ -407,10 +408,10 @@ function photo_upload($channel, $observer, $args) {
// this one is tricky because the item and the photo have the same permissions, those of the photo.
// Use the channel read_stream permissions to get the correct public_policy for the item and recalculate the
- // private flag accordingly. This may cause subtle bugs due to custom permissions roles. We want to use
+ // private flag accordingly. This may cause subtle bugs due to custom permissions roles. We want to use
// public policy when federating items to other sites, but should probably ignore them when accessing the item
// in the photos pages - using the photos permissions instead. We need the public policy to keep the photo
- // linked item from leaking into the feed when somebody has a channel with read_stream restrictions.
+ // linked item from leaking into the feed when somebody has a channel with read_stream restrictions.
$arr['public_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_stream'),true);
if($arr['public_policy'])
@@ -421,7 +422,7 @@ function photo_upload($channel, $observer, $args) {
$result = item_store($arr,false,$deliver);
$item_id = $result['item_id'];
- if($visible && $deliver)
+ if($visible && $deliver)
Zotlabs\Daemon\Master::Summon(array('Notifier', 'wall-new', $item_id));
}
@@ -443,9 +444,12 @@ function photo_upload($channel, $observer, $args) {
*
* @param array $channel
* @param array $observer
+ * @param array $sort_key (optional) default album
+ * @param array $direction (optional) default asc
+ *
* @return bool|array false if no view_storage permission or an array
- * * success (bool)
- * * albums (array)
+ * * \e boolean \b success
+ * * \e array \b albums
*/
function photos_albums_list($channel, $observer, $sort_key = 'album', $direction = 'asc') {
@@ -455,14 +459,11 @@ function photos_albums_list($channel, $observer, $sort_key = 'album', $direction
if(! perm_is_allowed($channel_id, $observer_xchan, 'view_storage'))
return false;
-
$sql_extra = permissions_sql($channel_id,$observer_xchan);
$sort_key = dbesc($sort_key);
$direction = dbesc($direction);
-
-
$albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and photo_usage IN ( %d, %d ) $sql_extra group by album order by $sort_key $direction",
intval($channel_id),
intval(PHOTO_NORMAL),
@@ -479,8 +480,8 @@ function photos_albums_list($channel, $observer, $sort_key = 'album', $direction
foreach($albums as $k => $album) {
$entry = array(
'text' => (($album['album']) ? $album['album'] : '/'),
- 'total' => $album['total'],
- 'url' => z_root() . '/photos/' . $channel['channel_address'] . '/album/' . bin2hex($album['album']),
+ 'total' => $album['total'],
+ 'url' => z_root() . '/photos/' . $channel['channel_address'] . '/album/' . bin2hex($album['album']),
'urlencode' => urlencode($album['album']),
'bin2hex' => bin2hex($album['album'])
);
@@ -506,7 +507,7 @@ function photos_album_widget($channelx,$observer,$sortkey = 'album',$direction =
'$title' => t('Photo Albums'),
'$albums' => $albums['albums'],
'$baseurl' => z_root(),
- '$upload' => ((perm_is_allowed($channelx['channel_id'],(($observer) ? $observer['xchan_hash'] : ''),'write_storage'))
+ '$upload' => ((perm_is_allowed($channelx['channel_id'],(($observer) ? $observer['xchan_hash'] : ''),'write_storage'))
? t('Upload New Photos') : '')
));
}
@@ -533,7 +534,7 @@ function photos_list_photos($channel, $observer, $album = '') {
$sql_extra = permissions_sql($channel_id);
if($album)
- $sql_extra .= " and album = '" . protect_sprintf(dbesc($album)) . "' ";
+ $sql_extra .= " and album = '" . protect_sprintf(dbesc($album)) . "' ";
$ret = array('success' => false);
@@ -647,7 +648,7 @@ function photos_create_item($channel, $creator_hash, $photo, $visible = false) {
$arr['aid'] = $channel['channel_account_id'];
$arr['uid'] = $channel['channel_id'];
$arr['mid'] = $mid;
- $arr['parent_mid'] = $mid;
+ $arr['parent_mid'] = $mid;
$arr['item_wall'] = 1;
$arr['item_origin'] = 1;
$arr['item_thread_top'] = 1;
@@ -663,9 +664,9 @@ function photos_create_item($channel, $creator_hash, $photo, $visible = false) {
$arr['deny_gid'] = $photo['deny_gid'];
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
-
- $arr['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']'
- . '[zmg]' . z_root() . '/photo/' . $photo['resource_id'] . '-' . $photo['imgscale'] . '[/zmg]'
+
+ $arr['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']'
+ . '[zmg]' . z_root() . '/photo/' . $photo['resource_id'] . '-' . $photo['imgscale'] . '[/zmg]'
. '[/zrl]';
$result = item_store($arr);
@@ -710,39 +711,39 @@ function gps2Num($coordPart) {
}
function profile_photo_set_profile_perms($uid, $profileid = 0) {
-
+
$allowcid = '';
if($profileid) {
$r = q("SELECT photo, profile_guid, id, is_default, uid
- FROM profile WHERE uid = %d and ( profile.id = %d OR profile.profile_guid = '%s') LIMIT 1",
+ FROM profile WHERE uid = %d and ( profile.id = %d OR profile.profile_guid = '%s') LIMIT 1",
intval($uid),
- intval($profileid),
+ intval($profileid),
dbesc($profileid)
);
- }
+ }
else {
logger('Resetting permissions on default-profile-photo for user'.local_channel());
- $r = q("SELECT photo, profile_guid, id, is_default, uid FROM profile
- WHERE profile.uid = %d AND is_default = 1 LIMIT 1",
- intval($uid)
+ $r = q("SELECT photo, profile_guid, id, is_default, uid FROM profile
+ WHERE profile.uid = %d AND is_default = 1 LIMIT 1",
+ intval($uid)
); //If no profile is given, we update the default profile
}
if(! $r)
return;
-
+
$profile = $r[0];
- if($profile['id'] && $profile['photo']) {
+ if($profile['id'] && $profile['photo']) {
preg_match("@\w*(?=-\d*$)@i", $profile['photo'], $resource_id);
$resource_id = $resource_id[0];
-
+
if (! intval($profile['is_default'])) {
- $r0 = q("SELECT channel_hash FROM channel WHERE channel_id = %d LIMIT 1",
- intval($uid)
+ $r0 = q("SELECT channel_hash FROM channel WHERE channel_id = %d LIMIT 1",
+ intval($uid)
);
//Should not be needed in future. Catches old int-profile-ids.
- $r1 = q("SELECT abook.abook_xchan FROM abook WHERE abook_profile = '%d' ",
+ $r1 = q("SELECT abook.abook_xchan FROM abook WHERE abook_profile = '%d' ",
intval($profile['id'])
);
$r2 = q("SELECT abook.abook_xchan FROM abook WHERE abook_profile = '%s'",
@@ -750,27 +751,27 @@ function profile_photo_set_profile_perms($uid, $profileid = 0) {
);
$allowcid = "<" . $r0[0]['channel_hash'] . ">";
foreach ($r1 as $entry) {
- $allowcid .= "<" . $entry['abook_xchan'] . ">";
+ $allowcid .= "<" . $entry['abook_xchan'] . ">";
}
foreach ($r2 as $entry) {
$allowcid .= "<" . $entry['abook_xchan'] . ">";
}
-
+
q("UPDATE photo SET allow_cid = '%s' WHERE resource_id = '%s' AND uid = %d",
dbesc($allowcid),
dbesc($resource_id),
intval($uid)
);
-
- }
+
+ }
else {
//Reset permissions on default profile picture to public
q("UPDATE photo SET allow_cid = '' WHERE photo_usage = %d AND uid = %d",
intval(PHOTO_PROFILE),
intval($uid)
- );
+ );
}
}
-
+
return;
}
diff --git a/include/plugin.php b/include/plugin.php
index 663d17959..80c303b42 100755
--- a/include/plugin.php
+++ b/include/plugin.php
@@ -41,7 +41,7 @@ function uninstall_plugin($plugin) {
$func();
}
- q("DELETE FROM `addon` WHERE `aname` = '%s' ",
+ q("DELETE FROM addon WHERE aname = '%s' ",
dbesc($plugin)
);
}
@@ -66,7 +66,7 @@ function install_plugin($plugin) {
$plugin_admin = (function_exists($plugin . '_plugin_admin') ? 1 : 0);
- q("INSERT INTO `addon` (`aname`, `installed`, `tstamp`, `plugin_admin`) VALUES ( '%s', 1, %d , %d ) ",
+ q("INSERT INTO addon (aname, installed, tstamp, plugin_admin) VALUES ( '%s', 1, %d , %d ) ",
dbesc($plugin),
intval($t),
$plugin_admin
@@ -126,7 +126,7 @@ function plugin_is_installed($name) {
function reload_plugins() {
$plugins = get_config('system', 'addon');
if(strlen($plugins)) {
- $r = q("SELECT * FROM `addon` WHERE `installed` = 1");
+ $r = q("SELECT * FROM addon WHERE installed = 1");
if(count($r))
$installed = $r;
else
@@ -143,7 +143,7 @@ function reload_plugins() {
if(file_exists($fname)) {
$t = @filemtime($fname);
foreach($installed as $i) {
- if(($i['aname'] == $pl) && ($i['tstamp'] != $t)) {
+ if(($i['aname'] == $pl) && ($i['tstamp'] != $t)) {
logger('Reloading plugin: ' . $i['aname']);
@include_once($fname);
@@ -155,7 +155,7 @@ function reload_plugins() {
$func = $pl . '_load';
$func();
}
- q("UPDATE `addon` SET `tstamp` = %d WHERE `id` = %d",
+ q("UPDATE addon SET tstamp = %d WHERE id = %d",
intval($t),
intval($i['id'])
);
@@ -184,7 +184,7 @@ function visible_plugin_list() {
* @return mixed|bool
*/
function register_hook($hook, $file, $function, $priority = 0) {
- $r = q("SELECT * FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `fn` = '%s' LIMIT 1",
+ $r = q("SELECT * FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s' LIMIT 1",
dbesc($hook),
dbesc($file),
dbesc($function)
@@ -192,7 +192,7 @@ function register_hook($hook, $file, $function, $priority = 0) {
if($r)
return true;
- $r = q("INSERT INTO `hook` (`hook`, `file`, `fn`, `priority`) VALUES ( '%s', '%s', '%s', '%s' )",
+ $r = q("INSERT INTO hook (hook, file, fn, priority) VALUES ( '%s', '%s', '%s', '%s' )",
dbesc($hook),
dbesc($file),
dbesc($function),
@@ -205,14 +205,14 @@ function register_hook($hook, $file, $function, $priority = 0) {
/**
* @brief unregisters a hook.
- *
+ *
* @param string $hook the name of the hook
* @param string $file the name of the file that hooks into
* @param string $function the name of the function that the hook called
* @return array
*/
function unregister_hook($hook, $file, $function) {
- $r = q("DELETE FROM hook WHERE hook = '%s' AND `file` = '%s' AND `fn` = '%s'",
+ $r = q("DELETE FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s'",
dbesc($hook),
dbesc($file),
dbesc($function)
@@ -224,7 +224,7 @@ function unregister_hook($hook, $file, $function) {
//
// It might not be obvious but themes can manually add hooks to the App::$hooks
-// 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.
// UPDATE: use insert_hook($hookname,$function_name) to do this
//
@@ -248,20 +248,22 @@ function load_hooks() {
/**
* @brief Inserts a hook into a page request.
*
- * Insert a short-lived hook into the running page request.
- * Hooks are normally persistent so that they can be called
+ * Insert a short-lived hook into the running page request.
+ * Hooks are normally persistent so that they can be called
* across asynchronous processes such as delivery and poll
* processes.
*
* insert_hook lets you attach a hook callback immediately
* which will not persist beyond the life of this page request
- * or the current process.
+ * or the current process.
*
* @param string $hook
* name of hook to attach callback
* @param string $fn
* function name of callback handler
- */
+ * @param int $version (optional) default 0
+ * @param int $priority (optional) default 0
+ */
function insert_hook($hook, $fn, $version = 0, $priority = 0) {
if(! is_array(App::$hooks))
@@ -293,7 +295,7 @@ function call_hooks($name, &$data = null) {
$hook[1] = unserialize($hook[1]);
}
elseif(strpos($hook[1],'::')) {
- // We shouldn't need to do this, but it appears that PHP
+ // We shouldn't need to do this, but it appears that PHP
// isn't able to directly execute a string variable with a class
// method in the manner we are attempting it, so we'll
// turn it into an array.
@@ -306,10 +308,10 @@ function call_hooks($name, &$data = null) {
$func($data);
else
$func($a, $data);
- }
+ }
else {
- // Don't do any DB write calls if we're currently logging a possibly failed DB call.
+ // Don't do any DB write calls if we're currently logging a possibly failed DB call.
if(! DBA::$logging) {
// The hook should be removed so we don't process it.
q("DELETE FROM hook WHERE hook = '%s' AND file = '%s' AND fn = '%s'",
@@ -370,7 +372,7 @@ function get_plugin_info($plugin){
} else {
$info[$k][] = array('name' => $v);
}
- }
+ }
else {
$info[$k] = $v;
}
@@ -407,8 +409,8 @@ function check_plugin_versions($info) {
if(array_key_exists('serverroles',$info)) {
$role = \Zotlabs\Lib\System::get_server_role();
if(! (
- stristr($info['serverroles'],'*')
- || stristr($info['serverroles'],'any')
+ stristr($info['serverroles'],'*')
+ || stristr($info['serverroles'],'any')
|| stristr($info['serverroles'],$role))) {
logger('serverrole limit: ' . $info['name'],LOGGER_NORMAL,LOG_WARNING);
return false;
@@ -425,8 +427,15 @@ function check_plugin_versions($info) {
$test = trim($test);
if(! $test)
continue;
+ if(strpos($test,'.')) {
+ $conf = explode('.',$test);
+ if(get_config(trim($conf[0]),trim($conf[1])))
+ return true;
+ else
+ return false;
+ }
if(! in_array($test,App::$plugins))
- $found = false;
+ $found = false;
}
}
if(! $found)
@@ -583,11 +592,11 @@ function format_css_if_exists($source) {
/*
* This basically calculates the baseurl. We have other functions to do that, but
- * there was an issue with script paths and mixed-content whose details are arcane
- * and perhaps lost in the message archives. The short answer is that we're ignoring
- * the URL which we are "supposed" to use, and generating script paths relative to
+ * there was an issue with script paths and mixed-content whose details are arcane
+ * and perhaps lost in the message archives. The short answer is that we're ignoring
+ * the URL which we are "supposed" to use, and generating script paths relative to
* the URL which we are currently using; in order to ensure they are found and aren't
- * blocked due to mixed content issues.
+ * blocked due to mixed content issues.
*/
function script_path() {
@@ -599,7 +608,7 @@ function script_path() {
$scheme = 'https';
else
$scheme = 'http';
-
+
// Some proxy setups may require using http_host
if(intval(App::$config['system']['script_path_use_http_host']))
@@ -631,7 +640,7 @@ function head_remove_js($src, $priority = 0) {
}
// We should probably try to register main.js with a high priority, but currently we handle it
-// separately and put it at the end of the html head block in case any other javascript is
+// separately and put it at the end of the html head block in case any other javascript is
// added outside the head_add_js construct.
function head_get_js() {
@@ -640,7 +649,7 @@ function head_get_js() {
if(App::$js_sources) {
ksort(App::$js_sources,SORT_NUMERIC);
foreach(App::$js_sources as $sources) {
- if(count($sources)) {
+ if(count($sources)) {
foreach($sources as $source) {
if($src === 'main.js')
continue;
@@ -655,7 +664,7 @@ function head_get_js() {
function head_get_main_js() {
$str = '';
$sources = array('main.js');
- if(count($sources))
+ if(count($sources))
foreach($sources as $source)
$str .= format_js_if_exists($source,true);
return $str;
diff --git a/include/queue_fn.php b/include/queue_fn.php
index 676620e2f..0950faf85 100644
--- a/include/queue_fn.php
+++ b/include/queue_fn.php
@@ -93,7 +93,7 @@ function queue_deliver($outq, $immediate = false) {
// your site has existed. Since we don't know for sure what these sites are,
// call them unknown
- q("insert into site (site_url, site_update, site_dead, site_type) values ('%s','%s',0,%d) ",
+ q("insert into site (site_url, site_update, site_dead, site_type, site_crypto) values ('%s','%s',0,%d,'') ",
dbesc($base),
dbesc(datetime_convert()),
intval(($outq['outq_driver'] === 'post') ? SITE_TYPE_NOTZOT : SITE_TYPE_UNKNOWN)
@@ -118,7 +118,7 @@ function queue_deliver($outq, $immediate = false) {
dbesc($base)
);
}
- q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s' limit 1",
+ q("update dreport set dreport_result = '%s', dreport_time = '%s' where dreport_queue = '%s'",
dbesc('accepted for delivery'),
dbesc(datetime_convert()),
dbesc($outq['outq_hash'])
diff --git a/include/security.php b/include/security.php
index 9b508d339..2f5de54c7 100644
--- a/include/security.php
+++ b/include/security.php
@@ -2,11 +2,12 @@
/**
* @file include/security.php
*
- * Some security related functions.
+ * @brief Some security related functions.
*/
/**
* @param int $user_record The account_id
+ * @param array $channel
* @param bool $login_initial default false
* @param bool $interactive default false
* @param bool $return
@@ -27,8 +28,8 @@ function authenticate_success($user_record, $channel = null, $login_initial = fa
$uid_to_load = $channel['channel_id'];
if(! $uid_to_load) {
- $uid_to_load = (((x($_SESSION,'uid')) && (intval($_SESSION['uid'])))
- ? intval($_SESSION['uid'])
+ $uid_to_load = (((x($_SESSION,'uid')) && (intval($_SESSION['uid'])))
+ ? intval($_SESSION['uid'])
: intval(App::$account['account_default_channel'])
);
}
@@ -89,21 +90,28 @@ function authenticate_success($user_record, $channel = null, $login_initial = fa
function atoken_login($atoken) {
if(! $atoken)
return false;
+
$_SESSION['authenticated'] = 1;
$_SESSION['visitor_id'] = $atoken['xchan_hash'];
$_SESSION['atoken'] = $atoken['atoken_id'];
\App::set_observer($atoken);
+
return true;
}
-
+/**
+ * @brief
+ *
+ * @param array $atoken
+ * @return array|null
+ */
function atoken_xchan($atoken) {
$c = channelx_by_n($atoken['atoken_uid']);
if($c) {
return [
- 'atoken_id' => $atoken['atoken_id'],
+ 'atoken_id' => $atoken['atoken_id'],
'xchan_hash' => substr($c['channel_hash'],0,16) . '.' . $atoken['atoken_name'],
'xchan_name' => $atoken['atoken_name'],
'xchan_addr' => t('guest:') . $atoken['atoken_name'] . '@' . \App::get_hostname(),
@@ -114,9 +122,9 @@ function atoken_xchan($atoken) {
'xchan_photo_l' => get_default_profile_photo(300),
'xchan_photo_m' => get_default_profile_photo(80),
'xchan_photo_s' => get_default_profile_photo(48)
-
];
}
+
return null;
}
@@ -133,7 +141,7 @@ function atoken_delete($atoken_id) {
);
if(! $c)
return;
-
+
$atoken_xchan = substr($c[0]['channel_hash'],0,16) . '.' . $r[0]['atoken_name'];
q("delete from atoken where atoken_id = %d",
@@ -145,12 +153,16 @@ function atoken_delete($atoken_id) {
);
}
-
-
-// in order for atoken logins to create content (such as posts) they need a stored xchan.
-// we'll create one on the first atoken_login; it can't really ever go away but perhaps
-// @fixme we should set xchan_deleted if it's expired or removed
-
+/**
+ * @brief
+ *
+ * In order for atoken logins to create content (such as posts) they need a stored xchan.
+ * we'll create one on the first atoken_login; it can't really ever go away but perhaps
+ * @fixme we should set xchan_deleted if it's expired or removed
+ *
+ * @param array $xchan
+ * @return void|boolean
+ */
function atoken_create_xchan($xchan) {
$r = q("select xchan_hash from xchan where xchan_hash = '%s'",
@@ -159,7 +171,7 @@ function atoken_create_xchan($xchan) {
if($r)
return;
- $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_photo_mimetype, xchan_photo_l, xchan_photo_m, xchan_photo_s )
+ $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_photo_mimetype, xchan_photo_l, xchan_photo_m, xchan_photo_s )
values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
dbesc($xchan['xchan_hash']),
dbesc($xchan['xchan_hash']),
@@ -202,12 +214,11 @@ function atoken_abook($uid,$xchan_hash) {
}
return false;
-
}
function pseudo_abook($xchan) {
- if(! $xchan)
+ if(! $xchan)
return false;
// set abook_pseudo to flag that we aren't really connected.
@@ -216,8 +227,8 @@ function pseudo_abook($xchan) {
$xchan['abook_blocked'] = 0;
$xchan['abook_ignored'] = 0;
$xchan['abook_pending'] = 0;
+
return $xchan;
-
}
@@ -228,7 +239,6 @@ function pseudo_abook($xchan) {
*
* @return bool|array false or channel record of the new channel
*/
-
function change_channel($change_channel) {
$ret = false;
@@ -260,7 +270,7 @@ function change_channel($change_channel) {
date_default_timezone_set($r[0]['channel_timezone']);
$ret = $r[0];
}
- $x = q("select * from xchan where xchan_hash = '%s' limit 1",
+ $x = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($hash)
);
if($x) {
@@ -275,7 +285,6 @@ function change_channel($change_channel) {
$arr = [ 'channel_id' => $change_channel, 'chanx' => $ret ];
call_hooks('change_channel', $arr);
-
}
return $ret;
@@ -285,11 +294,11 @@ function change_channel($change_channel) {
* @brief Creates an additional SQL where statement to check permissions.
*
* @param int $owner_id
- * @param bool $remote_observer - if unset use current observer
+ * @param bool $remote_observer (optional) use current observer if unset
+ * @param $table (optional)
*
* @return string additional SQL where statement
*/
-
function permissions_sql($owner_id, $remote_observer = null, $table = '') {
$local_channel = local_channel();
@@ -303,11 +312,10 @@ function permissions_sql($owner_id, $remote_observer = null, $table = '') {
if($table)
$table .= '.';
-
- $sql = " AND {$table}allow_cid = ''
- AND {$table}allow_gid = ''
- AND {$table}deny_cid = ''
- AND {$table}deny_gid = ''
+ $sql = " AND {$table}allow_cid = ''
+ AND {$table}allow_gid = ''
+ AND {$table}deny_cid = ''
+ AND {$table}deny_gid = ''
";
/**
@@ -319,7 +327,7 @@ function permissions_sql($owner_id, $remote_observer = null, $table = '') {
}
/**
- * Authenticated visitor. Unless pre-verified,
+ * Authenticated visitor. Unless pre-verified,
* check that the contact belongs to this $owner_id
* and load the groups the visitor belongs to.
* If pre-verified, the caller is expected to have already
@@ -358,7 +366,7 @@ function permissions_sql($owner_id, $remote_observer = null, $table = '') {
* @brief Creates an addiontal SQL where statement to check permissions for an item.
*
* @param int $owner_id
- * @param bool $remote_observer, use current observer if unset
+ * @param bool $remote_observer (optional) use current observer if unset
*
* @return string additional SQL where statement
*/
@@ -379,7 +387,7 @@ function item_permissions_sql($owner_id, $remote_observer = null) {
*/
if(($local_channel) && ($local_channel == $owner_id)) {
- $sql = '';
+ $sql = '';
}
/**
@@ -425,7 +433,7 @@ function item_permissions_sql($owner_id, $remote_observer = null) {
/**
* Remote visitors also need to be checked against the public_scope parameter if item_private is set.
* This function checks the various permutations of that field for any which apply to this observer.
- *
+ *
*/
@@ -448,9 +456,9 @@ function scopes_sql($uid,$observer) {
$str .= " or public_policy = 'contacts' ) ";
return $str;
}
-
-
-
+
+
+
@@ -500,7 +508,7 @@ function public_permissions_sql($observer_hash) {
* If the new page contains by any chance external elements, then the used security token is exposed by the referrer.
* Actually, important actions should not be triggered by Links / GET-Requests at all, but somethimes they still are,
* so this mechanism brings in some damage control (the attacker would be able to forge a request to a form of this type, but not to forms of other types).
- */
+ */
function get_form_security_token($typename = '') {
$timestamp = time();
@@ -549,7 +557,7 @@ function check_form_security_token_ForbiddenOnErr($typename = '', $formname = 'f
function init_groups_visitor($contact_id) {
$groups = array();
- $r = q("SELECT hash FROM `groups` left join group_member on groups.id = group_member.gid WHERE xchan = '%s' ",
+ $r = q("SELECT hash FROM groups left join group_member on groups.id = group_member.gid WHERE xchan = '%s' ",
dbesc($contact_id)
);
if($r) {
@@ -561,13 +569,13 @@ function init_groups_visitor($contact_id) {
-// This is used to determine which uid have posts which are visible to the logged in user (from the API) for the
+// This is used to determine which uid have posts which are visible to the logged in user (from the API) for the
// public_timeline, and we can use this in a community page by making
-// $perms = (PERMS_NETWORK|PERMS_PUBLIC) unless logged in.
+// $perms = (PERMS_NETWORK|PERMS_PUBLIC) unless logged in.
// Collect uids of everybody on this site who has opened their posts to everybody on this site (or greater visibility)
// We always include yourself if logged in because you can always see your own posts
// resolving granular permissions for the observer against every person and every post on the site
-// will likely be too expensive.
+// will likely be too expensive.
// Returns a string list of comma separated channel_ids suitable for direct inclusion in a SQL query
function stream_perms_api_uids($perms = NULL, $limit = 0, $rand = 0 ) {
diff --git a/include/selectors.php b/include/selectors.php
index d7d070d31..ab049fff6 100644
--- a/include/selectors.php
+++ b/include/selectors.php
@@ -7,7 +7,7 @@ function contact_profile_assign($current) {
$o .= "<select id=\"contact-profile-selector\" name=\"profile_assign\" class=\"form-control\"/>\r\n";
- $r = q("SELECT profile_guid, profile_name FROM `profile` WHERE `uid` = %d",
+ $r = q("SELECT profile_guid, profile_name FROM profile WHERE uid = %d",
intval($_SESSION['uid']));
if($r) {
diff --git a/include/socgraph.php b/include/socgraph.php
index 4cb5600ec..69365f80f 100644
--- a/include/socgraph.php
+++ b/include/socgraph.php
@@ -245,10 +245,10 @@ function common_friends($uid,$xchan,$start = 0,$limit=100000000,$shuffle = false
function count_common_friends_zcid($uid,$zcid) {
- $r = q("SELECT count(*) as `total`
- FROM `glink` left join `gcontact` on `glink`.`gcid` = `gcontact`.`id`
- where `glink`.`zcid` = %d
- and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 ) ",
+ $r = q("SELECT count(*) as total
+ FROM glink left join gcontact on glink.gcid = gcontact.id
+ where glink.zcid = %d
+ and gcontact.nurl in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 ) ",
intval($zcid),
intval($uid)
);
@@ -264,12 +264,12 @@ function common_friends_zcid($uid,$zcid,$start = 0, $limit = 9999,$shuffle = fal
if($shuffle)
$sql_extra = " order by rand() ";
else
- $sql_extra = " order by `gcontact`.`name` asc ";
+ $sql_extra = " order by gcontact.name asc ";
- $r = q("SELECT `gcontact`.*
- FROM `glink` left join `gcontact` on `glink`.`gcid` = `gcontact`.`id`
- where `glink`.`zcid` = %d
- and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 )
+ $r = q("SELECT gcontact.*
+ FROM glink left join gcontact on glink.gcid = gcontact.id
+ where glink.zcid = %d
+ and gcontact.nurl in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 )
$sql_extra limit %d offset %d",
intval($zcid),
intval($uid),
@@ -283,9 +283,9 @@ function common_friends_zcid($uid,$zcid,$start = 0, $limit = 9999,$shuffle = fal
function count_all_friends($uid,$cid) {
- $r = q("SELECT count(*) as `total`
- FROM `glink` left join `gcontact` on `glink`.`gcid` = `gcontact`.`id`
- where `glink`.`cid` = %d and `glink`.`uid` = %d ",
+ $r = q("SELECT count(*) as total
+ FROM glink left join gcontact on glink.gcid = gcontact.id
+ where glink.cid = %d and glink.uid = %d ",
intval($cid),
intval($uid)
);
@@ -299,10 +299,10 @@ function count_all_friends($uid,$cid) {
function all_friends($uid,$cid,$start = 0, $limit = 80) {
- $r = q("SELECT `gcontact`.*
- FROM `glink` left join `gcontact` on `glink`.`gcid` = `gcontact`.`id`
- where `glink`.`cid` = %d and `glink`.`uid` = %d
- order by `gcontact`.`name` asc LIMIT %d OFFSET %d ",
+ $r = q("SELECT gcontact.*
+ FROM glink left join gcontact on glink.gcid = gcontact.id
+ where glink.cid = %d and glink.uid = %d
+ order by gcontact.name asc LIMIT %d OFFSET %d ",
intval($cid),
intval($uid),
intval($limit),
@@ -319,7 +319,7 @@ function suggestion_query($uid, $myxchan, $start = 0, $limit = 80) {
if((! $uid) || (! $myxchan))
return array();
- $r = q("SELECT count(xlink_xchan) as `total`, xchan.* from xchan
+ $r = q("SELECT count(xlink_xchan) as total, xchan.* from xchan
left join xlink on xlink_link = xchan_hash
where xlink_xchan in ( select abook_xchan from abook where abook_channel = %d )
and not xlink_link in ( select abook_xchan from abook where abook_channel = %d )
@@ -339,7 +339,7 @@ function suggestion_query($uid, $myxchan, $start = 0, $limit = 80) {
if($r && count($r) >= ($limit -1))
return $r;
- $r2 = q("SELECT count(xlink_link) as `total`, xchan.* from xchan
+ $r2 = q("SELECT count(xlink_link) as total, xchan.* from xchan
left join xlink on xlink_link = xchan_hash
where xlink_xchan = ''
and not xlink_link in ( select abook_xchan from abook where abook_channel = %d )
@@ -465,11 +465,11 @@ function poco($a,$extended = false) {
$sql_extra = sprintf(" and abook_id = %d and abook_hidden = 0 ",intval($cid));
if($system_mode) {
- $r = q("SELECT count(*) as `total` from abook where abook_self = 1
+ $r = q("SELECT count(*) as total from abook where abook_self = 1
and abook_channel in (select uid from pconfig where cat = 'system' and k = 'suggestme' and v = '1') ");
}
else {
- $r = q("SELECT count(*) as `total` from abook where abook_channel = %d
+ $r = q("SELECT count(*) as total from abook where abook_channel = %d
$sql_extra ",
intval($channel_id)
);
diff --git a/include/statistics_fns.php b/include/statistics_fns.php
index ce2eee5e7..cbff3b0b7 100644
--- a/include/statistics_fns.php
+++ b/include/statistics_fns.php
@@ -64,7 +64,7 @@ function update_channels_active_monthly_stat() {
}
function update_local_posts_stat() {
- $posts = q("SELECT COUNT(*) AS local_posts FROM `item` WHERE item_wall = 1 ");
+ $posts = q("SELECT COUNT(*) AS local_posts FROM item WHERE item_wall = 1 ");
if (is_array($posts)) {
$local_posts_stat = intval($posts[0]["local_posts"]);
set_config('system','local_posts_stat',$local_posts_stat);
diff --git a/include/taxonomy.php b/include/taxonomy.php
index 067bd3246..0b4b2aa9a 100644
--- a/include/taxonomy.php
+++ b/include/taxonomy.php
@@ -386,7 +386,7 @@ function get_things($profile_hash,$uid) {
$things[$k] = null;
foreach($r as $rr) {
- $l = q("select xchan_name, xchan_photo_s, xchan_url from likes left join xchan on likee = xchan_hash where
+ $l = q("select xchan_name, xchan_photo_s, xchan_url from likes left join xchan on liker = xchan_hash where
target_type = '%s' and target_id = '%s' and channel_id = %d",
dbesc(ACTIVITY_OBJ_THING),
dbesc($rr['obj_obj']),
diff --git a/include/text.php b/include/text.php
index 9c4a4a5c5..b25eb8e46 100644
--- a/include/text.php
+++ b/include/text.php
@@ -4,6 +4,7 @@
*/
require_once("include/bbcode.php");
+require_once('include/hubloc.php');
// random string, there are 86 characters max in text mode, 128 for hex
// output is urlsafe
@@ -17,6 +18,7 @@ define('RANDOM_STRING_TEXT', 0x01 );
* @param string|SmartyEngine $s the string requiring macro substitution,
* or an instance of SmartyEngine
* @param array $r key value pairs (search => replace)
+ *
* @return string substituted string
*/
function replace_macros($s, $r) {
@@ -35,6 +37,7 @@ function replace_macros($s, $r) {
*
* @param number $size
* @param int $type
+ *
* @return string
*/
function random_string($size = 64, $type = RANDOM_STRING_HEX) {
@@ -52,14 +55,15 @@ function random_string($size = 64, $type = RANDOM_STRING_HEX) {
* that had an XSS attack vector due to stripping the high-bit on an 8-bit character
* after cleansing, and angle chars with the high bit set could get through as markup.
*
- * This is now disabled because it was interfering with some legitimate unicode sequences
- * and hopefully there aren't a lot of those browsers left.
+ * This is now disabled because it was interfering with some legitimate unicode sequences
+ * and hopefully there aren't a lot of those browsers left.
*
* Use this on any text input where angle chars are not valid or permitted
* They will be replaced with safer brackets. This may be filtered further
* if these are not allowed either.
*
* @param string $string Input string
+ *
* @return string Filtered string
*/
function notags($string) {
@@ -74,13 +78,13 @@ function notags($string) {
/**
* use this on "body" or "content" input where angle chars shouldn't be removed,
* and allow them to be safely displayed.
+ *
* @param string $string
+ *
* @return string
*/
function escape_tags($string) {
-
return(htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false));
-
}
@@ -182,7 +186,7 @@ function purify_html($s, $allow_position = false) {
// f6 plugins
- //abide - the use is pointless since we can't do anything with forms
+ //abide - the use is pointless since we can't do anything with forms
//equalizer
$def->info_global_attr['data-equalizer'] = new HTMLPurifier_AttrDef_Text;
@@ -272,14 +276,12 @@ function purify_html($s, $allow_position = false) {
}
-
$purifier = new HTMLPurifier($config);
return $purifier->purify($s);
}
-
/**
* @brief generate a string that's random, but usually pronounceable.
*
@@ -293,7 +295,7 @@ function autoname($len) {
if ($len <= 0)
return '';
- $vowels = array('a','a','ai','au','e','e','e','ee','ea','i','ie','o','ou','u');
+ $vowels = array('a','a','ai','au','e','e','e','ee','ea','i','ie','o','ou','u');
if (mt_rand(0, 5) == 4)
$vowels[] = 'y';
@@ -370,13 +372,12 @@ function xmlify($str) {
if(is_array($str)) {
- // allow to fall through so we ge a PHP error, as the log statement will
- // probably get lost in the noise unless we're specifically looking for it.
+ // allow to fall through so we ge a PHP error, as the log statement will
+ // probably get lost in the noise unless we're specifically looking for it.
btlogger('xmlify called with array: ' . print_r($str,true), LOGGER_NORMAL, LOG_WARNING);
}
-
$len = mb_strlen($str);
for($x = 0; $x < $len; $x ++) {
$char = mb_substr($str,$x,1);
@@ -412,27 +413,36 @@ function xmlify($str) {
return($buffer);
}
-// undo an xmlify
-// pass xml escaped text ($s), returns unescaped text
-
-
+/**
+ * @brief Undo an xmlify.
+ *
+ * Pass xml escaped text ($s), returns unescaped text.
+ *
+ * @param string $s
+ *
+ * @return string
+ */
function unxmlify($s) {
- $ret = str_replace('&amp;','&', $s);
- $ret = str_replace(array('&lt;','&gt;','&quot;','&apos;'),array('<','>','"',"'"),$ret);
+ $ret = str_replace('&amp;', '&', $s);
+ $ret = str_replace(array('&lt;', '&gt;', '&quot;', '&apos;'), array('<', '>', '"', "'"), $ret);
+
return $ret;
}
-// Automatic pagination.
-// To use, get the count of total items.
-// Then call App::set_pager_total($number_items);
-// Optionally call App::set_pager_itemspage($n) to the number of items to display on each page
-// Then call paginate($a) after the end of the display loop to insert the pager block on the page
-// (assuming there are enough items to paginate).
-// When using with SQL, the setting LIMIT %d, %d => App::$pager['start'],App::$pager['itemspage']
-// will limit the results to the correct items for the current page.
-// The actual page handling is then accomplished at the application layer.
-
-
+/**
+ * @brief Automatic pagination.
+ *
+ * To use, get the count of total items.
+ * Then call App::set_pager_total($number_items);
+ * Optionally call App::set_pager_itemspage($n) to the number of items to display on each page
+ * Then call paginate($a) after the end of the display loop to insert the pager block on the page
+ * (assuming there are enough items to paginate).
+ * When using with SQL, the setting LIMIT %d, %d => App::$pager['start'],App::$pager['itemspage']
+ * will limit the results to the correct items for the current page.
+ * The actual page handling is then accomplished at the application layer.
+ *
+ * @param App &$a
+ */
function paginate(&$a) {
$o = '';
$stripped = preg_replace('/(&page=[0-9]*)/','',App::$query_string);
@@ -451,15 +461,15 @@ function paginate(&$a) {
$o .= "<span class=\"pager_first\"><a href=\"$url"."&page=1\">" . t('first') . "</a></span> ";
- $numpages = App::$pager['total'] / App::$pager['itemspage'];
+ $numpages = App::$pager['total'] / App::$pager['itemspage'];
- $numstart = 1;
- $numstop = $numpages;
+ $numstart = 1;
+ $numstop = $numpages;
- if($numpages > 14) {
- $numstart = (($pagenum > 7) ? ($pagenum - 7) : 1);
- $numstop = (($pagenum > ($numpages - 7)) ? $numpages : ($numstart + 14));
- }
+ if($numpages > 14) {
+ $numstart = (($pagenum > 7) ? ($pagenum - 7) : 1);
+ $numstop = (($pagenum > ($numpages - 7)) ? $numpages : ($numstart + 14));
+ }
for($i = $numstart; $i <= $numstop; $i++){
if($i == App::$pager['page'])
@@ -484,6 +494,7 @@ function paginate(&$a) {
$o .= '<span class="pager_next">'."<a href=\"$url"."&page=".(App::$pager['page'] + 1).'">' . t('next') . '</a></span>';
$o .= '</div>'."\r\n";
}
+
return $o;
}
@@ -514,7 +525,6 @@ function alt_pager(&$a, $i, $more = '', $less = '') {
}
-
/**
* @brief Generate a guaranteed unique (for this domain) item ID for ATOM.
*
@@ -558,17 +568,23 @@ function photo_new_resource() {
return $resource;
}
-
-
-// for html,xml parsing - let's say you've got
-// an attribute foobar="class1 class2 class3"
-// and you want to find out if it contains 'class3'.
-// you can't use a normal sub string search because you
-// might match 'notclass3' and a regex to do the job is
-// possible but a bit complicated.
-// pass the attribute string as $attr and the attribute you
-// are looking for as $s - returns true if found, otherwise false
-
+/**
+ * @brief
+ *
+ * for html,xml parsing - let's say you've got
+ * an attribute foobar="class1 class2 class3"
+ * and you want to find out if it contains 'class3'.
+ * you can't use a normal sub string search because you
+ * might match 'notclass3' and a regex to do the job is
+ * possible but a bit complicated.
+ *
+ * pass the attribute string as $attr and the attribute you
+ * are looking for as $s - returns true if found, otherwise false
+ *
+ * @param string $attr attribute string
+ * @param string $s attribute you are looking for
+ * @return boolean true if found
+ */
function attribute_contains($attr, $s) {
$a = explode(' ', $attr);
if(count($a) && in_array($s, $a))
@@ -591,10 +607,9 @@ function attribute_contains($attr, $s) {
* was called, so no need to add it to the message anymore.
*
* @param string $msg Message to log
- * @param int $level A log level.
+ * @param int $level A log level
* @param int $priority - compatible with syslog
*/
-
function logger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) {
if(App::$module == 'setup' && is_writable('install.log')) {
@@ -612,7 +627,7 @@ function logger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) {
return;
$where = '';
-
+
// We require > 5.4 but leave the version check so that install issues (including version) can be logged
if(version_compare(PHP_VERSION, '5.4.0') >= 0) {
@@ -630,19 +645,23 @@ function logger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) {
@file_put_contents($pluginfo['filename'], $pluginfo['message'], FILE_APPEND);
}
-// like logger() but with a function backtrace to pinpoint certain classes
-// of problems which show up deep in the calling stack
-
-
+/**
+ * @brief like logger() but with a function backtrace to pinpoint certain classes
+ * of problems which show up deep in the calling stack.
+ *
+ * @param string $msg Message to log
+ * @param int $level A log level
+ * @param int $priority - compatible with syslog
+ */
function btlogger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) {
logger($msg, $level, $priority);
if(version_compare(PHP_VERSION, '5.4.0') >= 0) {
- $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+ $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
if($stack) {
for($x = 1; $x < count($stack); $x ++) {
logger('stack: ' . basename($stack[$x]['file']) . ':' . $stack[$x]['line'] . ':' . $stack[$x]['function'] . '()',$level, $priority);
- }
+ }
}
}
}
@@ -718,15 +737,17 @@ function activity_match($haystack,$needle) {
return false;
}
-
-// Pull out all #hashtags and @person tags from $s;
-// We also get @person@domain.com - which would make
-// the regex quite complicated as tags can also
-// end a sentence. So we'll run through our results
-// and strip the period from any tags which end with one.
-// Returns array of tags found, or empty array.
-
-
+/**
+ * @brief Pull out all #hashtags and @person tags from $s.
+ *
+ * We also get @person@domain.com - which would make
+ * the regex quite complicated as tags can also
+ * end a sentence. So we'll run through our results
+ * and strip the period from any tags which end with one.
+ *
+ * @param string $s
+ * @return Returns array of tags found, or empty array.
+ */
function get_tags($s) {
$ret = array();
$match = array();
@@ -797,9 +818,9 @@ function get_tags($s) {
// make sure the longer tags are returned first so that if two or more have common substrings
// we'll replace the longest ones first. Otherwise the common substring would be found in
- // both strings and the string replacement would link both to the shorter strings and
+ // both strings and the string replacement would link both to the shorter strings and
// fail to link the longer string. Hubzilla github issue #378
-
+
usort($ret,'tag_sort_length');
// logger('get_tags: ' . print_r($ret,true));
@@ -816,21 +837,15 @@ function tag_sort_length($a,$b) {
-function strip_zids($s) {
- return preg_replace('/[\?&]zid=(.*?)(&|$)/ism','$2',$s);
-}
-
-function strip_zats($s) {
- return preg_replace('/[\?&]zat=(.*?)(&|$)/ism','$2',$s);
-}
-
-
-// quick and dirty quoted_printable encoding
-
-
+/**
+ * @brief Quick and dirty quoted_printable encoding.
+ *
+ * @param string $s
+ * @return string
+ */
function qp($s) {
- return str_replace ("%","=",rawurlencode($s));
-}
+ return str_replace ("%", "=", rawurlencode($s));
+}
function get_mentions($item,$tags) {
@@ -889,9 +904,9 @@ function contact_block() {
$contacts = t('No connections');
$micropro = null;
} else {
-
+
$randfunc = db_getfunc('RAND');
-
+
$r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash WHERE abook_channel = %d $abook_flags and abook_archived = 0 and xchan_orphan = 0 and xchan_deleted = 0 $sql_extra ORDER BY $randfunc LIMIT %d",
intval(App::$profile['uid']),
intval($shown)
@@ -936,8 +951,8 @@ function chanlink_cid($d) {
}
function magiclink_url($observer,$myaddr,$url) {
- return (($observer)
- ? z_root() . '/magic?f=&dest=' . $url . '&addr=' . $myaddr
+ return (($observer)
+ ? z_root() . '/magic?f=&dest=' . $url . '&addr=' . $myaddr
: $url
);
}
@@ -1034,8 +1049,8 @@ function sslify($s) {
// Complain to your browser maker
$allow = get_config('system','sslify_everything');
-
- $pattern = (($allow) ? "/\<(.*?)src=\"(http\:.*?)\"(.*?)\>/" : "/\<img(.*?)src=\"(http\:.*?)\"(.*?)\>/" );
+
+ $pattern = (($allow) ? "/\<(.*?)src=\"(http\:.*?)\"(.*?)\>/" : "/\<img(.*?)src=\"(http\:.*?)\"(.*?)\>/" );
$matches = null;
$cnt = preg_match_all($pattern,$s,$matches,PREG_SET_ORDER);
@@ -1105,40 +1120,43 @@ function get_mood_verbs() {
return $arr;
}
-// Function to list all smilies, both internal and from addons
-// Returns array with keys 'texts' and 'icons'
+/**
+ * @brief Function to list all smilies, both internal and from addons.
+ *
+ * @return Returns array with keys 'texts' and 'icons'
+ */
function list_smilies() {
- $texts = array(
- '&lt;3',
- '&lt;/3',
- '&lt;\\3',
- ':-)',
- ';-)',
- ':-(',
- ':-P',
- ':-p',
- ':-"',
- ':-&quot;',
- ':-x',
- ':-X',
- ':-D',
- '8-|',
- '8-O',
- ':-O',
- '\\o/',
- 'o.O',
- 'O.o',
- 'o_O',
- 'O_o',
- ":'(",
- ":-!",
- ":-/",
- ":-[",
+ $texts = array(
+ '&lt;3',
+ '&lt;/3',
+ '&lt;\\3',
+ ':-)',
+ ';-)',
+ ':-(',
+ ':-P',
+ ':-p',
+ ':-"',
+ ':-&quot;',
+ ':-x',
+ ':-X',
+ ':-D',
+ '8-|',
+ '8-O',
+ ':-O',
+ '\\o/',
+ 'o.O',
+ 'O.o',
+ 'o_O',
+ 'O_o',
+ ":'(",
+ ":-!",
+ ":-/",
+ ":-[",
"8-)",
- ':beer',
- ':homebrew',
- ':coffee',
+ ':beer',
+ ':homebrew',
+ ':coffee',
':facepalm',
':like',
':dislike',
@@ -1146,38 +1164,38 @@ function list_smilies() {
);
$icons = array(
- '<img class="smiley" src="' . z_root() . '/images/smiley-heart.gif" alt="&lt;3" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-brokenheart.gif" alt="&lt;/3" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-brokenheart.gif" alt="&lt;\\3" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-smile.gif" alt=":-)" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-wink.gif" alt=";-)" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-frown.gif" alt=":-(" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-tongue-out.gif" alt=":-P" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-tongue-out.gif" alt=":-p" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-kiss.gif" alt=":-\"" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-kiss.gif" alt=":-\"" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-kiss.gif" alt=":-x" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-kiss.gif" alt=":-X" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-laughing.gif" alt=":-D" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-surprised.gif" alt="8-|" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-surprised.gif" alt="8-O" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-surprised.gif" alt=":-O" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-thumbsup.gif" alt="\\o/" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-Oo.gif" alt="o.O" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-Oo.gif" alt="O.o" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-Oo.gif" alt="o_O" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-Oo.gif" alt="O_o" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-cry.gif" alt=":\'(" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-foot-in-mouth.gif" alt=":-!" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-undecided.gif" alt=":-/" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-embarassed.gif" alt=":-[" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-cool.gif" alt="8-)" />',
- '<img class="smiley" src="' . z_root() . '/images/beer_mug.gif" alt=":beer" />',
- '<img class="smiley" src="' . z_root() . '/images/beer_mug.gif" alt=":homebrew" />',
- '<img class="smiley" src="' . z_root() . '/images/coffee.gif" alt=":coffee" />',
- '<img class="smiley" src="' . z_root() . '/images/smiley-facepalm.gif" alt=":facepalm" />',
- '<img class="smiley" src="' . z_root() . '/images/like.gif" alt=":like" />',
- '<img class="smiley" src="' . z_root() . '/images/dislike.gif" alt=":dislike" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-heart.gif" alt="&lt;3" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-brokenheart.gif" alt="&lt;/3" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-brokenheart.gif" alt="&lt;\\3" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-smile.gif" alt=":-)" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-wink.gif" alt=";-)" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-frown.gif" alt=":-(" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-tongue-out.gif" alt=":-P" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-tongue-out.gif" alt=":-p" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-kiss.gif" alt=":-\"" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-kiss.gif" alt=":-\"" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-kiss.gif" alt=":-x" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-kiss.gif" alt=":-X" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-laughing.gif" alt=":-D" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-surprised.gif" alt="8-|" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-surprised.gif" alt="8-O" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-surprised.gif" alt=":-O" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-thumbsup.gif" alt="\\o/" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-Oo.gif" alt="o.O" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-Oo.gif" alt="O.o" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-Oo.gif" alt="o_O" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-Oo.gif" alt="O_o" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-cry.gif" alt=":\'(" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-foot-in-mouth.gif" alt=":-!" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-undecided.gif" alt=":-/" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-embarassed.gif" alt=":-[" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-cool.gif" alt="8-)" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/beer_mug.gif" alt=":beer" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/beer_mug.gif" alt=":homebrew" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/coffee.gif" alt=":coffee" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-facepalm.gif" alt=":facepalm" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/like.gif" alt=":like" />',
+ '<img class="smiley" src="' . z_root() . '/images/emoticons/dislike.gif" alt=":dislike" />',
'<img class="smiley" src="' . z_root() . '/images/hz-16.png" alt=":hubzilla" />',
);
@@ -1208,7 +1226,7 @@ function list_smilies() {
* We will escape text between HTML pre and code blocks, and HTML attributes
* (such as urls) from being processed.
*
- * At a higher level, the bbcode [nosmile] tag can be used to prevent this
+ * At a higher level, the bbcode [nosmile] tag can be used to prevent this
* function from being executed by the prepare_text() routine when preparing
* bbcode source for HTML display.
*
@@ -1218,7 +1236,7 @@ function list_smilies() {
*/
function smilies($s, $sample = false) {
- if(intval(get_config('system', 'no_smilies'))
+ if(intval(get_config('system', 'no_smilies'))
|| (local_channel() && intval(get_pconfig(local_channel(), 'system', 'no_smilies'))))
return $s;
@@ -1255,8 +1273,8 @@ function smile_shield($m) {
return '<!--base64:' . base64special_encode($m[0]) . '-->';
}
-function smile_unshield($m) {
- return base64special_decode($m[1]);
+function smile_unshield($m) {
+ return base64special_decode($m[1]);
}
/**
@@ -1271,7 +1289,7 @@ function preg_heart($x) {
$t = '';
for($cnt = 0; $cnt < strlen($x[1]); $cnt ++)
- $t .= '<img class="smiley" src="' . z_root() . '/images/smiley-heart.gif" alt="&lt;3" />';
+ $t .= '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-heart.gif" alt="&lt;3" />';
$r = str_replace($x[0],$t,$x[0]);
@@ -1364,11 +1382,11 @@ function theme_attachments(&$item) {
$icon = getIconFromType($r['type']);
$label = (($r['title']) ? urldecode(htmlspecialchars($r['title'], ENT_COMPAT, 'UTF-8')) : t('Unknown Attachment'));
-
+
//some feeds provide an attachment where title an empty space
if($label == ' ')
$label = t('Unknown Attachment');
-
+
$title = t('Size') . ' ' . (($r['length']) ? userReadableSize($r['length']) : t('unknown'));
require_once('include/channel.php');
@@ -1508,7 +1526,7 @@ function generate_named_map($location) {
function prepare_body(&$item,$attach = false) {
- call_hooks('prepare_body_init', $item);
+ call_hooks('prepare_body_init', $item);
$s = '';
$photo = '';
@@ -1602,7 +1620,9 @@ function prepare_body(&$item,$attach = false) {
* @brief Given a text string, convert from bbcode to html and add smilie icons.
*
* @param string $text
- * @param sting $content_type
+ * @param sting $content_type (optional) default text/bbcode
+ * @param boolean $cache (optional) default false
+ *
* @return string
*/
function prepare_text($text, $content_type = 'text/bbcode', $cache = false) {
@@ -1621,19 +1641,18 @@ function prepare_text($text, $content_type = 'text/bbcode', $cache = false) {
$s = Markdown($text);
break;
-
case 'application/x-pdl';
$s = escape_tags($text);
break;
-
- // No security checking is done here at display time - so we need to verify
- // that the author is allowed to use PHP before storing. We also cannot allow
- // importation of PHP text bodies from other sites. Therefore this content
+
+ // No security checking is done here at display time - so we need to verify
+ // that the author is allowed to use PHP before storing. We also cannot allow
+ // importation of PHP text bodies from other sites. Therefore this content
// type is only valid for web pages (and profile details).
- // It may be possible to provide a PHP message body which is evaluated on the
- // sender's site before sending it elsewhere. In that case we will have a
- // different content-type here.
+ // It may be possible to provide a PHP message body which is evaluated on the
+ // sender's site before sending it elsewhere. In that case we will have a
+ // different content-type here.
case 'application/x-php':
ob_start();
@@ -1674,43 +1693,6 @@ function create_export_photo_body(&$item) {
}
/**
- * zidify_callback() and zidify_links() work together to turn any HTML a tags with class="zrl" into zid links
- * These will typically be generated by a bbcode '[zrl]' tag. This is done inside prepare_text() rather than bbcode()
- * because the latter is used for general purpose conversions and the former is used only when preparing text for
- * immediate display.
- *
- * Issues: Currently the order of HTML parameters in the text is somewhat rigid and inflexible.
- * We assume it looks like \<a class="zrl" href="xxxxxxxxxx"\> and will not work if zrl and href appear in a different order.
- *
- * @param array $match
- * @return string
- */
-function zidify_callback($match) {
- $is_zid = ((feature_enabled(local_channel(),'sendzid')) || (strpos($match[1],'zrl')) ? true : false);
- $replace = '<a' . $match[1] . ' href="' . (($is_zid) ? zid($match[2]) : $match[2]) . '"';
- $x = str_replace($match[0],$replace,$match[0]);
-
- return $x;
-}
-
-function zidify_img_callback($match) {
- $is_zid = ((feature_enabled(local_channel(),'sendzid')) || (strpos($match[1],'zrl')) ? true : false);
- $replace = '<img' . $match[1] . ' src="' . (($is_zid) ? zid($match[2]) : $match[2]) . '"';
-
- $x = str_replace($match[0],$replace,$match[0]);
-
- return $x;
-}
-
-
-function zidify_links($s) {
- $s = preg_replace_callback('/\<a(.*?)href\=\"(.*?)\"/ism','zidify_callback',$s);
- $s = preg_replace_callback('/\<img(.*?)src\=\"(.*?)\"/ism','zidify_img_callback',$s);
-
- return $s;
-}
-
-/**
* @brief Return atom link elements for all of our hubs.
*
* @return string
@@ -1735,16 +1717,20 @@ function feed_hublinks() {
return $hubxml;
}
-/* return atom link elements for salmon endpoints */
-
+/**
+ * @brief Return atom link elements for salmon endpoints
+ *
+ * @param string $nick
+ * @return string
+ */
function feed_salmonlinks($nick) {
$salmon = '<link rel="salmon" href="' . xmlify(z_root() . '/salmon/' . $nick) . '" />' . "\n" ;
- // old style links that status.net still needed as of 12/2010
+ // old style links that status.net still needed as of 12/2010
- $salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-replies" href="' . xmlify(z_root() . '/salmon/' . $nick) . '" />' . "\n" ;
- $salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-mention" href="' . xmlify(z_root() . '/salmon/' . $nick) . '" />' . "\n" ;
+ $salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-replies" href="' . xmlify(z_root() . '/salmon/' . $nick) . '" />' . "\n" ;
+ $salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-mention" href="' . xmlify(z_root() . '/salmon/' . $nick) . '" />' . "\n" ;
return $salmon;
}
@@ -1773,7 +1759,7 @@ function unamp($s) {
}
function layout_select($channel_id, $current = '') {
- $r = q("select mid, v from item left join iconfig on iconfig.iid = item.id
+ $r = q("select mid, v from item left join iconfig on iconfig.iid = item.id
where iconfig.cat = 'system' and iconfig.k = 'PDL' and item.uid = %d and item_type = %d ",
intval($channel_id),
intval(ITEM_TYPE_PDL)
@@ -1817,12 +1803,12 @@ function mimetype_select($channel_id, $current = 'text/bbcode') {
);
if($r) {
- if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) {
+ if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) {
if(local_channel() && get_account_id() == $r[0]['account_id']) {
$x[] = 'application/x-php';
}
}
- }
+ }
}
foreach($x as $y) {
@@ -1837,42 +1823,6 @@ function mimetype_select($channel_id, $current = 'text/bbcode') {
return $o;
}
-
-function lang_selector() {
-
- $langs = glob('view/*/hstrings.php');
-
- $lang_options = array();
- $selected = "";
-
- if(is_array($langs) && count($langs)) {
- $langs[] = '';
- if(! in_array('view/en/hstrings.php',$langs))
- $langs[] = 'view/en/';
- asort($langs);
- foreach($langs as $l) {
- if($l == '') {
- $lang_options[""] = t('default');
- continue;
- }
- $ll = substr($l,5);
- $ll = substr($ll,0,strrpos($ll,'/'));
- $selected = (($ll === App::$language && (x($_SESSION, 'language'))) ? $ll : $selected);
- $lang_options[$ll] = get_language_name($ll, $ll) . " ($ll)";
- }
- }
-
- $tpl = get_markup_template("lang_selector.tpl");
- $o = replace_macros($tpl, array(
- '$title' => t('Select an alternate language'),
- '$langs' => array($lang_options, $selected),
-
- ));
-
- return $o;
-}
-
-
function engr_units_to_bytes ($size_str) {
if(! $size_str)
return $size_str;
@@ -1922,9 +1872,8 @@ function base64special_decode($s) {
return base64_decode(strtr($s,',.','+/'));
}
-
/**
- * @ Return a div to clear floats.
+ * @brief Return a div to clear floats.
*
* @return string
*/
@@ -2100,7 +2049,7 @@ function ids_to_array($arr,$idx = 'id') {
$t = array();
if($arr) {
foreach($arr as $x) {
- if(array_key_exists($idx,$x) && strlen($x[$idx]) && (! in_array($x[$idx],$t))) {
+ if(array_key_exists($idx,$x) && strlen($x[$idx]) && (! in_array($x[$idx],$t))) {
$t[] = $x[$idx];
}
}
@@ -2111,23 +2060,33 @@ function ids_to_array($arr,$idx = 'id') {
-function ids_to_querystr($arr,$idx = 'id') {
+function ids_to_querystr($arr,$idx = 'id',$quote = false) {
$t = array();
if($arr) {
foreach($arr as $x) {
if(! in_array($x[$idx],$t)) {
- $t[] = $x[$idx];
+ if($quote)
+ $t[] = "'" . dbesc($x[$idx]) . "'";
+ else
+ $t[] = $x[$idx];
}
}
}
return(implode(',', $t));
}
-// Fetches xchan and hubloc data for an array of items with only an
-// author_xchan and owner_xchan. If $abook is true also include the abook info.
-// This is needed in the API to save extra per item lookups there.
-
-function xchan_query(&$items,$abook = true,$effective_uid = 0) {
+/**
+ * @brief Fetches xchan and hubloc data for an array of items with only an
+ * author_xchan and owner_xchan.
+ *
+ * If $abook is true also include the abook info. This is needed in the API to
+ * save extra per item lookups there.
+ *
+ * @param array[in,out] &$items
+ * @param boolean $abook If true also include the abook info
+ * @param number $effective_uid
+ */
+function xchan_query(&$items, $abook = true, $effective_uid = 0) {
$arr = array();
if($items && count($items)) {
@@ -2160,7 +2119,7 @@ function xchan_query(&$items,$abook = true,$effective_uid = 0) {
if(! $chans)
$chans = $xchans;
else
- $chans = array_merge($xchans,$chans);
+ $chans = array_merge($xchans,$chans);
}
if($items && count($items) && $chans && count($chans)) {
for($x = 0; $x < count($items); $x ++) {
@@ -2218,15 +2177,19 @@ function magic_link($s) {
return $s;
}
-// if $escape is true, dbesc() each element before adding quotes
-
-function stringify_array_elms(&$arr,$escape = false) {
+/**
+ * if $escape is true, dbesc() each element before adding quotes
+ *
+ * @param array[in,out] &$arr
+ * @param boolean $escape default false
+ */
+function stringify_array_elms(&$arr, $escape = false) {
for($x = 0; $x < count($arr); $x ++)
$arr[$x] = "'" . (($escape) ? dbesc($arr[$x]) : $arr[$x]) . "'";
}
/**
- * Indents a flat JSON string to make it more human-readable.
+ * @brief Indents a flat JSON string to make it more human-readable.
*
* @param string $json The original JSON string to process.
*
@@ -2250,7 +2213,7 @@ function jindent($json) {
if ($char == '"' && $prevChar != '\\') {
$outOfQuotes = !$outOfQuotes;
- // If this character is the end of an element,
+ // If this character is the end of an element,
// output a new line and indent the next line.
} else if(($char == '}' || $char == ']') && $outOfQuotes) {
$result .= $newLine;
@@ -2263,7 +2226,7 @@ function jindent($json) {
// Add the character to the result string.
$result .= $char;
- // If the last character was the beginning of an element,
+ // If the last character was the beginning of an element,
// output a new line and indent the next line.
if (($char == ',' || $char == '{' || $char == '[') && $outOfQuotes) {
$result .= $newLine;
@@ -2275,7 +2238,7 @@ function jindent($json) {
$result .= $indentStr;
}
}
-
+
$prevChar = $char;
}
@@ -2285,9 +2248,8 @@ function jindent($json) {
/**
* @brief Creates navigation menu for webpage, layout, blocks, menu sites.
*
- * @return string
+ * @return string with parsed HTML
*/
-
function design_tools() {
$channel = App::get_channel();
@@ -2336,7 +2298,7 @@ function website_portation_tools() {
'$file_import_text' => t('Import from cloud files:'),
'$desc' => t('/cloud/channel/path/to/folder'),
'$hint' => t('Enter path to website files'),
- '$select' => t('Select folder'),
+ '$select' => t('Select folder'),
'$export_label' => t('Export website...'),
'$file_download_text' => t('Export to a zip file'),
'$filename_desc' => t('website.zip'),
@@ -2344,12 +2306,17 @@ function website_portation_tools() {
'$cloud_export_text' => t('Export to cloud files'),
'$cloud_export_desc' => t('/path/to/export/folder'),
'$cloud_export_hint' => t('Enter a path to a cloud files destination.'),
- '$cloud_export_select' => t('Specify folder'),
+ '$cloud_export_select' => t('Specify folder'),
));
}
-/* case insensitive in_array() */
-
+/**
+ * @brief case insensitive in_array()
+ *
+ * @param string $needle
+ * @param array $haystack
+ * @return boolean
+ */
function in_arrayi($needle, $haystack) {
return in_array(strtolower($needle), array_map('strtolower', $haystack));
}
@@ -2358,10 +2325,13 @@ function normalise_openid($s) {
return trim(str_replace(array('http://','https://'),array('',''),$s),'/');
}
-// used in ajax endless scroll request to find out all the args that the master page was viewing.
-// This was using $_REQUEST, but $_REQUEST also contains all your cookies. So we're restricting it
-// to $_GET and $_POST.
-
+/**
+ * Used in ajax endless scroll request to find out all the args that the master page was viewing.
+ * This was using $_REQUEST, but $_REQUEST also contains all your cookies. So we're restricting it
+ * to $_GET and $_POST.
+ *
+ * @return string with additional URL parameters
+ */
function extra_query_args() {
$s = '';
if(count($_GET)) {
@@ -2380,6 +2350,7 @@ function extra_query_args() {
}
}
}
+
return $s;
}
@@ -2406,7 +2377,7 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
$termtype = ((strpos($tag,'@') === 0) ? TERM_MENTION : $termtype);
$termtype = ((strpos($tag,'#^[') === 0) ? TERM_BOOKMARK : $termtype);
- //is it a hash tag?
+ //is it a hash tag?
if(strpos($tag,'#') === 0) {
if(strpos($tag,'#^[') === 0) {
if(preg_match('/#\^\[(url|zrl)(.*?)\](.*?)\[\/(url|zrl)\]/',$tag,$match)) {
@@ -2421,7 +2392,7 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
return $replaced;
}
if($tag == '#getzot') {
- $basetag = 'getzot';
+ $basetag = 'getzot';
$url = 'http://hubzilla.org';
$newtag = '#[zrl=' . $url . ']' . $basetag . '[/zrl]';
$body = str_replace($tag,$newtag,$body);
@@ -2457,15 +2428,15 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
$str_tags .= $newtag;
}
return [
- 'replaced' => $replaced,
- 'termtype' => $termtype,
- 'term' => $basetag,
- 'url' => $url,
+ 'replaced' => $replaced,
+ 'termtype' => $termtype,
+ 'term' => $basetag,
+ 'url' => $url,
'contact' => $r[0]
- ];
+ ];
}
- //is it a person tag?
+ //is it a person tag?
if(strpos($tag,'@') === 0) {
@@ -2479,7 +2450,7 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
//get the person's name
$name = substr($tag,(($exclusive) ? 2 : 1)); // The name or name fragment we are going to replace
- $newname = $name; // a copy that we can mess with
+ $newname = $name; // a copy that we can mess with
$tagcid = 0;
$r = null;
@@ -2525,14 +2496,14 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
if($abook_id) { // if there was an id
// select channel with that id from the logged in user's address book
- $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
+ $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_id = %d AND abook_channel = %d LIMIT 1",
intval($abook_id),
intval($profile_uid)
);
}
else {
- $r = q("SELECT * FROM xchan
+ $r = q("SELECT * FROM xchan
WHERE xchan_hash like '%s%%' LIMIT 1",
dbesc($tagcid)
);
@@ -2561,7 +2532,7 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
}
//select someone from this user's contacts by name
- $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
+ $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1",
dbesc($newname),
intval($profile_uid)
@@ -2569,7 +2540,7 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
if(! $r) {
//select someone by attag or nick and the name passed in
- $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
+ $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
WHERE xchan_addr like ('%s') AND abook_channel = %d LIMIT 1",
dbesc(((strpos($newname,'@')) ? $newname : $newname . '@%')),
intval($profile_uid)
@@ -2580,7 +2551,7 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
// it's possible somebody has a name ending with '+', which we stripped off as a forum indicator
// This is very rare but we want to get it right.
- $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
+ $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash
WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1",
dbesc($newname . '+'),
intval($profile_uid)
@@ -2604,12 +2575,12 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
}
else {
- // check for a group/collection exclusion tag
+ // check for a group/collection exclusion tag
// note that we aren't setting $replaced even though we're replacing text.
// This tag isn't going to get a term attached to it. It's only used for
// access control. The link points to out own channel just so it doesn't look
- // weird - as all the other tags are linked to something.
+ // weird - as all the other tags are linked to something.
if(local_channel() && local_channel() == $profile_uid) {
require_once('include/group.php');
@@ -2654,10 +2625,10 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
}
return [
- 'replaced' => $replaced,
- 'termtype' => $termtype,
- 'term' => $newname,
- 'url' => $url,
+ 'replaced' => $replaced,
+ 'termtype' => $termtype,
+ 'term' => $newname,
+ 'url' => $url,
'contact' => $r[0]
];
}
@@ -2686,7 +2657,7 @@ function linkify_tags($a, &$body, $uid, $diaspora = false) {
if($fullnametagged)
continue;
- $success = handle_tag($a, $body, $access_tag, $str_tags, ($uid) ? $uid : App::$profile_uid , $tag, $diaspora);
+ $success = handle_tag($a, $body, $access_tag, $str_tags, ($uid) ? $uid : App::$profile_uid , $tag, $diaspora);
$results[] = array('success' => $success, 'access_tag' => $access_tag);
if($success['replaced']) $tagged[] = $tag;
}
@@ -2807,10 +2778,10 @@ function json_url_replace($old,$new,&$s) {
$s = $x;
return $replaced;
}
-
+
function item_url_replace($channel,&$item,$old,$new,$oldnick = '') {
-
+
if($item['attach']) {
json_url_replace($old,$new,$item['attach']);
if($oldnick)
@@ -2831,7 +2802,7 @@ function item_url_replace($channel,&$item,$old,$new,$oldnick = '') {
$item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey']));
$item['item_verified'] = 1;
}
-
+
$item['plink'] = str_replace($old,$new,$item['plink']);
if($oldnick)
$item['plink'] = str_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['plink']);
@@ -2839,7 +2810,7 @@ function item_url_replace($channel,&$item,$old,$new,$oldnick = '') {
$item['llink'] = str_replace($old,$new,$item['llink']);
if($oldnick)
$item['llink'] = str_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['llink']);
-
+
}
@@ -2877,7 +2848,6 @@ function perms2str($p) {
return $ret;
}
-
/**
* @brief Turn user/group ACLs stored as angle bracketed text into arrays.
*
@@ -2905,35 +2875,41 @@ function expand_acl($s) {
function acl2json($s) {
$s = expand_acl($s);
$s = json_encode($s);
+
return $s;
}
-
-// When editing a webpage - a dropdown is needed to select a page layout
-// On submit, the pdl_select value (which is the mid of an item with item_type = ITEM_TYPE_PDL) is stored in
-// the webpage's resource_id, with resource_type 'pdl'.
-
-// Then when displaying a webpage, we can see if it has a pdl attached. If not we'll
-// use the default site/page layout.
-
-// If it has a pdl we'll load it as we know the mid and pass the body through comanche_parser() which will generate the
-// page layout from the given description
-
-// @FIXME - there is apparently a very similar function called layout_select; this one should probably take precedence
-// and the other should be checked for compatibility and removed
-
-function pdl_selector($uid, $current="") {
+/**
+ * @brief When editing a webpage - a dropdown is needed to select a page layout
+ *
+ * On submit, the pdl_select value (which is the mid of an item with item_type = ITEM_TYPE_PDL)
+ * is stored in the webpage's resource_id, with resource_type 'pdl'.
+ *
+ * Then when displaying a webpage, we can see if it has a pdl attached. If not we'll
+ * use the default site/page layout.
+ *
+ * If it has a pdl we'll load it as we know the mid and pass the body through comanche_parser() which will generate the
+ * page layout from the given description
+ *
+ * @FIXME - there is apparently a very similar function called layout_select; this one should probably take precedence
+ * and the other should be checked for compatibility and removed
+ *
+ * @param int $uid
+ * @param string $current
+ * @return string HTML code for dropdown
+ */
+function pdl_selector($uid, $current='') {
$o = '';
$sql_extra = item_permissions_sql($uid);
- $r = q("select iconfig.*, mid from item_id left join item on iconfig.iid = item.id
+ $r = q("select iconfig.*, mid from item_id left join item on iconfig.iid = item.id
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'PDL' $sql_extra order by v asc",
intval($uid)
);
$arr = array('channel_id' => $uid, 'current' => $current, 'entries' => $r);
- call_hooks('pdl_selector',$arr);
+ call_hooks('pdl_selector', $arr);
$entries = $arr['entries'];
$current = $arr['current'];
@@ -2949,16 +2925,17 @@ function pdl_selector($uid, $current="") {
return $o;
}
-/*
- * array flatten_array_recursive(array);
- * returns a one-dimensional array from a multi-dimensional array
+/**
+ * @brief returns a one-dimensional array from a multi-dimensional array
* empty values are discarded
+ *
* example: print_r(flatten_array_recursive(array('foo','bar',array('baz','blip',array('zob','glob')),'','grip')));
*
- * Array ( [0] => foo [1] => bar [2] => baz [3] => blip [4] => zob [5] => glob [6] => grip )
+ * Array ( [0] => foo [1] => bar [2] => baz [3] => blip [4] => zob [5] => glob [6] => grip )
*
+ * @param array $arr multi-dimensional array
+ * @return one-dimensional array
*/
-
function flatten_array_recursive($arr) {
$ret = array();
@@ -2969,64 +2946,71 @@ function flatten_array_recursive($arr) {
if(is_array($a)) {
$tmp = flatten_array_recursive($a);
if($tmp) {
- $ret = array_merge($ret,$tmp);
+ $ret = array_merge($ret, $tmp);
}
}
elseif($a) {
$ret[] = $a;
}
}
+
return($ret);
-}
+}
-function text_highlight($s,$lang) {
+/**
+ * @brief Highlight Text.
+ *
+ * @param string $s Text to highlight
+ * @param string $lang Which language should be highlighted
+ * @return string
+ */
+function text_highlight($s, $lang) {
if($lang === 'js')
$lang = 'javascript';
if($lang === 'json') {
$lang = 'javascript';
- if(! strpos(trim($s),"\n"))
+ if(! strpos(trim($s), "\n"))
$s = jindent($s);
}
- if(! strpos('Text_Highlighter',get_include_path())) {
+ if(! strpos('Text_Highlighter', get_include_path())) {
set_include_path(get_include_path() . PATH_SEPARATOR . 'library/Text_Highlighter');
}
require_once('library/Text_Highlighter/Text/Highlighter.php');
- require_once('library/Text_Highlighter/Text/Highlighter/Renderer/Html.php');
- $options = array(
- 'numbers' => HL_NUMBERS_LI,
- 'tabsize' => 4,
- );
+ require_once('library/Text_Highlighter/Text/Highlighter/Renderer/Html.php');
+ $options = array(
+ 'numbers' => HL_NUMBERS_LI,
+ 'tabsize' => 4,
+ );
$tag_added = false;
- $s = trim(html_entity_decode($s,ENT_COMPAT));
- $s = str_replace(" ","\t",$s);
+ $s = trim(html_entity_decode($s, ENT_COMPAT));
+ $s = str_replace(" ", "\t", $s);
- // The highlighter library insists on an opening php tag for php code blocks. If
+ // The highlighter library insists on an opening php tag for php code blocks. If
// it isn't present, nothing is highlighted. So we're going to see if it's present.
- // If not, we'll add it, and then quietly remove it after we get the processed output back.
+ // If not, we'll add it, and then quietly remove it after we get the processed output back.
if($lang === 'php') {
- if(strpos('<?php',$s) !== 0) {
+ if(strpos('<?php', $s) !== 0) {
$s = '<?php' . "\n" . $s;
- $tag_added = true;
+ $tag_added = true;
}
-
- }
- $renderer = new Text_Highlighter_Renderer_HTML($options);
- $hl = Text_Highlighter::factory($lang);
- $hl->setRenderer($renderer);
+ }
+ $renderer = new Text_Highlighter_Renderer_HTML($options);
+ $hl = Text_Highlighter::factory($lang);
+ $hl->setRenderer($renderer);
$o = $hl->highlight($s);
- $o = str_replace([" ","\n"],["&nbsp;&nbsp;&nbsp;&nbsp;",''],$o);
+ $o = str_replace([" ", "\n"], ["&nbsp;&nbsp;&nbsp;&nbsp;", ''], $o);
if($tag_added) {
- $b = substr($o,0,strpos($o,'<li>'));
- $e = substr($o,strpos($o,'</li>'));
+ $b = substr($o, 0, strpos($o, '<li>'));
+ $e = substr($o, strpos($o, '</li>'));
$o = $b . $e;
}
- return('<code>' . $o . '</code>');
+ return('<code>' . $o . '</code>');
}
// function to convert multi-dimensional array to xml
@@ -3041,26 +3025,40 @@ function text_highlight($s,$lang) {
// echo (($xml->asXML('data.xml')) ? 'Your XML file has been generated successfully!' : 'Error generating XML file!');
function arrtoxml($root_elem,$arr) {
- $xml = new SimpleXMLElement('<' . $root_elem . '/>');
+ $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><' . $root_elem . '></' . $root_elem . '>', null, false);
array2XML($xml,$arr);
+
return $xml->asXML();
}
-function array2XML($obj, $array)
-{
- foreach ($array as $key => $value)
- {
- if(is_numeric($key))
- $key = 'item' . $key;
-
- if (is_array($value))
- {
- $node = $obj->addChild($key);
- array2XML($node, $value);
- }
- else
- {
- $obj->addChild($key, htmlspecialchars($value));
- }
- }
+function array2XML($obj, $array) {
+ foreach ($array as $key => $value) {
+ if(is_numeric($key))
+ $key = 'item' . $key;
+
+ if(is_array($value)) {
+ $node = $obj->addChild($key);
+ array2XML($node, $value);
+ } else {
+ $obj->addChild($key, htmlspecialchars($value));
+ }
+ }
}
+
+
+function create_table_from_array($table, $arr) {
+
+ if(! ($arr && $table))
+ return false;
+
+ if(dbesc_array($arr)) {
+ $r = dbq("INSERT INTO " . TQUOT . $table . TQUOT . " (" . TQUOT
+ . implode(TQUOT . ', ' . TQUOT, array_keys($arr))
+ . TQUOT . ") VALUES ('"
+ . implode("', '", array_values($arr))
+ . "')"
+ );
+ }
+
+ return $r;
+} \ No newline at end of file
diff --git a/include/widgets.php b/include/widgets.php
index 2e1e58717..dde8e7cd0 100644
--- a/include/widgets.php
+++ b/include/widgets.php
@@ -126,7 +126,7 @@ function widget_suggestions($arr) {
// Get two random entries from the top 20 returned.
// We'll grab the first one and the one immediately following.
- // This will throw some entropy intot he situation so you won't
+ // This will throw some entropy intot he situation so you won't
// be looking at the same two mug shots every time the widget runs
$index = ((count($r) > 2) ? mt_rand(0,count($r) - 2) : 0);
@@ -169,7 +169,7 @@ function widget_follow($args) {
intval($uid)
);
if($r)
- $total_channels = $r[0]['total'];
+ $total_channels = $r[0]['total'];
$limit = service_class_fetch($uid,'total_channels');
if($limit !== false) {
$abook_usage_message = sprintf( t("You have %1$.0f of %2$.0f allowed connections."), $total_channels, $limit);
@@ -212,15 +212,15 @@ function widget_savedsearch($arr) {
$search = ((x($_GET,'netsearch')) ? $_GET['netsearch'] : '');
if(! $search)
$search = ((x($_GET,'search')) ? $_GET['search'] : '');
-
+
if(x($_GET,'searchsave') && $search) {
- $r = q("select * from `term` where `uid` = %d and `ttype` = %d and `term` = '%s' limit 1",
+ $r = q("select * from term where uid = %d and ttype = %d and term = '%s' limit 1",
intval(local_channel()),
intval(TERM_SAVEDSEARCH),
dbesc($search)
);
if(! $r) {
- q("insert into `term` ( `uid`,`ttype`,`term` ) values ( %d, %d, '%s') ",
+ q("insert into term ( uid,ttype,term ) values ( %d, %d, '%s') ",
intval(local_channel()),
intval(TERM_SAVEDSEARCH),
dbesc($search)
@@ -229,7 +229,7 @@ function widget_savedsearch($arr) {
}
if(x($_GET,'searchremove') && $search) {
- q("delete from `term` where `uid` = %d and `ttype` = %d and `term` = '%s'",
+ q("delete from term where uid = %d and ttype = %d and term = '%s'",
intval(local_channel()),
intval(TERM_SAVEDSEARCH),
dbesc($search)
@@ -252,11 +252,11 @@ function widget_savedsearch($arr) {
$hasamp = ((strpos($srchurl,'&') !== false) ? true : false);
if(($hasamp) && (! $hasq))
- $srchurl = substr($srchurl,0,strpos($srchurl,'&')) . '?f=&' . substr($srchurl,strpos($srchurl,'&')+1);
+ $srchurl = substr($srchurl,0,strpos($srchurl,'&')) . '?f=&' . substr($srchurl,strpos($srchurl,'&')+1);
$o = '';
- $r = q("select `tid`,`term` from `term` WHERE `uid` = %d and `ttype` = %d ",
+ $r = q("select tid,term from term WHERE uid = %d and ttype = %d ",
intval(local_channel()),
intval(TERM_SAVEDSEARCH)
);
@@ -292,7 +292,7 @@ function widget_savedsearch($arr) {
function widget_sitesearch($arr) {
$search = ((x($_GET,'search')) ? $_GET['search'] : '');
-
+
$srchurl = App::$query_string;
$srchurl = rtrim(preg_replace('/search\=[^\&].*?(\&|$)/is','',$srchurl),'&');
@@ -304,7 +304,7 @@ function widget_sitesearch($arr) {
$hasamp = ((strpos($srchurl,'&') !== false) ? true : false);
if(($hasamp) && (! $hasq))
- $srchurl = substr($srchurl,0,strpos($srchurl,'&')) . '?f=&' . substr($srchurl,strpos($srchurl,'&')+1);
+ $srchurl = substr($srchurl,0,strpos($srchurl,'&')) . '?f=&' . substr($srchurl,strpos($srchurl,'&')+1);
$o = '';
@@ -554,7 +554,7 @@ function widget_affinity($arr) {
));
$arr = array('html' => $x);
call_hooks('main_slider',$arr);
- return $arr['html'];
+ return $arr['html'];
}
return '';
@@ -581,11 +581,11 @@ function widget_settings_menu($arr) {
if($abk)
$abook_self_id = $abk[0]['abook_id'];
- $hublocs = q("select count(*) as total from hubloc where hubloc_hash = '%s'",
+ $x = q("select count(*) as total from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0 ",
dbesc($channel['channel_hash'])
);
- $hublocs = (($hublocs[0]['total'] > 1) ? true : false);
+ $hublocs = (($x && $x[0]['total'] > 1) ? true : false);
$tabs = array(
array(
@@ -778,7 +778,7 @@ function widget_conversations($arr) {
'$messages' => $messages
));
- $o .= alt_pager($a,count($r));
+ //$o .= alt_pager($a,count($r));
}
@@ -802,10 +802,10 @@ function widget_design_tools($arr) {
// mod menu doesn't load a profile. For any modules which load a profile, check it.
// otherwise local_channel() is sufficient for permissions.
- if(App::$profile['profile_uid'])
+ if(App::$profile['profile_uid'])
if((App::$profile['profile_uid'] != local_channel()) && (! App::$is_sys))
return '';
-
+
if(! local_channel())
return '';
@@ -817,10 +817,10 @@ function widget_website_portation_tools($arr) {
// mod menu doesn't load a profile. For any modules which load a profile, check it.
// otherwise local_channel() is sufficient for permissions.
- if(App::$profile['profile_uid'])
+ if(App::$profile['profile_uid'])
if((App::$profile['profile_uid'] != local_channel()) && (! App::$is_sys))
return '';
-
+
if(! local_channel())
return '';
@@ -841,7 +841,7 @@ function widget_photo_albums($arr) {
return '';
require_once('include/photos.php');
$sortkey = ((array_key_exists('sortkey',$arr)) ? $arr['sortkey'] : 'album');
- $direction = ((array_key_exists('direction',$arr)) ? $arr['direction'] : 'asc');
+ $direction = ((array_key_exists('direction',$arr)) ? $arr['direction'] : 'asc');
return photos_album_widget($channelx, App::get_observer(),$sortkey,$direction);
}
@@ -898,26 +898,14 @@ function widget_chatroom_members() {
}
function widget_wiki_list($arr) {
-
require_once("include/wiki.php");
- $channel = null;
- if (argc() < 2 && local_channel()) {
- // This should not occur because /wiki should redirect to /wiki/channel ...
- $channel = \App::get_channel();
- } else {
- $channel = get_channel_by_nick(argv(1)); // Channel being viewed by observer
- }
- if (!$channel) {
- return '';
- }
+ $channel = channelx_by_n(App::$profile_uid);
$wikis = wiki_list($channel, get_observer_hash());
- if ($wikis) {
- return replace_macros(get_markup_template('wikilist.tpl'), array(
+ if($wikis) {
+ return replace_macros(get_markup_template('wikilist_widget.tpl'), array(
'$header' => t('Wiki List'),
'$channel' => $channel['channel_address'],
- '$wikis' => $wikis['wikis'],
- // If the observer is the local channel owner, show the wiki controls
- '$showControls' => ((local_channel() === intval($channel['channel_id'])) ? true : false)
+ '$wikis' => $wikis['wikis']
));
}
return '';
@@ -948,13 +936,18 @@ function widget_wiki_pages($arr) {
}
}
}
+ $can_create = perm_is_allowed(\App::$profile['uid'],get_observer_hash(),'write_pages');
+
return replace_macros(get_markup_template('wiki_page_list.tpl'), array(
'$hide' => $hide,
'$not_refresh' => $not_refresh,
'$header' => t('Wiki Pages'),
'$channel' => $channelname,
'$wikiname' => $wikiname,
- '$pages' => $pages
+ '$pages' => $pages,
+ '$canadd' => $can_create,
+ '$addnew' => t('Add new page'),
+ '$pageName' => array('pageName', t('Page name')),
));
}
@@ -965,7 +958,8 @@ function widget_wiki_page_history($arr) {
$pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
return replace_macros(get_markup_template('wiki_page_history.tpl'), array(
- '$pageHistory' => $pageHistory['history']
+ '$pageHistory' => $pageHistory['history'],
+ '$permsWrite' => $arr['permsWrite']
));
}
@@ -996,9 +990,9 @@ function widget_suggestedchats($arr) {
if(! feature_enabled(App::$profile['profile_uid'],'ajaxchat'))
return '';
- // There are reports that this tool does not ever remove chatrooms on dead sites,
+ // There are reports that this tool does not ever remove chatrooms on dead sites,
// and also will happily link to private chats which you cannot enter.
- // For those reasons, it will be disabled until somebody decides it's worth
+ // For those reasons, it will be disabled until somebody decides it's worth
// fixing and comes up with a plan for doing so.
return '';
@@ -1044,7 +1038,7 @@ function widget_item($arr) {
if($arr['title']) {
$r = q("select item.* from item left join iconfig on item.id = iconfig.iid
- where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s'
+ where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s'
and iconfig.k = 'WEBPAGE' and item_type = %d $sql_options $revision limit 1",
intval($channel_id),
dbesc($arr['title']),
@@ -1108,7 +1102,7 @@ function showtime(){
// timeValue += ((seconds < 10) ? ":0" : ":") + seconds
if(! military)
timeValue += (hours >= 12) ? " P.M." : " A.M."
- $('.clockface').html(timeValue)
+ $('.clockface').html(timeValue)
timerID = setTimeout("showtime()",1000)
timerRunning = true
}
@@ -1124,17 +1118,16 @@ return $o;
}
-
/**
- * @function widget_photo($arr)
- * widget to display a single photo.
- * @param array $arr;
- * 'src' => URL of photo
- * 'zrl' => true or false, use zid in url
- * 'style' => CSS string
- * URL must be an http or https URL
+ * @brief Widget to display a single photo.
+ *
+ * @param array $arr associative array with
+ * * \e string \b src URL of photo; URL must be an http or https URL
+ * * \e boolean \b zrl use zid in URL
+ * * \e string \b style CSS string
+ *
+ * @return string with parsed HTML
*/
-
function widget_photo($arr) {
$style = $zrl = false;
@@ -1142,7 +1135,7 @@ function widget_photo($arr) {
if(array_key_exists('src', $arr) && isset($arr['src']))
$url = $arr['src'];
- if(strpos($url,'http') !== 0)
+ if(strpos($url, 'http') !== 0)
return '';
if(array_key_exists('style', $arr) && isset($arr['style']))
@@ -1150,7 +1143,7 @@ function widget_photo($arr) {
// ensure they can't sneak in an eval(js) function
- if(strpbrk($style,'(\'"<>') !== false)
+ if(strpbrk($style, '(\'"<>') !== false)
$style = '';
if(array_key_exists('zrl', $arr) && isset($arr['zrl']))
@@ -1161,8 +1154,8 @@ function widget_photo($arr) {
$o = '<div class="widget">';
- $o .= '<img ' . (($zrl) ? ' class="zrl" ' : '')
- . (($style) ? ' style="' . $style . '"' : '')
+ $o .= '<img ' . (($zrl) ? ' class="zrl" ' : '')
+ . (($style) ? ' style="' . $style . '"' : '')
. ' src="' . $url . '" alt="' . t('photo/image') . '">';
$o .= '</div>';
@@ -1175,7 +1168,7 @@ function widget_cover_photo($arr) {
require_once('include/channel.php');
$o = '';
-
+
if(App::$module == 'channel' && $_REQUEST['mid'])
return '';
@@ -1191,7 +1184,7 @@ function widget_cover_photo($arr) {
if(array_key_exists('style', $arr) && isset($arr['style']))
$style = $arr['style'];
- else
+ else
$style = 'width:100%; height: auto;';
// ensure they can't sneak in an eval(js) function
@@ -1273,8 +1266,8 @@ function widget_photo_rand($arr) {
$o = '<div class="widget">';
- $o .= '<img class="zrl" '
- . (($style) ? ' style="' . $style . '"' : '')
+ $o .= '<img class="zrl" '
+ . (($style) ? ' style="' . $style . '"' : '')
. ' src="' . $url . '" alt="' . t('photo/image') . '">';
$o .= '</div>';
@@ -1304,7 +1297,7 @@ function widget_random_block($arr) {
$randfunc = db_getfunc('RAND');
$r = q("select item.* from item left join iconfig on item.id = iconfig.iid
- where item.uid = %d and iconfig.cat = 'system' and iconfig.v like '%s' and iconfig.k = 'BUILDBLOCK' and
+ where item.uid = %d and iconfig.cat = 'system' and iconfig.v like '%s' and iconfig.k = 'BUILDBLOCK' and
item_type = %d $sql_options order by $randfunc limit 1",
intval($channel_id),
dbesc('%' . $contains . '%'),
@@ -1411,14 +1404,23 @@ function widget_forums($arr) {
$perms_sql = item_permissions_sql(local_channel()) . item_normal();
- /**
- * We used to try and find public forums with custom permissions by checking to see if
- * send_stream was false and tag_deliver was true. However with the newer extensible
- * permissions infrastructure this makes for a very complicated query. Now we're only
- * checking channels that report themselves specifically as pubforums
- */
+ $xf = false;
- $r1 = q("select abook_id, xchan_hash, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_pubforum = 1 and xchan_deleted = 0 and abook_channel = %d order by xchan_name $limit ",
+ $x1 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'send_stream' and v = '0'",
+ intval(local_channel())
+ );
+ if($x1) {
+ $xc = ids_to_querystr($x1,'xchan',true);
+ $x2 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'tag_deliver' and v = '1' and xchan in (" . $xc . ") ",
+ intval(local_channel())
+ );
+ if($x2)
+ $xf = ids_to_querystr($x2,'xchan',true);
+ }
+
+ $sql_extra = (($xf) ? " and ( xchan_hash in (" . $xf . ") or xchan_pubforum = 1 ) " : " and xchan_pubforum = 1 ");
+
+ $r1 = q("select abook_id, xchan_hash, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d $sql_extra order by xchan_name $limit ",
intval(local_channel())
);
if(! $r1)
@@ -1440,11 +1442,11 @@ function widget_forums($arr) {
/**
* @FIXME
* This SQL makes the counts correct when you get forum posts arriving from different routes/sources
- * (like personal channels). However the network query for these posts doesn't yet include this
- * correction and it makes the SQL for that query pretty hairy so this is left as a future exercise.
+ * (like personal channels). However the network query for these posts doesn't yet include this
+ * correction and it makes the SQL for that query pretty hairy so this is left as a future exercise.
* It may make more sense in that query to look for the mention in the body rather than another join,
* but that makes it very inefficient.
- *
+ *
$r = q("select sum(item_unseen) as unseen from item left join term on oid = id where otype = %d and owner_xchan != '%s' and item.uid = %d and url = '%s' and ttype = %d $perms_sql ",
intval(TERM_OBJ_POST),
dbesc($r1[$x]['xchan_hash']),
@@ -1457,7 +1459,7 @@ function widget_forums($arr) {
*
* end @FIXME
*/
-
+
}
if($r1) {
@@ -1471,7 +1473,7 @@ function widget_forums($arr) {
}
$o .= '</ul></div>';
}
- return $o;
+ return $o;
}
@@ -1489,7 +1491,7 @@ function widget_tasklist($arr) {
$(".tasklist-tasks").html(data.html);
});
}
- </script>';
+ </script>';
$o .= '<div class="widget">' . '<h3>' . t('Tasks') . '</h3><div class="tasklist-tasks">';
$o .= '</div><form id="tasklist-new-form" action="" ><input id="tasklist-new-summary" type="text" name="summary" value="" /></form>';
@@ -1502,7 +1504,6 @@ function widget_tasklist($arr) {
function widget_helpindex($arr) {
$o .= '<div class="widget">';
- $o .= '<h3>' . t('Documentation') . '</h3>';
$level_0 = get_help_content('sitetoc');
if(! $level_0)
@@ -1516,7 +1517,7 @@ function widget_helpindex($arr) {
if(argc() > 2) {
$path = '';
for($x = 1; $x < argc(); $x ++) {
- $path .= argv($x) . '/';
+ $path .= argv($x) . '/';
$y = get_help_content($path . 'sitetoc');
if(! $y)
$y = get_help_content($path . 'toc');
@@ -1590,7 +1591,7 @@ function widget_admin($arr) {
call_hooks('admin_aside',$arr);
$o .= replace_macros(get_markup_template('admin_aside.tpl'), array(
- '$admin' => $aside,
+ '$admin' => $aside,
'$admtxt' => t('Admin'),
'$plugadmtxt' => t('Plugin Features'),
'$plugins' => $plugins,
@@ -1620,7 +1621,7 @@ function widget_album($args) {
if($args['title'])
$title = $args['title'];
- /**
+ /**
* This may return incorrect permissions if you have multiple directories of the same name.
* It is a limitation of the photo table using a name for a photo album instead of a folder hash
*/
@@ -1640,7 +1641,7 @@ function widget_album($args) {
$order = 'DESC';
$r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.imgscale, p.description, p.created FROM photo p INNER JOIN
- (SELECT resource_id, max(imgscale) imgscale FROM photo WHERE uid = %d AND album = '%s' AND imgscale <= 4 AND photo_usage IN ( %d, %d ) $sql_extra GROUP BY resource_id) ph
+ (SELECT resource_id, max(imgscale) imgscale FROM photo WHERE uid = %d AND album = '%s' AND imgscale <= 4 AND photo_usage IN ( %d, %d ) $sql_extra GROUP BY resource_id) ph
ON (p.resource_id = ph.resource_id AND p.imgscale = ph.imgscale)
ORDER BY created $order ",
intval($owner_uid),
@@ -1648,7 +1649,7 @@ function widget_album($args) {
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE)
);
-
+
//edit album name
$album_edit = null;
@@ -1661,7 +1662,7 @@ function widget_album($args) {
$twist = 'rotleft';
else
$twist = 'rotright';
-
+
$ext = $phototypes[$rr['mimetype']];
$imgalt_e = $rr['filename'];
diff --git a/include/wiki.php b/include/wiki.php
index d52308b08..332d4efe0 100644
--- a/include/wiki.php
+++ b/include/wiki.php
@@ -13,11 +13,15 @@ function wiki_list($channel, $observer_hash) {
dbesc(WIKI_ITEM_RESOURCE_TYPE),
intval($channel['channel_id'])
);
- foreach($wikis as &$w) {
- $w['rawName'] = get_iconfig($w, 'wiki', 'rawName');
- $w['htmlName'] = get_iconfig($w, 'wiki', 'htmlName');
- $w['urlName'] = get_iconfig($w, 'wiki', 'urlName');
- $w['path'] = get_iconfig($w, 'wiki', 'path');
+ if($wikis) {
+ foreach($wikis as &$w) {
+ $w['rawName'] = get_iconfig($w, 'wiki', 'rawName');
+ $w['htmlName'] = get_iconfig($w, 'wiki', 'htmlName');
+ $w['urlName'] = get_iconfig($w, 'wiki', 'urlName');
+ $w['path'] = get_iconfig($w, 'wiki', 'path');
+ $w['mimeType'] = get_iconfig($w, 'wiki', 'mimeType');
+ $w['lock'] = (($w['allow_cid'] || $w['allow_gid'] || $w['deny_cid'] || $w['deny_gid']) ? true : false);
+ }
}
// TODO: query db for wikis the observer can access. Return with two lists, for read and write access
return array('wikis' => $wikis);
@@ -29,14 +33,30 @@ function wiki_page_list($resource_id) {
if (!$w['path']) {
return array('pages' => null, 'wiki' => null);
}
- $pages = array();
+
+ $pages[] = [
+ 'resource_id' => '',
+ 'title' => 'Home',
+ 'url' => 'Home',
+ 'link_id' => 'id_wiki_home_0'
+ ];
+
if (is_dir($w['path']) === true) {
$files = array_diff(scandir($w['path']), array('.', '..', '.git'));
// TODO: Check that the files are all text files
-
+ $i = 1;
foreach($files as $file) {
- // strip the .md file extension and unwrap URL encoding to leave HTML encoded name
- $pages[] = array('title' => urldecode(substr($file, 0, -3)), 'url' => urlencode(substr($file, 0, -3)));
+ // strip the file extension and unwrap URL encoding to leave HTML encoded name
+ $title = substr($file, 0, strrpos($file,'.'));
+ if(urldecode($title) !== 'Home') {
+ $pages[] = [
+ 'resource_id' => $resource_id,
+ 'title' => urldecode($title),
+ 'url' => $title,
+ 'link_id' => 'id_' . substr($resource_id, 0, 10) . '_' . $i
+ ];
+ $i++;
+ }
}
}
@@ -73,7 +93,7 @@ function wiki_create_wiki($channel, $observer_hash, $wiki, $acl) {
$resource_id = random_string();
$r = q("SELECT mid FROM item WHERE resource_id = '%s' AND resource_type = '%s' AND uid = %d LIMIT 1",
dbesc($resource_id),
- dbesc(WIKI_ITEM_RESOURCE_TYPE),
+ dbesc(WIKI_ITEM_RESOURCE_TYPE),
intval($channel['channel_id'])
);
if (count($r))
@@ -121,12 +141,15 @@ function wiki_create_wiki($channel, $observer_hash, $wiki, $acl) {
if (!set_iconfig($arr, 'wiki', 'urlName', $wiki['urlName'], true)) {
return array('item' => null, 'success' => false);
}
+ if (!set_iconfig($arr, 'wiki', 'mimeType', $wiki['mimeType'], true)) {
+ return array('item' => null, 'success' => false);
+ }
$post = item_store($arr);
$item_id = $post['item_id'];
if ($item_id) {
- proc_run('php', "include/notifier.php", "activity", $item_id);
- return array('item' => $arr, 'success' => true);
+ \Zotlabs\Daemon\Master::Summon(array('Notifier', 'activity', $item_id));
+ return array('item' => $post['item'], 'success' => true);
} else {
return array('item' => null, 'success' => false);
}
@@ -150,8 +173,8 @@ function wiki_delete_wiki($resource_id) {
function wiki_get_wiki($resource_id) {
$item = q("SELECT * FROM item WHERE resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0 limit 1",
- dbesc(WIKI_ITEM_RESOURCE_TYPE),
- dbesc($resource_id)
+ dbesc(WIKI_ITEM_RESOURCE_TYPE),
+ dbesc($resource_id)
);
if (!$item) {
return array('wiki' => null, 'path' => null);
@@ -161,17 +184,21 @@ function wiki_get_wiki($resource_id) {
$rawName = get_iconfig($w, 'wiki', 'rawName');
$htmlName = get_iconfig($w, 'wiki', 'htmlName');
$urlName = get_iconfig($w, 'wiki', 'urlName');
+ $mimeType = get_iconfig($w, 'wiki', 'mimeType');
+
$path = get_iconfig($w, 'wiki', 'path');
if (!realpath(__DIR__ . '/../' . $path)) {
return array('wiki' => null, 'path' => null);
}
// Path to wiki exists
$abs_path = realpath(__DIR__ . '/../' . $path);
- return array( 'wiki' => $w,
- 'path' => $abs_path,
- 'rawName' => $rawName,
- 'htmlName' => $htmlName,
- 'urlName' => $urlName
+ return array(
+ 'wiki' => $w,
+ 'path' => $abs_path,
+ 'rawName' => $rawName,
+ 'htmlName' => $htmlName,
+ 'urlName' => $urlName,
+ 'mimeType' => $mimeType
);
}
}
@@ -192,22 +219,23 @@ function wiki_exists_by_name($uid, $urlName) {
function wiki_get_permissions($resource_id, $owner_id, $observer_hash) {
// TODO: For now, only the owner can edit
$sql_extra = item_permissions_sql($owner_id, $observer_hash);
- $r = q("SELECT * FROM item WHERE resource_type = '%s' AND resource_id = '%s' $sql_extra LIMIT 1",
- dbesc(WIKI_ITEM_RESOURCE_TYPE),
- dbesc($resource_id)
- );
-
+
+ if(local_channel() && local_channel == $owner_id) {
+ return [ 'read' => true, 'write' => true, 'success' => true ];
+ }
+
+ $r = q("SELECT * FROM item WHERE uid = %d and resource_type = '%s' AND resource_id = '%s' $sql_extra LIMIT 1",
+ intval($owner_id),
+ dbesc(WIKI_ITEM_RESOURCE_TYPE),
+ dbesc($resource_id)
+ );
+
if (!$r) {
return array('read' => false, 'write' => false, 'success' => true);
} else {
- $perms = get_all_perms($owner_id, $observer_hash);
// TODO: Create a new permission setting for wiki analogous to webpages. Until
// then, use webpage permissions
- if (!$perms['write_pages']) {
- $write = false;
- } else {
- $write = true;
- }
+ $write = perm_is_allowed($owner_id, $observer_hash,'write_pages');
return array('read' => true, 'write' => $write, 'success' => true);
}
}
@@ -217,7 +245,8 @@ function wiki_create_page($name, $resource_id) {
if (!$w['path']) {
return array('page' => null, 'wiki' => null, 'message' => 'Wiki not found.', 'success' => false);
}
- $page = array('rawName' => $name, 'htmlName' => escape_tags($name), 'urlName' => urlencode(escape_tags($name)), 'fileName' => urlencode(escape_tags($name)).'.md');
+
+ $page = array('rawName' => $name, 'htmlName' => escape_tags($name), 'urlName' => urlencode(escape_tags($name)), 'fileName' => urlencode(escape_tags($name)) . wiki_get_file_ext($w));
$page_path = $w['path'] . '/' . $page['fileName'];
if (is_file($page_path)) {
return array('page' => null, 'wiki' => null, 'message' => 'Page already exists.', 'success' => false);
@@ -239,11 +268,11 @@ function wiki_rename_page($arr) {
if (!$w['path']) {
return array('message' => 'Wiki not found.', 'success' => false);
}
- $page_path_old = $w['path'].'/'.$pageUrlName.'.md';
+ $page_path_old = $w['path'] . '/' . $pageUrlName . wiki_get_file_ext($w);
if (!is_readable($page_path_old) === true) {
return array('message' => 'Cannot read wiki page: ' . $page_path_old, 'success' => false);
}
- $page = array('rawName' => $pageNewName, 'htmlName' => escape_tags($pageNewName), 'urlName' => urlencode(escape_tags($pageNewName)), 'fileName' => urlencode(escape_tags($pageNewName)).'.md');
+ $page = array('rawName' => $pageNewName, 'htmlName' => escape_tags($pageNewName), 'urlName' => urlencode(escape_tags($pageNewName)), 'fileName' => urlencode(escape_tags($pageNewName)) . wiki_get_file_ext($w));
$page_path_new = $w['path'] . '/' . $page['fileName'] ;
if (is_file($page_path_new)) {
return array('message' => 'Page already exists.', 'success' => false);
@@ -264,7 +293,7 @@ function wiki_get_page_content($arr) {
if (!$w['path']) {
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
}
- $page_path = $w['path'].'/'.$pageUrlName.'.md';
+ $page_path = $w['path'] . '/' . $pageUrlName . wiki_get_file_ext($w);
if (is_readable($page_path) === true) {
if(filesize($page_path) === 0) {
$content = '';
@@ -275,7 +304,7 @@ function wiki_get_page_content($arr) {
}
}
// TODO: Check that the files are all text files
- return array('content' => json_encode($content), 'message' => '', 'success' => true);
+ return array('content' => json_encode($content), 'mimeType' => $w['mimeType'], 'message' => '', 'success' => true);
}
}
@@ -286,7 +315,7 @@ function wiki_page_history($arr) {
if (!$w['path']) {
return array('history' => null, 'message' => 'Error reading wiki', 'success' => false);
}
- $page_path = $w['path'].'/'.$pageUrlName.'.md';
+ $page_path = $w['path'] . '/' . $pageUrlName . wiki_get_file_ext($w);
if (!is_readable($page_path) === true) {
return array('history' => null, 'message' => 'Cannot read wiki page: ' . $page_path, 'success' => false);
}
@@ -311,12 +340,14 @@ function wiki_save_page($arr) {
if (!$w['path']) {
return array('message' => 'Error reading wiki', 'success' => false);
}
- $page_path = $w['path'].'/'.$pageUrlName.'.md';
+
+ $fileName = $pageUrlName . wiki_get_file_ext($w);
+ $page_path = $w['path'] . '/' . $fileName;
if (is_writable($page_path) === true) {
if(!file_put_contents($page_path, $content)) {
return array('message' => 'Error writing to page file', 'success' => false);
}
- return array('message' => '', 'success' => true);
+ return array('message' => '', 'filename' => $filename, 'success' => true);
} else {
return array('message' => 'Page file not writable', 'success' => false);
}
@@ -329,7 +360,7 @@ function wiki_delete_page($arr) {
if (!$w['path']) {
return array('message' => 'Error reading wiki', 'success' => false);
}
- $page_path = $w['path'].'/'.$pageUrlName.'.md';
+ $page_path = $w['path'] . '/' . $pageUrlName . wiki_get_file_ext($w);
if (is_writable($page_path) === true) {
if(!unlink($page_path)) {
return array('message' => 'Error deleting page file', 'success' => false);
@@ -351,7 +382,7 @@ function wiki_revert_page($arr) {
if (!$w['path']) {
return array('content' => $content, 'message' => 'Error reading wiki', 'success' => false);
}
- $page_path = $w['path'].'/'.$pageUrlName.'.md';
+ $page_path = $w['path'] . '/' . $pageUrlName . wiki_get_file_ext($w);
if (is_writable($page_path) === true) {
$reponame = ((array_key_exists('title', $w['wiki'])) ? urlencode($w['wiki']['title']) : 'repo');
@@ -363,7 +394,7 @@ function wiki_revert_page($arr) {
try {
$git->setIdentity($observer['xchan_name'], $observer['xchan_addr']);
foreach ($git->git->tree($commitHash) as $object) {
- if ($object['type'] == 'blob' && $object['file'] === $pageUrlName.'.md' ) {
+ if ($object['type'] == 'blob' && $object['file'] === $pageUrlName . wiki_get_file_ext($w)) {
$content = $git->git->cat->blob($object['hash']);
}
}
@@ -388,7 +419,7 @@ function wiki_compare_page($arr) {
if (!$w['path']) {
return array('message' => 'Error reading wiki', 'success' => false);
}
- $page_path = $w['path'].'/'.$pageUrlName.'.md';
+ $page_path = $w['path'] . '/' . $pageUrlName . wiki_get_file_ext($w);
if (is_readable($page_path) === true) {
$reponame = ((array_key_exists('title', $w['wiki'])) ? urlencode($w['wiki']['title']) : 'repo');
if($reponame === '') {
@@ -398,12 +429,12 @@ function wiki_compare_page($arr) {
$compareContent = $currentContent = '';
try {
foreach ($git->git->tree($currentCommit) as $object) {
- if ($object['type'] == 'blob' && $object['file'] === $pageUrlName.'.md' ) {
+ if ($object['type'] == 'blob' && $object['file'] === $pageUrlName . wiki_get_file_ext($w)) {
$currentContent = $git->git->cat->blob($object['hash']);
}
}
foreach ($git->git->tree($compareCommit) as $object) {
- if ($object['type'] == 'blob' && $object['file'] === $pageUrlName.'.md' ) {
+ if ($object['type'] == 'blob' && $object['file'] === $pageUrlName . wiki_get_file_ext($w)) {
$compareContent = $git->git->cat->blob($object['hash']);
}
}
@@ -466,15 +497,6 @@ function wiki_git_commit($arr) {
}
}
-function wiki_generate_page_filename($name) {
- $file = urlencode(escape_tags($name));
- if( $file === '') {
- return null;
- } else {
- return $file . '.md';
- }
-}
-
function wiki_convert_links($s, $wikiURL) {
if (strpos($s,'[[') !== false) {
@@ -502,7 +524,6 @@ function wiki_convert_links($s, $wikiURL) {
* @return string
*/
function wiki_generate_toc($s) {
-
if (strpos($s,'[toc]') !== false) {
//$toc_md = wiki_toc($s); // Generate Markdown-formatted list prior to HTML render
$toc_md = '<ul id="wiki-toc"></ul>'; // use the available jQuery plugin http://ndabas.github.io/toc/
@@ -544,6 +565,13 @@ function wiki_bbcode($s) {
return $s;
}
+function wiki_get_file_ext($arr) {
+ if($arr['mimeType'] == 'text/bbcode')
+ return '.bb';
+ else
+ return '.md';
+}
+
// This function is derived from
// http://stackoverflow.com/questions/32068537/generate-table-of-contents-from-markdown-in-php
function wiki_toc($content) {
@@ -552,36 +580,36 @@ function wiki_toc($content) {
// look for markdown TOC items
preg_match_all(
- '/^(?:=|-|#).*$/m',
- $source,
- $matches,
- PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE
+ '/^(?:=|-|#).*$/m',
+ $source,
+ $matches,
+ PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE
);
// preprocess: iterate matched lines to create an array of items
// where each item is an array(level, text)
$file_size = strlen($source);
foreach ($matches[0] as $item) {
- $found_mark = substr($item[0], 0, 1);
- if ($found_mark == '#') {
- // text is the found item
- $item_text = $item[0];
- $item_level = strrpos($item_text, '#') + 1;
- $item_text = substr($item_text, $item_level);
- } else {
- // text is the previous line (empty if <hr>)
- $item_offset = $item[1];
- $prev_line_offset = strrpos($source, "\n", -($file_size - $item_offset + 2));
- $item_text =
- substr($source, $prev_line_offset, $item_offset - $prev_line_offset - 1);
- $item_text = trim($item_text);
- $item_level = $found_mark == '=' ? 1 : 2;
- }
- if (!trim($item_text) OR strpos($item_text, '|') !== FALSE) {
- // item is an horizontal separator or a table header, don't mind
- continue;
- }
- $raw_toc[] = ['level' => $item_level, 'text' => trim($item_text)];
+ $found_mark = substr($item[0], 0, 1);
+ if ($found_mark == '#') {
+ // text is the found item
+ $item_text = $item[0];
+ $item_level = strrpos($item_text, '#') + 1;
+ $item_text = substr($item_text, $item_level);
+ } else {
+ // text is the previous line (empty if <hr>)
+ $item_offset = $item[1];
+ $prev_line_offset = strrpos($source, "\n", -($file_size - $item_offset + 2));
+ $item_text =
+ substr($source, $prev_line_offset, $item_offset - $prev_line_offset - 1);
+ $item_text = trim($item_text);
+ $item_level = $found_mark == '=' ? 1 : 2;
+ }
+ if (!trim($item_text) OR strpos($item_text, '|') !== FALSE) {
+ // item is an horizontal separator or a table header, don't mind
+ continue;
+ }
+ $raw_toc[] = ['level' => $item_level, 'text' => trim($item_text)];
}
$o = '';
foreach($raw_toc as $t) {
diff --git a/include/zid.php b/include/zid.php
new file mode 100644
index 000000000..ac6433e4c
--- /dev/null
+++ b/include/zid.php
@@ -0,0 +1,232 @@
+<?php
+
+
+function is_matrix_url($url) {
+
+ // in-memory cache to avoid repeated queries for the same host
+ static $remembered = [];
+
+ $m = @parse_url($url);
+ if($m['host']) {
+
+ if(array_key_exists($m['host'],$remembered))
+ return $remembered[$m['host']];
+
+ $r = q("select hubloc_url from hubloc where hubloc_host = '%s' and hubloc_network = 'zot' limit 1",
+ dbesc($m['host'])
+ );
+ if($r) {
+ $remembered[$m['host']] = true;
+ return true;
+ }
+ $remembered[$m['host']] = false;
+ }
+ return false;
+}
+
+/**
+ * @brief Adds a zid parameter to a url.
+ *
+ * @param string $s
+ * The url to accept the zid
+ * @param boolean $address
+ * $address to use instead of session environment
+ * @return string
+ *
+ * @hooks 'zid'
+ * string url - url to accept zid
+ * string zid - urlencoded zid
+ * string result - the return string we calculated, change it if you want to return something else
+ */
+
+function zid($s,$address = '') {
+ if (! strlen($s) || strpos($s,'zid='))
+ return $s;
+
+ $m = parse_url($s);
+ $fragment = ((array_key_exists('fragment',$m) && $m['fragment']) ? $m['fragment'] : false);
+ if($fragment !== false)
+ $s = str_replace('#' . $fragment,'',$s);
+
+ $has_params = ((strpos($s,'?')) ? true : false);
+ $num_slashes = substr_count($s, '/');
+ if (! $has_params)
+ $has_params = ((strpos($s, '&')) ? true : false);
+
+ $achar = strpos($s,'?') ? '&' : '?';
+
+ $mine = get_my_url();
+ $myaddr = (($address) ? $address : get_my_address());
+
+ /**
+ * @FIXME checking against our own channel url is no longer reliable. We may have a lot
+ * of urls attached to out channel. Should probably match against our site, since we
+ * will not need to remote authenticate on our own site anyway.
+ */
+
+ if ($mine && $myaddr && (! link_compare($mine,$s)))
+ $zurl = $s . (($num_slashes >= 3) ? '' : '/') . $achar . 'zid=' . urlencode($myaddr);
+ else
+ $zurl = $s;
+
+ // put fragment at the end
+
+ if($fragment)
+ $zurl .= '#' . $fragment;
+
+ $arr = array('url' => $s, 'zid' => urlencode($myaddr), 'result' => $zurl);
+ call_hooks('zid', $arr);
+
+ return $arr['result'];
+}
+
+
+function strip_zids($s) {
+ return preg_replace('/[\?&]zid=(.*?)(&|$)/ism','$2',$s);
+}
+
+function strip_zats($s) {
+ return preg_replace('/[\?&]zat=(.*?)(&|$)/ism','$2',$s);
+}
+
+
+/**
+ * zidify_callback() and zidify_links() work together to turn any HTML a tags with class="zrl" into zid links
+ * These will typically be generated by a bbcode '[zrl]' tag. This is done inside prepare_text() rather than bbcode()
+ * because the latter is used for general purpose conversions and the former is used only when preparing text for
+ * immediate display.
+ *
+ * Issues: Currently the order of HTML parameters in the text is somewhat rigid and inflexible.
+ * We assume it looks like \<a class="zrl" href="xxxxxxxxxx"\> and will not work if zrl and href appear in a different order.
+ *
+ * @param array $match
+ * @return string
+ */
+function zidify_callback($match) {
+ $is_zid = ((feature_enabled(local_channel(),'sendzid')) || (strpos($match[1],'zrl')) ? true : false);
+ $replace = '<a' . $match[1] . ' href="' . (($is_zid) ? zid($match[2]) : $match[2]) . '"';
+ $x = str_replace($match[0],$replace,$match[0]);
+
+ return $x;
+}
+
+function zidify_img_callback($match) {
+ $is_zid = ((feature_enabled(local_channel(),'sendzid')) || (strpos($match[1],'zrl')) ? true : false);
+ $replace = '<img' . $match[1] . ' src="' . (($is_zid) ? zid($match[2]) : $match[2]) . '"';
+
+ $x = str_replace($match[0],$replace,$match[0]);
+
+ return $x;
+}
+
+
+function zidify_links($s) {
+ $s = preg_replace_callback('/\<a(.*?)href\=\"(.*?)\"/ism','zidify_callback',$s);
+ $s = preg_replace_callback('/\<img(.*?)src\=\"(.*?)\"/ism','zidify_img_callback',$s);
+
+ return $s;
+}
+
+
+
+
+function zidify_text_callback($match) {
+ $is_zid = is_matrix_url($match[2]);
+ $replace = '<a' . $match[1] . ' href="' . (($is_zid) ? zid($match[2]) : $match[2]) . '"';
+ $x = str_replace($match[0],$replace,$match[0]);
+
+ return $x;
+}
+
+function zidify_text_img_callback($match) {
+ $is_zid = is_matrix_url($match[2]);
+ $replace = '<img' . $match[1] . ' src="' . (($is_zid) ? zid($match[2]) : $match[2]) . '"';
+
+ $x = str_replace($match[0],$replace,$match[0]);
+
+ return $x;
+}
+
+function zidify_text($s) {
+
+ $s = preg_replace_callback('/\<a(.*?)href\=\"(.*?)\"/ism','zidify_text_callback',$s);
+ $s = preg_replace_callback('/\<img(.*?)src\=\"(.*?)\"/ism','zidify_text_img_callback',$s);
+
+ return $s;
+
+
+}
+
+
+/**
+ * @brief preg_match function when fixing 'naked' links in mod item.php.
+ *
+ * Check if we've got a hubloc for the site and use a zrl if we do, a url if we don't.
+ * Remove any existing zid= param which may have been pasted by mistake - and will have
+ * the author's credentials. zid's are dynamic and can't really be passed around like
+ * that.
+ *
+ * @param array $matches
+ * @return string
+ */
+function red_zrl_callback($matches) {
+ require_once('include/hubloc.php');
+ $zrl = is_matrix_url($matches[2]);
+
+ $t = strip_zids($matches[2]);
+ if($t !== $matches[2]) {
+ $zrl = true;
+ $matches[2] = $t;
+ }
+
+ if($matches[1] === '#^')
+ $matches[1] = '';
+ if($zrl)
+ return $matches[1] . '#^[zrl=' . $matches[2] . ']' . $matches[2] . '[/zrl]';
+
+ return $matches[1] . '#^[url=' . $matches[2] . ']' . $matches[2] . '[/url]';
+}
+
+/**
+ * If we've got a url or zrl tag with a naked url somewhere in the link text,
+ * escape it with quotes unless the naked url is a linked photo.
+ *
+ * @param array $matches
+ * @return string
+ */
+
+function red_escape_zrl_callback($matches) {
+
+ // Uncertain why the url/zrl forms weren't picked up by the non-greedy regex.
+
+ if((strpos($matches[3], 'zmg') !== false) || (strpos($matches[3], 'img') !== false) || (strpos($matches[3],'zrl') !== false) || (strpos($matches[3],'url') !== false))
+ return $matches[0];
+
+ return '[' . $matches[1] . 'rl' . $matches[2] . ']' . $matches[3] . '"' . $matches[4] . '"' . $matches[5] . '[/' . $matches[6] . 'rl]';
+}
+
+function red_escape_codeblock($m) {
+ return '[$b64' . $m[2] . base64_encode($m[1]) . '[/' . $m[2] . ']';
+}
+
+function red_unescape_codeblock($m) {
+ return '[' . $m[2] . base64_decode($m[1]) . '[/' . $m[2] . ']';
+}
+
+
+function red_zrlify_img_callback($matches) {
+ require_once('include/hubloc.php');
+ $zrl = is_matrix_url($matches[2]);
+
+ $t = strip_zids($matches[2]);
+ if($t !== $matches[2]) {
+ $zrl = true;
+ $matches[2] = $t;
+ }
+
+ if($zrl)
+ return '[zmg' . $matches[1] . ']' . $matches[2] . '[/zmg]';
+
+ return $matches[0];
+}
+
diff --git a/include/zot.php b/include/zot.php
index 572cbaef8..77843c35b 100644
--- a/include/zot.php
+++ b/include/zot.php
@@ -110,20 +110,21 @@ function zot_get_hublocs($hash) {
* @param string $extra
* @returns string json encoded zot packet
*/
-function zot_build_packet($channel, $type = 'notify', $recipients = null, $remote_key = null, $secret = null, $extra = null) {
+function zot_build_packet($channel, $type = 'notify', $recipients = null, $remote_key = null, $methods = '', $secret = null, $extra = null) {
- $data = array(
+ $data = [
'type' => $type,
- 'sender' => array(
+ 'sender' => [
'guid' => $channel['channel_guid'],
'guid_sig' => base64url_encode(rsa_sign($channel['channel_guid'],$channel['channel_prvkey'])),
'url' => z_root(),
'url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])),
'sitekey' => get_config('system','pubkey')
- ),
+ ],
'callback' => '/post',
- 'version' => ZOT_REVISION
- );
+ 'version' => ZOT_REVISION,
+ 'encryption' => crypto_methods()
+ ];
if ($recipients) {
for ($x = 0; $x < count($recipients); $x ++)
@@ -146,120 +147,67 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot
// Hush-hush ultra top-secret mode
- if ($remote_key) {
- $data = crypto_encapsulate(json_encode($data),$remote_key);
+ if($remote_key) {
+ $algorithm = zot_best_algorithm($methods);
+ $data = crypto_encapsulate(json_encode($data),$remote_key, $algorithm);
}
return json_encode($data);
}
/**
- * @brief
- *
- * @see z_post_url()
- *
- * @param string $url
- * @param array $data
- * @return array see z_post_url() for returned data format
- */
-function zot_zot($url, $data) {
- return z_post_url($url, array('data' => $data));
-}
-
-/**
- * @brief Look up information about channel.
- *
- * @param string $webbie
- * does not have to be host qualified e.g. 'foo' is treated as 'foo\@thishub'
- * @param array $channel
- * (optional), if supplied permissions will be enumerated specifically for $channel
- * @param boolean $autofallback
- * fallback/failover to http if https connection cannot be established. Default is true.
- *
- * @return array see z_post_url() and \ref mod/zfinger.php
+ * @brief choose best encryption function from those available on both sites
+ *
+ * @param string $methods
+ * comma separated list of encryption methods
+ * @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.
*/
-function zot_finger($webbie, $channel = null, $autofallback = true) {
-
- if (strpos($webbie,'@') === false) {
- $address = $webbie;
- $host = App::get_hostname();
- } else {
- $address = substr($webbie,0,strpos($webbie,'@'));
- $host = substr($webbie,strpos($webbie,'@')+1);
- }
-
- $xchan_addr = $address . '@' . $host;
-
- if ((! $address) || (! $xchan_addr)) {
- logger('zot_finger: no address :' . $webbie);
- return array('success' => false);
- }
- logger('using xchan_addr: ' . $xchan_addr, LOGGER_DATA, LOG_DEBUG);
- // potential issue here; the xchan_addr points to the primary hub.
- // The webbie we were called with may not, so it might not be found
- // unless we query for hubloc_addr instead of xchan_addr
+function zot_best_algorithm($methods) {
- $r = q("select xchan.*, hubloc.* from xchan
- left join hubloc on xchan_hash = hubloc_hash
- where xchan_addr = '%s' and hubloc_primary = 1 limit 1",
- dbesc($xchan_addr)
- );
-
- if ($r) {
- $url = $r[0]['hubloc_url'];
+ if(\Zotlabs\Lib\System::get_server_role() !== 'pro')
+ return 'aes256cbc';
- if ($r[0]['hubloc_network'] && $r[0]['hubloc_network'] !== 'zot') {
- logger('zot_finger: alternate network: ' . $webbie);
- logger('url: '.$url.', net: '.var_export($r[0]['hubloc_network'],true), LOGGER_DATA, LOG_DEBUG);
- return array('success' => false);
+ if($methods) {
+ $x = explode(',',$methods);
+ if($x) {
+ $y = crypto_methods();
+ if($y) {
+ foreach($y as $yv) {
+ $yv = trim($yv);
+ if(in_array($yv,$x)) {
+ return($yv);
+ }
+ }
+ }
}
- } else {
- $url = 'https://' . $host;
}
- $rhs = '/.well-known/zot-info';
- $https = ((strpos($url,'https://') === 0) ? true : false);
-
- logger('zot_finger: ' . $address . ' at ' . $url, LOGGER_DEBUG);
-
- if ($channel) {
- $postvars = array(
- 'address' => $address,
- 'target' => $channel['channel_guid'],
- 'target_sig' => $channel['channel_guid_sig'],
- 'key' => $channel['channel_pubkey']
- );
-
- $result = z_post_url($url . $rhs,$postvars);
-
- if ((! $result['success']) && ($autofallback)) {
- if ($https) {
- logger('zot_finger: https failed. falling back to http');
- $result = z_post_url('http://' . $host . $rhs,$postvars);
- }
- }
- } else {
- $rhs .= '?f=&address=' . urlencode($address);
+ return 'aes256cbc';
+}
- $result = z_fetch_url($url . $rhs);
- if ((! $result['success']) && ($autofallback)) {
- if ($https) {
- logger('zot_finger: https failed. falling back to http');
- $result = z_fetch_url('http://' . $host . $rhs);
- }
- }
- }
- if (! $result['success'])
- logger('zot_finger: no results');
- return $result;
+/**
+ * @brief
+ *
+ * @see z_post_url()
+ *
+ * @param string $url
+ * @param array $data
+ * @return array see z_post_url() for returned data format
+ */
+function zot_zot($url, $data) {
+ return z_post_url($url, array('data' => $data));
}
/**
* @brief Refreshes after permission changed or friending, etc.
*
+ * The top half of this function is similar to \Zotlabs\Zot\Finger::run() and could potentially be
+ * consolidated.
+ *
* zot_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
* (abook entry) being added to a local channel and it may result in auto-permissions being granted.
@@ -281,6 +229,7 @@ function zot_finger($webbie, $channel = null, $autofallback = true) {
*
* @returns boolean true if successful, else false
*/
+
function zot_refresh($them, $channel = null, $force = false) {
if (array_key_exists('xchan_network', $them) && ($them['xchan_network'] !== 'zot')) {
@@ -296,12 +245,13 @@ function zot_refresh($them, $channel = null, $force = false) {
if ($them['hubloc_url']) {
$url = $them['hubloc_url'];
- } else {
+ }
+ else {
$r = null;
// 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
- // 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.
if(array_key_exists('xchan_addr',$them) && $them['xchan_addr']) {
$r = q("select hubloc_url, hubloc_primary from hubloc where hubloc_addr = '%s' order by hubloc_id desc",
@@ -332,7 +282,7 @@ function zot_refresh($them, $channel = null, $force = false) {
$token = random_string();
- $postvars = array();
+ $postvars = [];
$postvars['token'] = $token;
@@ -355,6 +305,8 @@ function zot_refresh($them, $channel = null, $force = false) {
$rhs = '/.well-known/zot-info';
+ logger('zot_refresh: ' . $url, LOGGER_DATA, LOG_INFO);
+
$result = z_post_url($url . $rhs,$postvars);
logger('zot_refresh: zot-info: ' . print_r($result,true), LOGGER_DATA, LOG_DEBUG);
@@ -391,10 +343,13 @@ function zot_refresh($them, $channel = null, $force = false) {
if($channel) {
if($j['permissions']['data']) {
- $permissions = crypto_unencapsulate(array(
+ $permissions = crypto_unencapsulate(
+ [
'data' => $j['permissions']['data'],
'key' => $j['permissions']['key'],
- 'iv' => $j['permissions']['iv']),
+ 'iv' => $j['permissions']['iv'],
+ 'alg' => $j['permissions']['alg']
+ ],
$channel['channel_prvkey']);
if($permissions)
$permissions = json_decode($permissions,true);
@@ -420,6 +375,10 @@ function zot_refresh($them, $channel = null, $force = false) {
$next_birthday = NULL_DATE;
}
+
+ // Keep original perms to check if we need to notify them
+ $previous_perms = get_all_perms($channel['channel_id'],$x['hash']);
+
$r = q("select * from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1",
dbesc($x['hash']),
intval($channel['channel_id'])
@@ -483,10 +442,6 @@ function zot_refresh($them, $channel = null, $force = false) {
}
}
- // Keep original perms to check if we need to notify them
- $previous_perms = get_all_perms($channel['channel_id'],$x['hash']);
-
-
$closeness = get_pconfig($channel['channel_id'],'system','new_abook_closeness');
if($closeness === false)
$closeness = 80;
@@ -516,13 +471,15 @@ function zot_refresh($them, $channel = null, $force = false) {
if($new_connection) {
if(! \Zotlabs\Access\Permissions::PermsCompare($new_perms,$previous_perms))
Zotlabs\Daemon\Master::Summon(array('Notifier','permission_create',$new_connection[0]['abook_id']));
- Zotlabs\Lib\Enotify::submit(array(
+ Zotlabs\Lib\Enotify::submit(
+ [
'type' => NOTIFY_INTRO,
'from_xchan' => $x['hash'],
'to_xchan' => $channel['channel_hash'],
- 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id'],
- ));
-
+ 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id']
+ ]
+ );
+
if(intval($permissions['view_stream'])) {
if(intval(get_pconfig($channel['channel_id'],'perm_limits','send_stream') & PERMS_PENDING)
|| (! intval($new_connection[0]['abook_pending'])))
@@ -531,11 +488,12 @@ function zot_refresh($them, $channel = null, $force = false) {
/** If there is a default group for this channel, add this connection to it */
+
$default_group = $channel['channel_default_group'];
if($default_group) {
require_once('include/group.php');
$g = group_rec_byhash($channel['channel_id'],$default_group);
- if($g)
+ if($g)
group_add_member($channel['channel_id'],'',$x['hash'],$g['id']);
}
@@ -571,11 +529,13 @@ function zot_refresh($them, $channel = null, $force = false) {
* * \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
+ * @param boolean $multiple (optional) default false
*
* @returns array|null null if site is blacklisted or not found, otherwise an
* array with an hubloc record
*/
-function zot_gethub($arr,$multiple = false) {
+
+function zot_gethub($arr, $multiple = false) {
if($arr['guid'] && $arr['guid_sig'] && $arr['url'] && $arr['url_sig']) {
@@ -586,8 +546,8 @@ function zot_gethub($arr,$multiple = false) {
$limit = (($multiple) ? '' : ' limit 1 ');
$sitekey = ((array_key_exists('sitekey',$arr) && $arr['sitekey']) ? " and hubloc_sitekey = '" . protect_sprintf($arr['sitekey']) . "' " : '');
-
- $r = q("select * from hubloc
+
+ $r = q("select hubloc.*, site.site_crypto from hubloc left join site on hubloc_url = site_url
where hubloc_guid = '%s' and hubloc_guid_sig = '%s'
and hubloc_url = '%s' and hubloc_url_sig = '%s'
$sitekey $limit",
@@ -624,9 +584,10 @@ function zot_gethub($arr,$multiple = false) {
* * \b success boolean true or false
* * \b message (optional) error string only if success is false
*/
+
function zot_register_hub($arr) {
- $result = array('success' => false);
+ $result = [ 'success' => false ];
if($arr['url'] && $arr['url_sig'] && $arr['guid'] && $arr['guid_sig']) {
@@ -685,6 +646,7 @@ function zot_register_hub($arr) {
* * \e boolean \b success boolean true or false
* * \e string \b message (optional) error string only if success is false
*/
+
function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
call_hooks('import_xchan', $arr);
@@ -754,15 +716,15 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
if(intval($r[0]['xchan_pubforum']) != intval($arr['public_forum']))
$pubforum_changed = 1;
- if(($r[0]['xchan_name_date'] != $arr['name_updated'])
- || ($r[0]['xchan_connurl'] != $arr['connections_url'])
+ if(($r[0]['xchan_name_date'] != $arr['name_updated'])
+ || ($r[0]['xchan_connurl'] != $arr['connections_url'])
|| ($r[0]['xchan_addr'] != $arr['address'])
|| ($r[0]['xchan_follow'] != $arr['follow_url'])
- || ($r[0]['xchan_connpage'] != $arr['connect_url'])
+ || ($r[0]['xchan_connpage'] != $arr['connect_url'])
|| ($r[0]['xchan_url'] != $arr['url'])
|| $hidden_changed || $adult_changed || $deleted_changed || $pubforum_changed ) {
- $rup = q("update xchan set xchan_name = '%s', xchan_name_date = '%s', xchan_connurl = '%s', xchan_follow = '%s',
- xchan_connpage = '%s', xchan_hidden = %d, xchan_selfcensored = %d, xchan_deleted = %d, xchan_pubforum = %d,
+ $rup = q("update xchan set xchan_name = '%s', xchan_name_date = '%s', xchan_connurl = '%s', xchan_follow = '%s',
+ xchan_connpage = '%s', xchan_hidden = %d, xchan_selfcensored = %d, xchan_deleted = %d, xchan_pubforum = %d,
xchan_addr = '%s', xchan_url = '%s' where xchan_hash = '%s'",
dbesc(($arr['name']) ? $arr['name'] : '-'),
dbesc($arr['name_updated']),
@@ -783,7 +745,8 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
$what .= 'xchan ';
$changed = true;
}
- } else {
+ }
+ else {
$import_photos = true;
if((($arr['site']['directory_mode'] === 'standalone')
@@ -819,7 +782,7 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
$changed = true;
}
- if ($import_photos) {
+ if($import_photos) {
require_once('include/photo/photo_driver.php');
@@ -828,9 +791,9 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
$local = q("select channel_account_id, channel_id from channel where channel_hash = '%s' limit 1",
dbesc($xchan_hash)
);
- if ($local) {
+ if($local) {
$ph = z_fetch_url($arr['photo'], true);
- if ($ph['success']) {
+ if($ph['success']) {
$hash = import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'], $local[0]['channel_id']);
@@ -868,11 +831,12 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
false
);
}
- } else {
+ }
+ else {
$photos = import_xchan_photo($arr['photo'], $xchan_hash);
}
- if ($photos) {
- if ($photos[4]) {
+ if($photos) {
+ if($photos[4]) {
// importing the photo failed somehow. Leave the photo_date alone so we can try again at a later date.
// This often happens when somebody joins the matrix with a bad cert.
$r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'
@@ -883,7 +847,8 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
dbesc($photos[3]),
dbesc($xchan_hash)
);
- } else {
+ }
+ else {
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s'
where xchan_hash = '%s'",
dbescdate(datetime_convert('UTC','UTC',$arr['photo_updated'])),
@@ -940,7 +905,8 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
$what .= 'profile ';
$changed = true;
}
- } else {
+ }
+ else {
logger('import_xchan: profile not available - hiding');
// they may have made it private
$r = q("delete from xprof where xprof_hash = '%s'",
@@ -993,16 +959,17 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
* @param array $arr - output of z_post_url()
* @param array $outq - The queue structure attached to this request
*/
+
function zot_process_response($hub, $arr, $outq) {
- if (! $arr['success']) {
+ if(! $arr['success']) {
logger('zot_process_response: failed: ' . $hub);
return;
}
$x = json_decode($arr['body'], true);
- if (! $x) {
+ if(! $x) {
logger('zot_process_response: No json from ' . $hub);
logger('zot_process_response: headers: ' . print_r($arr['header'],true), LOGGER_DATA, LOG_DEBUG);
}
@@ -1022,12 +989,12 @@ function zot_process_response($hub, $arr, $outq) {
}
}
- // we have a more descriptive delivery report, so discard the per hub 'queued' report.
+ // we have a more descriptive delivery report, so discard the per hub 'queued' report.
q("delete from dreport where dreport_queue = '%s' ",
dbesc($outq['outq_hash'])
);
-
+
// update the timestamp for this site
q("update site set site_dead = 0, site_update = '%s' where site_url = '%s'",
@@ -1060,6 +1027,7 @@ function zot_process_response($hub, $arr, $outq) {
* decrypted and json decoded notify packet from remote site
* @return array from zot_import()
*/
+
function zot_fetch($arr) {
logger('zot_fetch: ' . print_r($arr,true), LOGGER_DATA, LOG_DEBUG);
@@ -1068,7 +1036,7 @@ function zot_fetch($arr) {
// set $multiple param on zot_gethub() to return all matching hubs
// This allows us to recover from re-installs when a redundant (but invalid) hubloc for
- // this identity is widely dispersed throughout the network.
+ // this identity is widely dispersed throughout the network.
$ret_hubs = zot_gethub($arr['sender'],true);
if(! $ret_hubs) {
@@ -1077,21 +1045,23 @@ function zot_fetch($arr) {
}
foreach($ret_hubs as $ret_hub) {
- $data = array(
- 'type' => 'pickup',
- 'url' => z_root(),
- 'callback_sig' => base64url_encode(rsa_sign(z_root() . '/post',get_config('system','prvkey'))),
- 'callback' => z_root() . '/post',
- 'secret' => $arr['secret'],
- 'secret_sig' => base64url_encode(rsa_sign($arr['secret'],get_config('system','prvkey')))
- );
- $datatosend = json_encode(crypto_encapsulate(json_encode($data),$ret_hub['hubloc_sitekey']));
+ $data = [
+ 'type' => 'pickup',
+ 'url' => z_root(),
+ 'callback_sig' => base64url_encode(rsa_sign(z_root() . '/post', get_config('system','prvkey'))),
+ 'callback' => z_root() . '/post',
+ 'secret' => $arr['secret'],
+ 'secret_sig' => base64url_encode(rsa_sign($arr['secret'], get_config('system','prvkey')))
+ ];
+
+ $algorithm = zot_best_algorithm($ret_hub['site_crypto']);
+ $datatosend = json_encode(crypto_encapsulate(json_encode($data),$ret_hub['hubloc_sitekey'], $algorithm));
$fetch = zot_zot($url,$datatosend);
$result = zot_import($fetch, $arr['sender']['url']);
-
+
if($result)
return $result;
}
@@ -1137,6 +1107,11 @@ function zot_import($arr, $sender_url) {
$data = json_decode(crypto_unencapsulate($data,get_config('system','prvkey')),true);
}
+ if(! is_array($data)) {
+ logger('decode error');
+ return array();
+ }
+
if(! $data['success']) {
if($data['message'])
logger('remote pickup failed: ' . $data['message']);
@@ -1162,6 +1137,12 @@ function zot_import($arr, $sender_url) {
logger('zot_import: notify: ' . print_r($i['notify'],true), LOGGER_DATA, LOG_DEBUG);
+ if(! is_array($i['notify'])) {
+ logger('decode error');
+ continue;
+ }
+
+
$hub = zot_gethub($i['notify']['sender']);
if((! $hub) || ($hub['hubloc_url'] != $sender_url)) {
logger('zot_import: potential forgery: wrong site for sender: ' . $sender_url . ' != ' . print_r($i['notify'],true));
@@ -1195,7 +1176,7 @@ function zot_import($arr, $sender_url) {
if($recip_arr) {
stringify_array_elms($recip_arr);
$recips = implode(',',$recip_arr);
- $r = q("select channel_hash as hash from channel where channel_hash in ( " . $recips . " )
+ $r = q("select channel_hash as hash from channel where channel_hash in ( " . $recips . " )
and channel_removed = 0 ");
}
@@ -1352,6 +1333,7 @@ function zot_import($arr, $sender_url) {
* @param array $msg
* @return NULL|array
*/
+
function public_recips($msg) {
require_once('include/channel.php');
@@ -1403,7 +1385,7 @@ function public_recips($msg) {
$perm = 'post_mail';
$r = array();
-
+
$c = q("select channel_id, channel_hash from channel where channel_removed = 0");
if($c) {
foreach($c as $cc) {
@@ -1432,7 +1414,7 @@ function public_recips($msg) {
if(($tag['type'] === 'mention') && (strpos($tag['url'],z_root()) !== false)) {
$address = basename($tag['url']);
if($address) {
- $z = q("select channel_hash as hash from channel where channel_address = '%s'
+ $z = q("select channel_hash as hash from channel where channel_address = '%s'
and channel_removed = 0 limit 1",
dbesc($address)
);
@@ -1561,6 +1543,7 @@ function allowed_public_recips($msg) {
* @param boolean $request (optional) default false
* @return array
*/
+
function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $request = false) {
$result = array();
@@ -1605,12 +1588,12 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $
/**
* @FIXME: Somehow we need to block normal message delivery from our clones, as the delivered
- * message doesn't have ACL information in it as the cloned copy does. That copy
- * will normally arrive first via sync delivery, but this isn't guaranteed.
+ * message doesn't have ACL information in it as the cloned copy does. That copy
+ * 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
* hence the item could have the wrong ACL and *could* be used in subsequent deliveries or
* access checks. So far all attempts at identifying this situation precisely
- * have caused issues with delivery of relayed comments.
+ * have caused issues with delivery of relayed comments.
*/
// if(($d['hash'] === $sender['hash']) && ($sender['url'] !== z_root()) && (! $relay)) {
@@ -1743,7 +1726,7 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $
intval($channel['channel_id']),
dbesc($arr['owner_xchan'])
);
- $abook = (($ab) ? $ab[0] : null);
+ $abook = (($ab) ? $ab[0] : null);
if(intval($arr['item_deleted'])) {
@@ -1757,7 +1740,7 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $
$arr['uid'] = $channel['channel_id'];
$item_id = 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();
if($relay && $item_id) {
@@ -1779,7 +1762,7 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $
$item_id = $r[0]['id'];
if(intval($r[0]['item_deleted'])) {
- // It was deleted locally.
+ // It was deleted locally.
$DR->update('update ignored');
$result[] = $DR->get();
@@ -1806,8 +1789,8 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $
$result[] = $DR->get();
- // We need this line to ensure wall-to-wall comments are relayed (by falling through to the relay bit),
- // and at the same time not relay any other relayable posts more than once, because to do so is very wasteful.
+ // We need this line to ensure wall-to-wall comments are relayed (by falling through to the relay bit),
+ // and at the same time not relay any other relayable posts more than once, because to do so is very wasteful.
if(! intval($r[0]['item_origin']))
continue;
}
@@ -1821,7 +1804,7 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $
if(check_item_source($arr['uid'], $arr))
call_hooks('post_local', $arr);
-
+
$item_id = 0;
if(($arr['mid'] == $arr['parent_mid']) && (! post_is_importable($arr,$abook))) {
@@ -1870,6 +1853,7 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $
* * \e int \b mid
* @param int $uid
*/
+
function remove_community_tag($sender, $arr, $uid) {
if(! (activity_match($arr['verb'], ACTIVITY_TAG) && ($arr['obj_type'] == ACTIVITY_OBJ_TAGTERM)))
@@ -1934,10 +1918,13 @@ function remove_community_tag($sender, $arr, $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)
+ * @param array $orig
+ * @param int $uid
*/
+
function update_imported_item($sender, $item, $orig, $uid) {
// If this is a comment being updated, remove any privacy information
@@ -1957,7 +1944,7 @@ function update_imported_item($sender, $item, $orig, $uid) {
// because event_addtocal will parse the body to get the 'new' event details
if($orig['resource_type'] === 'event') {
- $res = event_addtocal($orig['id'],$uid);
+ $res = event_addtocal($orig['id'], $uid);
if(! $res)
logger('update event: failed');
}
@@ -1978,6 +1965,7 @@ function update_imported_item($sender, $item, $orig, $uid) {
* @param boolean $relay
* @return boolean|int post_id
*/
+
function delete_imported_item($sender, $item, $uid, $relay) {
logger('delete_imported_item invoked', LOGGER_DEBUG);
@@ -1995,13 +1983,14 @@ function delete_imported_item($sender, $item, $uid, $relay) {
intval($uid)
);
- if ($r) {
- if ($r[0]['author_xchan'] === $sender['hash'] || $r[0]['owner_xchan'] === $sender['hash'] || $r[0]['source_xchan'] === $sender['hash'])
+ if($r) {
+ if($r[0]['author_xchan'] === $sender['hash'] || $r[0]['owner_xchan'] === $sender['hash'] || $r[0]['source_xchan'] === $sender['hash'])
$ownership_valid = true;
$post_id = $r[0]['id'];
$item_found = true;
- } else {
+ }
+ else {
// perhaps the item is still in transit and the delete notification got here before the actual item did. Store it with the deleted flag set.
// item_store() won't try to deliver any notifications or start delivery chains if this flag is set.
@@ -2010,25 +1999,24 @@ function delete_imported_item($sender, $item, $uid, $relay) {
logger('delete received for non-existent item - storing item data.');
- /** @BUG $arr is undefined here, so this is dead code */
- if ($arr['author_xchan'] === $sender['hash'] || $arr['owner_xchan'] === $sender['hash'] || $arr['source_xchan'] === $sender['hash']) {
+ if($item['author_xchan'] === $sender['hash'] || $item['owner_xchan'] === $sender['hash'] || $item['source_xchan'] === $sender['hash']) {
$ownership_valid = true;
- $item_result = item_store($arr);
+ $item_result = item_store($item);
$post_id = $item_result['item_id'];
}
}
- if ($ownership_valid === false) {
+ if($ownership_valid === false) {
logger('delete_imported_item: failed: ownership issue');
return false;
}
require_once('include/items.php');
- if ($item_found) {
- if (intval($r[0]['item_deleted'])) {
+ if($item_found) {
+ if(intval($r[0]['item_deleted'])) {
logger('delete_imported_item: item was already deleted');
- if (! $relay)
+ if(! $relay)
return false;
// This is a bit hackish, but may have to suffice until the notification/delivery loop is optimised
@@ -2139,6 +2127,7 @@ function process_mail_delivery($sender, $arr, $deliveries) {
* * \e string \b hash a xchan_hash
* @param array $arr
*/
+
function process_rating_delivery($sender, $arr) {
logger('process_rating_delivery: ' . print_r($arr,true));
@@ -2198,6 +2187,7 @@ function process_rating_delivery($sender, $arr) {
* @param array $arr
* @param array $deliveries (unused)
*/
+
function process_profile_delivery($sender, $arr, $deliveries) {
logger('process_profile_delivery', LOGGER_DEBUG);
@@ -2232,15 +2222,15 @@ function process_location_delivery($sender,$arr,$deliveries) {
/**
* @brief checks for a moved UNO channel and sets the channel_moved flag
- *
+ *
* Currently the effect of this flag is to turn the channel into 'read-only' mode.
- * New content will not be processed (there was still an issue with blocking the
+ * New content will not be processed (there was still an issue with blocking the
* ability to post comments as of 10-Mar-2016).
- * We do not physically remove the channel at this time. The hub admin may choose
+ * We do not physically remove the channel at this time. The hub admin may choose
* to do so, but is encouraged to allow a grace period of several days in case there
* are any issues migrating content. This packet will generally be received by the
* original site when the basic channel import has been processed.
- *
+ *
* This will only be executed on the UNO system which is the old location
* if a new location is reported and there is only one location record.
* The rest of the hubloc syncronisation will be handled within
@@ -2252,7 +2242,7 @@ function process_location_delivery($sender,$arr,$deliveries) {
function check_location_move($sender_hash,$locations) {
if(! $locations)
- return;
+ return;
if(get_config('system','server_role') !== 'basic')
return;
@@ -2275,13 +2265,13 @@ function check_location_move($sender_hash,$locations) {
dbesc($sender_hash)
);
- // federation plugins may wish to notify connections
+ // federation plugins may wish to notify connections
// of the move on singleton networks
$arr = array('channel' => $r[0],'locations' => $locations);
call_hooks('location_move',$arr);
- }
+ }
}
@@ -2294,6 +2284,7 @@ function check_location_move($sender_hash,$locations) {
* @param boolean $absolute (optional) default false
* @return array
*/
+
function sync_locations($sender, $arr, $absolute = false) {
$ret = array();
@@ -2536,12 +2527,12 @@ function zot_encode_locations($channel) {
foreach($x as $hub) {
// if this is a local channel that has been deleted, the hubloc is no good - make sure it is marked deleted
- // so that nobody tries to use it.
+ // so that nobody tries to use it.
if(intval($channel['channel_removed']) && $hub['hubloc_url'] === z_root())
$hub['hubloc_deleted'] = 1;
- $ret[] = array(
+ $ret[] = [
'host' => $hub['hubloc_host'],
'address' => $hub['hubloc_addr'],
'primary' => (intval($hub['hubloc_primary']) ? true : false),
@@ -2550,7 +2541,7 @@ function zot_encode_locations($channel) {
'callback' => $hub['hubloc_callback'],
'sitekey' => $hub['hubloc_sitekey'],
'deleted' => (intval($hub['hubloc_deleted']) ? true : false)
- );
+ ];
}
}
@@ -2567,6 +2558,7 @@ function zot_encode_locations($channel) {
* @param number $suppress_update default 0
* @return boolean $updated if something changed
*/
+
function import_directory_profile($hash, $profile, $addr, $ud_flags = UPDATE_FLAGS_UPDATED, $suppress_update = 0) {
logger('import_directory_profile', LOGGER_DEBUG);
@@ -2701,6 +2693,7 @@ function import_directory_profile($hash, $profile, $addr, $ud_flags = UPDATE_FLA
* @param string $hash
* @param array $keywords
*/
+
function import_directory_keywords($hash, $keywords) {
$existing = array();
@@ -2745,6 +2738,7 @@ function import_directory_keywords($hash, $keywords) {
* @param string $addr
* @param int $flags (optional) default 0
*/
+
function update_modtime($hash, $guid, $addr, $flags = 0) {
$dirmode = intval(get_config('system', 'directory_mode'));
@@ -2777,6 +2771,7 @@ function update_modtime($hash, $guid, $addr, $flags = 0) {
* @param string $pubkey
* @return boolean true if updated or inserted
*/
+
function import_site($arr, $pubkey) {
if( (! is_array($arr)) || (! $arr['url']) || (! $arr['url_sig']))
return false;
@@ -2844,6 +2839,7 @@ function import_site($arr, $pubkey) {
$site_location = htmlspecialchars($arr['location'],ENT_COMPAT,'UTF-8',false);
$site_realm = htmlspecialchars($arr['realm'],ENT_COMPAT,'UTF-8',false);
$site_project = htmlspecialchars($arr['project'],ENT_COMPAT,'UTF-8',false);
+ $site_crypto = ((array_key_exists('encryption',$arr) && is_array($arr['encryption'])) ? htmlspecialchars(implode(',',$arr['encryption']),ENT_COMPAT,'UTF-8',false) : '');
$site_version = ((array_key_exists('version',$arr)) ? htmlspecialchars($arr['version'],ENT_COMPAT,'UTF-8',false) : '');
// You can have one and only one primary directory per realm.
@@ -2865,6 +2861,7 @@ function import_site($arr, $pubkey) {
|| ($siterecord['site_register'] != $register_policy)
|| ($siterecord['site_project'] != $site_project)
|| ($siterecord['site_realm'] != $site_realm)
+ || ($siterecord['site_crypto'] != $site_crypto)
|| ($siterecord['site_version'] != $site_version) ) {
$update = true;
@@ -2873,7 +2870,7 @@ function import_site($arr, $pubkey) {
// logger('import_site: stored: ' . print_r($siterecord,true));
- $r = q("update site set site_dead = 0, site_location = '%s', site_flags = %d, site_access = %d, site_directory = '%s', site_register = %d, site_update = '%s', site_sellpage = '%s', site_realm = '%s', site_type = %d, site_project = '%s', site_version = '%s'
+ $r = q("update site set site_dead = 0, site_location = '%s', site_flags = %d, site_access = %d, site_directory = '%s', site_register = %d, site_update = '%s', site_sellpage = '%s', site_realm = '%s', site_type = %d, site_project = '%s', site_version = '%s', site_crypto = '%s'
where site_url = '%s'",
dbesc($site_location),
intval($site_directory),
@@ -2886,6 +2883,7 @@ function import_site($arr, $pubkey) {
intval(SITE_TYPE_ZOT),
dbesc($site_project),
dbesc($site_version),
+ dbesc($site_crypto),
dbesc($url)
);
if(! $r) {
@@ -2903,8 +2901,8 @@ function import_site($arr, $pubkey) {
else {
$update = true;
- $r = q("insert into site ( site_location, site_url, site_access, site_flags, site_update, site_directory, site_register, site_sellpage, site_realm, site_type, site_project, site_version )
- values ( '%s', '%s', %d, %d, '%s', '%s', %d, '%s', '%s', %d, '%s', '%s' )",
+ $r = q("insert into site ( site_location, site_url, site_access, site_flags, site_update, site_directory, site_register, site_sellpage, site_realm, site_type, site_project, site_version, site_crypto )
+ values ( '%s', '%s', %d, %d, '%s', '%s', %d, '%s', '%s', %d, '%s', '%s', '%s' )",
dbesc($site_location),
dbesc($url),
intval($access_policy),
@@ -2916,7 +2914,8 @@ function import_site($arr, $pubkey) {
dbesc($site_realm),
intval(SITE_TYPE_ZOT),
dbesc($site_project),
- dbesc($site_version)
+ dbesc($site_version),
+ dbesc($site_crypto)
);
if(! $r) {
logger('import_site: record create failed. ' . print_r($arr,true));
@@ -2935,6 +2934,7 @@ function import_site($arr, $pubkey) {
* @param array $packet (optional) default null
* @param boolean $groups_changed (optional) default false
*/
+
function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
if(get_config('system','server_role') === 'basic')
@@ -2970,7 +2970,7 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
if(intval($channel['channel_removed']))
return;
- $h = q("select * from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0",
+ $h = q("select hubloc.*, site.site_crypto from hubloc left join site on site_url = hubloc_url where hubloc_hash = '%s' and hubloc_deleted = 0",
dbesc($channel['channel_hash'])
);
@@ -3057,7 +3057,7 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
foreach($synchubs as $hub) {
$hash = random_string();
- $n = zot_build_packet($channel,'notify',$env_recips,$hub['hubloc_sitekey'],$hash);
+ $n = zot_build_packet($channel,'notify',$env_recips,$hub['hubloc_sitekey'],$hub['site_crypto'],$hash);
queue_insert(array(
'hash' => $hash,
'account_id' => $channel['channel_account_id'],
@@ -3083,6 +3083,7 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
* @param array $deliveries
* @return array
*/
+
function process_channel_sync_delivery($sender, $arr, $deliveries) {
if(get_config('system','server_role') === 'basic')
@@ -3090,7 +3091,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
require_once('include/import.php');
- /** @FIXME this will sync red structures (channel, pconfig and abook).
+ /** @FIXME this will sync red structures (channel, pconfig and abook).
Eventually we need to make this application agnostic. */
$result = array();
@@ -3181,15 +3182,15 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
$arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] - 0x1000;
}
-
- $disallowed = [
- 'channel_id', 'channel_account_id', 'channel_primary', 'channel_prvkey',
- 'channel_address', 'channel_notifyflags', 'channel_removed', 'channel_deleted',
- 'channel_system', 'channel_r_stream', 'channel_r_profile', 'channel_r_abook',
- 'channel_r_storage', 'channel_r_pages', 'channel_w_stream', 'channel_w_wall',
- 'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall',
- 'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish',
- 'channel_a_delegate'
+
+ $disallowed = [
+ 'channel_id', 'channel_account_id', 'channel_primary', 'channel_prvkey',
+ 'channel_address', 'channel_notifyflags', 'channel_removed', 'channel_deleted',
+ 'channel_system', 'channel_r_stream', 'channel_r_profile', 'channel_r_abook',
+ 'channel_r_storage', 'channel_r_pages', 'channel_w_stream', 'channel_w_wall',
+ 'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall',
+ 'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish',
+ 'channel_a_delegate'
];
$clean = array();
@@ -3226,7 +3227,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
foreach($arr['abook'] as $abook) {
-
+
$abconfig = null;
@@ -3372,7 +3373,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
}
}
if(! $found) {
- $r = q("INSERT INTO `groups` ( hash, uid, visible, deleted, gname )
+ $r = q("INSERT INTO groups ( hash, uid, visible, deleted, gname )
VALUES( '%s', %d, %d, %d, '%s' ) ",
dbesc($cl['collection']),
intval($channel['channel_id']),
@@ -3446,7 +3447,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
// if somebody is in the group that wasn't before - add them
if(! $found) {
- q("INSERT INTO `group_member` (`uid`, `gid`, `xchan`)
+ q("INSERT INTO group_member (uid, gid, xchan)
VALUES( %d, %d, '%s' ) ",
intval($channel['channel_id']),
intval($y['id']),
@@ -3503,7 +3504,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
foreach($profile as $k => $v) {
if(in_array($k,$disallowed))
continue;
-
+
if($k === 'name')
$clean['fullname'] = $v;
elseif($k === 'with')
@@ -3514,15 +3515,16 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
$clean[$k] = $v;
/**
- * @TODO
+ * @TODO
* We also need to import local photos if a custom photo is selected
*/
}
if(count($clean)) {
foreach($clean as $k => $v) {
- $r = dbq("UPDATE profile set `" . dbesc($k) . "` = '" . dbesc($v)
- . "' where profile_guid = '" . dbesc($profile['profile_guid']) . "' and uid = " . intval($channel['channel_id']));
+ $r = dbq("UPDATE profile set " . TQUOT . dbesc($k) . TQUOT . " = '" . dbesc($v)
+ . "' where profile_guid = '" . dbesc($profile['profile_guid'])
+ . "' and uid = " . intval($channel['channel_id']));
}
}
}
@@ -3556,6 +3558,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
* * \e string \b xchan_url
* @return string
*/
+
function get_rpost_path($observer) {
if(! $observer)
return '';
@@ -3571,6 +3574,7 @@ function get_rpost_path($observer) {
* @param array $x
* @return boolean|string return false or a hash
*/
+
function import_author_zot($x) {
$hash = make_xchan_hash($x['guid'],$x['guid_sig']);
@@ -3610,6 +3614,7 @@ function import_author_zot($x) {
* @param array $data
* @return array
*/
+
function zot_reply_message_request($data) {
$ret = array('success' => false);
@@ -3646,7 +3651,7 @@ function zot_reply_message_request($data) {
if ($messages) {
$env_recips = null;
- $r = q("select * from hubloc where hubloc_hash = '%s' and hubloc_error = 0 and hubloc_deleted = 0",
+ $r = q("select hubloc.*, site.site_crypto from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and hubloc_error = 0 and hubloc_deleted = 0",
dbesc($sender_hash)
);
if (! $r) {
@@ -3668,7 +3673,7 @@ function zot_reply_message_request($data) {
* create a notify packet and drop the actual message packet in the queue for pickup
*/
- $n = zot_build_packet($c[0],'notify',$env_recips,(($private) ? $hub['hubloc_sitekey'] : null),$hash,array('message_id' => $data['message_id']));
+ $n = zot_build_packet($c[0],'notify',$env_recips,(($private) ? $hub['hubloc_sitekey'] : null),$hub['site_crypto'],$hash,array('message_id' => $data['message_id']));
queue_insert(array(
'hash' => $hash,
@@ -3715,18 +3720,18 @@ function zotinfo($arr) {
}
}
- $ztarget_hash = (($ztarget && $zsig) ? make_xchan_hash($ztarget,$zsig) : '' );
+ $ztarget_hash = (($ztarget && $zsig) ? make_xchan_hash($ztarget,$zsig) : '' );
$r = null;
if(strlen($zhash)) {
- $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
+ $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
where channel_hash = '%s' limit 1",
dbesc($zhash)
);
}
elseif(strlen($zguid) && strlen($zguid_sig)) {
- $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
+ $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
where channel_guid = '%s' and channel_guid_sig = '%s' limit 1",
dbesc($zguid),
dbesc($zguid_sig)
@@ -3745,7 +3750,7 @@ function zotinfo($arr) {
/**
* The special address '[system]' will return a system channel if one has been defined,
- * Or the first valid channel we find if there are no system channels.
+ * Or the first valid channel we find if there are no system channels.
*
* This is used by magic-auth if we have no prior communications with this site - and
* returns an identity on this site which we can use to create a valid hub record so that
@@ -3760,7 +3765,7 @@ function zotinfo($arr) {
$r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
where channel_removed = 0 order by channel_id limit 1");
}
- }
+ }
}
else {
$ret['message'] = 'Invalid request';
@@ -3785,7 +3790,7 @@ function zotinfo($arr) {
if($deleted || $censored || $sys_channel)
$searchable = false;
-
+
$public_forum = false;
$role = get_pconfig($e['channel_id'],'system','permissions_role');
@@ -3818,14 +3823,14 @@ function zotinfo($arr) {
if($p) {
if(! intval($p[0]['publish']))
- $searchable = false;
+ $searchable = false;
$profile['description'] = $p[0]['pdesc'];
$profile['birthday'] = $p[0]['dob'];
if(($profile['birthday'] != '0000-00-00') && (($bd = z_birthday($p[0]['dob'],$e['channel_timezone'])) !== ''))
$profile['next_birthday'] = $bd;
- if($age = age($p[0]['dob'],$e['channel_timezone'],''))
+ if($age = age($p[0]['dob'],$e['channel_timezone'],''))
$profile['age'] = $age;
$profile['gender'] = $p[0]['gender'];
$profile['marital'] = $p[0]['marital'];
@@ -3878,14 +3883,14 @@ function zotinfo($arr) {
$ret['adult_content'] = $adult_channel;
$ret['public_forum'] = $public_forum;
if($deleted)
- $ret['deleted'] = $deleted;
+ $ret['deleted'] = $deleted;
if(intval($e['channel_removed']))
$ret['deleted_locally'] = true;
// premium or other channel desiring some contact with potential followers before connecting.
// This is a template - %s will be replaced with the follow_url we discover for the return channel.
- if($special_channel)
+ if($special_channel)
$ret['connect_url'] = z_root() . '/connect/' . $e['channel_address'];
// This is a template for our follow url, %s will be replaced with a webbie
@@ -3905,6 +3910,11 @@ function zotinfo($arr) {
$permissions['connected'] = true;
}
+ // encrypt this with the default aes256cbc since we cannot be sure at this point which
+ // algorithms are preferred for communications with the remote site; notably
+ // because ztarget refers to an xchan and we don't necessarily know the origination
+ // location.
+
$ret['permissions'] = (($ztarget && $zkey) ? crypto_encapsulate(json_encode($permissions),$zkey) : $permissions);
if($permissions['view_profile'])
@@ -3935,6 +3945,8 @@ function zotinfo($arr) {
$ret['site']['directory_url'] = z_root() . '/dirsearch';
+ $ret['site']['encryption'] = crypto_methods();
+
// hide detailed site information if you're off the grid
if($dirmode != DIRECTORY_MODE_STANDALONE) {
@@ -3961,7 +3973,7 @@ function zotinfo($arr) {
$ret['site']['access_policy'] = 'tiered';
$ret['site']['accounts'] = account_total();
-
+
require_once('include/channel.php');
$ret['site']['channels'] = channel_total();
@@ -3972,17 +3984,17 @@ function zotinfo($arr) {
$r = q("select * from addon where hidden = 0");
if($r)
foreach($r as $rr)
- $visible_plugins[] = $rr['name'];
+ $visible_plugins[] = $rr['aname'];
}
- $ret['site']['plugins'] = $visible_plugins;
- $ret['site']['sitehash'] = get_config('system','location_hash');
- $ret['site']['sitename'] = get_config('system','sitename');
- $ret['site']['sellpage'] = get_config('system','sellpage');
- $ret['site']['location'] = get_config('system','site_location');
- $ret['site']['realm'] = get_directory_realm();
- $ret['site']['project'] = Zotlabs\Lib\System::get_platform_name() . ' ' . Zotlabs\Lib\System::get_server_role();
- $ret['site']['version'] = Zotlabs\Lib\System::get_project_version();
+ $ret['site']['plugins'] = $visible_plugins;
+ $ret['site']['sitehash'] = get_config('system','location_hash');
+ $ret['site']['sitename'] = get_config('system','sitename');
+ $ret['site']['sellpage'] = get_config('system','sellpage');
+ $ret['site']['location'] = get_config('system','site_location');
+ $ret['site']['realm'] = get_directory_realm();
+ $ret['site']['project'] = Zotlabs\Lib\System::get_platform_name() . ' ' . Zotlabs\Lib\System::get_server_role();
+ $ret['site']['version'] = Zotlabs\Lib\System::get_project_version();
}
@@ -4002,7 +4014,7 @@ function check_zotinfo($channel,$locations,&$ret) {
// This function will likely expand as we find more things to detect and fix.
// 1. Because magic-auth is reliant on it, ensure that the system channel has a valid hubloc
- // Force this to be the case if anything is found to be wrong with it.
+ // Force this to be the case if anything is found to be wrong with it.
// @FIXME ensure that the system channel exists in the first place and has an xchan
@@ -4022,9 +4034,9 @@ function check_zotinfo($channel,$locations,&$ret) {
logger('System channel locations are not valid. Attempting repair.');
- // Don't trust any existing records. Just get rid of them, but only do this
+ // Don't trust any existing records. Just get rid of them, but only do this
// for the sys channel as normal channels will be trickier.
-
+
q("delete from hubloc where hubloc_hash = '%s'",
dbesc($channel['channel_hash'])
);
@@ -4081,7 +4093,7 @@ function delivery_report_is_storable($dr) {
return false;
- // is the recipient one of our connections, or do we want to store every report?
+ // is the recipient one of our connections, or do we want to store every report?
$r = explode(' ', $dr['recipient']);
$rxchan = $r[0];
@@ -4092,15 +4104,15 @@ function delivery_report_is_storable($dr) {
// We always add ourself as a recipient to private and relayed posts
// So if a remote site says they can't find us, that's no big surprise
// and just creates a lot of extra report noise
-
+
if(($dr['location'] !== z_root()) && ($dr['sender'] === $rxchan) && ($dr['status'] === 'recipient_not_found'))
return false;
// If you have a private post with a recipient list, every single site is going to report
- // back a failed delivery for anybody on that list that isn't local to them. We're only
+ // back a failed delivery for anybody on that list that isn't local to them. We're only
// concerned about this if we have a local hubloc record which says we expected them to
// have a channel on that site.
-
+
$r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and hubloc_url = '%s'",
dbesc($rxchan),
dbesc($dr['location'])
@@ -4130,7 +4142,7 @@ function update_hub_connected($hub,$sitekey = '') {
* Any hub with the same URL and a different sitekey cannot be valid.
* Get rid of them (mark them deleted). There's a good chance they were re-installs.
*/
-
+
q("update hubloc set hubloc_deleted = 1, hubloc_error = 1 where hubloc_url = '%s' and hubloc_sitekey != '%s' ",
dbesc($hub['hubloc_url']),
dbesc($sitekey)
@@ -4141,7 +4153,7 @@ function update_hub_connected($hub,$sitekey = '') {
$sitekey = $hub['sitekey'];
}
- // $sender['sitekey'] is a new addition to the protocol to distinguish
+ // $sender['sitekey'] is a new addition to the protocol to distinguish
// hublocs coming from re-installed sites. Older sites will not provide
// this field and we have to still mark them valid, since we can't tell
// if this hubloc has the same sitekey as the packet we received.
@@ -4164,10 +4176,10 @@ function update_hub_connected($hub,$sitekey = '') {
if(intval($hub['hubloc_error'])) {
q("update hubloc set hubloc_error = 0 where hubloc_id = %d and hubloc_sitekey = '%s' ",
intval($hub['hubloc_id']),
- dbesc($sitekey)
+ dbesc($sitekey)
);
- if(intval($r[0]['hubloc_orphancheck'])) {
- q("update hubloc set hubloc_orhpancheck = 0 where hubloc_id = %d and hubloc_sitekey = '%s' ",
+ if(intval($hub['hubloc_orphancheck'])) {
+ q("update hubloc set hubloc_orphancheck = 0 where hubloc_id = %d and hubloc_sitekey = '%s' ",
intval($hub['hubloc_id']),
dbesc($sitekey)
);
@@ -4176,7 +4188,7 @@ function update_hub_connected($hub,$sitekey = '') {
dbesc($hub['hubloc_hash'])
);
}
-
+
return $hub['hubloc_url'];
}
@@ -4189,7 +4201,7 @@ function zot_reply_ping() {
// This will let us know if any important communication details
// that we may have stored are no longer valid, regardless of xchan details.
logger('POST: got ping send pong now back: ' . z_root() , LOGGER_DEBUG );
-
+
$ret['success'] = true;
$ret['site'] = array();
$ret['site']['url'] = z_root();
@@ -4263,7 +4275,7 @@ function zot_reply_pickup($data) {
/*
* If we made it to here, the signatures verify, but we still don't know if the tracking ID is valid.
* It wouldn't be an error if the tracking ID isn't found, because we may have sent this particular
- * queue item with another pickup (after the tracking ID for the other pickup was verified).
+ * queue item with another pickup (after the tracking ID for the other pickup was verified).
*/
$r = q("select outq_posturl from outq where outq_hash = '%s' and outq_posturl = '%s' limit 1",
@@ -4303,13 +4315,21 @@ function zot_reply_pickup($data) {
}
else
$ret['pickup'][] = array('notify' => json_decode($rr['outq_notify'],true),'message' => $x);
-
+
remove_queue_item($rr['outq_hash']);
}
}
}
- $encrypted = crypto_encapsulate(json_encode($ret),$sitekey);
+ // this is a bit of a hack because we don't have the hubloc_url here, only the callback url.
+ // worst case is we'll end up using aes256cbc if they've got a different post endpoint
+
+ $x = q("select site_crypto from site where site_url = '%s' limit 1",
+ dbesc(str_replace('/post','',$data['callback']))
+ );
+ $algorithm = zot_best_algorithm(($x) ? $x[0]['site_crypto'] : '');
+
+ $encrypted = crypto_encapsulate(json_encode($ret),$sitekey,$algorithm);
json_return_and_die($encrypted);
/* pickup: end */
@@ -4325,7 +4345,7 @@ function zot_reply_auth_check($data,$encrypted_packet) {
* Requestor visits /magic/?dest=somewhere on their own site with a browser
* magic redirects them to $destsite/post [with auth args....]
* $destsite sends an auth_check packet to originator site
- * The auth_check packet is handled here by the originator's site
+ * The auth_check packet is handled here by the originator's site
* - the browser session is still waiting
* inside $destsite/post for everything to verify
* If everything checks out we'll return a token to $destsite
@@ -4347,9 +4367,9 @@ function zot_reply_auth_check($data,$encrypted_packet) {
// garbage collect any old unused notifications
- // This was and should be 10 minutes but my hosting provider has time lag between the DB and
- // the web server. We should probably convert this to webserver time rather than DB time so
- // that the different clocks won't affect it and allow us to keep the time short.
+ // This was and should be 10 minutes but my hosting provider has time lag between the DB and
+ // the web server. We should probably convert this to webserver time rather than DB time so
+ // that the different clocks won't affect it and allow us to keep the time short.
Zotlabs\Zot\Verify::purge('auth','30 MINUTE');
@@ -4360,7 +4380,7 @@ function zot_reply_auth_check($data,$encrypted_packet) {
// We created a unique hash in mod/magic.php when we invoked remote auth, and stored it in
// the verify table. It is now coming back to us as 'secret' and is signed by a channel at the other end.
// First verify their signature. We will have obtained a zot-info packet from them as part of the sender
- // verification.
+ // verification.
if ((! $y) || (! rsa_verify($data['secret'], base64url_decode($data['secret_sig']),$y[0]['xchan_pubkey']))) {
logger('mod_zot: auth_check: sender not found or secret_sig invalid.');
@@ -4433,7 +4453,7 @@ function zot_reply_purge($sender,$recipients) {
if ($recipients) {
// basically this means "unfriend"
foreach ($recipients as $recip) {
- $r = q("select channel.*,xchan.* from channel
+ $r = q("select channel.*,xchan.* from channel
left join xchan on channel_hash = xchan_hash
where channel_guid = '%s' and channel_guid_sig = '%s' limit 1",
dbesc($recip['guid']),
@@ -4450,13 +4470,13 @@ function zot_reply_purge($sender,$recipients) {
}
}
$ret['success'] = true;
- }
+ }
else {
// Unfriend everybody - basically this means the channel has committed suicide
$arr = $sender;
$sender_hash = make_xchan_hash($arr['guid'],$arr['guid_sig']);
- remove_all_xchan_resources($sender_hash);
+ remove_all_xchan_resources($sender_hash);
$ret['success'] = true;
}
@@ -4471,7 +4491,7 @@ function zot_reply_refresh($sender,$recipients) {
// remote channel info (such as permissions or photo or something)
// has been updated. Grab a fresh copy and sync it.
- // The difference between refresh and force_refresh is that
+ // The difference between refresh and force_refresh is that
// force_refresh unconditionally creates a directory update record,
// even if no changes were detected upon processing.
@@ -4480,7 +4500,7 @@ function zot_reply_refresh($sender,$recipients) {
// This would be a permissions update, typically for one connection
foreach ($recipients as $recip) {
- $r = q("select channel.*,xchan.* from channel
+ $r = q("select channel.*,xchan.* from channel
left join xchan on channel_hash = xchan_hash
where channel_guid = '%s' and channel_guid_sig = '%s' limit 1",
dbesc($recip['guid']),
@@ -4488,17 +4508,17 @@ function zot_reply_refresh($sender,$recipients) {
);
$x = zot_refresh(array(
- 'xchan_guid' => $sender['guid'],
+ 'xchan_guid' => $sender['guid'],
'xchan_guid_sig' => $sender['guid_sig'],
'hubloc_url' => $sender['url']
), $r[0], (($msgtype === 'force_refresh') ? true : false));
}
- }
+ }
else {
// system wide refresh
$x = zot_refresh(array(
- 'xchan_guid' => $sender['guid'],
+ 'xchan_guid' => $sender['guid'],
'xchan_guid_sig' => $sender['guid_sig'],
'hubloc_url' => $sender['url']
), null, (($msgtype === 'force_refresh') ? true : false));
@@ -4521,7 +4541,7 @@ function zot_reply_notify($data) {
if($async) {
// add to receive queue
// qreceive_add($data);
- }
+ }
else {
$x = zot_fetch($data);
$ret['delivery_report'] = $x;
@@ -4530,4 +4550,4 @@ function zot_reply_notify($data) {
$ret['success'] = true;
json_return_and_die($ret);
-} \ No newline at end of file
+}