Merge branch '3.8RC'
This commit is contained in:
@@ -124,7 +124,7 @@ function account_store_lowlevel($arr) {
|
||||
'account_expires' => ((array_key_exists('account_expires',$arr)) ? $arr['account_expires'] : '0001-01-01 00:00:00'),
|
||||
'account_expire_notified' => ((array_key_exists('account_expire_notified',$arr)) ? $arr['account_expire_notified'] : '0001-01-01 00:00:00'),
|
||||
'account_service_class' => ((array_key_exists('account_service_class',$arr)) ? $arr['account_service_class'] : ''),
|
||||
'account_level' => ((array_key_exists('account_level',$arr)) ? $arr['account_level'] : '0'),
|
||||
'account_level' => '5',
|
||||
'account_password_changed' => ((array_key_exists('account_password_changed',$arr)) ? $arr['account_password_changed'] : '0001-01-01 00:00:00')
|
||||
];
|
||||
|
||||
@@ -215,7 +215,7 @@ function create_account($arr) {
|
||||
'account_created' => datetime_convert(),
|
||||
'account_flags' => intval($flags),
|
||||
'account_roles' => intval($roles),
|
||||
'account_level' => intval($techlevel),
|
||||
'account_level' => 5,
|
||||
'account_expires' => $expires,
|
||||
'account_service_class' => $default_service_class
|
||||
]
|
||||
@@ -821,13 +821,6 @@ function upgrade_bool_message($bbcode = false) {
|
||||
|
||||
function get_account_techlevel($account_id = 0) {
|
||||
|
||||
if(! $account_id) {
|
||||
$x = \App::get_account();
|
||||
}
|
||||
else {
|
||||
$x = get_account_by_id($account_id);
|
||||
}
|
||||
|
||||
return (($x) ? intval($x['account_level']) : 0);
|
||||
return (5);
|
||||
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("SELECT id, hash, gname FROM groups WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
$r = q("SELECT id, hash, gname FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
@@ -127,7 +127,10 @@ require_once('include/api_zot.php');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
$x = [ 'path' => App::$query_string ];
|
||||
call_hooks('api_not_found',$x);
|
||||
|
||||
header('HTTP/1.1 404 Not Found');
|
||||
logger('API call not implemented: ' . App::$query_string . ' - ' . print_r($_REQUEST,true));
|
||||
|
||||
@@ -12,7 +12,13 @@ function api_login(&$a){
|
||||
|
||||
require_once('include/oauth.php');
|
||||
|
||||
|
||||
if(array_key_exists('REDIRECT_REMOTE_USER',$_SERVER) && (! array_key_exists('HTTP_AUTHORIZATION',$_SERVER))) {
|
||||
$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['REDIRECT_REMOTE_USER'];
|
||||
}
|
||||
|
||||
// login with oauth
|
||||
|
||||
try {
|
||||
// OAuth 2.0
|
||||
$storage = new \Zotlabs\Identity\OAuth2Storage(\DBA::$dba->db);
|
||||
@@ -66,32 +72,27 @@ function api_login(&$a){
|
||||
logger($e->getMessage());
|
||||
}
|
||||
|
||||
// workarounds for HTTP-auth in CGI mode
|
||||
|
||||
foreach([ 'REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION' ] as $head) {
|
||||
if(array_key_exists('HTTP_AUTHORIZATION',$_SERVER)) {
|
||||
|
||||
/* Basic authentication */
|
||||
|
||||
if(array_key_exists($head,$_SERVER) && substr(trim($_SERVER[$head]),0,5) === 'Basic') {
|
||||
$userpass = @base64_decode(substr(trim($_SERVER[$head]),6)) ;
|
||||
if (substr(trim($_SERVER['HTTP_AUTHORIZATION']),0,5) === 'Basic') {
|
||||
$userpass = @base64_decode(substr(trim($_SERVER['HTTP_AUTHORIZATION']),6)) ;
|
||||
if(strlen($userpass)) {
|
||||
list($name, $password) = explode(':', $userpass);
|
||||
$_SERVER['PHP_AUTH_USER'] = $name;
|
||||
$_SERVER['PHP_AUTH_PW'] = $password;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Signature authentication */
|
||||
/* OpenWebAuth */
|
||||
|
||||
if(array_key_exists($head,$_SERVER) && substr(trim($_SERVER[$head]),0,9) === 'Signature') {
|
||||
if(substr(trim($_SERVER['HTTP_AUTHORIZATION']),0,9) === 'Signature') {
|
||||
|
||||
if($head !== 'HTTP_AUTHORIZATION') {
|
||||
$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER[$head];
|
||||
continue;
|
||||
}
|
||||
$record = null;
|
||||
|
||||
$sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER[$head]);
|
||||
$sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER['HTTP_AUTHORIZATION']);
|
||||
if($sigblock) {
|
||||
$keyId = str_replace('acct:','',$sigblock['keyId']);
|
||||
if($keyId) {
|
||||
@@ -108,16 +109,7 @@ function api_login(&$a){
|
||||
$record = [ 'channel' => $c, 'account' => $a[0] ];
|
||||
$channel_login = $c['channel_id'];
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if($record) {
|
||||
@@ -125,7 +117,6 @@ function api_login(&$a){
|
||||
if(! ($verified && $verified['header_signed'] && $verified['header_valid'])) {
|
||||
$record = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,7 +128,7 @@ function api_login(&$a){
|
||||
|
||||
// process normal login request
|
||||
|
||||
if(isset($_SERVER['PHP_AUTH_USER'])) {
|
||||
if(isset($_SERVER['PHP_AUTH_USER']) && (! $record)) {
|
||||
$channel_login = 0;
|
||||
$record = account_verify_password($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']);
|
||||
if($record && $record['channel']) {
|
||||
|
||||
@@ -350,20 +350,20 @@
|
||||
$r = null;
|
||||
|
||||
if($_REQUEST['group_id']) {
|
||||
$r = q("select * from groups where uid = %d and id = %d limit 1",
|
||||
$r = q("select * from pgrp where uid = %d and id = %d limit 1",
|
||||
intval(api_user()),
|
||||
intval($_REQUEST['group_id'])
|
||||
);
|
||||
}
|
||||
elseif($_REQUEST['group_name']) {
|
||||
$r = q("select * from groups where uid = %d and gname = '%s' limit 1",
|
||||
$r = q("select * from pgrp where uid = %d and gname = '%s' limit 1",
|
||||
intval(api_user()),
|
||||
dbesc($_REQUEST['group_name'])
|
||||
);
|
||||
}
|
||||
|
||||
if($r) {
|
||||
$x = q("select * from group_member left join abook on abook_xchan = xchan and abook_channel = group_member.uid left join xchan on group_member.xchan = xchan.xchan_hash
|
||||
$x = q("select * from pgrp_member left join abook on abook_xchan = xchan and abook_channel = pgrp_member.uid left join xchan on pgrp_member.xchan = xchan.xchan_hash
|
||||
where gid = %d",
|
||||
intval($r[0]['id'])
|
||||
);
|
||||
@@ -376,7 +376,7 @@
|
||||
if(api_user() === false)
|
||||
return false;
|
||||
|
||||
$r = q("select * from groups where uid = %d",
|
||||
$r = q("select * from pgrp where uid = %d",
|
||||
intval(api_user())
|
||||
);
|
||||
json_return_and_die($r);
|
||||
|
||||
@@ -1428,6 +1428,8 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
|
||||
|
||||
if(! $r) {
|
||||
attach_drop_photo($channel_id,$resource);
|
||||
$arr = ['channel_id' => $channel_id, 'resource' => $resource, 'is_photo'=>$is_photo];
|
||||
call_hooks("attach_delete",$arr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1486,6 +1488,9 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
$arr = ['channel_id' => $channel_id, 'resource' => $resource, 'is_photo'=>$is_photo];
|
||||
call_hooks("attach_delete",$arr);
|
||||
|
||||
file_activity($channel_id, $object, $object['allow_cid'], $object['allow_gid'], $object['deny_cid'], $object['deny_gid'], 'update', true);
|
||||
|
||||
return;
|
||||
|
||||
@@ -953,12 +953,14 @@ function bbcode($Text, $options = []) {
|
||||
$Text = preg_replace_callback("/[^\^]\[url\]([$URLSearchString]*)\[\/url\]/ism", 'tryoembed', $Text);
|
||||
}
|
||||
}
|
||||
|
||||
if (strpos($Text,'[/url]') !== false) {
|
||||
$Text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
|
||||
$Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
|
||||
}
|
||||
|
||||
if (strpos($Text,'[/zrl]') !== false) {
|
||||
$Text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
|
||||
@@ -966,9 +968,6 @@ function bbcode($Text, $options = []) {
|
||||
$Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a class="zrl" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
|
||||
}
|
||||
|
||||
if (get_account_techlevel() < 2)
|
||||
$Text = str_replace('<span class="bookmark-identifier">#^</span>', '', $Text);
|
||||
|
||||
// Perform MAIL Search
|
||||
if (strpos($Text,'[/mail]') !== false) {
|
||||
$Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
|
||||
|
||||
@@ -59,9 +59,10 @@ function bookmark_add($channel,$sender,$taxonomy,$private,$opts = null) {
|
||||
);
|
||||
if($r)
|
||||
logger('add_bookmark: duplicate menu entry', LOGGER_DEBUG);
|
||||
if(! $r)
|
||||
if(! $r) {
|
||||
$r = menu_add_item($menu_id,$channel_id,$iarr);
|
||||
|
||||
menu_sync_packet($channel_id,get_observer_hash(),$menu_id);
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
* @brief Channel related functions.
|
||||
*/
|
||||
|
||||
use Zotlabs\Access\PermissionRoles;
|
||||
use Zotlabs\Access\PermissionLimits;
|
||||
use Zotlabs\Access\Permissions;
|
||||
use Zotlabs\Daemon\Master;
|
||||
use Zotlabs\Lib\System;
|
||||
use Zotlabs\Render\Comanche;
|
||||
|
||||
require_once('include/zot.php');
|
||||
require_once('include/crypto.php');
|
||||
require_once('include/menu.php');
|
||||
@@ -236,7 +243,7 @@ function create_identity($arr) {
|
||||
$role_permissions = null;
|
||||
|
||||
if(array_key_exists('permissions_role',$arr) && $arr['permissions_role']) {
|
||||
$role_permissions = \Zotlabs\Access\PermissionRoles::role_perms($arr['permissions_role']);
|
||||
$role_permissions = PermissionRoles::role_perms($arr['permissions_role']);
|
||||
}
|
||||
|
||||
if($role_permissions && array_key_exists('directory_publish',$role_permissions))
|
||||
@@ -307,7 +314,7 @@ function create_identity($arr) {
|
||||
$perm_limits = site_default_perms();
|
||||
|
||||
foreach($perm_limits as $p => $v)
|
||||
\Zotlabs\Access\PermissionLimits::Set($r[0]['channel_id'],$p,$v);
|
||||
PermissionLimits::Set($r[0]['channel_id'],$p,$v);
|
||||
|
||||
if($role_permissions && array_key_exists('perms_auto',$role_permissions))
|
||||
set_pconfig($r[0]['channel_id'],'system','autoperms',intval($role_permissions['perms_auto']));
|
||||
@@ -383,7 +390,7 @@ function create_identity($arr) {
|
||||
$myperms = ((array_key_exists('perms_connect',$role_permissions)) ? $role_permissions['perms_connect'] : array());
|
||||
}
|
||||
else {
|
||||
$x = \Zotlabs\Access\PermissionRoles::role_perms('social');
|
||||
$x = PermissionRoles::role_perms('social');
|
||||
$myperms = $x['perms_connect'];
|
||||
}
|
||||
|
||||
@@ -399,7 +406,7 @@ function create_identity($arr) {
|
||||
]
|
||||
);
|
||||
|
||||
$x = \Zotlabs\Access\Permissions::FilledPerms($myperms);
|
||||
$x = Permissions::FilledPerms($myperms);
|
||||
foreach($x as $k => $v) {
|
||||
set_abconfig($newuid,$hash,'my_perms',$k,$v);
|
||||
}
|
||||
@@ -416,7 +423,7 @@ function create_identity($arr) {
|
||||
$autoperms = intval($role_permissions['perms_auto']);
|
||||
set_pconfig($newuid,'system','autoperms',$autoperms);
|
||||
if($autoperms) {
|
||||
$x = \Zotlabs\Access\Permissions::FilledPerms($role_permissions['perms_connect']);
|
||||
$x = Permissions::FilledPerms($role_permissions['perms_connect']);
|
||||
foreach($x as $k => $v) {
|
||||
set_pconfig($newuid,'autoperms',$k,$v);
|
||||
}
|
||||
@@ -440,7 +447,7 @@ function create_identity($arr) {
|
||||
// if our role_permissions indicate that we're using a default collection ACL, add it.
|
||||
|
||||
if(is_array($role_permissions) && $role_permissions['default_collection']) {
|
||||
$r = q("select hash from groups where uid = %d and gname = '%s' limit 1",
|
||||
$r = q("select hash from pgrp where uid = %d and gname = '%s' limit 1",
|
||||
intval($newuid),
|
||||
dbesc( t('Friends') )
|
||||
);
|
||||
@@ -482,7 +489,7 @@ function create_identity($arr) {
|
||||
*/
|
||||
call_hooks('create_identity', $newuid);
|
||||
|
||||
Zotlabs\Daemon\Master::Summon(array('Directory', $ret['channel']['channel_id']));
|
||||
Master::Summon(array('Directory', $ret['channel']['channel_id']));
|
||||
}
|
||||
|
||||
$ret['success'] = true;
|
||||
@@ -583,7 +590,7 @@ function change_channel_keys($channel) {
|
||||
|
||||
xchan_change_key($oldxchan,$newxchan,$stored);
|
||||
|
||||
Zotlabs\Daemon\Master::Summon(array('Notifier', 'keychange', $channel['channel_id']));
|
||||
Master::Summon([ 'Notifier', 'keychange', $channel['channel_id'] ]);
|
||||
|
||||
$ret['success'] = true;
|
||||
return $ret;
|
||||
@@ -666,7 +673,7 @@ function channel_change_address($channel,$new_address) {
|
||||
}
|
||||
}
|
||||
|
||||
Zotlabs\Daemon\Master::Summon(array('Notifier', 'refresh_all', $channel['channel_id']));
|
||||
Master::Summon(array('Notifier', 'refresh_all', $channel['channel_id']));
|
||||
|
||||
$ret['success'] = true;
|
||||
return $ret;
|
||||
@@ -759,7 +766,7 @@ function identity_basic_export($channel_id, $sections = null) {
|
||||
'project' => PLATFORM_NAME,
|
||||
'version' => STD_VERSION,
|
||||
'database' => DB_UPDATE_VERSION,
|
||||
'server_role' => Zotlabs\Lib\System::get_server_role()
|
||||
'server_role' => System::get_server_role()
|
||||
];
|
||||
|
||||
/*
|
||||
@@ -830,14 +837,14 @@ function identity_basic_export($channel_id, $sections = null) {
|
||||
$ret['hubloc'] = $r;
|
||||
}
|
||||
|
||||
$r = q("select * from groups where uid = %d ",
|
||||
$r = q("select * from pgrp where uid = %d ",
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
if($r)
|
||||
$ret['group'] = $r;
|
||||
|
||||
$r = q("select * from group_member where uid = %d ",
|
||||
$r = q("select * from pgrp_member where uid = %d ",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r)
|
||||
@@ -1425,7 +1432,7 @@ function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = fa
|
||||
}
|
||||
$menublock = get_pconfig($profile['uid'],'system','channel_menublock');
|
||||
if ($menublock && (! $block)) {
|
||||
$comanche = new Zotlabs\Render\Comanche();
|
||||
$comanche = new Comanche();
|
||||
$channel_menu .= $comanche->block($menublock);
|
||||
}
|
||||
|
||||
@@ -1701,7 +1708,7 @@ function zid_init() {
|
||||
dbesc($tmp_str)
|
||||
);
|
||||
if(! $r) {
|
||||
Zotlabs\Daemon\Master::Summon(array('Gprobe',bin2hex($tmp_str)));
|
||||
Master::Summon(array('Gprobe',bin2hex($tmp_str)));
|
||||
}
|
||||
if($r && remote_channel() && remote_channel() === $r[0]['hubloc_hash'])
|
||||
return;
|
||||
@@ -1907,7 +1914,7 @@ function is_public_profile() {
|
||||
|
||||
$channel = App::get_channel();
|
||||
if($channel) {
|
||||
$perm = \Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_profile');
|
||||
$perm = PermissionLimits::Get($channel['channel_id'],'view_profile');
|
||||
if($perm == PERMS_PUBLIC)
|
||||
return true;
|
||||
}
|
||||
@@ -2526,6 +2533,12 @@ function channel_remove($channel_id, $local = true, $unset_session = false) {
|
||||
|
||||
if(! $local) {
|
||||
|
||||
if(intval($r[0]['channel_removed'])) {
|
||||
// already removed. do not propagate deletion of a channel which
|
||||
// may have been removed locally at some previous time.
|
||||
return;
|
||||
}
|
||||
|
||||
$r = q("update channel set channel_deleted = '%s', channel_removed = 1 where channel_id = %d",
|
||||
dbesc(datetime_convert()),
|
||||
intval($channel_id)
|
||||
@@ -2545,11 +2558,11 @@ function channel_remove($channel_id, $local = true, $unset_session = false) {
|
||||
dbesc($channel['channel_hash'])
|
||||
);
|
||||
|
||||
Zotlabs\Daemon\Master::Summon(array('Notifier','purge_all',$channel_id));
|
||||
Master::Summon(array('Notifier','purge_all',$channel_id));
|
||||
}
|
||||
|
||||
|
||||
$r = q("select * from iconfig left join item on item.id = iconfig.iid
|
||||
$r = q("select iid from iconfig left join item on item.id = iconfig.iid
|
||||
where item.uid = %d",
|
||||
intval($channel_id)
|
||||
);
|
||||
@@ -2566,8 +2579,8 @@ function channel_remove($channel_id, $local = true, $unset_session = false) {
|
||||
q("DELETE FROM chatroom WHERE cr_uid = %d", intval($channel_id));
|
||||
q("DELETE FROM conv WHERE uid = %d", intval($channel_id));
|
||||
|
||||
q("DELETE FROM groups WHERE uid = %d", intval($channel_id));
|
||||
q("DELETE FROM group_member WHERE uid = %d", intval($channel_id));
|
||||
q("DELETE FROM pgrp WHERE uid = %d", intval($channel_id));
|
||||
q("DELETE FROM pgrp_member WHERE uid = %d", intval($channel_id));
|
||||
q("DELETE FROM event WHERE uid = %d", intval($channel_id));
|
||||
q("DELETE FROM mail WHERE channel_id = %d", intval($channel_id));
|
||||
q("DELETE FROM menu WHERE menu_channel_id = %d", intval($channel_id));
|
||||
@@ -2589,8 +2602,6 @@ function channel_remove($channel_id, $local = true, $unset_session = false) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$r = q("select id from item where uid = %d", intval($channel_id));
|
||||
if($r) {
|
||||
foreach($r as $rv) {
|
||||
@@ -2598,7 +2609,6 @@ function channel_remove($channel_id, $local = true, $unset_session = false) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
q("delete from abook where abook_xchan = '%s' and abook_self = 1 ",
|
||||
dbesc($channel['channel_hash'])
|
||||
);
|
||||
@@ -2658,7 +2668,7 @@ function channel_remove($channel_id, $local = true, $unset_session = false) {
|
||||
@rrmdir($f);
|
||||
}
|
||||
|
||||
Zotlabs\Daemon\Master::Summon(array('Directory',$channel_id));
|
||||
Master::Summon([ 'Directory', $channel_id ]);
|
||||
|
||||
if($channel_id == local_channel() && $unset_session) {
|
||||
App::$session->nuke();
|
||||
@@ -2797,3 +2807,6 @@ function pchan_to_chan($pchan) {
|
||||
return $chan;
|
||||
}
|
||||
|
||||
function channel_url($channel) {
|
||||
return (($channel) ? z_root() . '/channel/' . $channel['channel_address'] : z_root());
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ function remove_all_xchan_resources($xchan, $channel_id = 0) {
|
||||
$r = q("delete from event where event_xchan = '%s'",
|
||||
dbesc($xchan)
|
||||
);
|
||||
$r = q("delete from group_member where xchan = '%s'",
|
||||
$r = q("delete from pgrp_member where xchan = '%s'",
|
||||
dbesc($xchan)
|
||||
);
|
||||
$r = q("delete from mail where ( from_xchan = '%s' or to_xchan = '%s' )",
|
||||
@@ -404,7 +404,7 @@ function contact_remove($channel_id, $abook_id) {
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
$r = q("delete from group_member where xchan = '%s' and uid = %d",
|
||||
$r = q("delete from pgrp_member where xchan = '%s' and uid = %d",
|
||||
dbesc($abook['abook_xchan']),
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
@@ -888,6 +888,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
||||
'$user' => App::$user,
|
||||
'$threads' => $threads,
|
||||
'$wait' => t('Loading...'),
|
||||
'$conversation_tools' => t('Conversation Tools'),
|
||||
'$dropping' => ($page_dropping?t('Delete Selected Items'):False),
|
||||
));
|
||||
|
||||
@@ -1231,13 +1232,27 @@ function format_like($cnt, $arr, $type, $id) {
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper to allow addons to replace the status editor if desired.
|
||||
*/
|
||||
function status_editor($a, $x, $popup = false, $module='') {
|
||||
$hook_info = ['editor_html' => '', 'x' => $x, 'popup' => $popup, 'module' => $module];
|
||||
call_hooks('status_editor',$hook_info);
|
||||
if ($hook_info['editor_html'] == '') {
|
||||
return hz_status_editor($a, $x, $popup);
|
||||
} else {
|
||||
return $hook_info['editor_html'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is our general purpose content editor.
|
||||
* It was once nicknamed "jot" and you may see references to "jot" littered throughout the code.
|
||||
* They are referring to the content editor or components thereof.
|
||||
*/
|
||||
|
||||
function status_editor($a, $x, $popup = false) {
|
||||
function hz_status_editor($a, $x, $popup = false) {
|
||||
|
||||
$o = '';
|
||||
|
||||
@@ -1447,7 +1462,8 @@ function status_editor($a, $x, $popup = false) {
|
||||
'$expanded' => ((x($x, 'expanded')) ? $x['expanded'] : false),
|
||||
'$bbcode' => ((x($x, 'bbcode')) ? $x['bbcode'] : false),
|
||||
'$parent' => ((array_key_exists('parent',$x) && $x['parent']) ? $x['parent'] : 0),
|
||||
'$reset' => $reset
|
||||
'$reset' => $reset,
|
||||
'$is_owner' => ((local_channel() && (local_channel() == $x['profile_uid'])) ? true : false)
|
||||
));
|
||||
|
||||
if ($popup === true) {
|
||||
@@ -1644,319 +1660,6 @@ function prepare_page($item) {
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
function network_tabs() {
|
||||
|
||||
$no_active='';
|
||||
$starred_active = '';
|
||||
$new_active = '';
|
||||
$all_active = '';
|
||||
$search_active = '';
|
||||
$conv_active = '';
|
||||
$spam_active = '';
|
||||
$postord_active = '';
|
||||
|
||||
if(x($_GET,'new')) {
|
||||
$new_active = 'active';
|
||||
}
|
||||
|
||||
if(x($_GET,'search')) {
|
||||
$search_active = 'active';
|
||||
}
|
||||
|
||||
if(x($_GET,'star')) {
|
||||
$starred_active = 'active';
|
||||
}
|
||||
|
||||
if(x($_GET,'conv')) {
|
||||
$conv_active = 'active';
|
||||
}
|
||||
|
||||
if(x($_GET,'spam')) {
|
||||
$spam_active = 'active';
|
||||
}
|
||||
|
||||
if (($new_active == '')
|
||||
&& ($starred_active == '')
|
||||
&& ($conv_active == '')
|
||||
&& ($search_active == '')
|
||||
&& ($spam_active == '')) {
|
||||
$no_active = 'active';
|
||||
}
|
||||
|
||||
if ($no_active=='active' && x($_GET,'order')) {
|
||||
switch($_GET['order']){
|
||||
case 'post': $postord_active = 'active'; $no_active=''; break;
|
||||
case 'comment' : $all_active = 'active'; $no_active=''; break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($no_active=='active') $all_active='active';
|
||||
|
||||
$cmd = App::$cmd;
|
||||
|
||||
// tabs
|
||||
$tabs = array();
|
||||
|
||||
$tabs[] = array(
|
||||
'label' => t('Commented Order'),
|
||||
'url'=>z_root() . '/' . $cmd . '?f=&order=comment' . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : '') . ((x($_GET,'gid')) ? '&gid=' . $_GET['gid'] : ''),
|
||||
'sel'=>$all_active,
|
||||
'title'=> t('Sort by Comment Date'),
|
||||
);
|
||||
|
||||
$tabs[] = array(
|
||||
'label' => t('Posted Order'),
|
||||
'url'=>z_root() . '/' . $cmd . '?f=&order=post' . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : '') . ((x($_GET,'gid')) ? '&gid=' . $_GET['gid'] : ''),
|
||||
'sel'=>$postord_active,
|
||||
'title' => t('Sort by Post Date'),
|
||||
);
|
||||
|
||||
if(feature_enabled(local_channel(),'personal_tab')) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Personal'),
|
||||
'url' => z_root() . '/' . $cmd . '?f=' . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : '') . '&conv=1',
|
||||
'sel' => $conv_active,
|
||||
'title' => t('Posts that mention or involve you'),
|
||||
);
|
||||
}
|
||||
|
||||
if(feature_enabled(local_channel(),'new_tab')) {
|
||||
$tabs[] = array(
|
||||
'label' => t('New'),
|
||||
'url' => z_root() . '/' . $cmd . '?f=' . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : '') . '&new=1' . ((x($_GET,'gid')) ? '&gid=' . $_GET['gid'] : ''),
|
||||
'sel' => $new_active,
|
||||
'title' => t('Activity Stream - by date'),
|
||||
);
|
||||
}
|
||||
|
||||
if(feature_enabled(local_channel(),'star_posts')) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Starred'),
|
||||
'url'=>z_root() . '/' . $cmd . '/?f=' . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : '') . '&star=1',
|
||||
'sel'=>$starred_active,
|
||||
'title' => t('Favourite Posts'),
|
||||
);
|
||||
}
|
||||
// Not yet implemented
|
||||
|
||||
if(feature_enabled(local_channel(),'spam_filter')) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Spam'),
|
||||
'url'=> z_root() . '/network?f=&spam=1',
|
||||
'sel'=> $spam_active,
|
||||
'title' => t('Posts flagged as SPAM'),
|
||||
);
|
||||
}
|
||||
|
||||
$arr = array('tabs' => $tabs);
|
||||
call_hooks('network_tabs', $arr);
|
||||
|
||||
$tpl = get_markup_template('common_tabs.tpl');
|
||||
|
||||
return replace_macros($tpl, array('$tabs' => $arr['tabs']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param App $a
|
||||
* @param boolean $is_owner default false
|
||||
* @param string $nickname default null
|
||||
* @return void|string
|
||||
*/
|
||||
function profile_tabs($a, $is_owner = false, $nickname = null){
|
||||
|
||||
// Don't provide any profile tabs if we're running as the sys channel
|
||||
|
||||
if (App::$is_sys)
|
||||
return;
|
||||
|
||||
if (get_pconfig($uid, 'system', 'noprofiletabs'))
|
||||
return;
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
if (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;
|
||||
|
||||
if($uid == local_channel()) {
|
||||
$cal_link = '';
|
||||
}
|
||||
else {
|
||||
$cal_link = '/cal/' . $nickname;
|
||||
}
|
||||
|
||||
require_once('include/security.php');
|
||||
$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 = array(
|
||||
array(
|
||||
'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[] = array(
|
||||
'label' => t('About'),
|
||||
'url' => $pr,
|
||||
'sel' => ((argv(0) == 'profile') ? 'active' : ''),
|
||||
'title' => t('Profile Details'),
|
||||
'id' => 'profile-tab',
|
||||
'icon' => 'user'
|
||||
);
|
||||
}
|
||||
if ($p['view_storage']) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Photos'),
|
||||
'url' => z_root() . '/photos/' . $nickname,
|
||||
'sel' => ((argv(0) == 'photos') ? 'active' : ''),
|
||||
'title' => t('Photo Albums'),
|
||||
'id' => 'photo-tab',
|
||||
'icon' => 'photo'
|
||||
);
|
||||
$tabs[] = array(
|
||||
'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[] = array(
|
||||
'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 = Zotlabs\Lib\Chatroom::list_count($uid);
|
||||
if ($has_chats) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Chatrooms'),
|
||||
'url' => z_root() . '/chat/' . $nickname,
|
||||
'sel' => ((argv(0) == 'chat') ? 'active' : '' ),
|
||||
'title' => t('Chatrooms'),
|
||||
'id' => 'chat-tab',
|
||||
'icon' => 'comments-o'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
require_once('include/menu.php');
|
||||
$has_bookmarks = menu_list_count(local_channel(),'',MENU_BOOKMARK) + menu_list_count(local_channel(),'',MENU_SYSTEM|MENU_BOOKMARK);
|
||||
|
||||
if($is_owner && $has_bookmarks) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Bookmarks'),
|
||||
'url' => z_root() . '/bookmarks',
|
||||
'sel' => ((argv(0) == 'bookmarks') ? 'active' : ''),
|
||||
'title' => t('Saved Bookmarks'),
|
||||
'id' => 'bookmarks-tab',
|
||||
'icon' => 'bookmark'
|
||||
);
|
||||
}
|
||||
|
||||
if(feature_enabled($uid,'cards')) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Cards'),
|
||||
'url' => z_root() . '/cards/' . $nickname,
|
||||
'sel' => ((argv(0) == 'cards') ? 'active' : ''),
|
||||
'title' => t('View Cards'),
|
||||
'id' => 'cards-tab',
|
||||
'icon' => 'list'
|
||||
);
|
||||
}
|
||||
|
||||
if(feature_enabled($uid,'articles')) {
|
||||
$tabs[] = array(
|
||||
'label' => t('articles'),
|
||||
'url' => z_root() . '/articles/' . $nickname,
|
||||
'sel' => ((argv(0) == 'articles') ? 'active' : ''),
|
||||
'title' => t('View Articles'),
|
||||
'id' => 'articles-tab',
|
||||
'icon' => 'file-text-o'
|
||||
);
|
||||
}
|
||||
|
||||
if($has_webpages && feature_enabled($uid,'webpages')) {
|
||||
$tabs[] = array(
|
||||
'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[] = 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('profile_tabs.tpl');
|
||||
|
||||
return replace_macros($tpl, array(
|
||||
'$tabs' => $arr['tabs'],
|
||||
'$name' => App::$profile['channel_name'],
|
||||
'$thumb' => App::$profile['thumb']
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
function get_responses($conv_responses,$response_verbs,$ob,$item) {
|
||||
|
||||
$ret = array();
|
||||
|
||||
@@ -44,417 +44,98 @@ function feature_level($feature,$def) {
|
||||
return $def;
|
||||
}
|
||||
|
||||
function process_module_features_get($uid, $features) {
|
||||
unset($features[0]);
|
||||
foreach($features as $f) {
|
||||
$arr[] = [
|
||||
'feature_' . $f[0],
|
||||
$f[1],
|
||||
((intval(feature_enabled($uid, $f[0]))) ? "1" : ''),
|
||||
$f[2],
|
||||
[t('Off'),t('On')],
|
||||
(($f[4] === false) ? '' : 'disabled'),
|
||||
$f[5]
|
||||
];
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function process_module_features_post($uid, $features, $post_arr) {
|
||||
unset($features[0]);
|
||||
foreach($features as $f) {
|
||||
$k = $f[0];
|
||||
if(array_key_exists("feature_$k",$post_arr))
|
||||
set_pconfig($uid,'feature',$k, (string) $post_arr["feature_$k"]);
|
||||
else
|
||||
set_pconfig($uid,'feature', $k, '');
|
||||
}
|
||||
}
|
||||
|
||||
function get_features($filtered = true, $level = (-1)) {
|
||||
|
||||
$account = \App::get_account();
|
||||
|
||||
$arr = [
|
||||
|
||||
// General
|
||||
'general' => [
|
||||
'calendar' => [
|
||||
|
||||
t('General Features'),
|
||||
t('CalDAV'),
|
||||
|
||||
[
|
||||
'start_menu',
|
||||
t('New Member Links'),
|
||||
t('Display new member quick links menu'),
|
||||
(($account['account_created'] > datetime_convert('','','now - 60 days')) ? true : false),
|
||||
get_config('feature_lock','start_menu'),
|
||||
feature_level('start_menu',1),
|
||||
],
|
||||
|
||||
[
|
||||
'advanced_profiles',
|
||||
t('Advanced Profiles'),
|
||||
t('Additional profile sections and selections'),
|
||||
'cal_first_day',
|
||||
t('Start calendar week on Monday'),
|
||||
t('Default is Sunday'),
|
||||
false,
|
||||
get_config('feature_lock','advanced_profiles'),
|
||||
feature_level('advanced_profiles',1),
|
||||
],
|
||||
|
||||
[
|
||||
'profile_export',
|
||||
t('Profile Import/Export'),
|
||||
t('Save and load profile details across sites/channels'),
|
||||
false,
|
||||
get_config('feature_lock','profile_export'),
|
||||
feature_level('profile_export',3),
|
||||
],
|
||||
|
||||
[
|
||||
'webpages',
|
||||
t('Web Pages'),
|
||||
t('Provide managed web pages on your channel'),
|
||||
false,
|
||||
get_config('feature_lock','webpages'),
|
||||
feature_level('webpages',3),
|
||||
],
|
||||
|
||||
[
|
||||
'wiki',
|
||||
t('Wiki'),
|
||||
t('Provide a wiki for your channel'),
|
||||
false,
|
||||
get_config('feature_lock','wiki'),
|
||||
feature_level('wiki',2),
|
||||
],
|
||||
/*
|
||||
[
|
||||
'hide_rating',
|
||||
t('Hide Rating'),
|
||||
t('Hide the rating buttons on your channel and profile pages. Note: People can still rate you somewhere else.'),
|
||||
false,
|
||||
get_config('feature_lock','hide_rating'),
|
||||
feature_level('hide_rating',3),
|
||||
],
|
||||
*/
|
||||
[
|
||||
'private_notes',
|
||||
t('Private Notes'),
|
||||
t('Enables a tool to store notes and reminders (note: not encrypted)'),
|
||||
false,
|
||||
get_config('feature_lock','private_notes'),
|
||||
feature_level('private_notes',1),
|
||||
],
|
||||
|
||||
[
|
||||
'cards',
|
||||
t('Cards'),
|
||||
t('Create personal planning cards'),
|
||||
false,
|
||||
get_config('feature_lock','cards'),
|
||||
feature_level('cards',1),
|
||||
],
|
||||
|
||||
|
||||
[
|
||||
'articles',
|
||||
t('Articles'),
|
||||
t('Create interactive articles'),
|
||||
false,
|
||||
get_config('feature_lock','articles'),
|
||||
feature_level('articles',1),
|
||||
],
|
||||
|
||||
[
|
||||
'nav_channel_select',
|
||||
t('Navigation Channel Select'),
|
||||
t('Change channels directly from within the navigation dropdown menu'),
|
||||
false,
|
||||
get_config('feature_lock','nav_channel_select'),
|
||||
feature_level('nav_channel_select',3),
|
||||
],
|
||||
|
||||
[
|
||||
'photo_location',
|
||||
t('Photo Location'),
|
||||
t('If location data is available on uploaded photos, link this to a map.'),
|
||||
false,
|
||||
get_config('feature_lock','photo_location'),
|
||||
feature_level('photo_location',2),
|
||||
],
|
||||
|
||||
[
|
||||
'ajaxchat',
|
||||
t('Access Controlled Chatrooms'),
|
||||
t('Provide chatrooms and chat services with access control.'),
|
||||
true,
|
||||
get_config('feature_lock','ajaxchat'),
|
||||
feature_level('ajaxchat',1),
|
||||
],
|
||||
|
||||
|
||||
[
|
||||
'smart_birthdays',
|
||||
t('Smart Birthdays'),
|
||||
t('Make birthday events timezone aware in case your friends are scattered across the planet.'),
|
||||
true,
|
||||
get_config('feature_lock','smart_birthdays'),
|
||||
feature_level('smart_birthdays',2),
|
||||
],
|
||||
|
||||
[
|
||||
'event_tz_select',
|
||||
t('Event Timezone Selection'),
|
||||
t('Allow event creation in timezones other than your own.'),
|
||||
false,
|
||||
get_config('feature_lock','event_tz_select'),
|
||||
feature_level('event_tz_select',2),
|
||||
],
|
||||
|
||||
|
||||
[
|
||||
'premium_channel',
|
||||
t('Premium Channel'),
|
||||
t('Allows you to set restrictions and terms on those that connect with your channel'),
|
||||
false,
|
||||
get_config('feature_lock','premium_channel'),
|
||||
feature_level('premium_channel',4),
|
||||
],
|
||||
|
||||
[
|
||||
'advanced_dirsearch',
|
||||
t('Advanced Directory Search'),
|
||||
t('Allows creation of complex directory search queries'),
|
||||
false,
|
||||
get_config('feature_lock','advanced_dirsearch'),
|
||||
feature_level('advanced_dirsearch',4),
|
||||
],
|
||||
|
||||
[
|
||||
'advanced_theming',
|
||||
t('Advanced Theme and Layout Settings'),
|
||||
t('Allows fine tuning of themes and page layouts'),
|
||||
false,
|
||||
get_config('feature_lock','advanced_theming'),
|
||||
feature_level('advanced_theming',4),
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
'access_control' => [
|
||||
t('Access Control and Permissions'),
|
||||
|
||||
[
|
||||
'groups',
|
||||
t('Privacy Groups'),
|
||||
t('Enable management and selection of privacy groups'),
|
||||
true,
|
||||
get_config('feature_lock','groups'),
|
||||
feature_level('groups',0),
|
||||
],
|
||||
|
||||
[
|
||||
'multi_profiles',
|
||||
t('Multiple Profiles'),
|
||||
t('Ability to create multiple profiles'),
|
||||
false,
|
||||
get_config('feature_lock','multi_profiles'),
|
||||
feature_level('multi_profiles',3),
|
||||
],
|
||||
|
||||
|
||||
[
|
||||
'permcats',
|
||||
t('Permission Categories'),
|
||||
t('Create custom connection permission limits'),
|
||||
false,
|
||||
get_config('feature_lock','permcats'),
|
||||
feature_level('permcats',2),
|
||||
],
|
||||
|
||||
[
|
||||
'oauth_clients',
|
||||
t('OAuth1 Clients'),
|
||||
t('Manage OAuth1 authenticatication tokens for mobile and remote apps.'),
|
||||
false,
|
||||
get_config('feature_lock','oauth_clients'),
|
||||
feature_level('oauth_clients',1),
|
||||
],
|
||||
|
||||
[
|
||||
'oauth2_clients',
|
||||
t('OAuth2 Clients'),
|
||||
t('Manage OAuth2 authenticatication tokens for mobile and remote apps.'),
|
||||
false,
|
||||
get_config('feature_lock','oauth2_clients'),
|
||||
feature_level('oauth2_clients',1),
|
||||
],
|
||||
|
||||
[
|
||||
'access_tokens',
|
||||
t('Access Tokens'),
|
||||
t('Create access tokens so that non-members can access private content.'),
|
||||
false,
|
||||
get_config('feature_lock','access_tokens'),
|
||||
feature_level('access_tokens',2),
|
||||
],
|
||||
get_config('feature_lock','cal_first_day')
|
||||
]
|
||||
|
||||
],
|
||||
|
||||
// Post composition
|
||||
'composition' => [
|
||||
'channel_home' => [
|
||||
|
||||
t('Post Composition Features'),
|
||||
t('Channel Home'),
|
||||
|
||||
[
|
||||
'large_photos',
|
||||
t('Large Photos'),
|
||||
t('Include large (1024px) photo thumbnails in posts. If not enabled, use small (640px) photo thumbnails'),
|
||||
false,
|
||||
get_config('feature_lock','large_photos'),
|
||||
feature_level('large_photos',1),
|
||||
],
|
||||
|
||||
[
|
||||
'channel_sources',
|
||||
t('Channel Sources'),
|
||||
t('Automatically import channel content from other channels or feeds'),
|
||||
false,
|
||||
get_config('feature_lock','channel_sources'),
|
||||
feature_level('channel_sources',3),
|
||||
],
|
||||
|
||||
[
|
||||
'content_encrypt',
|
||||
t('Even More Encryption'),
|
||||
t('Allow optional encryption of content end-to-end with a shared secret key'),
|
||||
false,
|
||||
get_config('feature_lock','content_encrypt'),
|
||||
feature_level('content_encrypt',3),
|
||||
],
|
||||
|
||||
[
|
||||
'consensus_tools',
|
||||
t('Enable Voting Tools'),
|
||||
t('Provide a class of post which others can vote on'),
|
||||
false,
|
||||
get_config('feature_lock','consensus_tools'),
|
||||
feature_level('consensus_tools',3),
|
||||
],
|
||||
|
||||
[
|
||||
'disable_comments',
|
||||
t('Disable Comments'),
|
||||
t('Provide the option to disable comments for a post'),
|
||||
false,
|
||||
get_config('feature_lock','disable_comments'),
|
||||
feature_level('disable_comments',2),
|
||||
],
|
||||
|
||||
[
|
||||
'delayed_posting',
|
||||
t('Delayed Posting'),
|
||||
t('Allow posts to be published at a later date'),
|
||||
false,
|
||||
get_config('feature_lock','delayed_posting'),
|
||||
feature_level('delayed_posting',2),
|
||||
],
|
||||
|
||||
[
|
||||
'content_expire',
|
||||
t('Content Expiration'),
|
||||
t('Remove posts/comments and/or private messages at a future time'),
|
||||
false,
|
||||
get_config('feature_lock','content_expire'),
|
||||
feature_level('content_expire',1),
|
||||
],
|
||||
|
||||
[
|
||||
'suppress_duplicates',
|
||||
t('Suppress Duplicate Posts/Comments'),
|
||||
t('Prevent posts with identical content to be published with less than two minutes in between submissions.'),
|
||||
true,
|
||||
get_config('feature_lock','suppress_duplicates'),
|
||||
feature_level('suppress_duplicates',1),
|
||||
],
|
||||
|
||||
[
|
||||
'auto_save_draft',
|
||||
t('Auto-save drafts of posts and comments'),
|
||||
t('Automatically saves post and comment drafts in local browser storage to help prevent accidental loss of compositions'),
|
||||
true,
|
||||
get_config('feature_lock','auto_save_draft'),
|
||||
feature_level('auto_save_draft',1),
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
// Network Tools
|
||||
'net_module' => [
|
||||
|
||||
t('Network and Stream Filtering'),
|
||||
|
||||
[
|
||||
'archives',
|
||||
t('Search by Date'),
|
||||
'archives',
|
||||
t('Search by Date'),
|
||||
t('Ability to select posts by date ranges'),
|
||||
false,
|
||||
get_config('feature_lock','archives'),
|
||||
feature_level('archives',1),
|
||||
],
|
||||
|
||||
|
||||
[
|
||||
'savedsearch',
|
||||
t('Saved Searches'),
|
||||
t('Save search terms for re-use'),
|
||||
false,
|
||||
get_config('feature_lock','savedsearch'),
|
||||
feature_level('savedsearch',2),
|
||||
get_config('feature_lock','archives')
|
||||
],
|
||||
|
||||
[
|
||||
'order_tab',
|
||||
t('Alternate Stream Order'),
|
||||
t('Ability to order the stream by last post date, last comment date or unthreaded activities'),
|
||||
'tagadelic',
|
||||
t('Tag Cloud'),
|
||||
t('Provide a personal tag cloud on your channel page'),
|
||||
false,
|
||||
get_config('feature_lock','order_tab'),
|
||||
feature_level('order_tab',2),
|
||||
get_config('feature_lock','tagadelic'),
|
||||
],
|
||||
|
||||
[
|
||||
'name_tab',
|
||||
t('Contact Filter'),
|
||||
t('Ability to display only posts of a selected contact'),
|
||||
'channel_list_mode',
|
||||
t('Use blog/list mode'),
|
||||
t('Comments will be displayed separately'),
|
||||
false,
|
||||
get_config('feature_lock','name_tab'),
|
||||
feature_level('name_tab',1),
|
||||
],
|
||||
get_config('feature_lock','channel_list_mode'),
|
||||
]
|
||||
],
|
||||
|
||||
[
|
||||
'forums_tab',
|
||||
t('Forum Filter'),
|
||||
t('Ability to display only posts of a specific forum'),
|
||||
false,
|
||||
get_config('feature_lock','forums_tab'),
|
||||
feature_level('forums_tab',1),
|
||||
],
|
||||
'connections' => [
|
||||
|
||||
[
|
||||
'personal_tab',
|
||||
t('Personal Posts Filter'),
|
||||
t('Ability to display only posts that you\'ve interacted on'),
|
||||
false,
|
||||
get_config('feature_lock','personal_tab'),
|
||||
feature_level('personal_tab',1),
|
||||
],
|
||||
|
||||
[
|
||||
'affinity',
|
||||
t('Affinity Tool'),
|
||||
t('Filter stream activity by depth of relationships'),
|
||||
false,
|
||||
get_config('feature_lock','affinity'),
|
||||
feature_level('affinity',1),
|
||||
],
|
||||
|
||||
[
|
||||
'suggest',
|
||||
t('Suggest Channels'),
|
||||
t('Show friend and connection suggestions'),
|
||||
false,
|
||||
get_config('feature_lock','suggest'),
|
||||
feature_level('suggest',1),
|
||||
],
|
||||
t('Connections'),
|
||||
|
||||
[
|
||||
'connfilter',
|
||||
t('Connection Filtering'),
|
||||
t('Filter incoming posts from connections based on keywords/content'),
|
||||
false,
|
||||
get_config('feature_lock','connfilter'),
|
||||
feature_level('connfilter',3),
|
||||
],
|
||||
|
||||
|
||||
get_config('feature_lock','connfilter')
|
||||
]
|
||||
],
|
||||
|
||||
// Item tools
|
||||
'tools' => [
|
||||
'conversation' => [
|
||||
|
||||
t('Post/Comment Tools'),
|
||||
t('Conversation'),
|
||||
|
||||
[
|
||||
'commtag',
|
||||
@@ -462,16 +143,6 @@ function get_features($filtered = true, $level = (-1)) {
|
||||
t('Ability to tag existing posts'),
|
||||
false,
|
||||
get_config('feature_lock','commtag'),
|
||||
feature_level('commtag',1),
|
||||
],
|
||||
|
||||
[
|
||||
'categories',
|
||||
t('Post Categories'),
|
||||
t('Add categories to your posts'),
|
||||
false,
|
||||
get_config('feature_lock','categories'),
|
||||
feature_level('categories',1),
|
||||
],
|
||||
|
||||
[
|
||||
@@ -480,16 +151,6 @@ function get_features($filtered = true, $level = (-1)) {
|
||||
t('Add emoji reaction ability to posts'),
|
||||
true,
|
||||
get_config('feature_lock','emojis'),
|
||||
feature_level('emojis',1),
|
||||
],
|
||||
|
||||
[
|
||||
'filing',
|
||||
t('Saved Folders'),
|
||||
t('Ability to file posts under folders'),
|
||||
false,
|
||||
get_config('feature_lock','filing'),
|
||||
feature_level('filing',2),
|
||||
],
|
||||
|
||||
[
|
||||
@@ -498,7 +159,6 @@ function get_features($filtered = true, $level = (-1)) {
|
||||
t('Ability to dislike posts/comments'),
|
||||
false,
|
||||
get_config('feature_lock','dislike'),
|
||||
feature_level('dislike',1),
|
||||
],
|
||||
|
||||
[
|
||||
@@ -507,18 +167,270 @@ function get_features($filtered = true, $level = (-1)) {
|
||||
t('Ability to mark special posts with a star indicator'),
|
||||
false,
|
||||
get_config('feature_lock','star_posts'),
|
||||
feature_level('star_posts',1),
|
||||
]
|
||||
|
||||
],
|
||||
|
||||
'directory' => [
|
||||
|
||||
t('Directory'),
|
||||
|
||||
[
|
||||
'advanced_dirsearch',
|
||||
t('Advanced Directory Search'),
|
||||
t('Allows creation of complex directory search queries'),
|
||||
false,
|
||||
get_config('feature_lock','advanced_dirsearch'),
|
||||
]
|
||||
|
||||
],
|
||||
|
||||
'editor' => [
|
||||
|
||||
t('Editor'),
|
||||
|
||||
[
|
||||
'categories',
|
||||
t('Post Categories'),
|
||||
t('Add categories to your posts'),
|
||||
false,
|
||||
get_config('feature_lock','categories'),
|
||||
feature_level('categories',1),
|
||||
],
|
||||
|
||||
[
|
||||
'tagadelic',
|
||||
t('Tag Cloud'),
|
||||
t('Provide a personal tag cloud on your channel page'),
|
||||
'large_photos',
|
||||
t('Large Photos'),
|
||||
t('Include large (1024px) photo thumbnails in posts. If not enabled, use small (640px) photo thumbnails'),
|
||||
false,
|
||||
get_config('feature_lock','tagadelic'),
|
||||
feature_level('tagadelic',2),
|
||||
get_config('feature_lock','large_photos'),
|
||||
],
|
||||
|
||||
[
|
||||
'content_encrypt',
|
||||
t('Even More Encryption'),
|
||||
t('Allow optional encryption of content end-to-end with a shared secret key'),
|
||||
false,
|
||||
get_config('feature_lock','content_encrypt'),
|
||||
],
|
||||
|
||||
[
|
||||
'consensus_tools',
|
||||
t('Enable Voting Tools'),
|
||||
t('Provide a class of post which others can vote on'),
|
||||
false,
|
||||
get_config('feature_lock','consensus_tools'),
|
||||
],
|
||||
|
||||
[
|
||||
'disable_comments',
|
||||
t('Disable Comments'),
|
||||
t('Provide the option to disable comments for a post'),
|
||||
false,
|
||||
get_config('feature_lock','disable_comments'),
|
||||
],
|
||||
|
||||
[
|
||||
'delayed_posting',
|
||||
t('Delayed Posting'),
|
||||
t('Allow posts to be published at a later date'),
|
||||
false,
|
||||
get_config('feature_lock','delayed_posting'),
|
||||
],
|
||||
|
||||
[
|
||||
'content_expire',
|
||||
t('Content Expiration'),
|
||||
t('Remove posts/comments and/or private messages at a future time'),
|
||||
false,
|
||||
get_config('feature_lock','content_expire'),
|
||||
],
|
||||
|
||||
[
|
||||
'suppress_duplicates',
|
||||
t('Suppress Duplicate Posts/Comments'),
|
||||
t('Prevent posts with identical content to be published with less than two minutes in between submissions.'),
|
||||
true,
|
||||
get_config('feature_lock','suppress_duplicates'),
|
||||
],
|
||||
|
||||
[
|
||||
'auto_save_draft',
|
||||
t('Auto-save drafts of posts and comments'),
|
||||
t('Automatically saves post and comment drafts in local browser storage to help prevent accidental loss of compositions'),
|
||||
true,
|
||||
get_config('feature_lock','auto_save_draft'),
|
||||
]
|
||||
|
||||
],
|
||||
|
||||
'events' => [
|
||||
|
||||
t('Events'),
|
||||
|
||||
[
|
||||
'events_cal_first_day',
|
||||
t('Start calendar week on Monday'),
|
||||
t('Default is Sunday'),
|
||||
false,
|
||||
get_config('feature_lock','events_cal_first_day')
|
||||
],
|
||||
|
||||
[
|
||||
'smart_birthdays',
|
||||
t('Smart Birthdays'),
|
||||
t('Make birthday events timezone aware in case your friends are scattered across the planet.'),
|
||||
true,
|
||||
get_config('feature_lock','smart_birthdays'),
|
||||
],
|
||||
|
||||
[
|
||||
'event_tz_select',
|
||||
t('Event Timezone Selection'),
|
||||
t('Allow event creation in timezones other than your own.'),
|
||||
false,
|
||||
get_config('feature_lock','event_tz_select'),
|
||||
]
|
||||
|
||||
],
|
||||
|
||||
'manage' => [
|
||||
|
||||
t('Manage'),
|
||||
|
||||
[
|
||||
'nav_channel_select',
|
||||
t('Navigation Channel Select'),
|
||||
t('Change channels directly from within the navigation dropdown menu'),
|
||||
false,
|
||||
get_config('feature_lock','nav_channel_select'),
|
||||
]
|
||||
|
||||
],
|
||||
|
||||
'network' => [
|
||||
|
||||
t('Network'),
|
||||
|
||||
[
|
||||
'savedsearch',
|
||||
t('Saved Searches'),
|
||||
t('Save search terms for re-use'),
|
||||
false,
|
||||
get_config('feature_lock','savedsearch')
|
||||
],
|
||||
|
||||
[
|
||||
'filing',
|
||||
t('Saved Folders'),
|
||||
t('Ability to file posts under folders'),
|
||||
false,
|
||||
get_config('feature_lock','filing'),
|
||||
],
|
||||
|
||||
[
|
||||
'order_tab',
|
||||
t('Alternate Stream Order'),
|
||||
t('Ability to order the stream by last post date, last comment date or unthreaded activities'),
|
||||
false,
|
||||
get_config('feature_lock','order_tab')
|
||||
],
|
||||
|
||||
[
|
||||
'name_tab',
|
||||
t('Contact Filter'),
|
||||
t('Ability to display only posts of a selected contact'),
|
||||
false,
|
||||
get_config('feature_lock','name_tab')
|
||||
],
|
||||
|
||||
[
|
||||
'forums_tab',
|
||||
t('Forum Filter'),
|
||||
t('Ability to display only posts of a specific forum'),
|
||||
false,
|
||||
get_config('feature_lock','forums_tab')
|
||||
],
|
||||
|
||||
[
|
||||
'personal_tab',
|
||||
t('Personal Posts Filter'),
|
||||
t('Ability to display only posts that you\'ve interacted on'),
|
||||
false,
|
||||
get_config('feature_lock','personal_tab')
|
||||
],
|
||||
|
||||
[
|
||||
'affinity',
|
||||
t('Affinity Tool'),
|
||||
t('Filter stream activity by depth of relationships'),
|
||||
false,
|
||||
get_config('feature_lock','affinity')
|
||||
],
|
||||
|
||||
[
|
||||
'suggest',
|
||||
t('Suggest Channels'),
|
||||
t('Show friend and connection suggestions'),
|
||||
false,
|
||||
get_config('feature_lock','suggest')
|
||||
],
|
||||
|
||||
[
|
||||
'network_list_mode',
|
||||
t('Use blog/list mode'),
|
||||
t('Comments will be displayed separately'),
|
||||
false,
|
||||
get_config('feature_lock','network_list_mode'),
|
||||
]
|
||||
|
||||
],
|
||||
|
||||
'photos' => [
|
||||
|
||||
t('Photos'),
|
||||
|
||||
[
|
||||
'photo_location',
|
||||
t('Photo Location'),
|
||||
t('If location data is available on uploaded photos, link this to a map.'),
|
||||
false,
|
||||
get_config('feature_lock','photo_location'),
|
||||
]
|
||||
|
||||
],
|
||||
|
||||
'profiles' => [
|
||||
|
||||
t('Profiles'),
|
||||
|
||||
[
|
||||
'advanced_profiles',
|
||||
t('Advanced Profiles'),
|
||||
t('Additional profile sections and selections'),
|
||||
false,
|
||||
get_config('feature_lock','advanced_profiles')
|
||||
],
|
||||
|
||||
[
|
||||
'profile_export',
|
||||
t('Profile Import/Export'),
|
||||
t('Save and load profile details across sites/channels'),
|
||||
false,
|
||||
get_config('feature_lock','profile_export')
|
||||
],
|
||||
|
||||
[
|
||||
'multi_profiles',
|
||||
t('Multiple Profiles'),
|
||||
t('Ability to create multiple profiles'),
|
||||
false,
|
||||
get_config('feature_lock','multi_profiles')
|
||||
]
|
||||
|
||||
]
|
||||
|
||||
|
||||
];
|
||||
|
||||
$x = [ 'features' => $arr, ];
|
||||
@@ -526,8 +438,6 @@ function get_features($filtered = true, $level = (-1)) {
|
||||
|
||||
$arr = $x['features'];
|
||||
|
||||
$techlevel = (($level >= 0) ? $level : get_account_techlevel());
|
||||
|
||||
// removed any locked features and remove the entire category if this makes it empty
|
||||
|
||||
if($filtered) {
|
||||
@@ -538,9 +448,6 @@ function get_features($filtered = true, $level = (-1)) {
|
||||
for($y = 0; $y < count($arr[$k]); $y ++) {
|
||||
$disabled = false;
|
||||
if(is_array($arr[$k][$y])) {
|
||||
if($arr[$k][$y][5] > $techlevel) {
|
||||
$disabled = true;
|
||||
}
|
||||
if($arr[$k][$y][4] !== false) {
|
||||
$disabled = true;
|
||||
}
|
||||
@@ -561,3 +468,8 @@ function get_features($filtered = true, $level = (-1)) {
|
||||
|
||||
return $narr;
|
||||
}
|
||||
|
||||
function get_module_features($module) {
|
||||
$features = get_features(false);
|
||||
return $features[$module];
|
||||
}
|
||||
|
||||
@@ -14,11 +14,11 @@ function group_add($uid,$name,$public = 0) {
|
||||
// access lists. What we're doing here is reviving the dead group, but old content which
|
||||
// was restricted to this group may now be seen by the new group members.
|
||||
|
||||
$z = q("SELECT * FROM groups WHERE id = %d LIMIT 1",
|
||||
$z = q("SELECT * FROM pgrp WHERE id = %d LIMIT 1",
|
||||
intval($r)
|
||||
);
|
||||
if(($z) && $z[0]['deleted']) {
|
||||
q('UPDATE groups SET deleted = 0 WHERE id = %d', intval($z[0]['id']));
|
||||
q('UPDATE pgrp SET deleted = 0 WHERE id = %d', intval($z[0]['id']));
|
||||
notice( t('A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name.') . EOL);
|
||||
}
|
||||
return true;
|
||||
@@ -28,13 +28,13 @@ function group_add($uid,$name,$public = 0) {
|
||||
$dups = false;
|
||||
$hash = random_string() . $name;
|
||||
|
||||
$r = q("SELECT id FROM groups WHERE hash = '%s' LIMIT 1", dbesc($hash));
|
||||
$r = q("SELECT id FROM pgrp WHERE hash = '%s' LIMIT 1", dbesc($hash));
|
||||
if($r)
|
||||
$dups = true;
|
||||
} while($dups == true);
|
||||
|
||||
|
||||
$r = q("INSERT INTO groups ( hash, uid, visible, gname )
|
||||
$r = q("INSERT INTO pgrp ( hash, uid, visible, gname )
|
||||
VALUES( '%s', %d, %d, '%s' ) ",
|
||||
dbesc($hash),
|
||||
intval($uid),
|
||||
@@ -53,7 +53,7 @@ function group_add($uid,$name,$public = 0) {
|
||||
function group_rmv($uid,$name) {
|
||||
$ret = false;
|
||||
if(x($uid) && x($name)) {
|
||||
$r = q("SELECT id, hash FROM groups WHERE uid = %d AND gname = '%s' LIMIT 1",
|
||||
$r = q("SELECT id, hash FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($name)
|
||||
);
|
||||
@@ -98,13 +98,13 @@ function group_rmv($uid,$name) {
|
||||
}
|
||||
|
||||
// remove all members
|
||||
$r = q("DELETE FROM group_member WHERE uid = %d AND gid = %d ",
|
||||
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d ",
|
||||
intval($uid),
|
||||
intval($group_id)
|
||||
);
|
||||
|
||||
// remove group
|
||||
$r = q("UPDATE groups SET deleted = 1 WHERE uid = %d AND gname = '%s'",
|
||||
$r = q("UPDATE pgrp SET deleted = 1 WHERE uid = %d AND gname = '%s'",
|
||||
intval($uid),
|
||||
dbesc($name)
|
||||
);
|
||||
@@ -121,7 +121,7 @@ function group_rmv($uid,$name) {
|
||||
function group_byname($uid,$name) {
|
||||
if((! $uid) || (! strlen($name)))
|
||||
return false;
|
||||
$r = q("SELECT * FROM groups WHERE uid = %d AND gname = '%s' LIMIT 1",
|
||||
$r = q("SELECT * FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($name)
|
||||
);
|
||||
@@ -134,7 +134,7 @@ function group_byname($uid,$name) {
|
||||
function group_rec_byhash($uid,$hash) {
|
||||
if((! $uid) || (! strlen($hash)))
|
||||
return false;
|
||||
$r = q("SELECT * FROM groups WHERE uid = %d AND hash = '%s' LIMIT 1",
|
||||
$r = q("SELECT * FROM pgrp WHERE uid = %d AND hash = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($hash)
|
||||
);
|
||||
@@ -149,7 +149,7 @@ function group_rmv_member($uid,$name,$member) {
|
||||
return false;
|
||||
if(! ( $uid && $gid && $member))
|
||||
return false;
|
||||
$r = q("DELETE FROM group_member WHERE uid = %d AND gid = %d AND xchan = '%s' ",
|
||||
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' ",
|
||||
intval($uid),
|
||||
intval($gid),
|
||||
dbesc($member)
|
||||
@@ -169,7 +169,7 @@ function group_add_member($uid,$name,$member,$gid = 0) {
|
||||
if((! $gid) || (! $uid) || (! $member))
|
||||
return false;
|
||||
|
||||
$r = q("SELECT * FROM group_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1",
|
||||
$r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
intval($gid),
|
||||
dbesc($member)
|
||||
@@ -179,7 +179,7 @@ function group_add_member($uid,$name,$member,$gid = 0) {
|
||||
// we indicate success because the group member was in fact created
|
||||
// -- It was just created at another time
|
||||
if(! $r)
|
||||
$r = q("INSERT INTO group_member (uid, gid, xchan)
|
||||
$r = q("INSERT INTO pgrp_member (uid, gid, xchan)
|
||||
VALUES( %d, %d, '%s' ) ",
|
||||
intval($uid),
|
||||
intval($gid),
|
||||
@@ -194,9 +194,9 @@ function group_add_member($uid,$name,$member,$gid = 0) {
|
||||
function group_get_members($gid) {
|
||||
$ret = array();
|
||||
if(intval($gid)) {
|
||||
$r = q("SELECT * FROM group_member
|
||||
LEFT JOIN abook ON abook_xchan = group_member.xchan left join xchan on xchan_hash = abook_xchan
|
||||
WHERE gid = %d AND abook_channel = %d and group_member.uid = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ",
|
||||
$r = q("SELECT * FROM pgrp_member
|
||||
LEFT JOIN abook ON abook_xchan = pgrp_member.xchan left join xchan on xchan_hash = abook_xchan
|
||||
WHERE gid = %d AND abook_channel = %d and pgrp_member.uid = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ",
|
||||
intval($gid),
|
||||
intval(local_channel()),
|
||||
intval(local_channel())
|
||||
@@ -210,7 +210,7 @@ function group_get_members($gid) {
|
||||
function group_get_members_xchan($gid) {
|
||||
$ret = array();
|
||||
if(intval($gid)) {
|
||||
$r = q("SELECT xchan FROM group_member WHERE gid = %d AND uid = %d",
|
||||
$r = q("SELECT xchan FROM pgrp_member WHERE gid = %d AND uid = %d",
|
||||
intval($gid),
|
||||
intval(local_channel())
|
||||
);
|
||||
@@ -248,7 +248,7 @@ function mini_group_select($uid,$group = '') {
|
||||
$grps = array();
|
||||
$o = '';
|
||||
|
||||
$r = q("SELECT * FROM groups WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval($uid)
|
||||
);
|
||||
$grps[] = array('name' => '', 'hash' => '0', 'selected' => '');
|
||||
@@ -274,13 +274,13 @@ function group_side($every="connections",$each="group",$edit = false, $group_id
|
||||
|
||||
$o = '';
|
||||
|
||||
if(! (local_channel() && feature_enabled(local_channel(),'groups'))) {
|
||||
if(! (local_channel() && \Zotlabs\Lib\Apps::system_app_installed(local_channel(), 'Privacy Groups'))) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$groups = array();
|
||||
|
||||
$r = q("SELECT * FROM groups WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval($_SESSION['uid'])
|
||||
);
|
||||
$member_of = array();
|
||||
@@ -361,7 +361,7 @@ function expand_groups($g) {
|
||||
stringify_array_elms($x,true);
|
||||
$groups = implode(',', $x);
|
||||
if($groups) {
|
||||
$r = q("SELECT xchan FROM group_member WHERE gid IN ( select id from groups where hash in ( $groups ))");
|
||||
$r = q("SELECT xchan FROM pgrp_member WHERE gid IN ( select id from pgrp where hash in ( $groups ))");
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$ret[] = $rr['xchan'];
|
||||
@@ -375,7 +375,7 @@ function expand_groups($g) {
|
||||
|
||||
function member_of($c) {
|
||||
|
||||
$r = q("SELECT groups.gname, groups.id FROM groups LEFT JOIN group_member ON group_member.gid = groups.id WHERE group_member.xchan = '%s' AND groups.deleted = 0 ORDER BY groups.gname ASC ",
|
||||
$r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id WHERE pgrp_member.xchan = '%s' AND pgrp.deleted = 0 ORDER BY pgrp.gname ASC ",
|
||||
dbesc($c)
|
||||
);
|
||||
|
||||
@@ -385,7 +385,7 @@ function member_of($c) {
|
||||
|
||||
function groups_containing($uid,$c) {
|
||||
|
||||
$r = q("SELECT gid FROM group_member WHERE uid = %d AND group_member.xchan = '%s' ",
|
||||
$r = q("SELECT gid FROM pgrp_member WHERE uid = %d AND pgrp_member.xchan = '%s' ",
|
||||
intval($uid),
|
||||
dbesc($c)
|
||||
);
|
||||
|
||||
@@ -2,6 +2,50 @@
|
||||
|
||||
use \Michelf\MarkdownExtra;
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param string $path
|
||||
* @return string|unknown
|
||||
*/
|
||||
function get_help_fullpath($path,$suffix=null) {
|
||||
|
||||
$docroot = (\App::$override_helproot) ? \App::$override_helproot : 'doc/';
|
||||
$docroot = (substr($docroot,-1)!='/') ? $docroot .= '/' : $docroot;
|
||||
|
||||
// Determine the language and modify the path accordingly
|
||||
$x = determine_help_language();
|
||||
$lang = $x['language'];
|
||||
$url_idx = ($x['from_url'] ? 1 : 0);
|
||||
// The English translation is at the root of /doc/. Other languages are in
|
||||
// subfolders named by the language code such as "de", "es", etc.
|
||||
if($lang !== 'en') {
|
||||
$langpath = $lang . '/' . $path;
|
||||
} else {
|
||||
$langpath = $path;
|
||||
}
|
||||
|
||||
$newpath = (isset(\App::$override_helpfiles[$langpath])) ? \App::$override_helpfiles[$langpath] : $langpath;
|
||||
$newpath = ($newpath == $langpath) ? $docroot . $newpath : $newpath;
|
||||
|
||||
if ($suffix) {
|
||||
if (file_exists($newpath . $suffix)) {
|
||||
return $newpath;
|
||||
}
|
||||
} elseif (file_exists($newpath . '.md') ||
|
||||
file_exists($newpath . '.bb') ||
|
||||
file_exists($newpath . '.html')) {
|
||||
return $newpath;
|
||||
}
|
||||
|
||||
$newpath = (isset(\App::$override_helpfiles[$path])) ? \App::$override_helpfiles[$path] : null;
|
||||
|
||||
$newpath = (!$newpath) ? $docroot.$path : $newpath;
|
||||
return $newpath;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
@@ -9,7 +53,6 @@ use \Michelf\MarkdownExtra;
|
||||
* @return string|unknown
|
||||
*/
|
||||
function get_help_content($tocpath = false) {
|
||||
|
||||
global $lang;
|
||||
|
||||
$doctype = 'markdown';
|
||||
@@ -17,6 +60,8 @@ function get_help_content($tocpath = false) {
|
||||
$text = '';
|
||||
|
||||
$path = (($tocpath !== false) ? $tocpath : '');
|
||||
$docroot = (\App::$override_helproot) ? \App::$override_helproot : 'doc/';
|
||||
$docroot = (substr($docroot,-1)!='/') ? $docroot .= '/' : $docroot;
|
||||
|
||||
if($tocpath === false && argc() > 1) {
|
||||
$path = '';
|
||||
@@ -27,8 +72,9 @@ function get_help_content($tocpath = false) {
|
||||
}
|
||||
}
|
||||
|
||||
if($path) {
|
||||
|
||||
if($path) {
|
||||
$fullpath = get_help_fullpath($path);
|
||||
$title = basename($path);
|
||||
if(! $tocpath)
|
||||
\App::$page['title'] = t('Help:') . ' ' . ucwords(str_replace('-',' ',notags($title)));
|
||||
@@ -39,21 +85,22 @@ function get_help_content($tocpath = false) {
|
||||
// TODO: This is incompatible with the hierarchical TOC construction
|
||||
// defined in /Zotlabs/Widget/Helpindex.php.
|
||||
if($tocpath !== false &&
|
||||
load_doc_file('doc/' . $path . '.md') === '' &&
|
||||
load_doc_file('doc/' . $path . '.bb') === '' &&
|
||||
load_doc_file('doc/' . $path . '.html') === ''
|
||||
load_doc_file($fullpath . '.md') === '' &&
|
||||
load_doc_file($fullpath . '.bb') === '' &&
|
||||
load_doc_file($fullpath . '.html') === ''
|
||||
) {
|
||||
$path = $title;
|
||||
}
|
||||
$text = load_doc_file('doc/' . $path . '.md');
|
||||
$fullpath = get_help_fullpath($path);
|
||||
$text = load_doc_file($fullpath . '.md');
|
||||
|
||||
if(! $text) {
|
||||
$text = load_doc_file('doc/' . $path . '.bb');
|
||||
$text = load_doc_file($fullpath . '.bb');
|
||||
if($text)
|
||||
$doctype = 'bbcode';
|
||||
}
|
||||
if(! $text) {
|
||||
$text = load_doc_file('doc/' . $path . '.html');
|
||||
$text = load_doc_file($fullpath . '.html');
|
||||
if($text)
|
||||
$doctype = 'html';
|
||||
}
|
||||
@@ -64,12 +111,16 @@ function get_help_content($tocpath = false) {
|
||||
|
||||
if($tocpath === false) {
|
||||
if(! $text) {
|
||||
$text = load_doc_file('doc/Site.md');
|
||||
$path = 'Site';
|
||||
$fullpath = get_help_fullpath($path,'.md');
|
||||
$text = load_doc_file($fullpath . '.md');
|
||||
\App::$page['title'] = t('Help');
|
||||
}
|
||||
if(! $text) {
|
||||
$doctype = 'bbcode';
|
||||
$text = load_doc_file('doc/main.bb');
|
||||
$path = 'main';
|
||||
$fullpath = get_help_fullpath($path,'.md');
|
||||
$text = load_doc_file($fullpath . '.bb');
|
||||
goaway('/help/about/about');
|
||||
\App::$page['title'] = t('Help');
|
||||
}
|
||||
@@ -146,35 +197,7 @@ function determine_help_language() {
|
||||
}
|
||||
|
||||
function load_doc_file($s) {
|
||||
$path = 'doc';
|
||||
// Determine the language and modify the path accordingly
|
||||
$x = determine_help_language();
|
||||
$lang = $x['language'];
|
||||
$url_idx = ($x['from_url'] ? 1 : 0);
|
||||
// The English translation is at the root of /doc/. Other languages are in
|
||||
// subfolders named by the language code such as "de", "es", etc.
|
||||
if($lang !== 'en') {
|
||||
$path .= '/' . $lang;
|
||||
}
|
||||
|
||||
$b = basename($s);
|
||||
|
||||
for($i=1+$url_idx; $i<argc()-1; $i++) {
|
||||
$path .= '/' . argv($i);
|
||||
}
|
||||
$c = find_doc_file($path . '/' . $b);
|
||||
if($c)
|
||||
return $c;
|
||||
// Possibly a translation was requested that has not been translated, so fall
|
||||
// back to the English version
|
||||
$path = 'doc';
|
||||
for($i=1+$url_idx; $i<argc()-1; $i++) {
|
||||
$path .= '/' . argv($i);
|
||||
}
|
||||
$c = find_doc_file($path . '/' . $b);
|
||||
if($c)
|
||||
return $c;
|
||||
// Try one last time to find the file at the explicit path input to the function
|
||||
$c = find_doc_file($s);
|
||||
if($c)
|
||||
return $c;
|
||||
|
||||
@@ -24,6 +24,8 @@ function hubloc_store_lowlevel($arr) {
|
||||
'hubloc_status' => ((array_key_exists('hubloc_status',$arr)) ? $arr['hubloc_status'] : 0),
|
||||
'hubloc_url' => ((array_key_exists('hubloc_url',$arr)) ? $arr['hubloc_url'] : ''),
|
||||
'hubloc_url_sig' => ((array_key_exists('hubloc_url_sig',$arr)) ? $arr['hubloc_url_sig'] : ''),
|
||||
'hubloc_id_url' => ((array_key_exists('hubloc_id_url',$arr)) ? $arr['hubloc_id_url'] : ''),
|
||||
'hubloc_site_id' => ((array_key_exists('hubloc_site_id',$arr)) ? $arr['hubloc_site_id'] : ''),
|
||||
'hubloc_host' => ((array_key_exists('hubloc_host',$arr)) ? $arr['hubloc_host'] : ''),
|
||||
'hubloc_callback' => ((array_key_exists('hubloc_callback',$arr)) ? $arr['hubloc_callback'] : ''),
|
||||
'hubloc_connect' => ((array_key_exists('hubloc_connect',$arr)) ? $arr['hubloc_connect'] : ''),
|
||||
|
||||
@@ -93,7 +93,8 @@ function import_channel($channel, $account_id, $seize, $newname = '') {
|
||||
'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall',
|
||||
'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish',
|
||||
'channel_a_delegate', 'perm_limits', 'channel_password', 'channel_salt',
|
||||
'channel_moved'
|
||||
'channel_moved', 'channel_primary', 'channel_removed', 'channel_deleted',
|
||||
'channel_system'
|
||||
];
|
||||
|
||||
$clean = array();
|
||||
@@ -234,7 +235,7 @@ function import_hublocs($channel, $hublocs, $seize, $moving = false) {
|
||||
|
||||
if(($x = zot_gethub($arr,false)) === false) {
|
||||
unset($hubloc['hubloc_id']);
|
||||
create_table_from_array('hubloc', $hubloc);
|
||||
hubloc_store_lowlevel($hubloc);
|
||||
}
|
||||
else {
|
||||
q("UPDATE hubloc set hubloc_primary = %d, hubloc_deleted = %d where hubloc_id = %d",
|
||||
|
||||
@@ -4,7 +4,13 @@
|
||||
* @brief Items related functions.
|
||||
*/
|
||||
|
||||
use Zotlabs\Lib as Zlib;
|
||||
use Zotlabs\Lib\Enotify;
|
||||
use Zotlabs\Lib\MarkdownSoap;
|
||||
use Zotlabs\Lib\MessageFilter;
|
||||
use Zotlabs\Lib\IConfig;
|
||||
use Zotlabs\Access\PermissionLimits;
|
||||
use Zotlabs\Access\AccessList;
|
||||
use Zotlabs\Daemon\Master;
|
||||
|
||||
require_once('include/bbcode.php');
|
||||
require_once('include/oembed.php');
|
||||
@@ -234,10 +240,11 @@ function can_comment_on_post($observer_xchan, $item) {
|
||||
// logger('Comment_policy: ' . $item['comment_policy'], LOGGER_DEBUG);
|
||||
|
||||
$x = [
|
||||
'observer_hash' => $observer_xchan,
|
||||
'item' => $item,
|
||||
'allowed' => 'unset'
|
||||
'observer_hash' => $observer_xchan,
|
||||
'item' => $item,
|
||||
'allowed' => 'unset'
|
||||
];
|
||||
|
||||
/**
|
||||
* @hooks can_comment_on_post
|
||||
* Called when deciding whether or not to present a comment box for a post.
|
||||
@@ -245,26 +252,34 @@ function can_comment_on_post($observer_xchan, $item) {
|
||||
* * \e array \b item
|
||||
* * \e boolean \b allowed - return value
|
||||
*/
|
||||
|
||||
call_hooks('can_comment_on_post', $x);
|
||||
if($x['allowed'] !== 'unset')
|
||||
|
||||
if($x['allowed'] !== 'unset') {
|
||||
return $x['allowed'];
|
||||
}
|
||||
|
||||
if(! $observer_xchan)
|
||||
if(! $observer_xchan) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if($item['comment_policy'] === 'none')
|
||||
if($item['comment_policy'] === 'none') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(comments_are_now_closed($item))
|
||||
if(comments_are_now_closed($item)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if($observer_xchan === $item['author_xchan'] || $observer_xchan === $item['owner_xchan'])
|
||||
if($observer_xchan === $item['author_xchan'] || $observer_xchan === $item['owner_xchan']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch($item['comment_policy']) {
|
||||
case 'self':
|
||||
if($observer_xchan === $item['author_xchan'] || $observer_xchan === $item['owner_xchan'])
|
||||
if($observer_xchan === $item['author_xchan'] || $observer_xchan === $item['owner_xchan']) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 'public':
|
||||
case 'authenticated':
|
||||
@@ -276,17 +291,22 @@ function can_comment_on_post($observer_xchan, $item) {
|
||||
case 'any connections':
|
||||
case 'contacts':
|
||||
case '':
|
||||
if(array_key_exists('owner',$item) && get_abconfig($item['uid'],$item['owner']['abook_xchan'],'their_perms','post_comments')) {
|
||||
return true;
|
||||
if(local_channel() && get_abconfig(local_channel(),$item['owner_xchan'],'their_perms','post_comments')) {
|
||||
return true;
|
||||
}
|
||||
if(intval($item['item_wall']) && perm_is_allowed($item['uid'],$observer_xchan,'post_comments')) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'red'))
|
||||
if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'red')) {
|
||||
return true;
|
||||
if(strstr($item['comment_policy'],'site:') && strstr($item['comment_policy'],App::get_hostname()))
|
||||
}
|
||||
if(strstr($item['comment_policy'],'site:') && strstr($item['comment_policy'],App::get_hostname())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -365,7 +385,7 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$arr['public_policy'] = ((array_key_exists('public_policy',$arr)) ? escape_tags($arr['public_policy']) : map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_stream'),true));
|
||||
$arr['public_policy'] = ((array_key_exists('public_policy',$arr)) ? escape_tags($arr['public_policy']) : map_scope(PermissionLimits::Get($channel['channel_id'],'view_stream'),true));
|
||||
|
||||
if($arr['public_policy'])
|
||||
$arr['item_private'] = 1;
|
||||
@@ -393,7 +413,7 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
|
||||
$arr['deny_gid'] = $channel['channel_deny_gid'];
|
||||
}
|
||||
|
||||
$arr['comment_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'post_comments'));
|
||||
$arr['comment_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'],'post_comments'));
|
||||
|
||||
if ((! $arr['plink']) && (intval($arr['item_thread_top']))) {
|
||||
$arr['plink'] = substr(z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']),0,190);
|
||||
@@ -432,7 +452,7 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
|
||||
}
|
||||
|
||||
if($post_id && $deliver) {
|
||||
Zotlabs\Daemon\Master::Summon(array('Notifier','activity',$post_id));
|
||||
Master::Summon([ 'Notifier','activity',$post_id ]);
|
||||
}
|
||||
|
||||
$ret['success'] = true;
|
||||
@@ -730,7 +750,7 @@ function get_item_elements($x,$allow_code = false) {
|
||||
// was generated on the escaped content.
|
||||
|
||||
if($arr['mimetype'] === 'text/markdown')
|
||||
$arr['body'] = \Zotlabs\Lib\MarkdownSoap::unescape($arr['body']);
|
||||
$arr['body'] = MarkdownSoap::unescape($arr['body']);
|
||||
|
||||
if(array_key_exists('revision',$x)) {
|
||||
|
||||
@@ -989,7 +1009,7 @@ function encode_item($item,$mirror = false) {
|
||||
);
|
||||
|
||||
if($r)
|
||||
$comment_scope = \Zotlabs\Access\PermissionLimits::Get($item['uid'],'post_comments');
|
||||
$comment_scope = PermissionLimits::Get($item['uid'],'post_comments');
|
||||
else
|
||||
$comment_scope = 0;
|
||||
|
||||
@@ -2425,7 +2445,7 @@ function send_status_notifications($post_id,$item) {
|
||||
return;
|
||||
|
||||
|
||||
Zlib\Enotify::submit(array(
|
||||
Enotify::submit(array(
|
||||
'type' => NOTIFY_COMMENT,
|
||||
'from_xchan' => $item['author_xchan'],
|
||||
'to_xchan' => $r[0]['channel_hash'],
|
||||
@@ -2518,7 +2538,7 @@ function tag_deliver($uid, $item_id) {
|
||||
|
||||
$verb = urldecode(substr($item['verb'],strpos($item['verb'],'#')+1));
|
||||
if($poke_notify) {
|
||||
Zlib\Enotify::submit(array(
|
||||
Enotify::submit(array(
|
||||
'to_xchan' => $u[0]['channel_hash'],
|
||||
'from_xchan' => $item['author_xchan'],
|
||||
'type' => NOTIFY_POKE,
|
||||
@@ -2672,7 +2692,7 @@ function tag_deliver($uid, $item_id) {
|
||||
* Kill two birds with one stone. As long as we're here, send a mention notification.
|
||||
*/
|
||||
|
||||
Zlib\Enotify::submit(array(
|
||||
Enotify::submit(array(
|
||||
'to_xchan' => $u[0]['channel_hash'],
|
||||
'from_xchan' => $item['author_xchan'],
|
||||
'type' => NOTIFY_TAGSELF,
|
||||
@@ -2974,7 +2994,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent) {
|
||||
$private = (($channel['channel_allow_cid'] || $channel['channel_allow_gid']
|
||||
|| $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 1 : 0);
|
||||
|
||||
$new_public_policy = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_stream'),true);
|
||||
$new_public_policy = map_scope(PermissionLimits::Get($channel['channel_id'],'view_stream'),true);
|
||||
|
||||
if((! $private) && $new_public_policy)
|
||||
$private = 1;
|
||||
@@ -3017,7 +3037,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent) {
|
||||
dbesc($channel['channel_deny_gid']),
|
||||
intval($private),
|
||||
dbesc($new_public_policy),
|
||||
dbesc(map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'post_comments'))),
|
||||
dbesc(map_scope(PermissionLimits::Get($channel['channel_id'],'post_comments'))),
|
||||
dbesc($title),
|
||||
dbesc($body),
|
||||
intval($item_wall),
|
||||
@@ -3026,7 +3046,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent) {
|
||||
);
|
||||
|
||||
if($r)
|
||||
Zotlabs\Daemon\Master::Summon(array('Notifier','tgroup',$item_id));
|
||||
Master::Summon([ 'Notifier','tgroup',$item_id ]);
|
||||
else {
|
||||
logger('start_delivery_chain: failed to update item');
|
||||
// reset the source xchan to prevent loops
|
||||
@@ -3091,7 +3111,7 @@ function check_item_source($uid, $item) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (\Zotlabs\Lib\MessageFilter::evaluate($item, $r[0]['src_patt'], EMPTY_STR)) {
|
||||
if (MessageFilter::evaluate($item, $r[0]['src_patt'], EMPTY_STR)) {
|
||||
logger('source: text filter success');
|
||||
return true;
|
||||
}
|
||||
@@ -3114,7 +3134,7 @@ function post_is_importable($item,$abook) {
|
||||
if(! ($abook['abook_incl'] || $abook['abook_excl']))
|
||||
return true;
|
||||
|
||||
return \Zotlabs\Lib\MessageFilter::evaluate($item,$abook['abook_incl'],$abook['abook_excl']);
|
||||
return MessageFilter::evaluate($item,$abook['abook_incl'],$abook['abook_excl']);
|
||||
|
||||
}
|
||||
|
||||
@@ -3250,7 +3270,7 @@ function mail_store($arr) {
|
||||
'otype' => 'mail'
|
||||
);
|
||||
|
||||
Zlib\Enotify::submit($notif_params);
|
||||
Enotify::submit($notif_params);
|
||||
}
|
||||
|
||||
if($arr['conv_guid']) {
|
||||
@@ -3533,8 +3553,9 @@ function drop_items($items,$interactive = false,$stage = DROPITEM_NORMAL,$force
|
||||
|
||||
// multiple threads may have been deleted, send an expire notification
|
||||
|
||||
if($uid)
|
||||
Zotlabs\Daemon\Master::Summon(array('Notifier','expire',$uid));
|
||||
if($uid) {
|
||||
Master::Summon([ 'Notifier','expire',$uid ]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3642,8 +3663,9 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL,$force = fal
|
||||
// We'll rely on the undocumented behaviour that DROPITEM_PHASE1 is (hopefully) only
|
||||
// set if we know we're going to send delete notifications out to others.
|
||||
|
||||
if((intval($item['item_wall']) && ($stage != DROPITEM_PHASE2)) || ($stage == DROPITEM_PHASE1))
|
||||
Zotlabs\Daemon\Master::Summon(array('Notifier','drop',$notify_id));
|
||||
if((intval($item['item_wall']) && ($stage != DROPITEM_PHASE2)) || ($stage == DROPITEM_PHASE1)) {
|
||||
Master::Summon([ 'Notifier','drop',$notify_id ]);
|
||||
}
|
||||
|
||||
goaway(z_root() . '/' . $_SESSION['return_url']);
|
||||
}
|
||||
@@ -3767,21 +3789,34 @@ function delete_item_lowlevel($item, $stage = DROPITEM_NORMAL, $force = false) {
|
||||
* @brief Return the first post date.
|
||||
*
|
||||
* @param int $uid
|
||||
* @param boolean $wall (optional) default false
|
||||
* @param boolean $wall (optional) no longer used
|
||||
* @return string|boolean date string, otherwise false
|
||||
*/
|
||||
function first_post_date($uid, $wall = false) {
|
||||
|
||||
$wall_sql = (($wall) ? " and item_wall = 1 " : "" );
|
||||
$item_normal = item_normal();
|
||||
$sql_extra = '';
|
||||
|
||||
switch(App::$module) {
|
||||
case 'articles':
|
||||
$sql_extra .= " and item_type = 7 ";
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_type = 7 and item.item_deleted = 0
|
||||
and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
|
||||
and item.item_blocked = 0 ";
|
||||
break;
|
||||
case 'channel':
|
||||
$sql_extra = " and item_wall = 1 ";
|
||||
default:
|
||||
$item_normal = item_normal();
|
||||
break;
|
||||
}
|
||||
|
||||
$r = q("select id, created from item
|
||||
where uid = %d and id = parent $item_normal $wall_sql
|
||||
where uid = %d and id = parent $item_normal $sql_extra
|
||||
order by created asc limit 1",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
// logger('first_post_date: ' . $r[0]['id'] . ' ' . $r[0]['created'], LOGGER_DATA);
|
||||
return substr(datetime_convert('',date_default_timezone_get(),$r[0]['created']),0,10);
|
||||
}
|
||||
|
||||
@@ -3962,6 +3997,7 @@ function zot_feed($uid, $observer_hash, $arr) {
|
||||
$result = array();
|
||||
$mindate = null;
|
||||
$message_id = null;
|
||||
$wall = true;
|
||||
|
||||
require_once('include/security.php');
|
||||
|
||||
@@ -3973,6 +4009,10 @@ function zot_feed($uid, $observer_hash, $arr) {
|
||||
$message_id = $arr['message_id'];
|
||||
}
|
||||
|
||||
if(array_key_exists('wall',$arr)) {
|
||||
$wall = intval($arr['wall']);
|
||||
}
|
||||
|
||||
if(! $mindate)
|
||||
$mindate = NULL_DATE;
|
||||
|
||||
@@ -4001,6 +4041,10 @@ function zot_feed($uid, $observer_hash, $arr) {
|
||||
$limit = '';
|
||||
}
|
||||
|
||||
if($wall) {
|
||||
$sql_extra .= " and item_wall = 1 ";
|
||||
}
|
||||
|
||||
|
||||
$items = [];
|
||||
|
||||
@@ -4013,7 +4057,6 @@ function zot_feed($uid, $observer_hash, $arr) {
|
||||
|
||||
$r = q("SELECT parent, postopts FROM item
|
||||
WHERE uid IN ( %s )
|
||||
AND item_wall = 1
|
||||
AND item_private = 0
|
||||
$item_normal
|
||||
$sql_extra ORDER BY created ASC $limit",
|
||||
@@ -4023,7 +4066,6 @@ function zot_feed($uid, $observer_hash, $arr) {
|
||||
else {
|
||||
$r = q("SELECT parent, postopts FROM item
|
||||
WHERE uid = %d
|
||||
AND item_wall = 1
|
||||
$item_normal
|
||||
$sql_extra ORDER BY created ASC $limit",
|
||||
intval($uid)
|
||||
@@ -4117,7 +4159,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
|
||||
$sql_extra .= protect_sprintf(term_query('item', $arr['cat'], TERM_CATEGORY));
|
||||
|
||||
if($arr['gid'] && $uid) {
|
||||
$r = q("SELECT * FROM groups WHERE id = %d AND uid = %d LIMIT 1",
|
||||
$r = q("SELECT * FROM pgrp WHERE id = %d AND uid = %d LIMIT 1",
|
||||
intval($arr['group']),
|
||||
intval($uid)
|
||||
);
|
||||
@@ -4379,7 +4421,7 @@ function update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remo
|
||||
// sixteen bytes of the mid - which makes the link portable and not quite as daunting
|
||||
// as the entire mid. If it were the post_id the link would be less portable.
|
||||
|
||||
\Zotlabs\Lib\IConfig::Set(
|
||||
IConfig::Set(
|
||||
intval($post_id),
|
||||
'system',
|
||||
$page_type,
|
||||
@@ -4512,7 +4554,7 @@ function send_profile_photo_activity($channel,$photo,$profile) {
|
||||
|
||||
$arr['body'] = sprintf($t,$channel['channel_name'],$ptext) . "\n\n" . $ltext;
|
||||
|
||||
$acl = new Zotlabs\Access\AccessList($channel);
|
||||
$acl = new AccessList($channel);
|
||||
$x = $acl->get();
|
||||
$arr['allow_cid'] = $x['allow_cid'];
|
||||
|
||||
@@ -4743,7 +4785,7 @@ function item_create_edit_activity($post) {
|
||||
}
|
||||
}
|
||||
|
||||
\Zotlabs\Daemon\Master::Summon(array('Notifier', 'edit_activity', $post_id));
|
||||
Master::Summon([ 'Notifier', 'edit_activity', $post_id ]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,6 +38,15 @@ function js_strings() {
|
||||
// using the defaults set below if left untranslated, empty strings if
|
||||
// translated to "NONE" and the corresponding language strings
|
||||
// if translated to anything else
|
||||
'minutes' => tt('%d minutes', '%d minutes', '%d'),
|
||||
'hours' => tt('about %d hours', 'about %d hours', '%d'),
|
||||
'days' => tt('%d days', '%d days', '%d'),
|
||||
'months' => tt('%d months', '%d months', '%d'),
|
||||
'years' => tt('%d years', '%d years', '%d'),
|
||||
|
||||
// get plural function code
|
||||
'plural_func' => tf(),
|
||||
|
||||
'$t01' => ((t('timeago.prefixAgo') == 'timeago.prefixAgo') ? '' : ((t('timeago.prefixAgo') == 'NONE') ? '' : t('timeago.prefixAgo'))),
|
||||
'$t02' => ((t('timeago.prefixFromNow') == 'timeago.prefixFromNow') ? '' : ((t('timeago.prefixFromNow') == 'NONE') ? '' : t('timeago.prefixFromNow'))),
|
||||
'$t03' => ((t('timeago.suffixAgo') == 'timeago.suffixAgo') ? 'ago' : ((t('timeago.suffixAgo') == 'NONE') ? '' : t('timeago.suffixAgo'))),
|
||||
@@ -46,15 +55,15 @@ function js_strings() {
|
||||
// translatable main strings for jquery.timeago
|
||||
'$t05' => t('less than a minute'),
|
||||
'$t06' => t('about a minute'),
|
||||
'$t07' => t('%d minutes'),
|
||||
'$t07' => ta('%d minutes'),
|
||||
'$t08' => t('about an hour'),
|
||||
'$t09' => t('about %d hours'),
|
||||
'$t09' => ta('about %d hours'),
|
||||
'$t10' => t('a day'),
|
||||
'$t11' => t('%d days'),
|
||||
'$t11' => ta('%d days'),
|
||||
'$t12' => t('about a month'),
|
||||
'$t13' => t('%d months'),
|
||||
'$t13' => ta('%d months'),
|
||||
'$t14' => t('about a year'),
|
||||
'$t15' => t('%d years'),
|
||||
'$t15' => ta('%d years'),
|
||||
'$t16' => t(' '), // wordSeparator
|
||||
'$t17' => ((t('timeago.numbers') != 'timeago.numbers') ? t('timeago.numbers') : '[]'),
|
||||
|
||||
|
||||
@@ -254,6 +254,32 @@ function tt($singular, $plural, $count, $ctx = ''){
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return slash separated string of plurals translation forms
|
||||
*
|
||||
* @param string $k key in translations array
|
||||
* @return string
|
||||
*/
|
||||
function ta($k){
|
||||
|
||||
$t = App::$strings[$k];
|
||||
if (is_array($t))
|
||||
$t = implode("/", $t);
|
||||
return ($t == "" ? $k : $t);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return string_plural_select_xx function code
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
||||
function tf() {
|
||||
|
||||
$s = "plural_function_code";
|
||||
return (x(App::$strings, $s) ? App::$strings[$s] : "0");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Provide a fallback which will not collide with a function defined in
|
||||
* any language file.
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
*/
|
||||
|
||||
use Michelf\MarkdownExtra;
|
||||
|
||||
use League\HTMLToMarkdown\HtmlConverter;
|
||||
use League\HTMLToMarkdown\Environment;
|
||||
use League\HTMLToMarkdown\Converter\ConverterInterface;
|
||||
use League\HTMLToMarkdown\ElementInterface;
|
||||
|
||||
require_once("include/oembed.php");
|
||||
require_once("include/event.php");
|
||||
@@ -74,11 +78,14 @@ function markdown_to_bb($s, $use_zrl = false, $options = []) {
|
||||
|
||||
// Convert everything that looks like a link to a link
|
||||
if($use_zrl) {
|
||||
$s = str_replace(['[img', '/img]'], ['[zmg', '/zmg]'], $s);
|
||||
$s = preg_replace("/([^\]\=\{]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", '$1[zrl=$2$3]$2$3[/zrl]',$s);
|
||||
if (strpos($s,'[/img]') !== false) {
|
||||
$s = preg_replace_callback("/\[img\](.*?)\[\/img\]/ism", 'use_zrl_cb_img', $s);
|
||||
$s = preg_replace_callback("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", 'use_zrl_cb_img_x', $s);
|
||||
}
|
||||
$s = preg_replace_callback("/([^\]\=\{\/]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", 'use_zrl_cb_link',$s);
|
||||
}
|
||||
else {
|
||||
$s = preg_replace("/([^\]\=\{]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", '$1[url=$2$3]$2$3[/url]',$s);
|
||||
$s = preg_replace("/([^\]\=\{\/]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", '$1[url=$2$3]$2$3[/url]',$s);
|
||||
}
|
||||
|
||||
// remove duplicate adjacent code tags
|
||||
@@ -96,6 +103,41 @@ function markdown_to_bb($s, $use_zrl = false, $options = []) {
|
||||
return $s;
|
||||
}
|
||||
|
||||
function use_zrl_cb_link($match) {
|
||||
$res = '';
|
||||
$is_zid = is_matrix_url(trim($match[0]));
|
||||
|
||||
if($is_zid)
|
||||
$res = $match[1] . '[zrl=' . $match[2] . $match[3] . ']' . $match[2] . $match[3] . '[/zrl]';
|
||||
else
|
||||
$res = $match[1] . '[url=' . $match[2] . $match[3] . ']' . $match[2] . $match[3] . '[/url]';
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
function use_zrl_cb_img($match) {
|
||||
$res = '';
|
||||
$is_zid = is_matrix_url(trim($match[1]));
|
||||
|
||||
if($is_zid)
|
||||
$res = '[zmg]' . $match[1] . '[/zmg]';
|
||||
else
|
||||
$res = $match[0];
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
function use_zrl_cb_img_x($match) {
|
||||
$res = '';
|
||||
$is_zid = is_matrix_url(trim($match[3]));
|
||||
|
||||
if($is_zid)
|
||||
$res = '[zmg=' . $match[1] . 'x' . $match[2] . ']' . $match[3] . '[/zmg]';
|
||||
else
|
||||
$res = $match[0];
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
@@ -213,6 +255,9 @@ function bb_to_markdown($Text, $options = []) {
|
||||
|
||||
$Text = html2markdown($Text);
|
||||
|
||||
//html2markdown adds backslashes infront of hashes after a new line. remove them
|
||||
$Text = str_replace("\n\#", "\n#", $Text);
|
||||
|
||||
// It also adds backslashes to our attempt at getting around the html entity preservation for some weird reason.
|
||||
|
||||
//$Text = str_replace(array('&\\_lt\\_;','&\\_gt\\_;','&\\_amp\\_;'),array('<','>','&'),$Text);
|
||||
@@ -248,9 +293,14 @@ function bb_to_markdown($Text, $options = []) {
|
||||
* @param string $html The HTML code to convert
|
||||
* @return string Markdown representation of the given HTML text, empty on error
|
||||
*/
|
||||
function html2markdown($html) {
|
||||
function html2markdown($html,$options = []) {
|
||||
$markdown = '';
|
||||
$converter = new HtmlConverter();
|
||||
|
||||
$internal_errors = libxml_use_internal_errors(true);
|
||||
|
||||
$environment = Environment::createDefaultEnvironment($options);
|
||||
$environment->addConverter(new TableConverter());
|
||||
$converter = new HtmlConverter($environment);
|
||||
|
||||
try {
|
||||
$markdown = $converter->convert($html);
|
||||
@@ -258,5 +308,77 @@ function html2markdown($html) {
|
||||
logger("Invalid HTML. HTMLToMarkdown library threw an exception.");
|
||||
}
|
||||
|
||||
libxml_use_internal_errors($internal_errors);
|
||||
|
||||
return $markdown;
|
||||
}
|
||||
|
||||
// Tables are not an official part of the markdown specification.
|
||||
// This interface was suggested as a workaround.
|
||||
// author: Mark Hamstra
|
||||
// https://github.com/Mark-H/Docs
|
||||
|
||||
|
||||
class TableConverter implements ConverterInterface
|
||||
{
|
||||
/**
|
||||
* @param ElementInterface $element
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function convert(ElementInterface $element)
|
||||
{
|
||||
switch ($element->getTagName()) {
|
||||
case 'tr':
|
||||
$line = [];
|
||||
$i = 1;
|
||||
foreach ($element->getChildren() as $td) {
|
||||
$i++;
|
||||
$v = $td->getValue();
|
||||
$v = trim($v);
|
||||
if ($i % 2 === 0 || $v !== '') {
|
||||
$line[] = $v;
|
||||
}
|
||||
}
|
||||
return '| ' . implode(' | ', $line) . " |\n";
|
||||
case 'td':
|
||||
case 'th':
|
||||
return trim($element->getValue());
|
||||
case 'tbody':
|
||||
return trim($element->getValue());
|
||||
case 'thead':
|
||||
$headerLine = reset($element->getChildren())->getValue();
|
||||
$headers = explode(' | ', trim(trim($headerLine, "\n"), '|'));
|
||||
$hr = [];
|
||||
foreach ($headers as $td) {
|
||||
$length = strlen(trim($td)) + 2;
|
||||
$hr[] = str_repeat('-', $length > 3 ? $length : 3);
|
||||
}
|
||||
$hr = '|' . implode('|', $hr) . '|';
|
||||
return $headerLine . $hr . "\n";
|
||||
case 'table':
|
||||
$inner = $element->getValue();
|
||||
if (strpos($inner, '-----') === false) {
|
||||
$inner = explode("\n", $inner);
|
||||
$single = explode(' | ', trim($inner[0], '|'));
|
||||
$hr = [];
|
||||
foreach ($single as $td) {
|
||||
$length = strlen(trim($td)) + 2;
|
||||
$hr[] = str_repeat('-', $length > 3 ? $length : 3);
|
||||
}
|
||||
$hr = '|' . implode('|', $hr) . '|';
|
||||
array_splice($inner, 1, 0, $hr);
|
||||
$inner = implode("\n", $inner);
|
||||
}
|
||||
return trim($inner) . "\n\n";
|
||||
}
|
||||
return $element->getValue();
|
||||
}
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getSupportedTags()
|
||||
{
|
||||
return array('table', 'tr', 'thead', 'td', 'tbody');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
require_once('include/crypto.php');
|
||||
require_once('include/attach.php');
|
||||
require_once('include/msglib.php');
|
||||
|
||||
|
||||
function mail_prepare_binary($item) {
|
||||
@@ -498,11 +499,8 @@ function private_messages_drop($channel_id, $messageitem_id, $drop_conversation
|
||||
}
|
||||
else {
|
||||
xchan_mail_query($x[0]);
|
||||
$x[0]['mail_deleted'] = true;
|
||||
$r = q("DELETE FROM mail WHERE id = %d AND channel_id = %d",
|
||||
intval($messageitem_id),
|
||||
intval($channel_id)
|
||||
);
|
||||
$x[0]['mail_deleted'] = true;
|
||||
msg_drop($messageitem_id, $channel_id, $x[0]['conv_guid']);
|
||||
build_sync_packet($channel_id,array('mail' => array(encode_mail($x,true))));
|
||||
return true;
|
||||
}
|
||||
|
||||
28
include/msglib.php
Normal file
28
include/msglib.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/* Common private message processing functions */
|
||||
|
||||
function msg_drop($message_id, $channel_id, $conv_guid) {
|
||||
|
||||
// Delete message
|
||||
$r = q("DELETE FROM mail WHERE id = %d AND channel_id = %d",
|
||||
intval($message_id),
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
// Get new first message...
|
||||
$r = q("SELECT mid, parent_mid FROM mail WHERE conv_guid = '%s' AND channel_id = %d ORDER BY id ASC LIMIT 1",
|
||||
dbesc($conv_guid),
|
||||
intval($channel_id)
|
||||
);
|
||||
// ...and if wasn't first before...
|
||||
if ($r[0]['mid'] != $r[0]['parent_mid']) {
|
||||
// ...refer whole thread to it
|
||||
q("UPDATE mail SET parent_mid = '%s', mail_isreply = abs(mail_isreply - 1) WHERE conv_guid = '%s' AND channel_id = %d",
|
||||
dbesc($r[0]['mid']),
|
||||
dbesc($conv_guid),
|
||||
intval($channel_id)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
102
include/nav.php
102
include/nav.php
@@ -1,11 +1,11 @@
|
||||
<?php /** @file */
|
||||
|
||||
use \Zotlabs\Lib as Zlib;
|
||||
use \Zotlabs\Lib\Apps;
|
||||
use \Zotlabs\Lib\Chatroom;
|
||||
|
||||
require_once('include/security.php');
|
||||
require_once('include/menu.php');
|
||||
|
||||
|
||||
function nav($template = 'default') {
|
||||
|
||||
/**
|
||||
@@ -60,8 +60,6 @@ function nav($template = 'default') {
|
||||
//we could additionally use this to display important system notifications e.g. for updates
|
||||
));
|
||||
|
||||
$techlevel = get_account_techlevel();
|
||||
|
||||
// nav links: array of array('href', 'text', 'extra css classes', 'title')
|
||||
$nav = [];
|
||||
|
||||
@@ -93,7 +91,7 @@ function nav($template = 'default') {
|
||||
if(! $_SESSION['delegate']) {
|
||||
$nav['manage'] = array('manage', t('Channel Manager'), "", t('Manage your channels'),'manage_nav_btn');
|
||||
}
|
||||
if(feature_enabled(local_channel(),'groups'))
|
||||
if(Apps::system_app_installed(local_channel(), 'Privacy Groups'))
|
||||
$nav['group'] = array('group', t('Privacy Groups'),"", t('Manage your privacy groups'),'group_nav_btn');
|
||||
|
||||
$nav['settings'] = array('settings', t('Settings'),"", t('Account/Channel Settings'),'settings_nav_btn');
|
||||
@@ -199,40 +197,60 @@ function nav($template = 'default') {
|
||||
// turned off until somebody discovers this and figures out a good location for it.
|
||||
$powered_by = '';
|
||||
|
||||
$url = '';
|
||||
$settings_url = '';
|
||||
|
||||
if(App::$profile_uid && App::$nav_sel['raw_name']) {
|
||||
$active_app = q("SELECT app_url FROM app WHERE app_channel = %d AND app_name = '%s' LIMIT 1",
|
||||
intval(App::$profile_uid),
|
||||
dbesc(App::$nav_sel['raw_name'])
|
||||
);
|
||||
|
||||
|
||||
if($active_app) {
|
||||
$url = $active_app[0]['app_url'];
|
||||
if(strpos($active_app[0]['app_url'], ',')) {
|
||||
$urls = explode(',', $active_app[0]['app_url']);
|
||||
$url = trim($urls[0]);
|
||||
if($is_owner)
|
||||
$settings_url = trim($urls[1]);
|
||||
}
|
||||
else {
|
||||
$url = $active_app[0]['app_url'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(! $settings_url && isset(App::$nav_sel['settings_url']))
|
||||
$settings_url = App::$nav_sel['settings_url'];
|
||||
|
||||
//app bin
|
||||
if($is_owner) {
|
||||
//daily system apps import
|
||||
if(get_pconfig(local_channel(), 'system','import_system_apps') !== datetime_convert('UTC','UTC','now','Y-m-d')) {
|
||||
Zlib\Apps::import_system_apps();
|
||||
Apps::import_system_apps();
|
||||
set_pconfig(local_channel(), 'system','import_system_apps', datetime_convert('UTC','UTC','now','Y-m-d'));
|
||||
}
|
||||
|
||||
if(get_pconfig(local_channel(), 'system','force_import_system_apps') !== STD_VERSION) {
|
||||
Apps::import_system_apps();
|
||||
set_pconfig(local_channel(), 'system','force_import_system_apps', STD_VERSION);
|
||||
}
|
||||
|
||||
$syslist = array();
|
||||
$list = Zlib\Apps::app_list(local_channel(), false, ['nav_featured_app', 'nav_pinned_app']);
|
||||
$list = Apps::app_list(local_channel(), false, ['nav_featured_app', 'nav_pinned_app']);
|
||||
if($list) {
|
||||
foreach($list as $li) {
|
||||
$syslist[] = Zlib\Apps::app_encode($li);
|
||||
$syslist[] = Apps::app_encode($li);
|
||||
}
|
||||
}
|
||||
Zlib\Apps::translate_system_apps($syslist);
|
||||
Apps::translate_system_apps($syslist);
|
||||
}
|
||||
else {
|
||||
$syslist = Zlib\Apps::get_system_apps(true);
|
||||
$syslist = Apps::get_system_apps(true);
|
||||
}
|
||||
|
||||
usort($syslist,'Zotlabs\\Lib\\Apps::app_name_compare');
|
||||
|
||||
$syslist = Zlib\Apps::app_order(local_channel(),$syslist);
|
||||
$syslist = Apps::app_order(local_channel(),$syslist);
|
||||
|
||||
foreach($syslist as $app) {
|
||||
if(\App::$nav_sel['name'] == $app['name'])
|
||||
@@ -240,18 +258,18 @@ function nav($template = 'default') {
|
||||
|
||||
if($is_owner) {
|
||||
if(strpos($app['categories'],'nav_pinned_app') !== false) {
|
||||
$navbar_apps[] = Zlib\Apps::app_render($app,'navbar');
|
||||
$navbar_apps[] = Apps::app_render($app,'navbar');
|
||||
}
|
||||
else {
|
||||
$nav_apps[] = Zlib\Apps::app_render($app,'nav');
|
||||
$nav_apps[] = Apps::app_render($app,'nav');
|
||||
}
|
||||
}
|
||||
elseif(! $is_owner && strpos($app['requires'], 'local_channel') === false) {
|
||||
if(strpos($app['categories'],'nav_pinned_app') !== false) {
|
||||
$navbar_apps[] = Zlib\Apps::app_render($app,'navbar');
|
||||
$navbar_apps[] = Apps::app_render($app,'navbar');
|
||||
}
|
||||
else {
|
||||
$nav_apps[] = Zlib\Apps::app_render($app,'nav');
|
||||
$nav_apps[] = Apps::app_render($app,'nav');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -289,7 +307,8 @@ function nav($template = 'default') {
|
||||
'$addapps' => t('Add Apps'),
|
||||
'$orderapps' => t('Arrange Apps'),
|
||||
'$sysapps_toggle' => t('Toggle System Apps'),
|
||||
'$url' => (($url) ? $url : App::$cmd)
|
||||
'$url' => (($url) ? $url : z_root() . '/' . App::$cmd),
|
||||
'$settings_url' => $settings_url
|
||||
));
|
||||
|
||||
if(x($_SESSION, 'reload_avatar') && $observer) {
|
||||
@@ -311,15 +330,18 @@ function nav($template = 'default') {
|
||||
* Set a menu item in navbar as selected
|
||||
*
|
||||
*/
|
||||
function nav_set_selected($item){
|
||||
App::$nav_sel['raw_name'] = $item;
|
||||
$item = ['name' => $item];
|
||||
Zlib\Apps::translate_system_apps($item);
|
||||
function nav_set_selected($raw_name, $settings_url = ''){
|
||||
App::$nav_sel['raw_name'] = $raw_name;
|
||||
|
||||
$item = ['name' => $raw_name];
|
||||
Apps::translate_system_apps($item);
|
||||
|
||||
App::$nav_sel['name'] = $item['name'];
|
||||
|
||||
if($settings_url)
|
||||
App::$nav_sel['settings_url'] = z_root() . '/' . $settings_url;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function channel_apps($is_owner = false, $nickname = null) {
|
||||
|
||||
// Don't provide any channel apps if we're running as the sys channel
|
||||
@@ -419,8 +441,8 @@ function channel_apps($is_owner = false, $nickname = null) {
|
||||
}
|
||||
|
||||
|
||||
if ($p['chat'] && feature_enabled($uid,'ajaxchat')) {
|
||||
$has_chats = ZLib\Chatroom::list_count($uid);
|
||||
if ($p['chat'] && Apps::system_app_installed($uid,'Chatrooms')) {
|
||||
$has_chats = Chatroom::list_count($uid);
|
||||
if ($has_chats) {
|
||||
$tabs[] = [
|
||||
'label' => t('Chatrooms'),
|
||||
@@ -445,7 +467,7 @@ function channel_apps($is_owner = false, $nickname = null) {
|
||||
];
|
||||
}
|
||||
|
||||
if($p['view_pages'] && feature_enabled($uid,'cards')) {
|
||||
if($p['view_pages'] && Apps::system_app_installed($uid, 'Cards')) {
|
||||
$tabs[] = [
|
||||
'label' => t('Cards'),
|
||||
'url' => z_root() . '/cards/' . $nickname ,
|
||||
@@ -456,7 +478,7 @@ function channel_apps($is_owner = false, $nickname = null) {
|
||||
];
|
||||
}
|
||||
|
||||
if($p['view_pages'] && feature_enabled($uid,'articles')) {
|
||||
if($p['view_pages'] && Apps::system_app_installed($uid, 'Articles')) {
|
||||
$tabs[] = [
|
||||
'label' => t('Articles'),
|
||||
'url' => z_root() . '/articles/' . $nickname ,
|
||||
@@ -468,7 +490,7 @@ function channel_apps($is_owner = false, $nickname = null) {
|
||||
}
|
||||
|
||||
|
||||
if($has_webpages && feature_enabled($uid,'webpages')) {
|
||||
if($has_webpages && Apps::system_app_installed($uid, 'Webpages')) {
|
||||
$tabs[] = [
|
||||
'label' => t('Webpages'),
|
||||
'url' => z_root() . '/page/' . $nickname . '/home',
|
||||
@@ -480,21 +502,19 @@ function channel_apps($is_owner = false, $nickname = null) {
|
||||
}
|
||||
|
||||
|
||||
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'
|
||||
];
|
||||
}
|
||||
if ($p['view_wiki'] && Apps::system_app_installed($uid, 'Wiki')) {
|
||||
$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'),
|
||||
|
||||
@@ -48,6 +48,10 @@ function z_fetch_url($url, $binary = false, $redirects = 0, $opts = array()) {
|
||||
if(($redirects > 8) || (! $ch))
|
||||
return $ret;
|
||||
|
||||
if(! array_key_exists('request_target',$opts)) {
|
||||
$opts['request_target'] = 'get ' . get_request_string($url);
|
||||
}
|
||||
|
||||
@curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
@curl_setopt($ch, CURLINFO_HEADER_OUT, true);
|
||||
@curl_setopt($ch, CURLOPT_CAINFO, get_capath());
|
||||
@@ -157,7 +161,7 @@ function z_fetch_url($url, $binary = false, $redirects = 0, $opts = array()) {
|
||||
|
||||
if($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307 || $http_code == 308) {
|
||||
$matches = array();
|
||||
preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches);
|
||||
preg_match('/(Location:|URI:)(.*?)\n/i', $header, $matches);
|
||||
$newurl = trim(array_pop($matches));
|
||||
if(strpos($newurl,'/') === 0)
|
||||
$newurl = $url . $newurl;
|
||||
@@ -179,6 +183,7 @@ function z_fetch_url($url, $binary = false, $redirects = 0, $opts = array()) {
|
||||
}
|
||||
$ret['body'] = substr($s,strlen($header));
|
||||
$ret['header'] = $header;
|
||||
$ret['request_target'] = $opts['request_target'];
|
||||
|
||||
if(x($opts,'debug')) {
|
||||
$ret['debug'] = $curl_info;
|
||||
@@ -227,6 +232,10 @@ function z_post_url($url, $params, $redirects = 0, $opts = array()) {
|
||||
if(($redirects > 8) || (! $ch))
|
||||
return $ret;
|
||||
|
||||
if(! array_key_exists('request_target',$opts)) {
|
||||
$opts['request_target'] = 'get ' . get_request_string($url);
|
||||
}
|
||||
|
||||
@curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
@curl_setopt($ch, CURLINFO_HEADER_OUT, true);
|
||||
@curl_setopt($ch, CURLOPT_CAINFO, get_capath());
|
||||
@@ -359,6 +368,7 @@ function z_post_url($url, $params, $redirects = 0, $opts = array()) {
|
||||
|
||||
$ret['body'] = substr($s, strlen($header));
|
||||
$ret['header'] = $header;
|
||||
$ret['request_target'] = $opts['request_target'];
|
||||
|
||||
if(x($opts,'debug')) {
|
||||
$ret['debug'] = $curl_info;
|
||||
@@ -2042,6 +2052,22 @@ function jsonld_document_loader($url) {
|
||||
|
||||
require_once('library/jsonld/jsonld.php');
|
||||
|
||||
$recursion = 0;
|
||||
|
||||
$x = debug_backtrace();
|
||||
if($x) {
|
||||
foreach($x as $n) {
|
||||
if($n['function'] === __FUNCTION__) {
|
||||
$recursion ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if($recursion > 5) {
|
||||
logger('jsonld bomb detected at: ' . $url);
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
$cachepath = 'store/[data]/ldcache';
|
||||
if(! is_dir($cachepath))
|
||||
os_mkdir($cachepath, STORAGE_DEFAULT_PERMISSIONS, true);
|
||||
@@ -2064,3 +2090,17 @@ function jsonld_document_loader($url) {
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Given a URL, return everything after the host portion.
|
||||
* example https://foobar.com/gravy?g=5&y=6
|
||||
* returns /gravy?g=5&y=6
|
||||
* result always returns the leading slash
|
||||
*/
|
||||
|
||||
function get_request_string($url) {
|
||||
|
||||
$a = explode('/',$url,4);
|
||||
return '/' . ((count($a) > 3) ? $a[3] : EMPTY_STR);
|
||||
|
||||
}
|
||||
|
||||
@@ -16,11 +16,14 @@ require_once('include/security.php');
|
||||
*
|
||||
* @param int $uid The channel_id associated with the resource owner
|
||||
* @param string $observer_xchan The xchan_hash representing the observer
|
||||
* @param bool $internal_use (default true)
|
||||
* @param bool $check_siteblock (default true)
|
||||
* if false, bypass check for "Block Public" on the site
|
||||
* @param bool $default_ignored (default true)
|
||||
* if false, lie and pretend the ignored person has permissions you are ignoring (used in channel discovery)
|
||||
*
|
||||
* @returns array of all permissions, key is permission name, value is true or false
|
||||
*/
|
||||
function get_all_perms($uid, $observer_xchan, $internal_use = true) {
|
||||
function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ignored = true) {
|
||||
|
||||
$api = App::get_oauth_key();
|
||||
if($api)
|
||||
@@ -111,7 +114,7 @@ function get_all_perms($uid, $observer_xchan, $internal_use = true) {
|
||||
$blocked_anon_perms = \Zotlabs\Access\Permissions::BlockedAnonPerms();
|
||||
|
||||
|
||||
if(($x) && ($internal_use) && in_array($perm_name,$blocked_anon_perms) && intval($x[0]['abook_ignored'])) {
|
||||
if(($x) && ($default_ignored) && in_array($perm_name,$blocked_anon_perms) && intval($x[0]['abook_ignored'])) {
|
||||
$ret[$perm_name] = false;
|
||||
continue;
|
||||
}
|
||||
@@ -119,7 +122,7 @@ function get_all_perms($uid, $observer_xchan, $internal_use = true) {
|
||||
|
||||
// system is blocked to anybody who is not authenticated
|
||||
|
||||
if((! $observer_xchan) && intval(get_config('system', 'block_public'))) {
|
||||
if(($check_siteblock) && (! $observer_xchan) && intval(get_config('system', 'block_public'))) {
|
||||
$ret[$perm_name] = false;
|
||||
continue;
|
||||
}
|
||||
@@ -251,9 +254,11 @@ function get_all_perms($uid, $observer_xchan, $internal_use = true) {
|
||||
* @param int $uid The channel_id associated with the resource owner
|
||||
* @param string $observer_xchan The xchan_hash representing the observer
|
||||
* @param string $permission
|
||||
* @param boolean $check_siteblock (default true)
|
||||
* if false bypass check for "Block Public" at the site level
|
||||
* @return bool true if permission is allowed for observer on channel
|
||||
*/
|
||||
function perm_is_allowed($uid, $observer_xchan, $permission) {
|
||||
function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock = true) {
|
||||
|
||||
$api = App::get_oauth_key();
|
||||
if($api)
|
||||
@@ -326,7 +331,7 @@ function perm_is_allowed($uid, $observer_xchan, $permission) {
|
||||
|
||||
// system is blocked to anybody who is not authenticated
|
||||
|
||||
if((! $observer_xchan) && intval(get_config('system', 'block_public')))
|
||||
if(($check_siteblock) && (! $observer_xchan) && intval(get_config('system', 'block_public')))
|
||||
return false;
|
||||
|
||||
// Check if this $uid is actually the $observer_xchan
|
||||
|
||||
@@ -14,17 +14,17 @@
|
||||
* @param bool $uninstall uninstall plugin
|
||||
*/
|
||||
function handleerrors_plugin($plugin,$notice,$log,$uninstall=false){
|
||||
logger("Addons: [" . $plugin . "] Error: ".$log, LOGGER_ERROR);
|
||||
if ($notice != '') {
|
||||
notice("[" . $plugin . "] Error: ".$notice, LOGGER_ERROR);
|
||||
}
|
||||
logger("Addons: [" . $plugin . "] Error: ".$log, LOGGER_ERROR);
|
||||
if ($notice != '') {
|
||||
notice("[" . $plugin . "] Error: ".$notice, LOGGER_ERROR);
|
||||
}
|
||||
|
||||
if ($uninstall) {
|
||||
$idx = array_search($plugin, \App::$plugins);
|
||||
unset(\App::$plugins[$idx]);
|
||||
uninstall_plugin($plugin);
|
||||
set_config("system","addon", implode(", ",\App::$plugins));
|
||||
}
|
||||
if ($uninstall) {
|
||||
$idx = array_search($plugin, \App::$plugins);
|
||||
unset(\App::$plugins[$idx]);
|
||||
uninstall_plugin($plugin);
|
||||
set_config("system","addon", implode(", ",\App::$plugins));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,11 +109,16 @@ function install_plugin($plugin) {
|
||||
|
||||
$plugin_admin = (function_exists($plugin . '_plugin_admin') ? 1 : 0);
|
||||
|
||||
q("INSERT INTO addon (aname, installed, tstamp, plugin_admin) VALUES ( '%s', 1, %d , %d ) ",
|
||||
dbesc($plugin),
|
||||
intval($t),
|
||||
$plugin_admin
|
||||
$d = q("select * from addon where aname = '%s' limit 1",
|
||||
dbesc($plugin)
|
||||
);
|
||||
if(! $d) {
|
||||
q("INSERT INTO addon (aname, installed, tstamp, plugin_admin) VALUES ( '%s', 1, %d , %d ) ",
|
||||
dbesc($plugin),
|
||||
intval($t),
|
||||
$plugin_admin
|
||||
);
|
||||
}
|
||||
|
||||
load_plugin($plugin);
|
||||
}
|
||||
@@ -206,19 +211,19 @@ function reload_plugins() {
|
||||
if(function_exists($pl . '_unload')) {
|
||||
$func = $pl . '_unload';
|
||||
try {
|
||||
$func();
|
||||
$func();
|
||||
} catch (Exception $e) {
|
||||
handleerrors_plugin($plugin,"","UNLOAD FAILED (uninstalling) : ".$e->getMessage(),true);
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(function_exists($pl . '_load')) {
|
||||
$func = $pl . '_load';
|
||||
try {
|
||||
$func();
|
||||
$func();
|
||||
} catch (Exception $e) {
|
||||
handleerrors_plugin($plugin,"","LOAD FAILED (uninstalling): ".$e->getMessage(),true);
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
q("UPDATE addon SET tstamp = %d WHERE id = %d",
|
||||
@@ -366,28 +371,47 @@ function unregister_hook($hook, $file, $function) {
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// It might not be obvious but themes can manually add hooks to the App::$hooks
|
||||
// array in their theme_init() and use this to customise the app behaviour.
|
||||
// UPDATE: use insert_hook($hookname,$function_name) to do this
|
||||
//
|
||||
/**
|
||||
* @brief loads all active hooks into memory
|
||||
* alters: App::$hooks
|
||||
* Called during initialisation
|
||||
* Duplicated hooks are removed and the duplicates ignored
|
||||
*
|
||||
* It might not be obvious but themes can manually add hooks to the App::$hooks
|
||||
* array in their theme_init() and use this to customise the app behaviour.
|
||||
* use insert_hook($hookname,$function_name) to do this.
|
||||
*/
|
||||
|
||||
|
||||
function load_hooks() {
|
||||
|
||||
App::$hooks = array();
|
||||
App::$hooks = [];
|
||||
|
||||
$r = q("SELECT * FROM hook WHERE true ORDER BY priority DESC");
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
if(! array_key_exists($rr['hook'],App::$hooks))
|
||||
App::$hooks[$rr['hook']] = array();
|
||||
|
||||
App::$hooks[$rr['hook']][] = array($rr['file'],$rr['fn'],$rr['priority'],$rr['hook_version']);
|
||||
foreach($r as $rv) {
|
||||
$duplicated = false;
|
||||
if(! array_key_exists($rv['hook'],App::$hooks)) {
|
||||
App::$hooks[$rv['hook']] = [];
|
||||
}
|
||||
else {
|
||||
foreach(App::$hooks[$rv['hook']] as $h) {
|
||||
if($h[0] === $rv['file'] && $h[1] === $rv['fn']) {
|
||||
$duplicated = true;
|
||||
q("delete from hook where id = %d",
|
||||
intval($rv['id'])
|
||||
);
|
||||
logger('duplicate hook ' . $h[1] . ' removed');
|
||||
}
|
||||
}
|
||||
}
|
||||
if(! $duplicated) {
|
||||
App::$hooks[$rv['hook']][] = [ $rv['file'], $rv['fn'], $rv['priority'], $rv['hook_version']];
|
||||
}
|
||||
}
|
||||
}
|
||||
//logger('hooks: ' . print_r(App::$hooks,true));
|
||||
// logger('hooks: ' . print_r(App::$hooks,true));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -431,8 +455,28 @@ function insert_hook($hook, $fn, $version = 0, $priority = 0) {
|
||||
*/
|
||||
function call_hooks($name, &$data = null) {
|
||||
$a = 0;
|
||||
if((is_array(App::$hooks)) && (array_key_exists($name, App::$hooks))) {
|
||||
|
||||
if (isset(App::$hooks[$name])) {
|
||||
foreach(App::$hooks[$name] as $hook) {
|
||||
|
||||
if ($name != 'permit_hook') { // avoid looping
|
||||
$checkhook = [
|
||||
'name'=>$name,
|
||||
'hook'=>$hook,
|
||||
'data'=>$data,
|
||||
// Note: Since PHP uses COPY-ON-WRITE
|
||||
// for variables, there is no cost to
|
||||
// passing the $data structure (unless
|
||||
// the permit_hook processors change the
|
||||
// information it contains.
|
||||
'permit'=>true
|
||||
];
|
||||
call_hooks('permit_hook',$checkhook);
|
||||
if (!$checkhook['permit']) {
|
||||
continue;
|
||||
}
|
||||
$data = $checkhook['data'];
|
||||
}
|
||||
$origfn = $hook[1];
|
||||
if($hook[0])
|
||||
@include_once($hook[0]);
|
||||
@@ -958,9 +1002,8 @@ function format_js_if_exists($source) {
|
||||
function theme_include($file, $root = '') {
|
||||
|
||||
// Make sure $root ends with a slash / if it's not blank
|
||||
if($root !== '' && $root[strlen($root)-1] !== '/')
|
||||
if($root !== '' && substr($root,-1) !== '/')
|
||||
$root = $root . '/';
|
||||
|
||||
$theme_info = App::$theme_info;
|
||||
|
||||
if(array_key_exists('extends',$theme_info))
|
||||
@@ -991,21 +1034,54 @@ function theme_include($file, $root = '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
function get_intltext_template($s, $root = '') {
|
||||
$testroot = ($root=='') ? $testroot = "ROOT" : $root;
|
||||
$t = App::template_engine();
|
||||
|
||||
$t = App::template_engine();
|
||||
|
||||
$template = $t->get_intltext_template($s, $root);
|
||||
return $template;
|
||||
if (isset(\App::$override_intltext_templates[$testroot][$s]["content"])) {
|
||||
return \App::$override_intltext_templates[$testroot][$s]["content"];
|
||||
} else {
|
||||
if (isset(\App::$override_intltext_templates[$testroot][$s]["root"]) &&
|
||||
isset(\App::$override_intltext_templates[$testroot][$s]["file"])) {
|
||||
$s = \App::$override_intltext_templates[$testroot][$s]["file"];
|
||||
$root = \App::$override_intltext_templates[$testroot][$s]["root"];
|
||||
} elseif (\App::$override_templateroot) {
|
||||
$newroot = \App::$override_templateroot.$root;
|
||||
if ($newroot != '' && substr($newroot,-1) != '/' ) {
|
||||
$newroot .= '/';
|
||||
}
|
||||
$template = $t->get_intltext_template($s, $newroot);
|
||||
}
|
||||
$template = $t->get_intltext_template($s, $root);
|
||||
return $template;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get_markup_template($s, $root = '') {
|
||||
$testroot = ($root=='') ? $testroot = "ROOT" : $root;
|
||||
|
||||
$t = App::template_engine();
|
||||
$template = $t->get_markup_template($s, $root);
|
||||
return $template;
|
||||
$t = App::template_engine();
|
||||
|
||||
if (isset(\App::$override_markup_templates[$testroot][$s]["content"])) {
|
||||
return \App::$override_markup_templates[$testroot][$s]["content"];
|
||||
} else {
|
||||
if (isset(\App::$override_markup_templates[$testroot][$s]["root"]) &&
|
||||
isset(\App::$override_markup_templates[$testroot][$s]["file"])) {
|
||||
$root = \App::$override_markup_templates[$testroot][$s]["root"];
|
||||
$s = \App::$override_markup_templates[$testroot][$s]["file"];
|
||||
$template = $t->get_markup_template($s, $root);
|
||||
} elseif (\App::$override_templateroot) {
|
||||
$newroot = \App::$override_templateroot;
|
||||
if ($newroot != '' && substr($newroot,-1) != '/' ) {
|
||||
$newroot .= '/';
|
||||
}
|
||||
$newroot .= $root;
|
||||
$template = $t->get_markup_template($s, $newroot);
|
||||
} else {
|
||||
$template = $t->get_markup_template($s, $root);
|
||||
}
|
||||
return $template;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -370,7 +370,7 @@ function permissions_sql($owner_id, $remote_observer = null, $table = '') {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates an addiontal SQL where statement to check permissions for an item.
|
||||
* @brief Creates an additional SQL where statement to check permissions for an item.
|
||||
*
|
||||
* @param int $owner_id
|
||||
* @param bool $remote_observer (optional) use current observer if unset
|
||||
@@ -577,7 +577,7 @@ function init_groups_visitor($contact_id) {
|
||||
|
||||
// physical groups this channel is a member of
|
||||
|
||||
$r = q("SELECT hash FROM groups left join group_member on groups.id = group_member.gid WHERE xchan = '%s' ",
|
||||
$r = q("SELECT hash FROM pgrp left join pgrp_member on pgrp.id = pgrp_member.gid WHERE xchan = '%s' ",
|
||||
dbesc($contact_id)
|
||||
);
|
||||
if($r) {
|
||||
|
||||
@@ -3,21 +3,32 @@
|
||||
|
||||
function contact_profile_assign($current) {
|
||||
|
||||
$o = '';
|
||||
|
||||
$o .= "<select id=\"contact-profile-selector\" name=\"profile_assign\" class=\"form-control\"/>\r\n";
|
||||
|
||||
$r = q("SELECT profile_guid, profile_name FROM profile WHERE uid = %d",
|
||||
intval($_SESSION['uid']));
|
||||
intval($_SESSION['uid'])
|
||||
);
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$selected = (($rr['profile_guid'] == $current) ? " selected=\"selected\" " : "");
|
||||
$o .= "<option value=\"{$rr['profile_guid']}\" $selected >{$rr['profile_name']}</option>\r\n";
|
||||
$options[$rr['profile_guid']] = $rr['profile_name'];
|
||||
}
|
||||
}
|
||||
$o .= "</select>\r\n";
|
||||
|
||||
$select = [
|
||||
'profile_assign',
|
||||
t('Profile to assign new connections'),
|
||||
$current,
|
||||
'',
|
||||
$options
|
||||
];
|
||||
|
||||
$o = replace_macros(get_markup_template('field_select.tpl'),
|
||||
[
|
||||
'$field' => $select
|
||||
]
|
||||
);
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
|
||||
function contact_poll_interval($current, $disabled = false) {
|
||||
|
||||
@@ -37,7 +37,13 @@ function replace_macros($s, $r) {
|
||||
call_hooks('replace_macros', $arr);
|
||||
|
||||
$t = App::template_engine();
|
||||
$output = $t->replace_macros($arr['template'], $arr['params']);
|
||||
|
||||
try {
|
||||
$output = $t->replace_macros($arr['template'], $arr['params']);
|
||||
} catch (Exception $e) {
|
||||
logger("Unable to render template: ".$e->getMessage());
|
||||
$output = "<h3>ERROR: there was an error creating the output.</h3>";
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
@@ -2047,6 +2053,7 @@ function undo_post_tagging($s) {
|
||||
$cnt = preg_match_all('/([@#])(\!*)\[zrl=(.*?)\](.*?)\[\/zrl\]/ism',$s,$matches,PREG_SET_ORDER);
|
||||
if($cnt) {
|
||||
foreach($matches as $mtch) {
|
||||
$x = false;
|
||||
if($mtch[1] === '@') {
|
||||
$x = q("select xchan_addr, xchan_url from xchan where xchan_url = '%s' limit 1",
|
||||
dbesc($mtch[3])
|
||||
@@ -2730,7 +2737,7 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $i
|
||||
$grp = group_byname($profile_uid,$name);
|
||||
|
||||
if($grp) {
|
||||
$g = q("select hash from groups where id = %d and visible = 1 limit 1",
|
||||
$g = q("select hash from pgrp where id = %d and visible = 1 limit 1",
|
||||
intval($grp)
|
||||
);
|
||||
if($g && $exclusive) {
|
||||
@@ -2958,7 +2965,9 @@ function item_url_replace($channel,&$item,$old,$new,$oldnick = '') {
|
||||
json_url_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['target']);
|
||||
}
|
||||
|
||||
if(string_replace($old,$new,$item['body'])) {
|
||||
$x = preg_replace("/".preg_quote($old,'/')."\/(search|\w+\/".$channel['channel_address'].")/", $new.'/${1}', $item['body']);
|
||||
if($x) {
|
||||
$item['body'] = $x;
|
||||
$item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey']));
|
||||
$item['item_verified'] = 1;
|
||||
}
|
||||
@@ -3251,17 +3260,17 @@ function cleanup_bbcode($body) {
|
||||
* First protect any url inside certain bbcode tags so we don't double link it.
|
||||
*/
|
||||
|
||||
|
||||
$body = preg_replace_callback('/\[code(.*?)\[\/(code)\]/ism','\red_escape_codeblock',$body);
|
||||
$body = preg_replace_callback('/\[url(.*?)\[\/(url)\]/ism','\red_escape_codeblock',$body);
|
||||
$body = preg_replace_callback('/\[zrl(.*?)\[\/(zrl)\]/ism','\red_escape_codeblock',$body);
|
||||
|
||||
|
||||
$body = preg_replace_callback("/([^\]\='".'"'."\/\{]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\
|
||||
+\,\(\)]+)/ismu", '\nakedoembed', $body);
|
||||
|
||||
$body = preg_replace_callback("/([^\]\='".'"'."\/\{]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\
|
||||
+\,\(\)]+)/ismu", '\red_zrl_callback', $body);
|
||||
|
||||
|
||||
$body = preg_replace_callback('/\[\$b64zrl(.*?)\[\/(zrl)\]/ism','\red_unescape_codeblock',$body);
|
||||
$body = preg_replace_callback('/\[\$b64url(.*?)\[\/(url)\]/ism','\red_unescape_codeblock',$body);
|
||||
$body = preg_replace_callback('/\[\$b64code(.*?)\[\/(code)\]/ism','\red_unescape_codeblock',$body);
|
||||
@@ -3412,3 +3421,41 @@ function get_forum_channels($uid) {
|
||||
return $r;
|
||||
|
||||
}
|
||||
|
||||
function print_array($arr, $level = 0) {
|
||||
|
||||
$o = EMPTY_STR;
|
||||
$tabs = EMPTY_STR;
|
||||
|
||||
if(is_array($arr)) {
|
||||
for($x = 0; $x <= $level; $x ++) {
|
||||
$tabs .= "\t";
|
||||
}
|
||||
$o .= '[' . "\n";
|
||||
if(count($arr)) {
|
||||
foreach($arr as $k => $v) {
|
||||
if(is_array($v)) {
|
||||
$o .= $tabs . '[' . $k . '] => ' . print_array($v, $level + 1) . "\n";
|
||||
}
|
||||
else {
|
||||
$o .= $tabs . '[' . $k . '] => ' . print_val($v) . ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
$o .= substr($tabs,0,-1) . ']' . (($level) ? ',' : ';' ). "\n";
|
||||
return $o;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function print_val($v) {
|
||||
if(is_bool($v)) {
|
||||
if($v) return 'true';
|
||||
return 'false';
|
||||
}
|
||||
if(is_string($v)) {
|
||||
return "'" . $v . "'";
|
||||
}
|
||||
return $v;
|
||||
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ function xchan_change_key($oldx,$newx,$data) {
|
||||
$tables = [
|
||||
'abook' => 'abook_xchan',
|
||||
'abconfig' => 'xchan',
|
||||
'group_member' => 'xchan',
|
||||
'pgrp_member' => 'xchan',
|
||||
'chat' => 'chat_xchan',
|
||||
'chatpresence' => 'cp_xchan',
|
||||
'event' => 'event_xchan',
|
||||
|
||||
@@ -12,6 +12,7 @@ require_once('include/crypto.php');
|
||||
require_once('include/items.php');
|
||||
require_once('include/queue_fn.php');
|
||||
require_once('include/perm_upgrade.php');
|
||||
require_once('include/msglib.php');
|
||||
|
||||
|
||||
/**
|
||||
@@ -491,7 +492,7 @@ function zot_refresh($them, $channel = null, $force = false) {
|
||||
$profile_assign = get_pconfig($channel['channel_id'],'system','profile_assign','');
|
||||
|
||||
// Keep original perms to check if we need to notify them
|
||||
$previous_perms = get_all_perms($channel['channel_id'],$x['hash']);
|
||||
$previous_perms = get_all_perms($channel['channel_id'],$x['hash'],false);
|
||||
|
||||
$r = q("select * from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1",
|
||||
dbesc($x['hash']),
|
||||
@@ -560,7 +561,7 @@ function zot_refresh($them, $channel = null, $force = false) {
|
||||
|
||||
if($y) {
|
||||
logger("New introduction received for {$channel['channel_name']}");
|
||||
$new_perms = get_all_perms($channel['channel_id'],$x['hash']);
|
||||
$new_perms = get_all_perms($channel['channel_id'],$x['hash'],false);
|
||||
|
||||
// Send a clone sync packet and a permissions update if permissions have changed
|
||||
|
||||
@@ -1118,6 +1119,7 @@ function zot_process_response($hub, $arr, $outq) {
|
||||
}
|
||||
|
||||
foreach($x['delivery_report'] as $xx) {
|
||||
call_hooks('dreport_process',$xx);
|
||||
if(is_array($xx) && array_key_exists('message_id',$xx) && delivery_report_is_storable($xx)) {
|
||||
q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s','%s','%s','%s','%s' ) ",
|
||||
dbesc($xx['message_id']),
|
||||
@@ -1807,13 +1809,28 @@ function process_delivery($sender, $arr, $deliveries, $relay, $public = false, $
|
||||
else {
|
||||
$arr['item_wall'] = 0;
|
||||
}
|
||||
|
||||
|
||||
if((! perm_is_allowed($channel['channel_id'],$sender['hash'],$perm)) && (! $tag_delivery) && (! $local_public)) {
|
||||
logger("permission denied for delivery to channel {$channel['channel_id']} {$channel['channel_address']}");
|
||||
$DR->update('permission denied');
|
||||
$result[] = $DR->get();
|
||||
continue;
|
||||
}
|
||||
if ((! $tag_delivery) && (! $local_public)) {
|
||||
$allowed = (perm_is_allowed($channel['channel_id'],$sender['hash'],$perm));
|
||||
|
||||
if((! $allowed) && $perm == 'post_comments') {
|
||||
$parent = q("select * from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($arr['parent_mid']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if ($parent) {
|
||||
$allowed = can_comment_on_post($d['hash'],$parent[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (! $allowed) {
|
||||
logger("permission denied for delivery to channel {$channel['channel_id']} {$channel['channel_address']}");
|
||||
$DR->update('permission denied');
|
||||
$result[] = $DR->get();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if($arr['mid'] != $arr['parent_mid']) {
|
||||
|
||||
@@ -2315,16 +2332,13 @@ function process_mail_delivery($sender, $arr, $deliveries) {
|
||||
}
|
||||
|
||||
|
||||
$r = q("select id from mail where mid = '%s' and channel_id = %d limit 1",
|
||||
$r = q("select id, conv_guid from mail where mid = '%s' and channel_id = %d limit 1",
|
||||
dbesc($arr['mid']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if($r) {
|
||||
if(intval($arr['mail_recalled'])) {
|
||||
$x = q("delete from mail where id = %d and channel_id = %d",
|
||||
intval($r[0]['id']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
msg_drop($r[0]['id'], $channel['channel_id'], $r[0]['conv_guid']);
|
||||
$DR->update('mail recalled');
|
||||
$result[] = $DR->get();
|
||||
logger('mail_recalled');
|
||||
@@ -3306,13 +3320,13 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
|
||||
}
|
||||
|
||||
if($groups_changed) {
|
||||
$r = q("select hash as collection, visible, deleted, gname as name from groups where uid = %d",
|
||||
$r = q("select hash as collection, visible, deleted, gname as name from pgrp where uid = %d",
|
||||
intval($uid)
|
||||
);
|
||||
if($r)
|
||||
$info['collections'] = $r;
|
||||
|
||||
$r = q("select groups.hash as collection, group_member.xchan as member from groups left join group_member on groups.id = group_member.gid where group_member.uid = %d",
|
||||
$r = q("select pgrp.hash as collection, pgrp_member.xchan as member from pgrp left join pgrp_member on pgrp.id = pgrp_member.gid where pgrp_member.uid = %d",
|
||||
intval($uid)
|
||||
);
|
||||
if($r)
|
||||
@@ -3557,13 +3571,13 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
}
|
||||
|
||||
$disallowed = [
|
||||
'channel_id', 'channel_account_id', 'channel_primary', 'channel_prvkey',
|
||||
'channel_address', 'channel_notifyflags', 'channel_removed', 'channel_deleted',
|
||||
'channel_system', 'channel_r_stream', 'channel_r_profile', 'channel_r_abook',
|
||||
'channel_r_storage', 'channel_r_pages', 'channel_w_stream', 'channel_w_wall',
|
||||
'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall',
|
||||
'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish',
|
||||
'channel_a_delegate'
|
||||
'channel_id', 'channel_account_id', 'channel_primary', 'channel_prvkey',
|
||||
'channel_address', 'channel_notifyflags', 'channel_removed', 'channel_deleted',
|
||||
'channel_system', 'channel_r_stream', 'channel_r_profile', 'channel_r_abook',
|
||||
'channel_r_storage', 'channel_r_pages', 'channel_w_stream', 'channel_w_wall',
|
||||
'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall',
|
||||
'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish',
|
||||
'channel_a_delegate', 'channel_moved'
|
||||
];
|
||||
|
||||
$clean = array();
|
||||
@@ -3720,7 +3734,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
// sync collections (privacy groups) oh joy...
|
||||
|
||||
if(array_key_exists('collections',$arr) && is_array($arr['collections']) && count($arr['collections'])) {
|
||||
$x = q("select * from groups where uid = %d",
|
||||
$x = q("select * from pgrp where uid = %d",
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
foreach($arr['collections'] as $cl) {
|
||||
@@ -3736,7 +3750,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
if(($y['gname'] != $cl['name'])
|
||||
|| ($y['visible'] != $cl['visible'])
|
||||
|| ($y['deleted'] != $cl['deleted'])) {
|
||||
q("update groups set gname = '%s', visible = %d, deleted = %d where hash = '%s' and uid = %d",
|
||||
q("update pgrp set gname = '%s', visible = %d, deleted = %d where hash = '%s' and uid = %d",
|
||||
dbesc($cl['name']),
|
||||
intval($cl['visible']),
|
||||
intval($cl['deleted']),
|
||||
@@ -3745,14 +3759,14 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
);
|
||||
}
|
||||
if(intval($cl['deleted']) && (! intval($y['deleted']))) {
|
||||
q("delete from group_member where gid = %d",
|
||||
q("delete from pgrp_member where gid = %d",
|
||||
intval($y['id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(! $found) {
|
||||
$r = q("INSERT INTO groups ( hash, uid, visible, deleted, gname )
|
||||
$r = q("INSERT INTO pgrp ( hash, uid, visible, deleted, gname )
|
||||
VALUES( '%s', %d, %d, %d, '%s' ) ",
|
||||
dbesc($cl['collection']),
|
||||
intval($channel['channel_id']),
|
||||
@@ -3776,10 +3790,10 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
}
|
||||
}
|
||||
if(! $found_local) {
|
||||
q("delete from group_member where gid = %d",
|
||||
q("delete from pgrp_member where gid = %d",
|
||||
intval($y['id'])
|
||||
);
|
||||
q("update groups set deleted = 1 where id = %d and uid = %d",
|
||||
q("update pgrp set deleted = 1 where id = %d and uid = %d",
|
||||
intval($y['id']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
@@ -3789,7 +3803,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
}
|
||||
|
||||
// reload the group list with any updates
|
||||
$x = q("select * from groups where uid = %d",
|
||||
$x = q("select * from pgrp where uid = %d",
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
@@ -3816,7 +3830,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
if(isset($y['hash']) && isset($members[$y['hash']])) {
|
||||
foreach($members[$y['hash']] as $member) {
|
||||
$found = false;
|
||||
$z = q("select xchan from group_member where gid = %d and uid = %d and xchan = '%s' limit 1",
|
||||
$z = q("select xchan from pgrp_member where gid = %d and uid = %d and xchan = '%s' limit 1",
|
||||
intval($y['id']),
|
||||
intval($channel['channel_id']),
|
||||
dbesc($member)
|
||||
@@ -3827,7 +3841,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
// if somebody is in the group that wasn't before - add them
|
||||
|
||||
if(! $found) {
|
||||
q("INSERT INTO group_member (uid, gid, xchan)
|
||||
q("INSERT INTO pgrp_member (uid, gid, xchan)
|
||||
VALUES( %d, %d, '%s' ) ",
|
||||
intval($channel['channel_id']),
|
||||
intval($y['id']),
|
||||
@@ -3838,7 +3852,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
}
|
||||
|
||||
// now retrieve a list of members we have on this site
|
||||
$m = q("select xchan from group_member where gid = %d and uid = %d",
|
||||
$m = q("select xchan from pgrp_member where gid = %d and uid = %d",
|
||||
intval($y['id']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
@@ -3846,7 +3860,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
foreach($m as $mm) {
|
||||
// if the local existing member isn't in the list we just received - remove them
|
||||
if(! in_array($mm['xchan'],$members[$y['hash']])) {
|
||||
q("delete from group_member where xchan = '%s' and gid = %d and uid = %d",
|
||||
q("delete from pgrp_member where xchan = '%s' and gid = %d and uid = %d",
|
||||
dbesc($mm['xchan']),
|
||||
intval($y['id']),
|
||||
intval($channel['channel_id'])
|
||||
@@ -4419,7 +4433,7 @@ function zotinfo($arr) {
|
||||
if(! $ret['follow_url'])
|
||||
$ret['follow_url'] = z_root() . '/follow?f=&url=%s';
|
||||
|
||||
$permissions = get_all_perms($e['channel_id'],$ztarget_hash,false);
|
||||
$permissions = get_all_perms($e['channel_id'],$ztarget_hash,false,false);
|
||||
|
||||
if($ztarget_hash) {
|
||||
$permissions['connected'] = false;
|
||||
|
||||
Reference in New Issue
Block a user