Merge branch '2.4RC'

This commit is contained in:
Mario Vavti
2017-05-31 09:56:35 +02:00
2860 changed files with 126970 additions and 86784 deletions

View File

@@ -209,7 +209,7 @@ function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $
// Retrieve all columns except 'data'
$r = q("select id, aid, uid, hash, filename, filetype, filesize, revision, folder, os_storage, is_dir, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d $sql_extra ORDER BY $orderby $limit",
$r = q("select id, aid, uid, hash, filename, filetype, filesize, revision, folder, os_path, display_path, os_storage, is_dir, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d $sql_extra ORDER BY $orderby $limit",
intval($channel_id)
);
@@ -284,6 +284,7 @@ function attach_by_hash($hash, $observer_hash, $rev = 0) {
return $ret;
}
function attach_can_view_folder($uid,$ob_hash,$folder_hash) {
$sql_extra = permissions_sql($uid,$ob_hash);
@@ -348,7 +349,7 @@ function attach_by_hash_nodata($hash, $observer_hash, $rev = 0) {
// Now we'll see if we can access the attachment
$r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, is_dir, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_extra limit 1",
$r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, os_path, display_path, is_dir, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_extra limit 1",
intval($r[0]['uid']),
dbesc($hash)
);
@@ -531,7 +532,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
if($options === 'update' && $arr && array_key_exists('revision',$arr))
$sql_options = " and revision = " . intval($arr['revision']) . " ";
$x = q("select id, aid, uid, filename, filetype, filesize, hash, revision, folder, os_storage, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where hash = '%s' and uid = %d $sql_options limit 1",
$x = q("select id, aid, uid, filename, filetype, filesize, hash, revision, folder, os_storage, is_photo, os_path, display_path, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where hash = '%s' and uid = %d $sql_options limit 1",
dbesc($arr['hash']),
intval($channel_id)
);
@@ -702,11 +703,11 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$os_relpath .= $folder_hash . '/';
}
$os_relpath .= $hash;
$os_relpath .= $hash;
$os_relpath = ltrim($os_relpath,'/');
// not yet used
$os_path = '';
$display_path = '';
$os_path = $os_relpath;
$display_path = $pathname . '/' . $filename;
if($src)
@file_put_contents($os_basepath . $os_relpath,@file_get_contents($src));
@@ -810,7 +811,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
if($is_photo) {
$args = array( 'source' => $source, 'visible' => $visible, 'resource_id' => $hash, 'album' => basename($pathname), 'os_path' => $os_basepath . $os_relpath, 'filename' => $filename, 'getimagesize' => $gis, 'directory' => $direct, 'options' => $options );
$args = array( 'source' => $source, 'visible' => $visible, 'resource_id' => $hash, 'album' => $pathname, 'os_syspath' => $os_basepath . $os_relpath, 'os_path' => $os_path, 'display_path' => $display_path, 'filename' => $filename, 'getimagesize' => $gis, 'directory' => $direct, 'options' => $options );
if($arr['contact_allow'])
$args['contact_allow'] = $arr['contact_allow'];
if($arr['group_allow'])
@@ -914,7 +915,7 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') {
if(count($paths) > 1) {
$curpath = array_shift($paths);
$r = q("select hash, id, is_dir from attach where uid = %d and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id) . " limit 1",
$r = q("select hash, id, is_dir from attach where uid = %d and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id,$observer_hash) . " limit 1",
intval($channel_id),
dbesc($curpath)
);
@@ -929,7 +930,7 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') {
else
$paths = array($pathname);
$r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, is_photo, is_dir, os_storage, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and folder = '%s' and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id),
$r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_path, display_path, is_photo, is_dir, os_storage, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and folder = '%s' and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id),
intval($channel_id),
dbesc($parent_hash),
dbesc($paths[0])
@@ -968,12 +969,15 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
$sql_options = '';
$basepath = 'store/' . $channel['channel_address'];
$os_basepath = 'store/' . $channel['channel_address'];
logger('attach_mkdir: basepath: ' . $basepath);
logger('attach_mkdir: basepath: ' . $os_basepath);
if(! is_dir($basepath))
os_mkdir($basepath,STORAGE_DEFAULT_PERMISSIONS, true);
if(! is_dir($os_basepath))
os_mkdir($os_basepath,STORAGE_DEFAULT_PERMISSIONS, true);
$os_basepath .= '/';
if(! perm_is_allowed($channel_id, $observer_hash, 'write_storage')) {
$ret['message'] = t('Permission denied.');
@@ -1019,10 +1023,13 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
$lpath = '';
$lfile = $arr['folder'];
$dpath = '';
$sql_options = permissions_sql($channel['channel_id']);
do {
$r = q("select filename, hash, flags, is_dir, folder from attach where uid = %d and hash = '%s' and is_dir != 0
$r = q("select filename, hash, flags, is_dir, folder, display_path from attach where uid = %d and hash = '%s' and is_dir = 1
$sql_options limit 1",
intval($channel['channel_id']),
dbesc($lfile)
@@ -1032,22 +1039,26 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
$ret['message'] = t('Path not found.');
return $ret;
}
$dpath = $r[0]['filename'] . (($dpath) ? '/' . $dpath : '');
if($lfile)
$lpath = $r[0]['hash'] . '/' . $lpath;
$lpath = $r[0]['hash'] . (($lpath) ? '/' . $lpath : '');
$lfile = $r[0]['folder'];
} while ( ($r[0]['folder']) && intval($r[0]['is_dir'])) ;
$path = $basepath . '/' . $lpath;
$path = $lpath;
}
else
$path = $basepath . '/';
$path .= $arr['hash'];
$path = '';
$created = datetime_convert();
// not yet used
$os_path = '';
$display_path = '';
$os_path = ltrim($path . '/' . $arr['hash'],'/');
$display_path = ltrim($dpath . '/' . $arr['filename'],'/');
$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' ) ",
@@ -1062,7 +1073,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
dbesc($arr['folder']),
intval(1),
intval(1),
dbescbin($path),
dbescbin($os_basepath . $os_path),
dbesc($created),
dbesc($created),
dbesc($os_path),
@@ -1074,7 +1085,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
);
if($r) {
if(os_mkdir($path, STORAGE_DEFAULT_PERMISSIONS, true)) {
if(os_mkdir($os_basepath . $os_path, STORAGE_DEFAULT_PERMISSIONS, true)) {
$ret['success'] = true;
// update the parent folder's lastmodified timestamp
@@ -1092,7 +1103,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
$ret['data'] = $z[0];
}
else {
logger('attach_mkdir: ' . mkdir . ' ' . $path . ' failed.');
logger('attach_mkdir: ' . mkdir . ' ' . $os_basepath . $os_path . ' failed.');
$ret['message'] = t('mkdir failed.');
}
}
@@ -2212,10 +2223,23 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
intval($r[0]['id'])
);
$x = attach_syspaths($channel_id,$resource_id);
$t1 = q("update attach set os_path = '%s', display_path = '%s' where id = %d",
dbesc($x['os_path']),
dbesc($x['path']),
intval($r[0]['id'])
);
if($r[0]['is_photo']) {
$t = q("update photo set album = '%s', filename = '%s' where resource_id = '%s' and uid = %d",
$t = q("update photo set album = '%s', filename = '%s', os_path = '%s', display_path = '%s'
where resource_id = '%s' and uid = %d",
dbesc($newdirname),
dbesc($filename),
dbesc($x['os_path']),
dbesc($x['path']),
dbesc($resource_id),
intval($channel_id)
);
@@ -2243,8 +2267,9 @@ function attach_folder_select_list($channel_id) {
if($r) {
foreach($r as $rv) {
$x = attach_folder_rpaths($r,$rv);
if($x)
if($x) {
$out[$x[0]] = $x[1];
}
}
}
@@ -2266,7 +2291,6 @@ function attach_folder_rpaths($all_folders,$that_folder) {
continue;
if($selected['hash'] == $parent_hash) {
$path = '/' . $selected['filename'] . $path;
$current_hash = $selected['hash'];
$parent_hash = $selected['folder'];
$found = true;
break;
@@ -2280,3 +2304,54 @@ function attach_folder_rpaths($all_folders,$that_folder) {
return (($error) ? false : [ $current_hash , $path ]);
}
function attach_syspaths($channel_id,$attach_hash) {
$os_path = '';
$path = '';
do {
$r = q("select folder, filename, hash from attach where hash = '%s' and uid = %d",
dbesc($attach_hash),
intval($channel_id)
);
if(! $r)
break;
$os_path = $r[0]['hash'] . (($os_path) ? '/' . $os_path : '');
$path = $r[0]['filename'] . (($path) ? '/' . $path : '');
$attach_hash = $r[0]['folder'];
}
while($attach_hash);
return [ 'os_path' => $os_path, 'path' => $path ];
}
function attach_upgrade() {
$r = q("select id, uid, hash from attach where os_path = '' and display_path = '' limit 100");
if($r) {
foreach($r as $rv) {
$x = attach_syspaths($rv['uid'],$rv['hash']);
if($x) {
$w = q("update attach set os_path = '%s', display_path = '%s' where id = %d",
dbesc($x['os_path']),
dbesc($x['path']),
intval($rv['id'])
);
$y = q("update photo set os_path = '%s', display_path = '%s' where uid = %d and resource_id = '%s'",
dbesc($x['os_path']),
dbesc($x['path']),
intval($rv['uid']),
dbesc($rv['hash'])
);
}
}
}
}

View File

@@ -776,7 +776,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) {

View File

@@ -57,8 +57,9 @@ function identity_check_service_class($account_id) {
* Plugins can set additional policies such as full name requirements, character
* sets, multi-byte length, etc.
*
* @hooks validate_channelname
* * \e array \b name
* @param string $name
*
* @returns nil return if name is valid, or string describing the error state.
*/
function validate_channelname($name) {
@@ -69,7 +70,7 @@ function validate_channelname($name) {
if (strlen($name) > 255)
return t('Name too long');
$arr = array('name' => $name);
$arr = ['name' => $name];
call_hooks('validate_channelname', $arr);
if (x($arr, 'message'))
@@ -242,24 +243,22 @@ function create_identity($arr) {
$expire = 0;
$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' ) ",
intval($arr['account_id']),
intval($primary),
dbesc($name),
dbesc($nick),
dbesc($guid),
dbesc($sig),
dbesc($hash),
dbesc($key['prvkey']),
dbesc($key['pubkey']),
intval($pageflags),
intval($system),
intval($expire),
dbesc(App::$timezone)
$r = channel_store_lowlevel(
[
'channel_account_id' => intval($arr['account_id']),
'channel_primary' => intval($primary),
'channel_name' => $name,
'channel_address' => $nick,
'channel_guid' => $guid,
'channel_guid_sig' => $sig,
'channel_hash' => $hash,
'channel_prvkey' => $key['prvkey'],
'channel_pubkey' => $key['pubkey'],
'channel_pageflags' => intval($pageflags),
'channel_system' => intval($system),
'channel_expire_days' => intval($expire),
'channel_timezone' => App::$timezone
]
);
$r = q("select * from channel where channel_account_id = %d
@@ -465,7 +464,6 @@ function create_identity($arr) {
* if true, set this default unconditionally
* if $force is false only do this if there is no existing default
*/
function set_default_login_identity($account_id, $channel_id, $force = true) {
$r = q("select account_default_channel from account where account_id = %d limit 1",
intval($account_id)
@@ -480,12 +478,29 @@ function set_default_login_identity($account_id, $channel_id, $force = true) {
}
}
/**
* @brief Return an array with default list of sections to export.
*
* @hooks get_default_export_sections
* * \e array \b sections
* @return array with default section names to export
*/
function get_default_export_sections() {
$sections = [ 'channel', 'connections', 'config', 'apps', 'chatrooms', 'events', 'webpages', 'mail', 'wikis' ];
$sections = [
'channel',
'connections',
'config',
'apps',
'chatrooms',
'events',
'webpages',
'mail',
'wikis'
];
$cb = [ 'sections' => $sections ];
call_hooks('get_default_export_sections', $cb);
return $cb['sections'];
}
@@ -495,15 +510,17 @@ function get_default_export_sections() {
* which would be necessary to create a nomadic identity clone. This includes
* most channel resources and connection information with the exception of content.
*
* @hooks identity_basic_export
* * \e int \b channel_id
* * \e array \b sections
* * \e array \b data
* @param int $channel_id
* Channel_id to export
* @param boolean $items
* Include channel posts (wall items), default false
*
* @param array $sections (optional)
* Which sections to include in the export, default see get_default_export_sections()
* @returns array
* See function for details
*/
function identity_basic_export($channel_id, $sections = null) {
/*
@@ -513,16 +530,16 @@ function identity_basic_export($channel_id, $sections = null) {
if(! $sections) {
$sections = get_default_export_sections();
}
$ret = [];
// 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'] = [
'project' => PLATFORM_NAME,
'version' => STD_VERSION,
'database' => DB_UPDATE_VERSION,
'project' => PLATFORM_NAME,
'version' => STD_VERSION,
'database' => DB_UPDATE_VERSION,
'server_role' => Zotlabs\Lib\System::get_server_role()
];
@@ -539,6 +556,8 @@ function identity_basic_export($channel_id, $sections = null) {
$ret['relocate'] = [ 'channel_address' => $r[0]['channel_address'], 'url' => z_root()];
if(in_array('channel',$sections)) {
$ret['channel'] = $r[0];
unset($ret['channel']['channel_password']);
unset($ret['channel']['channel_salt']);
}
}
@@ -549,8 +568,7 @@ function identity_basic_export($channel_id, $sections = null) {
if($r)
$ret['profile'] = $r;
$r = q("select mimetype, content, os_storage from photo
$r = q("select mimetype, content, os_storage from photo
where imgscale = 4 and photo_usage = %d and uid = %d limit 1",
intval(PHOTO_PROFILE),
intval($channel_id)
@@ -558,8 +576,8 @@ function identity_basic_export($channel_id, $sections = null) {
if($r) {
$ret['photo'] = [
'type' => $r[0]['mimetype'],
'data' => (($r[0]['os_storage'])
'type' => $r[0]['mimetype'],
'data' => (($r[0]['os_storage'])
? base64url_encode(file_get_contents($r[0]['content'])) : base64url_encode($r[0]['content']))
];
}
@@ -605,7 +623,6 @@ function identity_basic_export($channel_id, $sections = null) {
);
if($r)
$ret['group_member'] = $r;
}
if(in_array('config',$sections)) {
@@ -614,7 +631,7 @@ function identity_basic_export($channel_id, $sections = null) {
);
if($r)
$ret['config'] = $r;
// All other term types will be included in items, if requested.
$r = q("select * from term where ttype in (%d,%d) and uid = %d",
@@ -641,7 +658,6 @@ function identity_basic_export($channel_id, $sections = null) {
if($r)
$ret['likes'] = $r;
}
if(in_array('apps',$sections)) {
@@ -667,7 +683,6 @@ function identity_basic_export($channel_id, $sections = null) {
$ret['chatroom'] = $r;
}
if(in_array('events',$sections)) {
$r = q("select * from event where uid = %d",
intval($channel_id)
@@ -697,7 +712,7 @@ function identity_basic_export($channel_id, $sections = null) {
$ret['menu'][] = menu_element($ret['channel'],$m);
}
}
$r = q("select * from item where item_type in ( "
$r = q("select * from item where item_type in ( "
. ITEM_TYPE_BLOCK . "," . ITEM_TYPE_PDL . "," . ITEM_TYPE_WEBPAGE . " ) and uid = %d",
intval($channel_id)
);
@@ -707,7 +722,6 @@ function identity_basic_export($channel_id, $sections = null) {
$r = fetch_post_tags($r,true);
foreach($r as $rr)
$ret['webpages'][] = encode_item($rr,true);
}
}
@@ -758,7 +772,7 @@ function identity_basic_export($channel_id, $sections = null) {
* 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
$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(),
@@ -1193,11 +1207,6 @@ function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = fa
else
$tpl = get_markup_template('profile_vcard.tpl');
require_once('include/widgets.php');
// if(! feature_enabled($profile['uid'],'hide_rating'))
$z = widget_rating(array('target' => $profile['channel_hash']));
$o .= replace_macros($tpl, array(
'$zcard' => $zcard,
'$profile' => $profile,
@@ -1211,7 +1220,7 @@ function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = fa
'$chanmenu' => $channel_menu,
'$diaspora' => $diaspora,
'$reddress' => $reddress,
'$rating' => $z,
'$rating' => '',
'$contact_block' => $contact_block,
'$editmenu' => profile_edit_menu($profile['uid'])
));
@@ -1399,15 +1408,15 @@ function get_my_address() {
}
/**
* @brief
* @brief Add visitor's zid to our xchan and attempt authentication.
*
* If somebody arrives at our site using a zid, add their xchan to our DB if we don't have it already.
* If somebody arrives at our site using a zid, add their xchan to our DB if we
* don't have it already.
* And if they aren't already authenticated here, attempt reverse magic auth.
*
*
* @hooks 'zid_init'
* string 'zid' - their zid
* string 'url' - the destination url
* @hooks zid_init
* * \e string \b zid - their zid
* * \e string \b url - the destination url
*/
function zid_init() {
$tmp_str = get_my_address();
@@ -1436,12 +1445,9 @@ function zid_init() {
}
/**
* @brief
*
* If somebody arrives at our site using a zat, authenticate them
* @brief If somebody arrives at our site using a zat, authenticate them.
*
*/
function zat_init() {
if(local_channel() || remote_channel())
return;
@@ -1453,7 +1459,6 @@ function zat_init() {
$xchan = atoken_xchan($r[0]);
atoken_login($xchan);
}
}
@@ -1486,7 +1491,7 @@ function get_theme_uid() {
*
* @param int $size
* one of (300, 80, 48)
* @returns string
* @returns string with path to profile photo
*/
function get_default_profile_photo($size = 300) {
$scheme = get_config('system','default_profile_photo');
@@ -1608,7 +1613,7 @@ function get_profile_fields_basic($filter = 0) {
$profile_fields_basic = (($filter == 0) ? get_config('system','profile_fields_basic') : null);
if(! $profile_fields_basic)
$profile_fields_basic = array('fullname','pdesc','chandesc','gender','dob','dob_tz','address','locality','region','postal_code','country_name','marital','sexual','homepage','hometown','keywords','about','contact');
$profile_fields_basic = array('fullname','pdesc','chandesc','comms','gender','dob','dob_tz','address','locality','region','postal_code','country_name','marital','sexual','homepage','hometown','keywords','about','contact');
$x = array();
if($profile_fields_basic)
@@ -1979,7 +1984,6 @@ function channel_manual_conv_update($channel_id) {
$x = get_config('system','manual_conversation_update', 1);
return intval($x);
}
@@ -1995,6 +1999,47 @@ function remote_login() {
}
function channel_store_lowlevel($arr) {
$store = [
'channel_account_id' => ((array_key_exists('channel_account_id',$arr)) ? $arr['channel_account_id'] : '0'),
'channel_primary' => ((array_key_exists('channel_primary',$arr)) ? $arr['channel_primary'] : '0'),
'channel_name' => ((array_key_exists('channel_name',$arr)) ? $arr['channel_name'] : ''),
'channel_address' => ((array_key_exists('channel_address',$arr)) ? $arr['channel_address'] : ''),
'channel_guid' => ((array_key_exists('channel_guid',$arr)) ? $arr['channel_guid'] : ''),
'channel_guid_sig' => ((array_key_exists('channel_guid_sig',$arr)) ? $arr['channel_guid_sig'] : ''),
'channel_hash' => ((array_key_exists('channel_hash',$arr)) ? $arr['channel_hash'] : ''),
'channel_timezone' => ((array_key_exists('channel_timezone',$arr)) ? $arr['channel_timezone'] : 'UTC'),
'channel_location' => ((array_key_exists('channel_location',$arr)) ? $arr['channel_location'] : ''),
'channel_theme' => ((array_key_exists('channel_theme',$arr)) ? $arr['channel_theme'] : ''),
'channel_startpage' => ((array_key_exists('channel_startpage',$arr)) ? $arr['channel_startpage'] : ''),
'channel_pubkey' => ((array_key_exists('channel_pubkey',$arr)) ? $arr['channel_pubkey'] : ''),
'channel_prvkey' => ((array_key_exists('channel_prvkey',$arr)) ? $arr['channel_prvkey'] : ''),
'channel_notifyflags' => ((array_key_exists('channel_notifyflags',$arr)) ? $arr['channel_notifyflags'] : '65535'),
'channel_pageflags' => ((array_key_exists('channel_pageflags',$arr)) ? $arr['channel_pageflags'] : '0'),
'channel_dirdate' => ((array_key_exists('channel_dirdate',$arr)) ? $arr['channel_dirdate'] : NULL_DATE),
'channel_lastpost' => ((array_key_exists('channel_lastpost',$arr)) ? $arr['channel_lastpost'] : NULL_DATE),
'channel_deleted' => ((array_key_exists('channel_deleted',$arr)) ? $arr['channel_deleted'] : NULL_DATE),
'channel_max_anon_mail' => ((array_key_exists('channel_max_anon_mail',$arr)) ? $arr['channel_max_anon_mail'] : '10'),
'channel_max_friend_req' => ((array_key_exists('channel_max_friend_req',$arr)) ? $arr['channel_max_friend_req'] : '10'),
'channel_expire_days' => ((array_key_exists('channel_expire_days',$arr)) ? $arr['channel_expire_days'] : '0'),
'channel_passwd_reset' => ((array_key_exists('channel_passwd_reset',$arr)) ? $arr['channel_passwd_reset'] : ''),
'channel_default_group' => ((array_key_exists('channel_default_group',$arr)) ? $arr['channel_default_group'] : ''),
'channel_allow_cid' => ((array_key_exists('channel_allow_cid',$arr)) ? $arr['channel_allow_cid'] : ''),
'channel_allow_gid' => ((array_key_exists('channel_allow_gid',$arr)) ? $arr['channel_allow_gid'] : ''),
'channel_deny_cid' => ((array_key_exists('channel_deny_cid',$arr)) ? $arr['channel_deny_cid'] : ''),
'channel_deny_gid' => ((array_key_exists('channel_deny_gid',$arr)) ? $arr['channel_deny_gid'] : ''),
'channel_removed' => ((array_key_exists('channel_removed',$arr)) ? $arr['channel_removed'] : '0'),
'channel_system' => ((array_key_exists('channel_system',$arr)) ? $arr['channel_system'] : '0'),
'channel_moved' => ((array_key_exists('channel_moved',$arr)) ? $arr['channel_moved'] : ''),
'channel_password' => ((array_key_exists('channel_password',$arr)) ? $arr['channel_password'] : ''),
'channel_salt' => ((array_key_exists('channel_salt',$arr)) ? $arr['channel_salt'] : '')
];
return create_table_from_array('channel',$store);
}
function profile_store_lowlevel($arr) {
@@ -2046,4 +2091,235 @@ function profile_store_lowlevel($arr) {
];
return create_table_from_array('profile',$store);
}
}
// Included here for completeness, but this is a very dangerous operation.
// It is the caller's responsibility to confirm the requestor's intent and
// authorisation to do this.
function account_remove($account_id,$local = true,$unset_session=true) {
logger('account_remove: ' . $account_id);
if(! intval($account_id)) {
logger('account_remove: no account.');
return false;
}
// Don't let anybody nuke the only admin account.
$r = q("select account_id from account where (account_roles & %d) > 0",
intval(ACCOUNT_ROLE_ADMIN)
);
if($r !== false && count($r) == 1 && $r[0]['account_id'] == $account_id) {
logger("Unable to remove the only remaining admin account");
return false;
}
$r = q("select * from account where account_id = %d limit 1",
intval($account_id)
);
$account_email=$r[0]['account_email'];
if(! $r) {
logger('account_remove: No account with id: ' . $account_id);
return false;
}
$x = q("select channel_id from channel where channel_account_id = %d",
intval($account_id)
);
if($x) {
foreach($x as $xx) {
channel_remove($xx['channel_id'],$local,false);
}
}
$r = q("delete from account where account_id = %d",
intval($account_id)
);
if ($unset_session) {
unset($_SESSION['authenticated']);
unset($_SESSION['uid']);
notice( sprintf(t("User '%s' deleted"),$account_email) . EOL);
goaway(z_root());
}
return $r;
}
/**
* @brief Removes a channel.
*
* @hooks channel_remove
* * \e array \b entry from channel tabel for $channel_id
* @param int $channel_id
* @param boolean $local default true
* @param boolean $unset_session default false
*/
function channel_remove($channel_id, $local = true, $unset_session = false) {
if(! $channel_id)
return;
logger('Removing channel: ' . $channel_id);
logger('local only: ' . intval($local));
$r = q("select * from channel where channel_id = %d limit 1", intval($channel_id));
if(! $r) {
logger('channel not found: ' . $channel_id);
return;
}
$channel = $r[0];
call_hooks('channel_remove', $r[0]);
if(! $local) {
$r = q("update channel set channel_deleted = '%s', channel_removed = 1 where channel_id = %d",
dbesc(datetime_convert()),
intval($channel_id)
);
q("delete from pconfig where uid = %d",
intval($channel_id)
);
logger('deleting hublocs',LOGGER_DEBUG);
$r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s'",
dbesc($channel['channel_hash'])
);
$r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s'",
dbesc($channel['channel_hash'])
);
Zotlabs\Daemon\Master::Summon(array('Notifier','purge_all',$channel_id));
}
$r = q("select * from iconfig left join item on item.id = iconfig.iid
where item.uid = %d",
intval($channel_id)
);
if($r) {
foreach($r as $rr) {
q("delete from iconfig where iid = %d",
intval($rr['iid'])
);
}
}
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
q("delete from abook where abook_xchan = '%s' and abook_self = 1 ",
dbesc($channel['channel_hash'])
);
$r = q("update channel set channel_deleted = '%s', channel_removed = 1 where channel_id = %d",
dbesc(datetime_convert()),
intval($channel_id)
);
// if this was the default channel, set another one as default
if(App::$account['account_default_channel'] == $channel_id) {
$r = q("select channel_id from channel where channel_account_id = %d and channel_removed = 0 limit 1",
intval(App::$account['account_id']),
intval(PAGE_REMOVED));
if ($r) {
$rr = q("update account set account_default_channel = %d where account_id = %d",
intval($r[0]['channel_id']),
intval(App::$account['account_id']));
logger("Default channel deleted, changing default to channel_id " . $r[0]['channel_id']);
}
else {
$rr = q("update account set account_default_channel = 0 where account_id = %d",
intval(App::$account['account_id'])
);
}
}
logger('deleting hublocs',LOGGER_DEBUG);
$r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s' and hubloc_url = '%s' ",
dbesc($channel['channel_hash']),
dbesc(z_root())
);
// Do we have any valid hublocs remaining?
$hublocs = 0;
$r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0",
dbesc($channel['channel_hash'])
);
if($r)
$hublocs = count($r);
if(! $hublocs) {
$r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s' ",
dbesc($channel['channel_hash'])
);
}
//remove from file system
$r = q("select channel_address from channel where channel_id = %d limit 1",
intval($channel_id)
);
if($r) {
$channel_address = $r[0]['channel_address'] ;
}
if($channel_address) {
$f = 'store/' . $channel_address.'/';
logger('delete '. $f);
if(is_dir($f)) {
@rrmdir($f);
}
}
Zotlabs\Daemon\Master::Summon(array('Directory',$channel_id));
if($channel_id == local_channel() && $unset_session) {
App::$session->nuke();
goaway(z_root());
}
}
/**
* @brief This checks if a channel is allowed to publish executable code.
*
* It is up to the caller to determine if the observer or local_channel
* is in fact the resource owner whose channel_id is being checked.
*
* @param int $channel_id
* @return boolean
*/
function channel_codeallowed($channel_id) {
if(! intval($channel_id))
return false;
$x = channelx_by_n($channel_id);
if(($x) && ($x['channel_pageflags'] & PAGE_ALLOWCODE))
return true;
return false;
}

View File

@@ -23,6 +23,7 @@ function abook_store_lowlevel($arr) {
'abook_unconnected' => ((array_key_exists('abook_unconnected',$arr)) ? $arr['abook_unconnected'] : 0),
'abook_self' => ((array_key_exists('abook_self',$arr)) ? $arr['abook_self'] : 0),
'abook_feed' => ((array_key_exists('abook_feed',$arr)) ? $arr['abook_feed'] : 0),
'abook_not_here' => ((array_key_exists('abook_not_here',$arr)) ? $arr['abook_not_here'] : 0),
'abook_profile' => ((array_key_exists('abook_profile',$arr)) ? $arr['abook_profile'] : ''),
'abook_incl' => ((array_key_exists('abook_incl',$arr)) ? $arr['abook_incl'] : ''),
'abook_excl' => ((array_key_exists('abook_excl',$arr)) ? $arr['abook_excl'] : ''),
@@ -188,232 +189,6 @@ function abook_toggle_flag($abook,$flag) {
}
// Included here for completeness, but this is a very dangerous operation.
// It is the caller's responsibility to confirm the requestor's intent and
// authorisation to do this.
function user_remove($uid) {
}
function account_remove($account_id,$local = true,$unset_session=true) {
logger('account_remove: ' . $account_id);
if(! intval($account_id)) {
logger('account_remove: no account.');
return false;
}
// Don't let anybody nuke the only admin account.
$r = q("select account_id from account where (account_roles & %d) > 0",
intval(ACCOUNT_ROLE_ADMIN)
);
if($r !== false && count($r) == 1 && $r[0]['account_id'] == $account_id) {
logger("Unable to remove the only remaining admin account");
return false;
}
$r = q("select * from account where account_id = %d limit 1",
intval($account_id)
);
$account_email=$r[0]['account_email'];
if(! $r) {
logger('account_remove: No account with id: ' . $account_id);
return false;
}
$x = q("select channel_id from channel where channel_account_id = %d",
intval($account_id)
);
if($x) {
foreach($x as $xx) {
channel_remove($xx['channel_id'],$local,false);
}
}
$r = q("delete from account where account_id = %d",
intval($account_id)
);
if ($unset_session) {
unset($_SESSION['authenticated']);
unset($_SESSION['uid']);
notice( sprintf(t("User '%s' deleted"),$account_email) . EOL);
goaway(z_root());
}
return $r;
}
// recursively delete a directory
function rrmdir($path)
{
if (is_dir($path) === true)
{
$files = array_diff(scandir($path), array('.', '..'));
foreach ($files as $file)
{
rrmdir(realpath($path) . '/' . $file);
}
return rmdir($path);
}
else if (is_file($path) === true)
{
return unlink($path);
}
return false;
}
function channel_remove($channel_id, $local = true, $unset_session=false) {
if(! $channel_id)
return;
logger('Removing channel: ' . $channel_id);
logger('channel_remove: local only: ' . intval($local));
$r = q("select * from channel where channel_id = %d limit 1", intval($channel_id));
if(! $r) {
logger('channel_remove: channel not found: ' . $channel_id);
return;
}
$channel = $r[0];
call_hooks('channel_remove',$r[0]);
if(! $local) {
$r = q("update channel set channel_deleted = '%s', channel_removed = 1 where channel_id = %d",
dbesc(datetime_convert()),
intval($channel_id)
);
q("delete from pconfig where uid = %d",
intval($channel_id)
);
logger('deleting hublocs',LOGGER_DEBUG);
$r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s'",
dbesc($channel['channel_hash'])
);
$r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s'",
dbesc($channel['channel_hash'])
);
Zotlabs\Daemon\Master::Summon(array('Notifier','purge_all',$channel_id));
}
$r = q("select * from iconfig left join item on item.id = iconfig.iid
where item.uid = %d",
intval($channel_id)
);
if($r) {
foreach($r as $rr) {
q("delete from iconfig where iid = %d",
intval($rr['iid'])
);
}
}
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
q("delete from abook where abook_xchan = '%s' and abook_self = 1 ",
dbesc($channel['channel_hash'])
);
$r = q("update channel set channel_deleted = '%s', channel_removed = 1 where channel_id = %d",
dbesc(datetime_convert()),
intval($channel_id)
);
// if this was the default channel, set another one as default
if(App::$account['account_default_channel'] == $channel_id) {
$r = q("select channel_id from channel where channel_account_id = %d and channel_removed = 0 limit 1",
intval(App::$account['account_id']),
intval(PAGE_REMOVED));
if ($r) {
$rr = q("update account set account_default_channel = %d where account_id = %d",
intval($r[0]['channel_id']),
intval(App::$account['account_id']));
logger("Default channel deleted, changing default to channel_id " . $r[0]['channel_id']);
}
else {
$rr = q("update account set account_default_channel = 0 where account_id = %d",
intval(App::$account['account_id'])
);
}
}
logger('deleting hublocs',LOGGER_DEBUG);
$r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s' and hubloc_url = '%s' ",
dbesc($channel['channel_hash']),
dbesc(z_root())
);
// Do we have any valid hublocs remaining?
$hublocs = 0;
$r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0",
dbesc($channel['channel_hash'])
);
if($r)
$hublocs = count($r);
if(! $hublocs) {
$r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s' ",
dbesc($channel['channel_hash'])
);
}
//remove from file system
$r = q("select channel_address from channel where channel_id = %d limit 1",
intval($channel_id)
);
if($r)
$channel_address = $r[0]['channel_address'] ;
if ($channel_address !== '') {
$f = 'store/' . $channel_address.'/';
logger ('delete '. $f);
if(is_dir($f))
@rrmdir($f);
}
Zotlabs\Daemon\Master::Summon(array('Directory',$channel_id));
if($channel_id == local_channel() && $unset_session) {
App::$session->nuke();
goaway(z_root());
}
}
/**
* mark any hubs "offline" that haven't been heard from in more than 30 days
@@ -430,10 +205,10 @@ function mark_orphan_hubsxchans() {
if($dirmode == DIRECTORY_MODE_NORMAL)
return;
$r = q("update hubloc set hubloc_error = 1 where hubloc_error = 0
$r = q("update hubloc set hubloc_error = 1 where hubloc_error = 0
and hubloc_network = 'zot' and hubloc_connected < %s - interval %s",
db_utcnow(), db_quoteinterval('36 day')
);
db_utcnow(), db_quoteinterval('36 day')
);
// $realm = get_directory_realm();
// if($realm == DIRECTORY_REALM) {
@@ -547,13 +322,13 @@ function remove_all_xchan_resources($xchan, $channel_id = 0) {
// directory servers need to keep the record around for sync purposes - mark it deleted
$r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s'",
dbesc($xchan)
);
$r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s'",
dbesc($xchan)
);
$r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s'",
dbesc($xchan)
);
$r = q("update xchan set xchan_deleted = 1 where xchan_hash = '%s'",
dbesc($xchan)
);
}
}
}

View File

@@ -2,10 +2,6 @@
require_once('include/items.php');
// Note: the code in 'item_extract_images' and 'item_redir_and_replace_images'
// is identical to the code in mod/message.php for 'item_extract_images' and
// 'item_redir_and_replace_images'
function item_extract_images($body) {
@@ -375,13 +371,14 @@ function localize_item(&$item){
* * \e array \b children
* @return number
*/
function count_descendants($item) {
$total = count($item['children']);
if ($total > 0) {
foreach ($item['children'] as $child) {
if (! visible_activity($child))
if($total > 0) {
foreach($item['children'] as $child) {
if(! visible_activity($child))
$total --;
$total += count_descendants($child);
@@ -408,8 +405,8 @@ function visible_activity($item) {
if(intval($item['item_notshown']))
return false;
foreach ($hidden_activities as $act) {
if ((activity_match($item['verb'], $act)) && ($item['mid'] != $item['parent_mid'])) {
foreach($hidden_activities as $act) {
if((activity_match($item['verb'], $act)) && ($item['mid'] != $item['parent_mid'])) {
return false;
}
}
@@ -614,6 +611,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
$owner_photo = '';
$owner_name = '';
$sparkle = '';
$is_new = false;
if($mode === 'search' || $mode === 'community') {
if(((activity_match($item['verb'],ACTIVITY_LIKE)) || (activity_match($item['verb'],ACTIVITY_DISLIKE)))
@@ -682,6 +680,9 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
$has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false);
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
$is_new = true;
$tmp_item = array(
'template' => $tpl,
'toplevel' => 'toplevel_item',
@@ -738,6 +739,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
'wait' => t('Please wait'),
'thread_level' => 1,
'has_tags' => $has_tags,
'is_new' => $is_new
);
$arr = array('item' => $item, 'output' => $tmp_item);
@@ -870,98 +872,6 @@ function best_link_url($item) {
function item_photo_menu($item){
$contact = null;
$ssl_state = false;
$sub_link="";
$poke_link="";
$contact_url="";
$pm_url="";
$vsrc_link = "";
$follow_url = "";
$local_channel = local_channel();
if($local_channel) {
$ssl_state = true;
if(! count(App::$contacts))
load_contact_links($local_channel);
$channel = App::get_channel();
$channel_hash = (($channel) ? $channel['channel_hash'] : '');
}
if(($local_channel) && $local_channel == $item['uid']) {
$vsrc_link = 'javascript:viewsrc(' . $item['id'] . '); return false;';
if($item['parent'] == $item['id'] && $channel && ($channel_hash != $item['author_xchan'])) {
$sub_link = 'javascript:dosubthread(' . $item['id'] . '); return false;';
}
if($channel) {
$unsub_link = 'javascript:dounsubthread(' . $item['id'] . '); return false;';
}
}
$profile_link = chanlink_hash($item['author_xchan']);
if($item['uid'] > 0)
$pm_url = z_root() . '/mail/new/?f=&hash=' . $item['author_xchan'];
if(App::$contacts && array_key_exists($item['author_xchan'],App::$contacts))
$contact = App::$contacts[$item['author_xchan']];
else
if($local_channel && $item['author']['xchan_addr'])
$follow_url = z_root() . '/follow/?f=&url=' . $item['author']['xchan_addr'];
if($contact) {
$poke_link = z_root() . '/poke/?f=&c=' . $contact['abook_id'];
if (! intval($contact['abook_self']))
$contact_url = z_root() . '/connedit/' . $contact['abook_id'];
$posts_link = z_root() . '/network/?cid=' . $contact['abook_id'];
$clean_url = normalise_link($item['author-link']);
}
$rating_enabled = get_config('system','rating_enabled');
$ratings_url = (($rating_enabled) ? z_root() . '/ratings/' . urlencode($item['author_xchan']) : '');
$post_menu = Array(
t("View Source") => $vsrc_link,
t("Follow Thread") => $sub_link,
t("Unfollow Thread") => $unsub_link,
);
$author_menu = array(
t("View Profile") => $profile_link,
t("Activity/Posts") => $posts_link,
t("Connect") => $follow_url,
t("Edit Connection") => $contact_url,
t("Message") => $pm_url,
t('Ratings') => $ratings_url,
t("Poke") => $poke_link
);
$args = array('item' => $item, 'post_menu' => $post_menu, 'author_menu' => $author_menu);
call_hooks('item_photo_menu', $args);
$menu = array_merge($args['post_menu'],$args['author_menu']);
$o = "";
foreach($menu as $k=>$v){
if(strpos($v,'javascript:') === 0) {
$v = substr($v,11);
$o .= "<li><a href=\"#\" onclick=\"$v\">$k</a></li>\n";
}
elseif ($v!="") $o .= "<li><a href=\"$v\">$k</a></li>\n";
}
return $o;
}
function thread_action_menu($item,$mode = '') {
$menu = [];
@@ -1007,6 +917,24 @@ function thread_action_menu($item,$mode = '') {
}
function author_is_pmable($xchan) {
$x = [ 'xchan' => $xchan, 'result' => 'unset' ];
call_hooks('author_is_pmable',$x);
if($x['result'] !== 'unset')
return $x['result'];
if($xchan['xchan_network'] === 'zot')
return true;
return false;
}
function thread_author_menu($item, $mode = '') {
$menu = [];
@@ -1021,14 +949,19 @@ function thread_author_menu($item, $mode = '') {
}
$profile_link = chanlink_hash($item['author_xchan']);
if($item['uid'] > 0)
$pm_url = z_root() . '/mail/new/?f=&hash=' . $item['author_xchan'];
if(App::$contacts && array_key_exists($item['author_xchan'],App::$contacts))
$contact = App::$contacts[$item['author_xchan']];
else
if($local_channel && $item['author']['xchan_addr'])
$follow_url = z_root() . '/follow/?f=&url=' . $item['author']['xchan_addr'];
$follow_url = z_root() . '/follow/?f=&url=' . urlencode($item['author']['xchan_addr']);
if($item['uid'] > 0 && author_is_pmable($item['author']))
$pm_url = z_root() . '/mail/new/?f=&hash=' . urlencode($item['author_xchan']);
if($contact) {
$poke_link = z_root() . '/poke/?f=&c=' . $contact['abook_id'];
@@ -1176,8 +1109,8 @@ function builtin_activity_puller($item, &$conv_responses) {
if((activity_match($item['verb'], $verb)) && ($item['id'] != $item['parent'])) {
$name = (($item['author']['xchan_name']) ? $item['author']['xchan_name'] : t('Unknown'));
$url = (($item['author_xchan'] && $item['author']['xchan_photo_s'])
? '<a href="' . chanlink_hash($item['author_xchan']) . '">' . '<img class="dropdown-menu-img-xs" src="' . zid($item['author']['xchan_photo_s']) . '" alt="' . urlencode($name) . '" />' . $name . '</a>'
: '<a href="#" class="disabled">' . $name . '</a>'
? '<a class="dropdown-item" href="' . chanlink_hash($item['author_xchan']) . '">' . '<img class="menu-img-1" src="' . zid($item['author']['xchan_photo_s']) . '" alt="' . urlencode($name) . '" />' . $name . '</a>'
: '<a class="dropdown-item" href="#" class="disabled">' . $name . '</a>'
);
if(! $item['thr_parent'])
@@ -1608,6 +1541,15 @@ function prepare_page($item) {
// the template will get passed an unobscured title.
$body = prepare_body($item, true);
if(App::$page['template'] == 'none') {
$tpl = 'page_display_empty.tpl';
return replace_macros(get_markup_template($tpl), array(
'$body' => $body['html']
));
}
$tpl = get_pconfig($item['uid'], 'system', 'pagetemplate');
if (! $tpl)
$tpl = 'page_display.tpl';
@@ -1770,6 +1712,9 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
if (App::$is_sys)
return;
if (get_pconfig($uid, 'system', 'noprofiletabs'))
return;
$channel = App::get_channel();
if (is_null($nickname))
@@ -1779,6 +1724,9 @@ 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())
return;
if($uid == local_channel()) {
$cal_link = '';
}
@@ -1801,9 +1749,6 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
$has_webpages = (($r) ? true : false);
if (get_pconfig($uid, 'system', 'noprofiletabs'))
return;
if (x($_GET, 'tab'))
$tab = notags(trim($_GET['tab']));
@@ -1817,6 +1762,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
'sel' => ((argv(0) == 'channel') ? 'active' : ''),
'title' => t('Status Messages and Posts'),
'id' => 'status-tab',
'icon' => 'home'
),
);
@@ -1829,6 +1775,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
'sel' => ((argv(0) == 'profile') ? 'active' : ''),
'title' => t('Profile Details'),
'id' => 'profile-tab',
'icon' => 'user'
);
}
if ($p['view_storage']) {
@@ -1838,6 +1785,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
'sel' => ((argv(0) == 'photos') ? 'active' : ''),
'title' => t('Photo Albums'),
'id' => 'photo-tab',
'icon' => 'photo'
);
$tabs[] = array(
'label' => t('Files'),
@@ -1845,6 +1793,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
'sel' => ((argv(0) == 'cloud' || argv(0) == 'sharedwithme') ? 'active' : ''),
'title' => t('Files and Storage'),
'id' => 'files-tab',
'icon' => 'folder-open'
);
}
@@ -1855,6 +1804,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
'sel' => ((argv(0) == 'cal' || argv(0) == 'events') ? 'active' : ''),
'title' => t('Events'),
'id' => 'event-tab',
'icon' => 'calendar'
);
}
@@ -1868,6 +1818,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
'sel' => ((argv(0) == 'chat') ? 'active' : '' ),
'title' => t('Chatrooms'),
'id' => 'chat-tab',
'icon' => 'comments-o'
);
}
}
@@ -1881,6 +1832,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
'sel' => ((argv(0) == 'bookmarks') ? 'active' : ''),
'title' => t('Saved Bookmarks'),
'id' => 'bookmarks-tab',
'icon' => 'bookmark'
);
}
@@ -1891,27 +1843,34 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
'sel' => ((argv(0) == 'webpages') ? 'active' : ''),
'title' => t('View Webpages'),
'id' => 'webpages-tab',
'icon' => 'newspaper-o'
);
}
if(feature_enabled($uid,'wiki') && (get_account_techlevel($account_id) > 3)) {
$tabs[] = array(
'label' => t('Wikis'),
'url' => z_root() . '/wiki/' . $nickname,
'sel' => ((argv(0) == 'wiki') ? 'active' : ''),
'title' => t('Wiki'),
'id' => 'wiki-tab',
);
if ($p['view_wiki']) {
if(feature_enabled($uid,'wiki') && (get_account_techlevel($account_id) > 3)) {
$tabs[] = array(
'label' => t('Wikis'),
'url' => z_root() . '/wiki/' . $nickname,
'sel' => ((argv(0) == 'wiki') ? 'active' : ''),
'title' => t('Wiki'),
'id' => 'wiki-tab',
'icon' => 'pencil-square-o'
);
}
}
$arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs);
call_hooks('profile_tabs', $arr);
$tpl = get_markup_template('common_tabs.tpl');
$tpl = get_markup_template('profile_tabs.tpl');
return replace_macros($tpl,array('$tabs' => $arr['tabs']));
return replace_macros($tpl, array(
'$tabs' => $arr['tabs'],
'$name' => App::$profile['channel_name'],
'$thumb' => App::$profile['thumb']
));
}
@@ -1922,15 +1881,11 @@ function get_responses($conv_responses,$response_verbs,$ob,$item) {
$ret[$v] = array();
$ret[$v]['count'] = ((x($conv_responses[$v],$item['mid'])) ? $conv_responses[$v][$item['mid']] : '');
$ret[$v]['list'] = ((x($conv_responses[$v],$item['mid'])) ? $conv_responses[$v][$item['mid'] . '-l'] : '');
if(count($ret[$v]['list']) > MAX_LIKERS) {
$ret[$v]['list_part'] = array_slice($ret[$v]['list'], 0, MAX_LIKERS);
array_push($ret[$v]['list_part'], '<a href="#" data-toggle="modal" data-target="#' . $v . 'Modal-'
. (($ob) ? $ob->get_id() : $item['id']) . '"><b>' . t('View all') . '</b></a>');
} else {
$ret[$v]['list_part'] = '';
}
$ret[$v]['button'] = get_response_button_text($v,$ret[$v]['count']);
$ret[$v]['title'] = $conv_responses[$v]['title'];
if($ret[$v]['count'] > MAX_LIKERS) {
$ret[$v]['modal'] = true;
}
}
$count = 0;

View File

@@ -55,6 +55,7 @@ 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);
@@ -67,18 +68,33 @@ function AES128CBC_decrypt($data,$key,$iv) {
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) {
function AES256CTR_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"));
return openssl_encrypt($data,'aes-256-ctr',str_pad($key,32,"\0"),OPENSSL_RAW_DATA,str_pad($iv,16,"\0"));
}
function STD_decrypt($data,$key,$iv) {
function AES256CTR_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"));
return openssl_decrypt($data,'aes-256-ctr',str_pad($key,32,"\0"),OPENSSL_RAW_DATA,str_pad($iv,16,"\0"));
}
function CAMELLIA256CFB_encrypt($data,$key,$iv) {
$key = substr($key,0,32);
$iv = substr($iv,0,16);
return openssl_encrypt($data,'camellia-256-cfb',str_pad($key,32,"\0"),OPENSSL_RAW_DATA,str_pad($iv,16,"\0"));
}
function CAMELLIA256CFB_decrypt($data,$key,$iv) {
$key = substr($key,0,32);
$iv = substr($iv,0,16);
return openssl_decrypt($data,'camellia-256-cfb',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);
@@ -91,6 +107,20 @@ function CAST5CBC_decrypt($data,$key,$iv) {
return openssl_decrypt($data,'cast5-cbc',str_pad($key,16,"\0"),OPENSSL_RAW_DATA,str_pad($iv,8,"\0"));
}
function CAST5CFB_encrypt($data,$key,$iv) {
$key = substr($key,0,16);
$iv = substr($iv,0,8);
return openssl_encrypt($data,'cast5-cfb',str_pad($key,16,"\0"),OPENSSL_RAW_DATA,str_pad($iv,8,"\0"));
}
function CAST5CFB_decrypt($data,$key,$iv) {
$key = substr($key,0,16);
$iv = substr($iv,0,8);
return openssl_decrypt($data,'cast5-cfb',str_pad($key,16,"\0"),OPENSSL_RAW_DATA,str_pad($iv,8,"\0"));
}
function crypto_encapsulate($data,$pubkey,$alg='aes256cbc') {
$fn = strtoupper($alg) . '_encrypt';
@@ -142,17 +172,13 @@ function other_encapsulate($data,$pubkey,$alg) {
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' ];
$r = [ 'aes256ctr', 'camellia256cfb', 'cast5cfb', 'aes256cbc', 'aes128cbc', 'cast5cbc' ];
call_hooks('crypto_methods',$r);
return $r;

View File

@@ -15,7 +15,7 @@ class DBA {
static public $scheme = 'mysql';
static public $logging = false;
static public $install_script = 'install/schema_mysql.sql';
static public $install_script = 'schema_mysql.sql';
static public $null_date = '0001-01-01 00:00:00';
static public $utc_now = 'UTC_TIMESTAMP()';
static public $tquot = "`";
@@ -46,7 +46,7 @@ class DBA {
if(!($port))
$port = 5432;
self::$install_script = 'install/schema_postgres.sql';
self::$install_script = 'schema_postgres.sql';
self::$utc_now = "now() at time zone 'UTC'";
self::$tquot = '"';
self::$scheme = 'pgsql';
@@ -163,7 +163,9 @@ abstract class dba_driver {
}
function get_install_script() {
return \DBA::$install_script;
if(file_exists('install/' . PLATFORM_NAME . '/' . \DBA::$install_script))
return 'install/' . PLATFORM_NAME . '/' . \DBA::$install_script;
return 'install/' . \DBA::$install_script;
}
function get_table_quote() {
@@ -450,7 +452,7 @@ function db_getfunc($f) {
function db_logger($s,$level = LOGGER_NORMAL,$syslog = LOG_INFO) {
if(\DBA::$logging)
if(\DBA::$logging || ! \DBA::$dba)
return;
$saved = \DBA::$dba->debug;

View File

@@ -185,26 +185,17 @@ function sync_directories($dirmode) {
/** @FIXME What to do if we're in a different realm? */
if ((! $r) && (z_root() != DIRECTORY_FALLBACK_MASTER)) {
$r = array();
$r[] = array(
'site_url' => DIRECTORY_FALLBACK_MASTER,
'site_flags' => DIRECTORY_MODE_PRIMARY,
'site_update' => NULL_DATE,
'site_directory' => DIRECTORY_FALLBACK_MASTER . '/dirsearch',
'site_realm' => DIRECTORY_REALM,
'site_valid' => 1,
'site_crypto' => 'aes256cbc'
);
$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']),
dbesc($r[0]['site_crypto'])
$x = site_store_lowlevel(
[
'site_url' => DIRECTORY_FALLBACK_MASTER,
'site_flags' => DIRECTORY_MODE_PRIMARY,
'site_update' => NULL_DATE,
'site_directory' => DIRECTORY_FALLBACK_MASTER . '/dirsearch',
'site_realm' => DIRECTORY_REALM,
'site_valid' => 1,
'site_crypto' => 'aes256cbc'
]
);
$r = q("select * from site where site_flags in (%d, %d) and site_url != '%s' and site_type = %d ",

View File

@@ -65,4 +65,4 @@ function phpiniSizeToBytes($val) {
}
return (int)$val;
}
}

View File

@@ -249,6 +249,15 @@ function bbtoevent($s) {
$ev = array();
$match = '';
if(preg_match("/\[event\](.*?)\[\/event\]/is",$s,$match)) {
// only parse one object per event tag
$x = ical_to_ev($match[1]);
if($x)
$ev = $x[0];
}
$match = '';
if(preg_match("/\[event\-summary\](.*?)\[\/event\-summary\]/is",$s,$match))
$ev['summary'] = $match[1];
@@ -283,6 +292,8 @@ function bbtoevent($s) {
$ev['nofinish'] = 1;
}
// logger('bbtoevent: ' . print_r($ev,true));
return $ev;
}
@@ -555,6 +566,136 @@ function event_addtocal($item_id, $uid) {
}
function ical_to_ev($s) {
require_once('vendor/autoload.php');
$saved_timezone = date_default_timezone_get();
date_default_timezone_set('Australia/Sydney');
$ical = VObject\Reader::read($s);
$ev = [];
if($ical) {
if($ical->VEVENT) {
foreach($ical->VEVENT as $event) {
$ev[] = parse_vobject($event,'event');
}
}
if($ical->VTODO) {
foreach($ical->VTODO as $event) {
$ev[] = parse_vobject($event,'task');
}
}
}
date_default_timezone_set($saved_timezone);
return $ev;
}
function parse_vobject($ical, $type) {
$ev = [];
if(! isset($ical->DTSTART)) {
logger('no event start');
return $ev;
}
$ev['etype'] = $type;
$dtstart = $ical->DTSTART->getDateTime();
$ev['adjust'] = (($ical->DTSTART->isFloating()) ? 0 : 1);
$ev['dtstart'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC',
$dtstart->format(\DateTime::W3C));
if(isset($ical->DUE)) {
$dtend = $ical->DUE->getDateTime();
$ev['dtend'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC',
$dtend->format(\DateTime::W3C));
}
elseif(isset($ical->DTEND)) {
$dtend = $ical->DTEND->getDateTime();
$ev['dtend'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC',
$dtend->format(\DateTime::W3C));
}
else
$ev['nofinish'] = 1;
if($ev['dtstart'] === $ev['dtend'])
$ev['nofinish'] = 1;
if(isset($ical->CREATED)) {
$created = $ical->CREATED->getDateTime();
$ev['created'] = datetime_convert('UTC','UTC',$created->format(\DateTime::W3C));
}
if(isset($ical->{'DTSTAMP'})) {
$edited = $ical->{'DTSTAMP'}->getDateTime();
$ev['edited'] = datetime_convert('UTC','UTC',$edited->format(\DateTime::W3C));
}
if(isset($ical->{'LAST-MODIFIED'})) {
$edited = $ical->{'LAST-MODIFIED'}->getDateTime();
$ev['edited'] = datetime_convert('UTC','UTC',$edited->format(\DateTime::W3C));
}
if(isset($ical->{'X-ZOT-LOCATION'}))
$ev['location'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-LOCATION'});
elseif(isset($ical->LOCATION))
$ev['location'] = (string) $ical->LOCATION;
if(isset($ical->{'X-ZOT-DESCRIPTION'}))
$ev['description'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-DESCRIPTION'});
elseif(isset($ical->DESCRIPTION))
$ev['description'] = (string) $ical->DESCRIPTION;
if(isset($ical->{'X-ZOT-SUMMARY'}))
$ev['summary'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-SUMMARY'});
elseif(isset($ical->SUMMARY))
$ev['summary'] = (string) $ical->SUMMARY;
if(isset($ical->PRIORITY))
$ev['event_priority'] = intval((string) $ical->PRIORITY);
if(isset($ical->UID)) {
$evuid = (string) $ical->UID;
$ev['event_hash'] = $evuid;
}
if(isset($ical->SEQUENCE)) {
$ev['event_sequence'] = (string) $ical->SEQUENCE;
}
if(isset($ical->STATUS)) {
$ev['event_status'] = (string) $ical->STATUS;
}
if(isset($ical->{'COMPLETED'})) {
$completed = $ical->{'COMPLETED'}->getDateTime();
$ev['event_status_date'] = datetime_convert('UTC','UTC',$completed->format(\DateTime::W3C));
}
if(isset($ical->{'PERCENT-COMPLETE'})) {
$ev['event_percent'] = (string) $ical->{'PERCENT-COMPLETE'} ;
}
$ev['event_vdata'] = $ical->serialize();
return $ev;
}
function parse_ical_file($f,$uid) {
require_once('vendor/autoload.php');
@@ -610,22 +751,21 @@ function event_import_ical($ical, $uid) {
}
$dtstart = $ical->DTSTART->getDateTime();
$ev['adjust'] = (($ical->DTSTART->isFloating()) ? 1 : 0);
$ev['adjust'] = (($ical->DTSTART->isFloating()) ? 0 : 1);
// logger('dtstart: ' . var_export($dtstart,true));
$ev['dtstart'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC',
$dtstart->format(\DateTime::W3C));
if(isset($ical->DTEND)) {
$dtend = $ical->DTEND->getDateTime();
$ev['dtend'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC',
$dtend->format(\DateTime::W3C));
}
else
else {
$ev['nofinish'] = 1;
}
if($ev['dtstart'] === $ev['dtend'])
$ev['nofinish'] = 1;
@@ -635,6 +775,7 @@ function event_import_ical($ical, $uid) {
$ev['created'] = datetime_convert('UTC','UTC',$created->format(\DateTime::W3C));
}
if(isset($ical->{'LAST-MODIFIED'})) {
$edited = $ical->{'LAST-MODIFIED'}->getDateTime();
$ev['edited'] = datetime_convert('UTC','UTC',$edited->format(\DateTime::W3C));
@@ -713,7 +854,7 @@ function event_import_ical_task($ical, $uid) {
$dtstart = $ical->DTSTART->getDateTime();
$ev['adjust'] = (($ical->DTSTART->isFloating()) ? 1 : 0);
$ev['adjust'] = (($ical->DTSTART->isFloating()) ? 0 : 1);
// logger('dtstart: ' . var_export($dtstart,true));

File diff suppressed because it is too large Load Diff

View File

@@ -49,7 +49,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
$arr = array('url' => $url, 'channel' => array());
call_hooks('follow', $arr);
call_hooks('follow_init', $arr);
if($arr['channel']['success'])
$ret = $arr['channel'];

View File

@@ -1,5 +1,7 @@
<?php
use \Michelf\MarkdownExtra;
/**
* @brief
*
@@ -15,7 +17,7 @@ function get_help_content($tocpath = false) {
$text = '';
$path = (($tocpath !== false) ? $tocpath : '');
if($tocpath === false && argc() > 1) {
$path = '';
for($x = 1; $x < argc(); $x ++) {
@@ -55,7 +57,7 @@ function get_help_content($tocpath = false) {
if(! $text) {
$doctype = 'bbcode';
$text = load_doc_file('doc/main.bb');
goaway('/help/about/about_hubzilla');
goaway('/help/about/about_hubzilla');
\App::$page['title'] = t('Help');
}
@@ -69,12 +71,11 @@ function get_help_content($tocpath = false) {
}
if($doctype === 'html')
$content = parseIdentityAwareHTML($text);
if($doctype === 'markdown') {
require_once('library/markdown.php');
$content = parseIdentityAwareHTML($text);
if($doctype === 'markdown') {
# escape #include tags
$text = preg_replace('/#include/ism', '%%include', $text);
$content = Markdown($text);
$content = MarkdownExtra::defaultTransform($text);
$content = preg_replace('/%%include/ism', '#include', $content);
}
if($doctype === 'bbcode') {
@@ -99,8 +100,7 @@ function preg_callback_help_include($matches) {
$include = str_replace(' target="_blank"','',$include);
}
elseif(preg_match('/\.md$/', $matches[1])) {
require_once('library/markdown.php');
$include = Markdown($include);
$include = MarkdownExtra::defaultTransform($include);
}
return $include;
}

View File

@@ -1,6 +1,17 @@
<?php /** @file */
<?php
/**
* @file include/hubloc.php
* @brief Hubloc related functions.
*/
/**
* @brief Create an array for hubloc table and insert record.
*
* Creates an assoziative array which will be inserted into the hubloc table.
*
* @param array $arr An assoziative array with hubloc values
* @return boolean|PDOStatement
*/
function hubloc_store_lowlevel($arr) {
$store = [
@@ -25,10 +36,36 @@ function hubloc_store_lowlevel($arr) {
'hubloc_deleted' => ((array_key_exists('hubloc_deleted',$arr)) ? $arr['hubloc_deleted'] : 0)
];
return create_table_from_array('hubloc',$store);
return create_table_from_array('hubloc', $store);
}
function site_store_lowlevel($arr) {
$store = [
'site_url' => ((array_key_exists('site_url',$arr)) ? $arr['site_url'] : ''),
'site_access' => ((array_key_exists('site_access',$arr)) ? $arr['site_access'] : 0),
'site_flags' => ((array_key_exists('site_flags',$arr)) ? $arr['site_flags'] : 0),
'site_update' => ((array_key_exists('site_update',$arr)) ? $arr['site_update'] : NULL_DATE),
'site_pull' => ((array_key_exists('site_pull',$arr)) ? $arr['site_pull'] : NULL_DATE),
'site_sync' => ((array_key_exists('site_sync',$arr)) ? $arr['site_sync'] : NULL_DATE),
'site_directory' => ((array_key_exists('site_directory',$arr)) ? $arr['site_directory'] : ''),
'site_register' => ((array_key_exists('site_register',$arr)) ? $arr['site_register'] : 0),
'site_sellpage' => ((array_key_exists('site_sellpage',$arr)) ? $arr['site_sellpage'] : ''),
'site_location' => ((array_key_exists('site_location',$arr)) ? $arr['site_location'] : ''),
'site_realm' => ((array_key_exists('site_realm',$arr)) ? $arr['site_realm'] : ''),
'site_valid' => ((array_key_exists('site_valid',$arr)) ? $arr['site_valid'] : 0),
'site_dead' => ((array_key_exists('site_dead',$arr)) ? $arr['site_dead'] : 0),
'site_type' => ((array_key_exists('site_type',$arr)) ? $arr['site_type'] : 0),
'site_project' => ((array_key_exists('site_project',$arr)) ? $arr['site_project'] : ''),
'site_version' => ((array_key_exists('site_version',$arr)) ? $arr['site_version'] : ''),
'site_crypto' => ((array_key_exists('site_crypto',$arr)) ? $arr['site_crypto'] : '')
];
return create_table_from_array('site', $store);
}
function prune_hub_reinstalls() {
@@ -45,9 +82,8 @@ function prune_hub_reinstalls() {
// see if this url has more than one sitekey, indicating it has been re-installed.
if(count($x) > 1) {
$d1 = datetime_convert('UTC','UTC',$x[0]['c']);
$d2 = datetime_convert('UTC','UTC','now - 3 days');
$d1 = datetime_convert('UTC', 'UTC', $x[0]['c']);
$d2 = datetime_convert('UTC', 'UTC', 'now - 3 days');
// allow some slop period, say 3 days - just in case this is a glitch or transient occurrence
// Then remove any hublocs pointing to the oldest entry.
@@ -63,18 +99,22 @@ function prune_hub_reinstalls() {
}
}
/**
* @brief Remove obsolete hublocs.
*
* Get rid of any hublocs which are ours but aren't valid anymore -
* e.g. they point to a different and perhaps transient URL that we aren't using.
*
* I need to stress that this shouldn't happen. fix_system_urls() fixes hublocs
* when it discovers the URL has changed. So it's unclear how we could end up
* with URLs pointing to the old site name. But it happens. This may be an artifact
* of an old bug or maybe a regression in some newer code. In any event, they
* mess up communications and we have to take action if we find any.
*/
function remove_obsolete_hublocs() {
logger('remove_obsolete_hublocs',LOGGER_DEBUG);
// Get rid of any hublocs which are ours but aren't valid anymore -
// e.g. they point to a different and perhaps transient URL that we aren't using.
// I need to stress that this shouldn't happen. fix_system_urls() fixes hublocs
// when it discovers the URL has changed. So it's unclear how we could end up
// with URLs pointing to the old site name. But it happens. This may be an artifact
// of an old bug or maybe a regression in some newer code. In any event, they
// mess up communications and we have to take action if we find any.
logger('remove_obsolete_hublocs', LOGGER_DEBUG);
// First make sure we have any hublocs (at all) with this URL and sitekey.
// We don't want to perform this operation while somebody is in the process
@@ -82,27 +122,25 @@ function remove_obsolete_hublocs() {
$r = q("select hubloc_id from hubloc where hubloc_url = '%s' and hubloc_sitekey = '%s'",
dbesc(z_root()),
dbesc(get_config('system','pubkey'))
dbesc(get_config('system', 'pubkey'))
);
if((! $r) || (! count($r)))
return;
$channels = array();
// Good. We have at least one *valid* hubloc.
// Do we have any invalid ones?
$r = q("select hubloc_id from hubloc where hubloc_sitekey = '%s' and hubloc_url != '%s'",
dbesc(get_config('system','pubkey')),
dbesc(get_config('system', 'pubkey')),
dbesc(z_root())
);
$p = q("select hubloc_id from hubloc where hubloc_sitekey != '%s' and hubloc_url = '%s'",
dbesc(get_config('system','pubkey')),
dbesc(get_config('system', 'pubkey')),
dbesc(z_root())
);
if(is_array($r) && is_array($p))
$r = array_merge($r,$p);
$r = array_merge($r, $p);
if(! $r)
return;
@@ -111,8 +149,8 @@ function remove_obsolete_hublocs() {
logger('remove_obsolete_hublocs: removing ' . count($r) . ' hublocs.');
$interval = ((get_config('system','delivery_interval') !== false)
? intval(get_config('system','delivery_interval')) : 2 );
$interval = ((get_config('system', 'delivery_interval') !== false)
? intval(get_config('system', 'delivery_interval')) : 2 );
foreach($r as $rr) {
q("update hubloc set hubloc_deleted = 1 where hubloc_id = %d",
@@ -120,10 +158,10 @@ function remove_obsolete_hublocs() {
);
$x = q("select channel_id from channel where channel_hash = '%s' limit 1",
dbesc($rr['hubloc_hash'])
dbesc($rr['hubloc_hash'])
);
if($x) {
Zotlabs\Daemon\Master::Summon(array('Notifier','location',$x[0]['channel_id']));
Zotlabs\Daemon\Master::Summon(array('Notifier', 'location', $x[0]['channel_id']));
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}
@@ -131,8 +169,15 @@ function remove_obsolete_hublocs() {
}
// This actually changes other structures to match the given (presumably current) hubloc primary selection
/**
* @brief Change primary hubloc.
*
* This actually changes other structures to match the given (presumably current)
* hubloc primary selection.
*
* @param array $hubloc
* @return boolean
*/
function hubloc_change_primary($hubloc) {
if(! is_array($hubloc)) {
@@ -170,7 +215,7 @@ function hubloc_change_primary($hubloc) {
dbesc($hubloc['hubloc_hash'])
);
if(! $r) {
logger('xchan not found');
logger('xchan not found');
return false;
}
if($r[0]['xchan_addr'] === $hubloc['hubloc_addr']) {
@@ -179,7 +224,7 @@ function hubloc_change_primary($hubloc) {
}
$url = $hubloc['hubloc_url'];
$lwebbie = substr($hubloc['hubloc_addr'],0,strpos($hubloc['hubloc_addr'],'@'));
$lwebbie = substr($hubloc['hubloc_addr'], 0, strpos($hubloc['hubloc_addr'], '@'));
$r = q("update xchan set xchan_addr = '%s', xchan_url = '%s', xchan_follow = '%s', xchan_connurl = '%s' where xchan_hash = '%s'",
dbesc($hubloc['hubloc_addr']),
@@ -191,14 +236,19 @@ function hubloc_change_primary($hubloc) {
if(! $r)
logger('xchan_update failed.');
logger('primary hubloc changed.' . print_r($hubloc,true),LOGGER_DEBUG);
logger('primary hubloc changed.' . print_r($hubloc, true), LOGGER_DEBUG);
return true;
}
// We use the post url to distinguish between http and https hublocs.
// The https might be alive, and the http dead.
/**
* @brief Mark a hubloc as down.
*
* We use the post url to distinguish between http and https hublocs.
* The https might be alive, and the http dead.
*
* @param string $posturl Hubloc callback url which to disable
*/
function hubloc_mark_as_down($posturl) {
$r = q("update hubloc set hubloc_status = ( hubloc_status | %d ) where hubloc_callback = '%s'",
intval(HUBLOC_OFFLINE),
@@ -208,22 +258,21 @@ function hubloc_mark_as_down($posturl) {
function ping_site($url) {
$ret = array('success' => false);
$sys = get_sys_channel();
$m = zot_build_packet($sys,'ping');
$r = zot_zot($url . '/post',$m);
$m = zot_build_packet($sys, 'ping');
$r = zot_zot($url . '/post', $m);
if(! $r['success']) {
$ret['message'] = 'no answer from ' . $url;
return $ret;
}
$packet_result = json_decode($r['body'],true);
$packet_result = json_decode($r['body'], true);
if(! $packet_result['success']) {
$ret['message'] = 'packet failure from ' . $url;
$ret['message'] = 'packet failure from ' . $url;
return $ret;
}

File diff suppressed because it is too large Load Diff

View File

@@ -298,11 +298,13 @@ function add_source_route($iid, $hash) {
* or other processing is performed.
*
* @param array $arr
* @param boolean $allow_code (optional) default false
* @param boolean $deliver (optional) default true
* @returns array
* * \e boolean \b success true or false
* * \e array \b activity the resulting activity if successful
*/
function post_activity_item($arr,$allow_code = false,$deliver = true) {
function post_activity_item($arr, $allow_code = false, $deliver = true) {
$ret = array('success' => false);
@@ -336,18 +338,6 @@ function post_activity_item($arr,$allow_code = false,$deliver = true) {
if(! array_key_exists('mimetype',$arr))
$arr['mimetype'] = 'text/bbcode';
if(array_key_exists('item_private',$arr) && $arr['item_private']) {
$arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype']));
if($channel) {
if($channel['channel_hash'] === $arr['author_xchan']) {
$arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
$arr['item_verified'] = 1;
}
}
}
$arr['mid'] = ((x($arr,'mid')) ? $arr['mid'] : item_message_id());
$arr['parent_mid'] = ((x($arr,'parent_mid')) ? $arr['parent_mid'] : $arr['mid']);
$arr['thr_parent'] = ((x($arr,'thr_parent')) ? $arr['thr_parent'] : $arr['mid']);
@@ -360,7 +350,7 @@ function post_activity_item($arr,$allow_code = false,$deliver = true) {
if(($is_comment) && ($arr['obj_type'] === ACTIVITY_OBJ_NOTE))
$arr['obj_type'] = ACTIVITY_OBJ_COMMENT;
if(! ( array_key_exists('allow_cid',$arr) || array_key_exists('allow_gid',$arr)
if(! ( array_key_exists('allow_cid',$arr) || array_key_exists('allow_gid',$arr)
|| array_key_exists('deny_cid',$arr) || array_key_exists('deny_gid',$arr))) {
$arr['allow_cid'] = $channel['channel_allow_cid'];
$arr['allow_gid'] = $channel['channel_allow_gid'];
@@ -542,12 +532,7 @@ function get_item_elements($x,$allow_code = false) {
$arr = array();
if($allow_code)
$arr['body'] = $x['body'];
else
$arr['body'] = (($x['body']) ? htmlspecialchars($x['body'],ENT_COMPAT,'UTF-8',false) : '');
$key = get_config('system','pubkey');
$arr['body'] = $x['body'];
$maxlen = get_max_import_size();
@@ -629,6 +614,9 @@ function get_item_elements($x,$allow_code = false) {
if(in_array('notshown',$x['flags']))
$arr['item_notshown'] = 1;
if(in_array('obscured',$x['flags']))
$arr['item_obscured'] = 1;
// hidden item are no longer propagated - notshown may be a suitable alternative
if(in_array('hidden',$x['flags']))
@@ -649,26 +637,62 @@ function get_item_elements($x,$allow_code = false) {
return array();
// save a potentially expensive lookup if author == owner
if($arr['author_xchan'] === make_xchan_hash($x['owner']['guid'],$x['owner']['guid_sig']))
$arr['owner_xchan'] = $arr['author_xchan'];
else {
$xchan_hash = import_author_xchan($x['owner']);
if($xchan_hash)
if($xchan_hash) {
$arr['owner_xchan'] = $xchan_hash;
else
}
else {
return array();
}
}
// Check signature on the body text received.
// This presents an issue that we aren't verifying the text that is actually displayed
// on this site. We are however verifying the received text was exactly as received.
// We have every right to strip content that poses a security risk. You are welcome to
// create a plugin to verify the content after filtering if this offends you.
if($arr['sig']) {
// check the supplied signature against the supplied content.
// Note that we will purify the content which could change it.
$r = q("select xchan_pubkey from xchan where xchan_hash = '%s' limit 1",
dbesc($arr['author_xchan'])
);
if($r && rsa_verify($x['body'],base64url_decode($arr['sig']),$r[0]['xchan_pubkey']))
$arr['item_verified'] = 1;
else
logger('get_item_elements: message verification failed.');
if($r) {
if($r[0]['xchan_pubkey']) {
if(rsa_verify($x['body'],base64url_decode($arr['sig']),$r[0]['xchan_pubkey'])) {
$arr['item_verified'] = 1;
}
else {
logger('get_item_elements: message verification failed.');
}
}
else {
// If we don't have a public key, strip the signature so it won't show as invalid.
// This won't happen in normal use, but could happen if import_author_xchan()
// failed to load the zot-info packet due to a server failure and had
// to create an alternate xchan with network 'unknown'
unset($arr['sig']);
}
}
}
// if the input is markdown, remove one level of html escaping.
// It will be re-applied in item_store() and/or item_store_update().
// Do this after signature checking as the original signature
// was generated on the escaped content.
if($arr['mimetype'] === 'text/markdown')
$arr['body'] = \Zotlabs\Lib\MarkdownSoap::unescape($arr['body']);
if(array_key_exists('revision',$x)) {
// extended export encoding
@@ -695,7 +719,7 @@ function get_item_elements($x,$allow_code = false) {
// local only $arr['item_relay'] = $x['item_relay'];
$arr['item_mentionsme'] = $x['item_mentionsme'];
$arr['item_nocomment'] = $x['item_nocomment'];
// local only $arr['item_obscured'] = $x['item_obscured'];
$arr['item_obscured'] = $x['item_obscured'];
// local only $arr['item_verified'] = $x['item_verified'];
$arr['item_retained'] = $x['item_retained'];
$arr['item_rss'] = $x['item_rss'];
@@ -768,6 +792,8 @@ function import_author_xchan($x) {
if($arr['xchan_hash'])
return $arr['xchan_hash'];
$y = false;
if((! array_key_exists('network', $x)) || ($x['network'] === 'zot')) {
$y = import_author_zot($x);
}
@@ -778,11 +804,11 @@ function import_author_xchan($x) {
$y = import_author_rss($x);
}
if($x['network'] === 'unknown') {
if(! $y) {
$y = import_author_unknown($x);
}
return(($y) ? $y : false);
return($y);
}
/**
@@ -940,13 +966,6 @@ function encode_item($item,$mirror = false) {
$key = get_config('system','prvkey');
if(array_key_exists('item_obscured',$item) && intval($item['item_obscured'])) {
if($item['title'])
$item['title'] = crypto_unencapsulate(json_decode($item['title'],true),$key);
if($item['body'])
$item['body'] = crypto_unencapsulate(json_decode($item['body'],true),$key);
}
// If we're trying to backup an item so that it's recoverable or for export/imprt,
// add all the attributes we need to recover it
@@ -1120,7 +1139,7 @@ function encode_item_xchan($xchan) {
$ret['address'] = $xchan['xchan_addr'];
$ret['url'] = $xchan['xchan_url'];
$ret['network'] = $xchan['xchan_network'];
$ret['photo'] = array('mimetype' => $xchan['xchan_photo_mimetype'], 'src' => $xchan['xchan_photo_m']);
$ret['photo'] = [ 'mimetype' => $xchan['xchan_photo_mimetype'], 'src' => $xchan['xchan_photo_m'] ];
$ret['guid'] = $xchan['xchan_guid'];
$ret['guid_sig'] = $xchan['xchan_guid_sig'];
@@ -1304,6 +1323,8 @@ function encode_item_flags($item) {
$ret[] = 'nsfw';
if(intval($item['item_consensus']))
$ret[] = 'consensus';
if(intval($item['item_obscured']))
$ret[] = 'obscured';
if(intval($item['item_private']))
$ret[] = 'private';
@@ -1456,6 +1477,26 @@ function get_profile_elements($x) {
}
function item_sign(&$item) {
if(array_key_exists('sig',$item) && $item['sig'])
return;
$r = q("select channel_prvkey from channel where channel_id = %d and channel_hash = '%s' ",
intval($item['uid']),
dbesc($item['author_xchan'])
);
if(! $r)
return;
$item['sig'] = base64url_encode(rsa_sign($item['body'],$r[0]['channel_prvkey']));
$item['item_verified'] = 1;
}
/**
* @brief
*
@@ -1479,7 +1520,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
if(array_key_exists('cancel',$arr) && $arr['cancel']) {
logger('cancelled by plugin');
return $ret;
}
}
if(! $arr['uid']) {
logger('item_store: no uid');
@@ -1533,35 +1574,30 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
// obsolete, but needed so as not to throw not-null constraints on some database driveres
$arr['item_flags'] = ((x($arr,'item_flags')) ? intval($arr['item_flags']) : 0 );
// only detect language if we have text content, and if the post is private but not yet
// obscured, make it so.
if((! array_key_exists('item_obscured',$arr)) || $arr['item_obscured'] == 0) {
$arr['lang'] = detect_language($arr['body']);
// apply the input filter here - if it is obscured it has been filtered already
$arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype']));
$arr['lang'] = detect_language($arr['body']);
if(local_channel() && (local_channel() == $arr['uid']) && (! $arr['sig'])) {
$channel = App::get_channel();
if($channel['channel_hash'] === $arr['author_xchan']) {
$arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
$arr['item_verified'] = 1;
}
}
$allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages');
if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) {
$translate = array('item' => $arr, 'from' => $arr['lang'], 'to' => $allowed_languages, 'translated' => false);
call_hooks('item_translate', $translate);
if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) {
logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']);
$ret['message'] = 'language not accepted';
return $ret;
}
$arr = $translate['item'];
// apply the input filter here
$arr['body'] = trim(z_input_filter($arr['body'],$arr['mimetype'],$allow_exec));
item_sign($arr);
if(! array_key_exists('sig',$arr))
$arr['sig'] = '';
$allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages');
if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) {
$translate = array('item' => $arr, 'from' => $arr['lang'], 'to' => $allowed_languages, 'translated' => false);
call_hooks('item_translate', $translate);
if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) {
logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']);
$ret['message'] = 'language not accepted';
return $ret;
}
$arr = $translate['item'];
}
if((x($arr,'obj')) && is_array($arr['obj'])) {
@@ -1808,9 +1844,12 @@ logger('revision: ' . $arr['revision']);
intval($arr['revision'])
);
if($r && count($r)) {
if($r) {
// This will gives us a fresh copy of what's now in the DB and undo the db escaping,
// which really messes up the notifications
$current_post = $r[0]['id'];
$arr = $r[0]; // This will gives us a fresh copy of what's now in the DB and undo the db escaping, which really messes up the notifications
$arr = $r[0];
logger('item_store: created item ' . $current_post, LOGGER_DEBUG);
}
else {
@@ -1869,7 +1908,7 @@ logger('revision: ' . $arr['revision']);
// 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.
// suspected of being an older cloned item if the creation time is older than that.
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 ",
@@ -1915,7 +1954,7 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
if(array_key_exists('cancel',$arr) && $arr['cancel']) {
logger('cancelled by plugin');
return $ret;
}
}
if(! intval($arr['uid'])) {
logger('item_store_update: no uid');
@@ -1957,33 +1996,25 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
return $ret;
}
if((! array_key_exists('item_obscured', $arr)) || $arr['item_obscured'] == 0) {
$arr['lang'] = detect_language($arr['body']);
$arr['lang'] = detect_language($arr['body']);
// apply the input filter here
// apply the input filter here - if it is obscured it has been filtered already
$arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype']));
$arr['body'] = trim(z_input_filter($arr['body'],$arr['mimetype'],$allow_exec));
if(local_channel() && (local_channel() == $arr['uid']) && (! $arr['sig'])) {
$channel = App::get_channel();
if($channel['channel_hash'] === $arr['author_xchan']) {
$arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
$arr['item_verified'] = 1;
}
}
item_sign($arr);
$allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages');
$allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages');
if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) {
$translate = array('item' => $arr, 'from' => $arr['lang'], 'to' => $allowed_languages, 'translated' => false);
call_hooks('item_translate', $translate);
if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) {
logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']);
$ret['message'] = 'language not accepted';
return $ret;
}
$arr = $translate['item'];
if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) {
$translate = array('item' => $arr, 'from' => $arr['lang'], 'to' => $allowed_languages, 'translated' => false);
call_hooks('item_translate', $translate);
if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) {
logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']);
$ret['message'] = 'language not accepted';
return $ret;
}
$arr = $translate['item'];
}
if((x($arr,'obj')) && is_array($arr['obj'])) {
@@ -2515,15 +2546,7 @@ function tag_deliver($uid, $item_id) {
// Now let's check if this mention was inside a reshare so we don't spam a forum
// If it's private we may have to unobscure it momentarily so that we can parse it.
$body = '';
if(intval($item['item_obscured'])) {
$key = get_config('system','prvkey');
if($item['body'])
$body = crypto_unencapsulate(json_decode($item['body'],true),$key);
}
else
$body = $item['body'];
$body = $item['body'];
$body = preg_replace('/\[share(.*?)\[\/share\]/','',$body);
@@ -2674,11 +2697,6 @@ function tgroup_check($uid,$item) {
$body = $item['body'];
if(array_key_exists('item_obscured',$item) && intval($item['item_obscured']) && $body) {
$key = get_config('system','prvkey');
$body = crypto_unencapsulate(json_decode($body,true),$key);
}
$body = preg_replace('/\[share(.*?)\[\/share\]/','',$body);
// $pattern = '/@\!?\[zrl\=' . preg_quote($term['url'],'/') . '\]' . preg_quote($term['term'] . '+','/') . '\[\/zrl\]/';
@@ -2772,7 +2790,6 @@ function start_delivery_chain($channel, $item, $item_id, $parent) {
$item_origin = 1;
$item_uplink = 0;
$item_nocomment = 0;
$item_obscured = 0;
$flag_bits = $item['item_flags'];
@@ -2795,11 +2812,10 @@ 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_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),
intval($item_obscured),
intval($flag_bits),
dbesc($channel['channel_hash']),
dbesc($channel['channel_allow_cid']),
@@ -2989,8 +3005,14 @@ function mail_store($arr) {
$arr['body'] = escape_tags($arr['body']);
}
if(array_key_exists('attach',$arr) && is_array($arr['attach']))
$arr['attach'] = json_encode($arr['attach']);
if(array_key_exists('attach',$arr)) {
if(is_array($arr['attach'])) {
$arr['attach'] = json_encode($arr['attach']);
}
}
else {
$arr['attach'] = '';
}
$arr['account_id'] = ((x($arr,'account_id')) ? intval($arr['account_id']) : 0);
$arr['mid'] = ((x($arr,'mid')) ? notags(trim($arr['mid'])) : random_string());
@@ -3001,6 +3023,7 @@ function mail_store($arr) {
$arr['title'] = ((x($arr,'title')) ? trim($arr['title']) : '');
$arr['parent_mid'] = ((x($arr,'parent_mid')) ? notags(trim($arr['parent_mid'])) : '');
$arr['body'] = ((x($arr,'body')) ? trim($arr['body']) : '');
$arr['sig'] = ((x($arr,'sig')) ? trim($arr['sig']) : '');
$arr['conv_guid'] = ((x($arr,'conv_guid')) ? trim($arr['conv_guid']) : '');
$arr['mail_flags'] = ((x($arr,'mail_flags')) ? intval($arr['mail_flags']) : 0 );
@@ -3773,7 +3796,7 @@ function zot_feed($uid,$observer_hash,$arr) {
if(! is_sys_channel($uid))
$sql_extra = item_permissions_sql($uid,$observer_hash);
$limit = " LIMIT 100 ";
$limit = " LIMIT 5000 ";
if($mindate > NULL_DATE) {
$sql_extra .= " and ( created > '$mindate' or changed > '$mindate' ) ";
@@ -3785,15 +3808,7 @@ function zot_feed($uid,$observer_hash,$arr) {
}
$items = array();
/** @FIXME re-unite these SQL statements. There is no need for them to be separate. The mySQL is convoluted with misuse of group by. As it stands, there is a slight difference where the postgres version doesn't remove the duplicate parents up to 100. In practice this doesn't matter. It could be made to match behavior by adding "distinct on (parent) " to the front of the selection list, at a not-worth-it performance penalty (page temp results to disk). duplicates are still ignored in the in() clause, you just get less than 100 parents if there are many children. */
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
$groupby = '';
} else {
$groupby = 'GROUP BY parent';
}
$items = [];
$item_normal = item_normal();
@@ -3802,7 +3817,7 @@ function zot_feed($uid,$observer_hash,$arr) {
WHERE uid != %d
$item_normal
AND item_wall = 1
and item_private = 0 $sql_extra $groupby ORDER BY created ASC $limit",
and item_private = 0 $sql_extra ORDER BY created ASC $limit",
intval($uid)
);
}
@@ -3810,19 +3825,25 @@ function zot_feed($uid,$observer_hash,$arr) {
$r = q("SELECT parent, created, postopts from item
WHERE uid = %d $item_normal
AND item_wall = 1
$sql_extra $groupby ORDER BY created ASC $limit",
$sql_extra ORDER BY created ASC $limit",
intval($uid)
);
}
$parents = [];
if($r) {
for($x = 0; $x < count($r); $x ++) {
if(strpos($r[$x]['postopts'],'nodeliver') !== false) {
unset($r[$x]);
}
foreach($r as $rv) {
if(array_key_exists($rv['parent'],$parents))
continue;
if(strpos($rv['postopts'],'nodeliver') !== false)
continue;
$parents[$rv['parent']] = $rv;
if(count($parents) > 200)
break;
}
$parents_str = ids_to_querystr($r,'parent');
$parents_str = ids_to_querystr($parents,'parent');
$sys_query = ((is_sys_channel($uid)) ? $sql_extra : '');
$item_normal = item_normal();
@@ -3940,6 +3961,10 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
}
}
if(intval($arr['compat']) === 1) {
$sql_extra = " AND author_xchan = owner_xchan and item_wall = 1 and item_private = 0 ";
}
if ($arr['datequery']) {
$sql_extra3 .= protect_sprintf(sprintf(" AND item.created <= '%s' ", dbesc(datetime_convert('UTC','UTC',$arr['datequery']))));
}
@@ -4479,12 +4504,12 @@ function item_create_edit_activity($post) {
$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;
@@ -4510,10 +4535,10 @@ function item_create_edit_activity($post) {
array('rel' => 'photo', 'type' => $item_author['xchan_photo_mimetype'], 'href' => $item_author['xchan_photo_m'])),
),
));
$x = post_activity_item($new_item);
$x = post_activity_item($new_item);
$post_id = $x['id'];
if($post_id) {
@@ -4528,5 +4553,5 @@ function item_create_edit_activity($post) {
}
\Zotlabs\Daemon\Master::Summon(array('Notifier', 'edit_activity', $post_id));
}

View File

@@ -4,12 +4,13 @@
* @brief Some functions for BB conversions for Diaspora protocol.
*/
use Michelf\MarkdownExtra;
use Markdownify\Converter;
require_once("include/oembed.php");
require_once("include/event.php");
require_once("library/markdown.php");
require_once("include/html2bbcode.php");
require_once("include/bbcode.php");
require_once("library/markdownify/markdownify.php");
function get_bb_tag_pos($s, $name, $occurance = 1) {
@@ -73,7 +74,7 @@ function bb_tag_preg_replace($pattern, $replace, $name, $s) {
function share_shield($m) {
return str_replace($m[1],'!=+=+=!' . base64url_encode($m[1]) . '=+!=+!=',$m[0]);
}
}
function share_unshield($m) {
$x = str_replace(array('!=+=+=!','=+!=+!='),array('',''),$m[1]);
@@ -184,7 +185,7 @@ function markdown_to_bb($s, $use_zrl = false) {
// This seems to work
$s = preg_replace('/\#([^\s\#])/','&#35;$1',$s);
$s = Markdown($s);
$s = MarkdownExtra::defaultTransform($s);
$s = str_replace("\r","",$s);
@@ -198,10 +199,10 @@ function markdown_to_bb($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);
}
// remove duplicate adjacent code tags
@@ -299,7 +300,7 @@ function bb2dmention_callback($match) {
$r = q("select xchan_addr from xchan where xchan_url = '%s'",
dbesc($match[2])
);
);
if($r)
return '@{' . $match[3] . ' ; ' . $r[0]['xchan_addr'] . '}';
@@ -333,7 +334,7 @@ function bb2diaspora_itemwallwall(&$item,$uplink = false) {
$has_meta = true;
if($item['author_xchan'] != $item['owner_xchan']) {
if($item['mid'] == $item['parent_mid'])
if($item['mid'] == $item['parent_mid'])
$wallwall = true;
else {
if(! $has_meta) {
@@ -348,12 +349,12 @@ function bb2diaspora_itemwallwall(&$item,$uplink = false) {
if(($wallwall) && (is_array($item['author'])) && $item['author']['xchan_url'] && $item['author']['xchan_name'] && $item['author']['xchan_photo_s']) {
logger('bb2diaspora_itemwallwall: wall to wall post',LOGGER_DEBUG);
// post will come across with the owner's identity. Throw a preamble onto the post to indicate the true author.
$item['body'] = "\n\n"
. '[quote]'
. '[img]' . $item['author']['xchan_photo_s'] . '[/img]'
. ' '
. '[url=' . $item['author']['xchan_url'] . '][b]' . $item['author']['xchan_name'] . '[/b][/url]' . "\n\n"
. $item['body']
$item['body'] = "\n\n"
. '[quote]'
. '[img]' . $item['author']['xchan_photo_s'] . '[/img]'
. ' '
. '[url=' . $item['author']['xchan_url'] . '][b]' . $item['author']['xchan_name'] . '[/b][/url]' . "\n\n"
. $item['body']
. '[/quote]';
}
@@ -366,7 +367,6 @@ function bb2diaspora_itemwallwall(&$item,$uplink = false) {
function bb2diaspora_itembody($item, $force_update = false, $have_channel = false, $uplink = false) {
if(! get_iconfig($item,'diaspora','fields')) {
$force_update = true;
}
@@ -453,7 +453,7 @@ function bb2diaspora_itembody($item, $force_update = false, $have_channel = fals
return html_entity_decode($body);
}
function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
function bb2diaspora($Text, $preserve_nl = false, $fordiaspora = true) {
// Re-enabling the converter again.
// The bbcode parser now handles youtube-links (and the other stuff) correctly.
@@ -490,17 +490,16 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
// Convert it to HTML - don't try oembed
$Text = bbcode($Text, $preserve_nl, false);
// Markdownify does not preserve previously escaped html entities such as <> and &.
// Markdownify does not preserve previously escaped html entities such as <> and &.
$Text = str_replace(array('&lt;','&gt;','&amp;'),array('&_lt_;','&_gt_;','&_amp_;'),$Text);
// Now convert HTML to Markdown
$md = new Markdownify(false, false, false);
$md = new Converter(Converter::LINK_AFTER_CONTENT, false, false);
$Text = $md->parseString($Text);
// It also adds backslashes to our attempt at getting around the html entity preservation for some weird reason.
// 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);
@@ -510,7 +509,7 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
// So take off the angle brackets of any such URL
$Text = preg_replace("/<http(.*?)>/is", "http$1", $Text);
// Remove empty zrl links
// Remove empty zrl links
$Text = preg_replace("/\[zrl\=\].*?\[\/zrl\]/is", "", $Text);
// Remove all unconverted tags
@@ -521,7 +520,7 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
$Text = trim($Text);
call_hooks('bb2diaspora',$Text);
call_hooks('bb2diaspora', $Text);
return $Text;
}
@@ -543,22 +542,22 @@ function format_event_diaspora($ev) {
$o .= '**' . (($ev['summary']) ? bb2diaspora($ev['summary']) : bb2diaspora($ev['desc'])) . '**' . "\n";
$o .= t('Starts:') . ' ' . '['
. (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC',
. (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC',
$ev['start'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
: day_translate(datetime_convert('UTC', 'UTC',
$ev['start'] , $bd_format)))
. '](' . z_root() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['start'])) . ")\n";
if(! $ev['nofinish'])
$o .= t('Finishes:') . ' ' . '['
. (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC',
$o .= t('Finishes:') . ' ' . '['
. (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC',
$ev['finish'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
: day_translate(datetime_convert('UTC', 'UTC',
$ev['finish'] , $bd_format )))
. '](' . z_root() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['finish'])) . ")\n";
if(strlen($ev['location']))
$o .= t('Location:') . bb2diaspora($ev['location'])
$o .= t('Location:') . bb2diaspora($ev['location'])
. "\n";
$o .= "\n";

View File

@@ -13,10 +13,8 @@ function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $rep
$ret = array('success' => false);
$is_reply = false;
$a = get_app();
$observer_hash = get_observer_hash();
if($uid) {
$r = q("select * from channel where channel_id = %d limit 1",
intval($uid)
@@ -37,13 +35,15 @@ function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $rep
$body = cleanup_bbcode($body);
$results = linkify_tags($a, $body, $uid);
if(preg_match_all("/\[attachment\](.*?)\[\/attachment\]/",((strpos($body,'[/crypt]')) ? $_POST['media_str'] : $body),$match))
$attaches = $match[1];
if(! $raw) {
if(preg_match_all("/\[attachment\](.*?)\[\/attachment\]/",((strpos($body,'[/crypt]')) ? $_POST['media_str'] : $body),$match)) {
$attaches = $match[1];
}
}
$attachments = '';
if(preg_match_all('/(\[attachment\](.*?)\[\/attachment\])/',$body,$match)) {
if((! $raw) && preg_match_all('/(\[attachment\](.*?)\[\/attachment\])/',$body,$match)) {
$attachments = array();
foreach($match[2] as $mtch) {
$hash = substr($mtch,0,strpos($mtch,','));
@@ -186,19 +186,21 @@ function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $rep
if($subject)
$subject = str_rot47(base64url_encode($subject));
if($body)
if(($body )&& (! $raw))
$body = str_rot47(base64url_encode($body));
$sig = ''; // placeholder
$mimetype = ''; //placeholder
$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 )",
$r = q("INSERT INTO mail ( account_id, conv_guid, mail_obscured, channel_id, from_xchan, to_xchan, mail_mimetype, 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', '%s', %d )",
intval($channel['channel_account_id']),
dbesc($conv_guid),
intval(1),
intval($channel['channel_id']),
dbesc($channel['channel_hash']),
dbesc($recipient),
dbesc(($mimetype)? $mimetype : 'text/bbcode'),
dbesc($subject),
dbesc($body),
dbesc($sig),
@@ -514,6 +516,9 @@ function private_messages_fetch_conversation($channel_id, $messageitem_id, $upda
if($messages[$k]['body'])
$messages[$k]['body'] = base64url_decode(str_rot47($messages[$k]['body']));
}
if($messages[$k]['mail_raw'])
$messages[$k]['body'] = mail_prepare_binary([ 'id' => $messages[$k]['id'] ]);
}

View File

@@ -2,6 +2,10 @@
use \Zotlabs\Lib as Zlib;
require_once('include/security.php');
require_once('include/menu.php');
function nav() {
/**
@@ -36,14 +40,15 @@ EOT;
}
elseif(remote_channel())
$observer = App::get_observer();
require_once('include/conversation.php');
$is_owner = (((local_channel()) && (App::$profile['profile_uid'] == local_channel())) ? true : false);
$channel_apps[] = channel_apps($is_owner, App::$profile['channel_address']);
$myident = (($channel) ? $channel['xchan_addr'] : '');
$sitelocation = (($myident) ? $myident : App::get_hostname());
/**
*
* Provide a banner/logo/whatever
@@ -55,10 +60,9 @@ EOT;
if($banner === false)
$banner = get_config('system','sitename');
//the notifications template is in hdr.tpl
App::$page['header'] .= replace_macros(get_markup_template('hdr.tpl'), array(
'$baseurl' => z_root(),
'$sitelocation' => $sitelocation,
'$banner' => $banner
//we could additionally use this to display important system notifications e.g. for updates
));
$server_role = get_config('system','server_role');
@@ -66,21 +70,21 @@ EOT;
$techlevel = get_account_techlevel();
// nav links: array of array('href', 'text', 'extra css classes', 'title')
$nav = Array();
$nav = [];
/**
* Display login or logout
*/
$nav['usermenu']=array();
$nav['usermenu'] = [];
$userinfo = null;
$nav['loginmenu']=array();
$nav['loginmenu'] = [];
if($observer) {
$userinfo = array(
$userinfo = [
'icon' => $observer['xchan_photo_m'],
'name' => $observer['xchan_addr'],
);
];
}
elseif(! $_SESSION['authenticated']) {
@@ -96,38 +100,21 @@ EOT;
if($chans && count($chans) > 1 && feature_enabled(local_channel(),'nav_channel_select') && (! $basic))
$nav['channels'] = $chans;
$nav['logout'] = Array('logout',t('Logout'), "", t('End this session'),'logout_nav_btn');
$nav['logout'] = ['logout',t('Logout'), "", t('End this session'),'logout_nav_btn'];
// user menu
//$nav['usermenu'][] = Array('channel/' . $channel['channel_address'], t('Home'), "", t('Your posts and conversations'),'channel_nav_btn');
$nav['usermenu'][] = Array('profile/' . $channel['channel_address'], t('View Profile'), "", t('Your profile page'),'profile_nav_btn');
$nav['usermenu'][] = ['profile/' . $channel['channel_address'], t('View Profile'), "", t('Your profile page'),'profile_nav_btn'];
if(feature_enabled(local_channel(),'multi_profiles') && (! $basic))
$nav['usermenu'][] = Array('profiles', t('Edit Profiles'),"", t('Manage/Edit profiles'),'profiles_nav_btn');
$nav['usermenu'][] = ['profiles', t('Edit Profiles'),"", t('Manage/Edit profiles'),'profiles_nav_btn'];
else
$nav['usermenu'][] = Array('profiles/' . $prof[0]['id'], t('Edit Profile'),"", t('Edit your profile'),'profiles_nav_btn');
$nav['usermenu'][] = ['profiles/' . $prof[0]['id'], t('Edit Profile'),"", t('Edit your profile'),'profiles_nav_btn'];
//$nav['usermenu'][] = Array('photos/' . $channel['channel_address'], t('Photos'), "", t('Your photos'),'photos_nav_btn');
//$nav['usermenu'][] = Array('cloud/' . $channel['channel_address'],t('Files'),"",t('Your files'),'cloud_nav_btn');
//if((! $basic) && feature_enabled(local_channel(),'ajaxchat'))
// $nav['usermenu'][] = Array('chat/' . $channel['channel_address'], t('Chat'),"",t('Your chatrooms'),'chat_nav_btn');
//require_once('include/menu.php');
//$has_bookmarks = menu_list_count(local_channel(),'',MENU_BOOKMARK) + menu_list_count(local_channel(),'',MENU_SYSTEM|MENU_BOOKMARK);
//if(($has_bookmarks) && (! $basic)) {
// $nav['usermenu'][] = Array('bookmarks', t('Bookmarks'), "", t('Your bookmarks'),'bookmarks_nav_btn');
//}
//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('Wikis'),"",t('Your wikis'),'wiki_nav_btn');
}
else {
if(! get_account_id()) {
$nav['login'] = login(true,'main-login',false,false);
$nav['loginmenu'][] = Array('login',t('Login'),'',t('Sign in'),'login_nav_btn');
$nav['loginmenu'][] = ['login',t('Login'),'',t('Sign in'),'login_nav_btn'];
App::$page['content'] .= replace_macros(get_markup_template('nav_login.tpl'),
[
'$nav' => $nav,
@@ -137,7 +124,7 @@ EOT;
}
else
$nav['alogout'] = Array('logout',t('Logout'), "", t('End this session'),'logout_nav_btn');
$nav['alogout'] = ['logout',t('Logout'), "", t('End this session'),'logout_nav_btn'];
}
@@ -152,14 +139,14 @@ EOT;
if(! local_channel()) {
$nav['rusermenu'] = array(
$homelink,
t('Get me home'),
t('Take 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');
$nav['register'] = ['register',t('Register'), "", t('Create an account'),'register_nav_btn'];
if(! get_config('system','hide_help')) {
$help_url = z_root() . '/help?f=&cmd=' . App::$cmd;
@@ -171,15 +158,10 @@ EOT;
//point directly to /help if $context_help is empty - this can be removed once we have context help for all modules
$enable_context_help = (($context_help) ? true : false);
}
$nav['help'] = array($help_url, t('Help'), "", t('Help and documentation'), 'help_nav_btn', $context_help, $enable_context_help);
$nav['help'] = [$help_url, t('Help'), "", t('Help and documentation'), 'help_nav_btn', $context_help, $enable_context_help];
}
if(! $basic)
$nav['apps'] = array('apps', t('Apps'), "", t('Applications, utilities, links, games'),'apps_nav_btn');
$nav['search'] = array('search', t('Search'), "", t('Search site @name, #tag, ?docs, content'));
$nav['directory'] = array('directory', t('Directory'), "", t('Channel Directory'),'directory_nav_btn');
$nav['search'] = ['search', t('Search'), "", t('Search site @name, #tag, ?docs, content')];
/**
@@ -246,15 +228,13 @@ EOT;
$banner = get_config('system','sitename');
$x = array('nav' => $nav, 'usermenu' => $userinfo );
call_hooks('nav', $x);
// Not sure the best place to put this on the page. So I'm implementing it but leaving it
// turned off until somebody discovers this and figures out a good location for it.
$powered_by = '';
// $powered_by = '<strong>red<img class="smiley" src="' . z_root() . '/images/rm-16.png" alt="r#" />matrix</strong>';
//app bin
if(local_channel()) {
if(get_pconfig(local_channel(), 'system','initial_import_system_apps') === false) {
@@ -278,7 +258,7 @@ EOT;
usort($syslist,'Zotlabs\\Lib\\Apps::app_name_compare');
foreach($syslist as $app) {
$navapps[] = Zlib\Apps::app_render($app,'nav');
$nav_apps[] = Zlib\Apps::app_render($app,'nav');
}
$tpl = get_markup_template('nav.tpl');
@@ -296,8 +276,10 @@ EOT;
'$powered_by' => $powered_by,
'$help' => t('@name, #tag, ?doc, content'),
'$pleasewait' => t('Please wait...'),
'$navapps' => $navapps,
'$addapps' => t('Add Apps')
'$nav_apps' => $nav_apps,
'$channel_apps' => $channel_apps,
'$addapps' => t('Add Apps'),
'$sysapps_toggle' => t('Toggle System Apps')
));
if(x($_SESSION, 'reload_avatar') && $observer) {
@@ -336,3 +318,168 @@ function nav_set_selected($item){
);
App::$nav_sel[$item] = 'active';
}
function channel_apps($is_owner = false, $nickname = null) {
// Don't provide any channel apps if we're running as the sys channel
if(App::$is_sys)
return '';
if(! get_pconfig($uid, 'system', 'channelapps','1'))
return '';
$channel = App::get_channel();
if($channel && is_null($nickname))
$nickname = $channel['channel_address'];
$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()) {
return;
}
else {
$cal_link = '/cal/' . $nickname;
}
$sql_options = item_permissions_sql($uid);
$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'
and item.item_delayed = 0 and item.item_deleted = 0
and ( iconfig.k = 'WEBPAGE' and item_type = %d )
$sql_options limit 1",
intval($uid),
dbesc('home'),
intval(ITEM_TYPE_WEBPAGE)
);
$has_webpages = (($r) ? true : false);
if(x($_GET, 'tab'))
$tab = notags(trim($_GET['tab']));
$url = z_root() . '/channel/' . $nickname;
$pr = z_root() . '/profile/' . $nickname;
$tabs = [
[
'label' => t('Channel'),
'url' => $url,
'sel' => ((argv(0) == 'channel') ? 'active' : ''),
'title' => t('Status Messages and Posts'),
'id' => 'status-tab',
'icon' => 'home'
],
];
$p = get_all_perms($uid,get_observer_hash());
if ($p['view_profile']) {
$tabs[] = [
'label' => t('About'),
'url' => $pr,
'sel' => ((argv(0) == 'profile') ? 'active' : ''),
'title' => t('Profile Details'),
'id' => 'profile-tab',
'icon' => 'user'
];
}
if ($p['view_storage']) {
$tabs[] = [
'label' => t('Photos'),
'url' => z_root() . '/photos/' . $nickname,
'sel' => ((argv(0) == 'photos') ? 'active' : ''),
'title' => t('Photo Albums'),
'id' => 'photo-tab',
'icon' => 'photo'
];
$tabs[] = [
'label' => t('Files'),
'url' => z_root() . '/cloud/' . $nickname,
'sel' => ((argv(0) == 'cloud' || argv(0) == 'sharedwithme') ? 'active' : ''),
'title' => t('Files and Storage'),
'id' => 'files-tab',
'icon' => 'folder-open'
];
}
if($p['view_stream'] && $cal_link) {
$tabs[] = [
'label' => t('Events'),
'url' => z_root() . $cal_link,
'sel' => ((argv(0) == 'cal' || argv(0) == 'events') ? 'active' : ''),
'title' => t('Events'),
'id' => 'event-tab',
'icon' => 'calendar'
];
}
if ($p['chat'] && feature_enabled($uid,'ajaxchat')) {
$has_chats = ZLib\Chatroom::list_count($uid);
if ($has_chats) {
$tabs[] = [
'label' => t('Chatrooms'),
'url' => z_root() . '/chat/' . $nickname,
'sel' => ((argv(0) == 'chat') ? 'active' : '' ),
'title' => t('Chatrooms'),
'id' => 'chat-tab',
'icon' => 'comments-o'
];
}
}
$has_bookmarks = menu_list_count(local_channel(),'',MENU_BOOKMARK) + menu_list_count(local_channel(),'',MENU_SYSTEM|MENU_BOOKMARK);
if ($is_owner && $has_bookmarks) {
$tabs[] = [
'label' => t('Bookmarks'),
'url' => z_root() . '/bookmarks',
'sel' => ((argv(0) == 'bookmarks') ? 'active' : ''),
'title' => t('Saved Bookmarks'),
'id' => 'bookmarks-tab',
'icon' => 'bookmark'
];
}
if($has_webpages && feature_enabled($uid,'webpages')) {
$tabs[] = [
'label' => t('Webpages'),
'url' => z_root() . '/page/' . $nickname . '/home',
'sel' => ((argv(0) == 'webpages') ? 'active' : ''),
'title' => t('View Webpages'),
'id' => 'webpages-tab',
'icon' => 'newspaper-o'
];
}
if ($p['view_wiki']) {
if(feature_enabled($uid,'wiki') && (get_account_techlevel($account_id) > 3)) {
$tabs[] = [
'label' => t('Wikis'),
'url' => z_root() . '/wiki/' . $nickname,
'sel' => ((argv(0) == 'wiki') ? 'active' : ''),
'title' => t('Wiki'),
'id' => 'wiki-tab',
'icon' => 'pencil-square-o'
];
}
}
$arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs);
call_hooks('profile_tabs', $arr);
call_hooks('channel_apps', $arr);
return replace_macros(get_markup_template('profile_tabs.tpl'),
[
'$tabs' => $arr['tabs'],
'$name' => App::$profile['channel_name'],
'$thumb' => App::$profile['thumb']
]
);
}

File diff suppressed because it is too large Load Diff

View File

@@ -149,7 +149,14 @@ function oembed_fetch_url($embedurl){
if ($action !== 'block') {
// try oembed autodiscovery
$redirects = 0;
$result = z_fetch_url($furl, false, $redirects, array('timeout' => 30, 'accept_content' => "text/*", 'novalidate' => true ));
$result = z_fetch_url($furl, false, $redirects,
[
'timeout' => 30,
'accept_content' => "text/*",
'novalidate' => true,
'session' => ((local_channel() && $zrl) ? true : false)
]
);
if($result['success'])
$html_text = $result['body'];
@@ -200,7 +207,7 @@ function oembed_fetch_url($embedurl){
if ($txt[0]!="{") $txt='{"type":"error"}';
//save in cache
// save in cache
if(! get_config('system','oembed_cache_disable'))
Zlib\Cache::set('[' . App::$videowidth . '] ' . $furl, $txt);

View File

@@ -314,11 +314,12 @@ function perm_is_allowed($uid, $observer_xchan, $permission) {
'channel_id' => $uid,
'observer_hash' => $observer_xchan,
'permission' => $permission,
'result' => false);
'result' => 'unset');
call_hooks('perm_is_allowed', $arr);
if($arr['result'])
return true;
if($arr['result'] !== 'unset') {
return $arr['result'];
}
$global_perms = \Zotlabs\Access\Permissions::Perms();

View File

@@ -330,6 +330,7 @@ abstract class photo_driver {
$p['photo_usage'] = intval($arr['photo_usage']);
$p['os_storage'] = intval($arr['os_storage']);
$p['os_path'] = $arr['os_path'];
$p['os_syspath'] = ((array_key_exists('os_syspath',$arr)) ? $arr['os_syspath'] : '');
$p['display_path'] = (($arr['display_path']) ? $arr['display_path'] : '');
if(! intval($p['imgscale']))
@@ -380,7 +381,7 @@ abstract class photo_driver {
dbesc($p['album']),
intval($this->getHeight()),
intval($this->getWidth()),
(intval($p['os_storage']) ? dbescbin($p['os_path']) : dbescbin($this->imageString())),
(intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())),
intval($p['os_storage']),
intval(strlen($this->imageString())),
intval($p['imgscale']),
@@ -411,7 +412,7 @@ abstract class photo_driver {
dbesc($p['album']),
intval($this->getHeight()),
intval($this->getWidth()),
(intval($p['os_storage']) ? dbescbin($p['os_path']) : dbescbin($this->imageString())),
(intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())),
intval($p['os_storage']),
intval(strlen($this->imageString())),
intval($p['imgscale']),
@@ -429,90 +430,6 @@ abstract class photo_driver {
return $r;
}
// should be obsolete now
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",
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'
where id = %d",
intval($aid),
intval($uid),
dbesc($xchan),
dbesc($rid),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc(basename($filename)),
dbesc($this->getType()),
dbesc($album),
intval($this->getHeight()),
intval($this->getWidth()),
dbescbin($this->imageString()),
intval(strlen($this->imageString())),
intval($scale),
intval($photo_usage),
dbesc($allow_cid),
dbesc($allow_gid),
dbesc($deny_cid),
dbesc($deny_gid),
intval($x[0]['id'])
);
}
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 )
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s' )",
intval($aid),
intval($uid),
dbesc($xchan),
dbesc($rid),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc(basename($filename)),
dbesc($this->getType()),
dbesc($album),
intval($this->getHeight()),
intval($this->getWidth()),
dbescbin($this->imageString()),
intval(strlen($this->imageString())),
intval($scale),
intval($photo_usage),
dbesc($allow_cid),
dbesc($allow_gid),
dbesc($deny_cid),
dbesc($deny_gid)
);
}
return $r;
}
}

View File

@@ -67,8 +67,8 @@ function photo_upload($channel, $observer, $args) {
$os_storage = 0;
if($args['os_path'] && $args['getimagesize']) {
$imagedata = @file_get_contents($args['os_path']);
if($args['os_syspath'] && $args['getimagesize']) {
$imagedata = @file_get_contents($args['os_syspath']);
$filename = $args['filename'];
$filesize = strlen($imagedata);
// this is going to be deleted if it exists
@@ -153,7 +153,7 @@ function photo_upload($channel, $observer, $args) {
return $ret;
}
$exif = $ph->orient(($args['os_path']) ? $args['os_path'] : $src);
$exif = $ph->orient(($args['os_syspath']) ? $args['os_syspath'] : $src);
@unlink($src);
@@ -180,7 +180,8 @@ function photo_upload($channel, $observer, $args) {
'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']
'os_storage' => $os_storage, 'os_syspath' => $args['os_syspath'],
'os_path' => $args['os_path'], 'display_path' => $args['display_path']
);
if($args['created'])
$p['created'] = $args['created'];
@@ -205,7 +206,7 @@ function photo_upload($channel, $observer, $args) {
$errors = true;
unset($p['os_storage']);
unset($p['os_path']);
unset($p['os_syspath']);
if(($width > 1024 || $height > 1024) && (! $errors))
$ph->scaleImage(1024);
@@ -336,19 +337,13 @@ function photo_upload($channel, $observer, $args) {
if($item['mid'] === $item['parent_mid']) {
$item['body'] = $summary;
$item['mimetype'] = 'text/bbcode';
$item['obj_type'] = ACTIVITY_OBJ_PHOTO;
$item['obj'] = json_encode($object);
$item['tgt_type'] = ACTIVITY_OBJ_ALBUM;
$item['target'] = json_encode($target);
if($item['author_xchan'] === $channel['channel_hash']) {
$item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey']));
$item['item_verified'] = 1;
}
else {
$item['sig'] = '';
}
$force = true;
}
@@ -451,7 +446,7 @@ function photo_upload($channel, $observer, $args) {
* * \e boolean \b success
* * \e array \b albums
*/
function photos_albums_list($channel, $observer, $sort_key = 'album', $direction = 'asc') {
function photos_albums_list($channel, $observer, $sort_key = 'display_path', $direction = 'asc') {
$channel_id = $channel['channel_id'];
$observer_xchan = (($observer) ? $observer['xchan_hash'] : '');
@@ -464,17 +459,34 @@ function photos_albums_list($channel, $observer, $sort_key = 'album', $direction
$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),
// intval(PHOTO_PROFILE)
//);
// this query provides the same results but might perform better
$albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and os_storage = 1 $sql_extra group by album order by $sort_key $direction",
$r = q("select display_path, hash from attach where is_dir = 1 and uid = %d $sql_extra order by $sort_key $direction",
intval($channel_id)
);
array_unshift($r,[ 'display_path' => '/', 'hash' => '' ]);
$str = ids_to_querystr($r,'hash',true);
$albums = [];
if($str) {
$x = q("select count( distinct hash ) as total, folder from attach where is_photo = 1 and uid = %d and folder in ( $str ) $sql_extra group by folder ",
intval($channel_id)
);
if($x) {
require_once('include/attach.php');
foreach($r as $rv) {
foreach($x as $xv) {
if($xv['folder'] === $rv['hash']) {
if($xv['total'] != 0 && attach_can_view_folder($channel_id,$observer_xchan,$xv['folder'])) {
$albums[] = [ 'album' => $rv['display_path'], 'folder' => $xv['folder'], 'total' => $xv['total'] ];
}
continue;
}
}
}
}
}
// add various encodings to the array so we can just loop through and pick them out in a template
$ret = array('success' => false);
@@ -485,11 +497,12 @@ function photos_albums_list($channel, $observer, $sort_key = 'album', $direction
foreach($albums as $k => $album) {
$entry = array(
'text' => (($album['album']) ? $album['album'] : '/'),
'shorttext' => (($album['album']) ? ellipsify($album['album'],28) : '/'),
'jstext' => (($album['album']) ? addslashes($album['album']) : '/'),
'total' => $album['total'],
'url' => z_root() . '/photos/' . $channel['channel_address'] . '/album/' . bin2hex($album['album']),
'url' => z_root() . '/photos/' . $channel['channel_address'] . '/album/' . $album['folder'],
'urlencode' => urlencode($album['album']),
'bin2hex' => bin2hex($album['album'])
'bin2hex' => $album['folder']
);
$ret['albums'][] = $entry;
}
@@ -500,7 +513,7 @@ function photos_albums_list($channel, $observer, $sort_key = 'album', $direction
return $ret;
}
function photos_album_widget($channelx,$observer,$sortkey = 'album',$direction = 'asc') {
function photos_album_widget($channelx,$observer,$sortkey = 'display_path',$direction = 'asc') {
$o = '';
@@ -513,6 +526,7 @@ function photos_album_widget($channelx,$observer,$sortkey = 'album',$direction =
$o = replace_macros(get_markup_template('photo_albums.tpl'),array(
'$nick' => $channelx['channel_address'],
'$title' => t('Photo Albums'),
'$recent' => t('Recent Photos'),
'$albums' => $albums['albums'],
'$baseurl' => z_root(),
'$upload' => ((perm_is_allowed($channelx['channel_id'],(($observer) ? $observer['xchan_hash'] : ''),'write_storage'))
@@ -570,13 +584,15 @@ function photos_list_photos($channel, $observer, $album = '') {
* @param string $album name of the album
* @return boolean
*/
function photos_album_exists($channel_id, $album) {
$r = q("SELECT id FROM photo WHERE album = '%s' AND uid = %d limit 1",
function photos_album_exists($channel_id, $observer_hash, $album) {
$sql_extra = permissions_sql($channel_id,$observer_hash);
$r = q("SELECT folder, hash, is_dir, filename, os_path, display_path FROM attach WHERE hash = '%s' AND is_dir = 1 AND uid = %d $sql_extra limit 1",
dbesc($album),
intval($channel_id)
);
return (($r) ? true : false);
return (($r) ? $r[0] : false);
}
/**
@@ -609,14 +625,15 @@ function photos_album_rename($channel_id, $oldname, $newname) {
*/
function photos_album_get_db_idstr($channel_id, $album, $remote_xchan = '') {
if ($remote_xchan) {
$r = q("SELECT distinct resource_id from photo where xchan = '%s' and uid = %d and album = '%s' ",
if($remote_xchan) {
$r = q("SELECT hash from attach where creator = '%s' and uid = %d and folder = '%s' ",
dbesc($remote_xchan),
intval($channel_id),
dbesc($album)
);
} else {
$r = q("SELECT distinct resource_id from photo where uid = %d and album = '%s' ",
}
else {
$r = q("SELECT hash from attach where uid = %d and folder = '%s' ",
intval($channel_id),
dbesc($album)
);
@@ -624,7 +641,7 @@ function photos_album_get_db_idstr($channel_id, $album, $remote_xchan = '') {
if ($r) {
$arr = array();
foreach ($r as $rr) {
$arr[] = "'" . dbesc($rr['resource_id']) . "'" ;
$arr[] = "'" . dbesc($rr['hash']) . "'" ;
}
$str = implode(',',$arr);
return $str;

View File

@@ -356,6 +356,7 @@ function get_plugin_info($plugin){
return $info;
$f = file_get_contents("addon/$plugin/$plugin.php");
$f = escape_tags($f);
$r = preg_match("|/\*.*\*/|msU", $f, $m);
if ($r){

View File

@@ -1,99 +0,0 @@
<?php /** @file */
/**
* Functions to assist in probing various legacy networks to figure out what kind of capabilities might be present.
*/
function net_have_driver($net) {
if(function_exists('net_discover_' . $net))
return true;
return false;
}
function probe_well_known($addr) {
$ret = array();
$ret['src'] = $addr;
if(strpos($addr,'@') !== false) {
$ret['address'] = $addr;
}
else {
$ret['url'] = $addr;
}
if(stristr($addr,'facebook.com')) {
$ret['network'] = 'facebook';
}
if(stristr($addr,'google.com')) {
$ret['network'] = 'google';
}
if(stristr($addr,'linkedin.com')) {
$ret['network'] = 'linkedin';
}
call_hooks('probe_well_known', $ret);
if(array_key_exists('network',$ret) && net_have_driver($ret['network'])) {
$fn = 'net_discover_' . $ret['network'];
$ret = $fn($ret);
}
return $ret;
}
function probe_webfinger($addr) {
}
function probe_legacy_webfinger($addr) {
}
function probe_zot($addr) {
}
function probe_dfrn($addr) {
}
function probe_diaspora($addr) {
}
function probe_legacy_feed($addr) {
}
function probe_activity_stream($addr) {
}

View File

@@ -146,10 +146,14 @@ 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, site_crypto) values ('%s','%s',0,%d,'') ",
dbesc($base),
dbesc(datetime_convert()),
intval(($outq['outq_driver'] === 'post') ? SITE_TYPE_NOTZOT : SITE_TYPE_UNKNOWN)
site_store_lowlevel(
[
'site_url' => $base,
'site_update' => datetime_convert(),
'site_dead' => 0,
'site_type' => intval(($outq['outq_driver'] === 'post') ? SITE_TYPE_NOTZOT : SITE_TYPE_UNKNOWN),
'site_crypto' => ''
]
);
}
}

View File

@@ -597,18 +597,24 @@ function stream_perms_api_uids($perms = NULL, $limit = 0, $rand = 0 ) {
$random_sql = (($rand) ? " ORDER BY " . db_getfunc('RAND') . " " : '');
if(local_channel())
$ret[] = local_channel();
$x = q("select uid from pconfig where cat = 'perm_limits' and k = 'view_stream' and ( v & %d ) > 0 ",
intval($perms)
);
$x = q("select uid, v from pconfig where cat = 'perm_limits' and k = 'view_stream' ");
if($x) {
$ids = ids_to_querystr($x,'uid');
$r = q("select channel_id from channel where channel_id in ( $ids ) and ( channel_pageflags & %d ) = 0 and channel_system = 0 and channel_removed = 0 $random_sql $limit_sql ",
intval(PAGE_ADULT|PAGE_CENSORED)
);
if($r) {
foreach($r as $rr)
if(! in_array($rr['channel_id'], $ret))
$ret[] = $rr['channel_id'];
$y = [];
foreach($x as $xv) {
if(intval($xv['v']) & $perms) {
$y[] = $xv;
}
}
if($y) {
$ids = ids_to_querystr($y,'uid');
$r = q("select channel_id from channel where channel_id in ( $ids ) and ( channel_pageflags & %d ) = 0 and channel_system = 0 and channel_removed = 0 $random_sql $limit_sql ",
intval(PAGE_ADULT|PAGE_CENSORED)
);
if($r) {
foreach($r as $rr)
if(! in_array($rr['channel_id'], $ret))
$ret[] = $rr['channel_id'];
}
}
}
@@ -635,19 +641,25 @@ function stream_perms_xchans($perms = NULL ) {
if(local_channel())
$ret[] = get_observer_hash();
$x = q("select uid from pconfig where cat = 'perm_limits' and k = 'view_stream' and ( v & %d ) > 0 ",
intval($perms)
);
$x = q("select uid from pconfig where cat = 'perm_limits' and k = 'view_stream' ");
if($x) {
$ids = ids_to_querystr($x,'uid');
$r = q("select channel_hash from channel where channel_id in ( $ids ) and ( channel_pageflags & %d ) = 0 and channel_system = 0 and channel_removed = 0 ",
intval(PAGE_ADULT|PAGE_CENSORED)
);
$y = [];
foreach($x as $xv) {
if(intval($xv['v']) & $perms) {
$y[] = $xv;
}
}
if($y) {
$ids = ids_to_querystr($y,'uid');
$r = q("select channel_hash from channel where channel_id in ( $ids ) and ( channel_pageflags & %d ) = 0 and channel_system = 0 and channel_removed = 0 ",
intval(PAGE_ADULT|PAGE_CENSORED)
);
if($r) {
foreach($r as $rr)
if(! in_array($rr['channel_hash'], $ret))
$ret[] = $rr['channel_hash'];
if($r) {
foreach($r as $rr)
if(! in_array($rr['channel_hash'], $ret))
$ret[] = $rr['channel_hash'];
}
}
}
$str = '';

View File

@@ -3,8 +3,10 @@
* @file include/text.php
*/
require_once("include/bbcode.php");
use \Zotlabs\Lib as Zlib;
use \Michelf\MarkdownExtra;
require_once("include/bbcode.php");
// random string, there are 86 characters max in text mode, 128 for hex
// output is urlsafe
@@ -88,12 +90,10 @@ function escape_tags($string) {
}
function z_input_filter($channel_id,$s,$type = 'text/bbcode') {
function z_input_filter($s,$type = 'text/bbcode',$allow_code = false) {
if($type === 'text/bbcode')
return escape_tags($s);
if($type === 'text/markdown')
return escape_tags($s);
if($type == 'text/plain')
return escape_tags($s);
if($type == 'application/x-pdl')
@@ -103,15 +103,15 @@ function z_input_filter($channel_id,$s,$type = 'text/bbcode') {
return $s;
}
$r = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id where channel_id = %d limit 1",
intval($channel_id)
);
if($r) {
if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) {
if(local_channel() && (get_account_id() == $r[0]['account_id'])) {
return $s;
}
}
if($allow_code) {
if($type === 'text/markdown')
return htmlspecialchars($s,ENT_QUOTES);
return $s;
}
if($type === 'text/markdown') {
$x = new Zlib\MarkdownSoap($s);
return $x->clean();
}
if($type === 'text/html')
@@ -121,13 +121,23 @@ function z_input_filter($channel_id,$s,$type = 'text/bbcode') {
}
/**
* @brief Use HTMLPurifier to get standards compliant HTML.
*
* Use the <a href="http://htmlpurifier.org/" target="_blank">HTMLPurifier</a>
* library to get filtered and standards compliant HTML.
*
* @see HTMLPurifier
*
* @param string $s raw HTML
* @param boolean $allow_position allow CSS position
* @return string standards compliant filtered HTML
*/
function purify_html($s, $allow_position = false) {
require_once('library/HTMLPurifier.auto.php');
require_once('include/html2bbcode.php');
/**
* @FIXME this function has html output, not bbcode - so safely purify these
* require_once('include/html2bbcode.php');
* $s = html2bb_video($s);
* $s = oembed_html2bbcode($s);
*/
@@ -136,6 +146,15 @@ function purify_html($s, $allow_position = false) {
$config->set('Cache.DefinitionImpl', null);
$config->set('Attr.EnableID', true);
// If enabled, target=blank attributes are added to all links.
//$config->set('HTML.TargetBlank', true);
//$config->set('Attr.AllowedFrameTargets', ['_blank', '_self', '_parent', '_top']);
// restore old behavior of HTMLPurifier < 4.8, only used when targets allowed at all
// do not add rel="noreferrer" to all links with target attributes
//$config->set('HTML.TargetNoreferrer', false);
// do not add noopener rel attributes to links which have a target attribute associated with them
//$config->set('HTML.TargetNoopener', false);
//Allow some custom data- attributes used by built-in libs.
//In this way members which do not have allowcode set can still use the built-in js libs in webpages to some extent.
@@ -273,7 +292,6 @@ function purify_html($s, $allow_position = false) {
new HTMLPurifier_AttrDef_CSS_Length(),
new HTMLPurifier_AttrDef_CSS_Percentage()
));
}
$purifier = new HTMLPurifier($config);
@@ -756,9 +774,9 @@ function activity_match($haystack,$needle) {
}
/**
* @brief Pull out all #hashtags and @person tags from $s.
* @brief Pull out all \#hashtags and \@person tags from $s.
*
* We also get @person@domain.com - which would make
* 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.
@@ -853,6 +871,11 @@ function tag_sort_length($a,$b) {
return((mb_strlen($b) < mb_strlen($a)) ? (-1) : 1);
}
function total_sort($a,$b) {
if($a['total'] == $b['total'])
return 0;
return(($b['total'] > $a['total']) ? 1 : (-1));
}
/**
@@ -1143,12 +1166,11 @@ function get_mood_verbs() {
*
* @return Returns array with keys 'texts' and 'icons'
*/
function list_smilies() {
function list_smilies($default_only = false) {
$texts = array(
'&lt;3',
'&lt;/3',
'&lt;\\3',
':-)',
';-)',
':-(',
@@ -1184,7 +1206,6 @@ function list_smilies() {
$icons = array(
'<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=":-(" />',
@@ -1218,25 +1239,16 @@ function list_smilies() {
);
$x = get_config('feature','emoji');
if($x === false)
$x = 1;
if($x) {
if(! App::$emojitab)
App::$emojitab = json_decode(file_get_contents('library/emoji.json'),true);
foreach(App::$emojitab as $e) {
if(strpos($e['shortname'],':tone') === 0)
continue;
$texts[] = $e['shortname'];
$icons[] = '<img class="smiley emoji" height="16" width="16" src="images/emoji/' . $e['unicode'] . '.png' . '" alt="' . $e['name'] . '" />';
}
}
$params = array('texts' => $texts, 'icons' => $icons);
if($default_only)
return $params;
call_hooks('smilie', $params);
return $params;
}
/**
* @brief Replaces text emoticons with graphical images.
*
@@ -1365,20 +1377,7 @@ function link_compare($a, $b) {
function unobscure(&$item) {
if(array_key_exists('item_obscured',$item) && intval($item['item_obscured'])) {
$key = get_config('system','prvkey');
if($item['title'])
$item['title'] = crypto_unencapsulate(json_decode($item['title'],true),$key);
if($item['body'])
$item['body'] = crypto_unencapsulate(json_decode($item['body'],true),$key);
if(get_config('system','item_cache')) {
q("update item set title = '%s', body = '%s', item_obscured = 0 where id = %d",
dbesc($item['title']),
dbesc($item['body']),
intval($item['id'])
);
}
}
return;
}
function unobscure_mail(&$item) {
@@ -1467,11 +1466,10 @@ function format_hashtags(&$item) {
continue;
if(strpos($item['body'], $t['url']))
continue;
if($s)
$s .= '&nbsp';
$s .= ' ';
$s .= '#<a href="' . zid($t['url']) . '" >' . $term . '</a>';
$s .= '<span class="badge badge-pill badge-info"><i class="fa fa-hashtag"></i>&nbsp;<a class="text-white" href="' . zid($t['url']) . '" >' . $term . '</a></span>';
}
}
@@ -1491,11 +1489,9 @@ function format_mentions(&$item) {
continue;
if(strpos($item['body'], $t['url']))
continue;
if($s)
$s .= '&nbsp';
$s .= '@<a href="' . zid($t['url']) . '" >' . $term . '</a>';
$s .= ' ';
$s .= '<span class="badge badge-pill badge-success"><i class="fa fa-at"></i>&nbsp;<a class="text-white" href="' . zid($t['url']) . '" >' . $term . '</a></span>';
}
}
@@ -1650,8 +1646,8 @@ function prepare_text($text, $content_type = 'text/bbcode', $cache = false) {
break;
case 'text/markdown':
require_once('library/markdown.php');
$s = Markdown($text);
$text = Zlib\MarkdownSoap::unescape($text);
$s = MarkdownExtra::defaultTransform($text);
break;
case 'application/x-pdl';
@@ -1806,23 +1802,9 @@ function mimetype_select($channel_id, $current = 'text/bbcode') {
);
if(App::$is_sys) {
if((App::$is_sys) || (channel_codeallowed($channel_id) && $channel_id == local_channel())){
$x[] = 'application/x-php';
}
else {
$r = q("select account_id, account_roles, channel_pageflags from account left join channel on account_id = channel_account_id where
channel_id = %d limit 1",
intval($channel_id)
);
if($r) {
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) {
$selected = (($y == $current) ? ' selected="selected" ' : '');
@@ -2062,7 +2044,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];
}
}
@@ -2078,7 +2060,7 @@ function ids_to_querystr($arr,$idx = 'id',$quote = false) {
if($arr) {
foreach($arr as $x) {
if(! in_array($x[$idx],$t)) {
if($quote)
if($quote)
$t[] = "'" . dbesc($x[$idx]) . "'";
else
$t[] = $x[$idx];
@@ -2095,7 +2077,7 @@ function ids_to_querystr($arr,$idx = 'id',$quote = false) {
* 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[in,out] array &$items
* @param boolean $abook If true also include the abook info
* @param number $effective_uid
*/
@@ -2191,10 +2173,10 @@ function magic_link($s) {
}
/**
* if $escape is true, dbesc() each element before adding quotes
* @brief If $escape is true, dbesc() each element before adding quotes.
*
* @param array[in,out] &$arr
* @param boolean $escape default false
* @param[in,out] array &$arr
* @param boolean $escape (optional) default false
*/
function stringify_array_elms(&$arr, $escape = false) {
for($x = 0; $x < count($arr); $x ++)
@@ -2205,7 +2187,6 @@ function stringify_array_elms(&$arr, $escape = false) {
* @brief Indents a flat JSON string to make it more human-readable.
*
* @param string $json The original JSON string to process.
*
* @return string Indented version of the original JSON string.
*/
function jindent($json) {
@@ -3058,7 +3039,15 @@ function array2XML($obj, $array) {
}
}
/**
* @brief Inserts an array into $table.
*
* @TODO Why is this function in include/text.php?
*
* @param string $table
* @param array $arr
* @return boolean|PDOStatement
*/
function create_table_from_array($table, $arr) {
if(! ($arr && $table))
@@ -3138,3 +3127,14 @@ function array_escape_tags(&$v,$k) {
$v = escape_tags($v);
}
function ellipsify($s,$maxlen) {
if($maxlen & 1)
$maxlen --;
if($maxlen < 4)
$maxlen = 4;
if(mb_strlen($s) < $maxlen)
return $s;
return mb_substr($s,0,$maxlen / 2) . '...' . mb_substr($s,mb_strlen($s) - ($maxlen / 2));
}

File diff suppressed because it is too large Load Diff

View File

@@ -165,9 +165,6 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot
function zot_best_algorithm($methods) {
if(\Zotlabs\Lib\System::get_server_role() !== 'pro')
return 'aes256cbc';
$x = [ 'methods' => $methods, 'result' => '' ];
call_hooks('zot_best_algorithm',$x);
if($x['result'])
@@ -313,8 +310,6 @@ function zot_refresh($them, $channel = null, $force = false) {
$result = z_post_url($url . $rhs,$postvars);
logger('zot_refresh: zot-info: ' . print_r($result,true), LOGGER_DATA, LOG_DEBUG);
if ($result['success']) {
$j = json_decode($result['body'],true);
@@ -324,6 +319,8 @@ function zot_refresh($them, $channel = null, $force = false) {
return false;
}
logger('zot-info: ' . print_r($result,true), LOGGER_DATA, LOG_DEBUG);
$signed_token = ((is_array($j) && array_key_exists('signed_token',$j)) ? $j['signed_token'] : null);
if($signed_token) {
$valid = rsa_verify('token.' . $token,base64url_decode($signed_token),$j['key']);
@@ -334,10 +331,7 @@ function zot_refresh($them, $channel = null, $force = false) {
}
else {
logger('No signed token from ' . $url . $rhs, LOGGER_NORMAL, LOG_WARNING);
// after 2017-01-01 this will be a hard error unless you over-ride it.
if((time() > 1483228800) && (! get_config('system','allow_unsigned_zotfinger'))) {
return false;
}
return false;
}
$x = import_xchan($j, (($force) ? UPDATE_FLAGS_FORCED : UPDATE_FLAGS_UPDATED));
@@ -2903,22 +2897,24 @@ 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, site_crypto )
values ( '%s', '%s', %d, %d, '%s', '%s', %d, '%s', '%s', %d, '%s', '%s', '%s' )",
dbesc($site_location),
dbesc($url),
intval($access_policy),
intval($site_directory),
dbesc(datetime_convert()),
dbesc($directory_url),
intval($register_policy),
dbesc($sellpage),
dbesc($site_realm),
intval(SITE_TYPE_ZOT),
dbesc($site_project),
dbesc($site_version),
dbesc($site_crypto)
$r = site_store_lowlevel(
[
'site_location' => $site_location,
'site_url' => $url,
'site_access' => intval($access_policy),
'site_flags' => intval($site_directory),
'site_update' => datetime_convert(),
'site_directory' => $directory_url,
'site_register' => intval($register_policy),
'site_sellpage' => $sellpage,
'site_realm' => $site_realm,
'site_type' => intval(SITE_TYPE_ZOT),
'site_project' => $site_project,
'site_version' => $site_version,
'site_crypto' => $site_crypto
]
);
if(! $r) {
logger('import_site: record create failed. ' . print_r($arr,true));
}
@@ -2960,6 +2956,8 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
return;
$channel = $r[0];
unset($channel['channel_password']);
unset($channel['channel_salt']);
translate_channel_perms_outbound($channel);
if($packet && array_key_exists('abook',$packet) && $packet['abook']) {
@@ -3162,8 +3160,8 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
if(array_key_exists('menu',$arr) && $arr['menu'])
sync_menus($channel,$arr['menu']);
if(array_key_exists('menu',$arr) && $arr['menu'])
sync_menus($channel,$arr['menu']);
if(array_key_exists('file',$arr) && $arr['file'])
sync_files($channel,$arr['file']);
if(array_key_exists('wiki',$arr) && $arr['wiki'])
sync_items($channel,$arr['wiki'],((array_key_exists('relocate',$arr)) ? $arr['relocate'] : null));
@@ -3228,12 +3226,10 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
}
$disallowed = array('abook_id','abook_account','abook_channel','abook_rating','abook_rating_text');
$disallowed = array('abook_id','abook_account','abook_channel','abook_rating','abook_rating_text','abook_not_here');
foreach($arr['abook'] as $abook) {
$abconfig = null;
if(array_key_exists('abconfig',$abook) && is_array($abook['abconfig']) && count($abook['abconfig']))
@@ -3584,21 +3580,62 @@ function get_rpost_path($observer) {
function import_author_zot($x) {
// Check that we have both a hubloc and xchan record - as occasionally storage calls will fail and
// we may only end up with one; which results in posts with no author name or photo and are a bit
// of a hassle to repair. If either or both are missing, do a full discovery probe.
$hash = make_xchan_hash($x['guid'],$x['guid_sig']);
$r = q("select hubloc_url from hubloc where hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_primary = 1 limit 1",
$r1 = q("select hubloc_url, hubloc_updated, site_dead from hubloc left join site on
hubloc_url = site_url where hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_primary = 1 limit 1",
dbesc($x['guid']),
dbesc($x['guid_sig'])
);
if ($r) {
logger('import_author_zot: in cache', LOGGER_DEBUG);
$r2 = q("select xchan_hash from xchan where xchan_guid = '%s' and xchan_guid_sig = '%s' limit 1",
dbesc($x['guid']),
dbesc($x['guid_sig'])
);
$site_dead = false;
if($r1 && intval($r1[0]['site_dead'])) {
$site_dead = true;
}
// We have valid and somewhat fresh information.
if($r1 && $r2 && $r1[0]['hubloc_updated'] > datetime_convert('UTC','UTC','now - 1 week')) {
logger('in cache', LOGGER_DEBUG);
return $hash;
}
logger('import_author_zot: entry not in cache - probing: ' . print_r($x,true), LOGGER_DEBUG);
logger('not in cache or cache stale - probing: ' . print_r($x,true), LOGGER_DEBUG,LOG_INFO);
// The primary hub may be dead. Try to find another one associated with this identity that is
// still alive. If we find one, use that url for the discovery/refresh probe. Otherwise, the dead site
// is all we have and there is no point probing it. Just return the hash indicating we have a
// cached entry and the identity is valid. It's just unreachable until they bring back their
// server from the grave or create another clone elsewhere.
if($site_dead) {
logger('dead site - ignoring', LOGGER_DEBUG,LOG_INFO);
$r = q("select hubloc_url from hubloc left join site on hubloc_url = site_url
where hubloc_hash = '%s' and site_dead = 0",
dbesc($hash)
);
if($r) {
logger('found another site that is not dead: ' . $r[0]['hubloc_url'], LOGGER_DEBUG,LOG_INFO);
$x['url'] = $r[0]['hubloc_url'];
}
else {
return $hash;
}
}
$them = array('hubloc_url' => $x['url'], 'xchan_guid' => $x['guid'], 'xchan_guid_sig' => $x['guid_sig']);
if (zot_refresh($them))
if(zot_refresh($them))
return $hash;
return false;