diff options
Diffstat (limited to 'Zotlabs')
43 files changed, 812 insertions, 328 deletions
diff --git a/Zotlabs/Access/PermissionRoles.php b/Zotlabs/Access/PermissionRoles.php index 8b116adc5..94c49c44f 100644 --- a/Zotlabs/Access/PermissionRoles.php +++ b/Zotlabs/Access/PermissionRoles.php @@ -7,6 +7,9 @@ use Zotlabs\Lib as Zlib; class PermissionRoles { + static public function version() { + return 1; + } static function role_perms($role) { @@ -160,6 +163,7 @@ class PermissionRoles { $ret['limits'] = PermissionLimits::Std_Limits(); break; + case 'custom': default: break; } @@ -174,7 +178,48 @@ class PermissionRoles { return $ret; } + static public function new_custom_perms($uid,$perm,$abooks) { + + // set permissionlimits for this permission here, for example: + + // if($perm === 'mynewperm') + // \Zotlabs\Access\PermissionLimits::Set($uid,$perm,1); + + + // set autoperms here if applicable + // choices are to set to 0, 1, or the value of an existing perm + + if(get_pconfig($uid,'system','autoperms')) { + + $c = channelx_by_n($uid); + $value = 0; + // if($perm === 'mynewperm') + // $value = get_abconfig($uid,$c['channel_hash'],'autoperms','someexistingperm')); + + if($c) { + set_abconfig($uid,$c['channel_hash'],'autoperms',$perm,$value); + } + + + } + + // now set something for all existing connections. + + if($abooks) { + foreach($abooks as $ab) { + switch($perm) { + // case 'mynewperm': + // choices are to set to 1, set to 0, or clone an existing perm + // set_abconfig($uid,$ab['abook_xchan'],'my_perms',$perm, + // get_abconfig($uid,$ab['abook_xchan'],'my_perms','someexistingperm')); + + default: + break; + } + } + } + } static public function roles() { diff --git a/Zotlabs/Access/Permissions.php b/Zotlabs/Access/Permissions.php index 61ea51a48..5fded5f03 100644 --- a/Zotlabs/Access/Permissions.php +++ b/Zotlabs/Access/Permissions.php @@ -10,9 +10,20 @@ class Permissions { /** * Extensible permissions. * To add new permissions, add to the list of $perms below, with a simple description. + * * Also visit PermissionRoles.php and add to the $ret['perms_connect'] property for any role * if this permission should be granted to new connections. * + * Next look at PermissionRoles::new_custom_perms() and provide a handler for updating custom + * permission roles. You will want to set a default PermissionLimit for each channel and also + * provide a sane default for any existing connections. You may or may not wish to provide a + * default auto permission. If in doubt, leave this alone as custom permissions by definition + * are the responsibility of the channel owner to manage. You just don't want to create any + * suprises or break things so you have an opportunity to provide sane settings. + * + * Update the version here and in PermissionRoles + * + * * Permissions with 'view' in the name are considered read permissions. Anything * else requires authentication. Read permission limits are PERMS_PUBLIC and anything else * is given PERMS_SPECIFIC. @@ -23,6 +34,11 @@ class Permissions { * */ + static public function version() { + // This must match the version in PermissionRoles.php before permission updates can run. + return 1; + } + static public function Perms($filter = '') { diff --git a/Zotlabs/Daemon/Notifier.php b/Zotlabs/Daemon/Notifier.php index 36edbc057..63ced4f56 100644 --- a/Zotlabs/Daemon/Notifier.php +++ b/Zotlabs/Daemon/Notifier.php @@ -491,7 +491,7 @@ class Notifier { // Now we have collected recipients (except for external mentions, FIXME) // Let's reduce this to a set of hubs. - $r = q("select * from hubloc where hubloc_hash in (" . implode(',',$recipients) . ") + $r = q("select hubloc.*, site.site_crypto from hubloc left join site on site_url = hubloc_url where hubloc_hash in (" . implode(',',$recipients) . ") and hubloc_error = 0 and hubloc_deleted = 0" ); @@ -603,8 +603,8 @@ class Notifier { $packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null)); } elseif($packet_type === 'request') { - $packet = zot_build_packet($channel,$packet_type,$env_recips,$hub['hubloc_sitekey'],$hash, - array('message_id' => $request_message_id) + $packet = zot_build_packet($channel,$packet_type,$env_recips,$hub['hubloc_sitekey'],$hub['site_crypto'], + $hash, array('message_id' => $request_message_id) ); } @@ -618,7 +618,7 @@ class Notifier { )); } else { - $packet = zot_build_packet($channel,'notify',$env_recips,(($private) ? $hub['hubloc_sitekey'] : null),$hash); + $packet = zot_build_packet($channel,'notify',$env_recips,(($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'],$hash); queue_insert(array( 'hash' => $hash, 'account_id' => $target_item['aid'], diff --git a/Zotlabs/Daemon/Ratenotif.php b/Zotlabs/Daemon/Ratenotif.php index 1cba5e26d..a94b89004 100644 --- a/Zotlabs/Daemon/Ratenotif.php +++ b/Zotlabs/Daemon/Ratenotif.php @@ -77,7 +77,7 @@ class Ratenotif { continue; $hash = random_string(); - $n = zot_build_packet($channel,'notify',null,null,$hash); + $n = zot_build_packet($channel,'notify',null,null,'',$hash); queue_insert(array( 'hash' => $hash, diff --git a/Zotlabs/Lib/AConfig.php b/Zotlabs/Lib/AConfig.php index ab8648a18..4e7c5483f 100644 --- a/Zotlabs/Lib/AConfig.php +++ b/Zotlabs/Lib/AConfig.php @@ -10,8 +10,8 @@ class AConfig { return XConfig::Load('a_' . $account_id); } - static public function Get($account_id,$family,$key) { - return XConfig::Get('a_' . $account_id,$family,$key); + static public function Get($account_id,$family,$key,$default = false) { + return XConfig::Get('a_' . $account_id,$family,$key, $default); } static public function Set($account_id,$family,$key,$value) { diff --git a/Zotlabs/Lib/AbConfig.php b/Zotlabs/Lib/AbConfig.php index cb5d96951..dfc9efc6c 100644 --- a/Zotlabs/Lib/AbConfig.php +++ b/Zotlabs/Lib/AbConfig.php @@ -16,7 +16,7 @@ class AbConfig { } - static public function Get($chan,$xhash,$family,$key) { + static public function Get($chan,$xhash,$family,$key, $default = false) { $r = q("select * from abconfig where chan = %d and xchan = '%s' and cat = '%s' and k = '%s' limit 1", intval($chan), dbesc($xhash), @@ -26,7 +26,7 @@ class AbConfig { if($r) { return ((preg_match('|^a:[0-9]+:{.*}$|s', $r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']); } - return false; + return $default; } diff --git a/Zotlabs/Lib/Apps.php b/Zotlabs/Lib/Apps.php index a2f253299..46486bb5a 100644 --- a/Zotlabs/Lib/Apps.php +++ b/Zotlabs/Lib/Apps.php @@ -38,6 +38,7 @@ class Apps { if(plugin_is_installed($plugin)) { $x = self::parse_app_description($f,$translate); if($x) { + $x['plugin'] = $plugin; $ret[] = $x; } } @@ -54,7 +55,6 @@ class Apps { return; $apps = self::get_system_apps(false); - self::$installed_system_apps = q("select * from app where app_system = 1 and app_channel = %d", intval(local_channel()) ); @@ -68,7 +68,7 @@ class Apps { if($id !== true) { // if we already installed this app, but it changed, preserve any categories we created $s = ''; - $r = q("select * from term where otype = %d and oid = d", + $r = q("select * from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($id) ); @@ -100,6 +100,8 @@ class Apps { } $notfound = true; foreach(self::$installed_system_apps as $iapp) { + if($app['plugin'] && (! $iapp['app_plugin'])) + return(1); if($iapp['app_id'] == hash('whirlpool',$app['name'])) { $notfound = false; if($iapp['app_version'] != $app['version']) { @@ -238,9 +240,9 @@ class Apps { 'Profile Photo' => t('Profile Photo') ); - if(array_key_exists($arr['name'],$apps)) + if(array_key_exists($arr['name'],$apps)) { $arr['name'] = $apps[$arr['name']]; - + } } @@ -267,6 +269,9 @@ class Apps { self::translate_system_apps($papp); + if(($papp['plugin']) && (! plugin_is_installed($papp['plugin']))) + return ''; + $papp['papp'] = self::papp_encode($papp); if(! strstr($papp['url'],'://')) @@ -339,7 +344,9 @@ class Apps { '$purchase' => (($papp['page'] && (! $installed)) ? t('Purchase') : ''), '$install' => (($hosturl && $mode == 'view') ? $install_action : ''), '$edit' => ((local_channel() && $installed && $mode == 'edit') ? t('Edit') : ''), - '$delete' => ((local_channel() && $installed && $mode == 'edit') ? t('Delete') : '') + '$delete' => ((local_channel() && $installed && $mode == 'edit') ? t('Delete') : ''), + '$undelete' => ((local_channel() && $installed && $mode == 'edit') ? t('Undelete') : ''), + '$deleted' => $papp['deleted'] )); } @@ -359,7 +366,7 @@ class Apps { if($r) { if(! $r[0]['app_system']) { if($app['categories'] && (! $app['term'])) { - $r[0]['term'] = q("select * from term where otype = %d and oid = d", + $r[0]['term'] = q("select * from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), intval($r[0]['id']) ); @@ -382,31 +389,60 @@ class Apps { intval($uid) ); if($x) { - $x[0]['app_deleted'] = 1; - q("delete from term where otype = %d and oid = %d", - intval(TERM_OBJ_APP), - intval($x[0]['id']) - ); - if($x[0]['app_system']) { - $r = q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d", - dbesc($app['guid']), - intval($uid) + if(! intval($x[0]['app_deleted'])) { + $x[0]['app_deleted'] = 1; + q("delete from term where otype = %d and oid = %d", + intval(TERM_OBJ_APP), + intval($x[0]['id']) ); + if($x[0]['app_system']) { + $r = q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d", + dbesc($app['guid']), + intval($uid) + ); + } + else { + $r = q("delete from app where app_id = '%s' and app_channel = %d", + dbesc($app['guid']), + intval($uid) + ); + + // we don't sync system apps - they may be completely different on the other system + build_sync_packet($uid,array('app' => $x)); + } } else { - $r = q("delete from app where app_id = '%s' and app_channel = %d", + self::app_undestroy($uid,$app); + } + } + } + } + + + static public function app_undestroy($uid,$app) { + + // undelete a system app + + if($uid && $app['guid']) { + + $x = q("select * from app where app_id = '%s' and app_channel = %d limit 1", + dbesc($app['guid']), + intval($uid) + ); + if($x) { + if($x[0]['app_system']) { + $r = q("update app set app_deleted = 0 where app_id = '%s' and app_channel = %d", dbesc($app['guid']), intval($uid) ); - - // we don't sync system apps - they may be completely different on the other system - build_sync_packet($uid,array('app' => $x)); } } } } + + static public function app_installed($uid,$app) { $r = q("select id from app where app_id = '%s' and app_version = '%s' and app_channel = %d limit 1", @@ -421,7 +457,7 @@ class Apps { static public function app_list($uid, $deleted = false, $cat = '') { if($deleted) - $sql_extra = " and app_deleted = 1 "; + $sql_extra = ""; else $sql_extra = " and app_deleted = 0 "; @@ -494,13 +530,14 @@ class Apps { $darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : ''); $darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : ''); $darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : ''); + $darray['app_plugin'] = ((x($arr,'plugin')) ? escape_tags($arr['plugin']) : ''); $darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : ''); $darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0); $darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0); $created = datetime_convert(); - $r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited, app_system, app_deleted ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )", + $r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited, app_system, app_plugin, app_deleted ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', %d )", dbesc($darray['app_id']), dbesc($darray['app_sig']), dbesc($darray['app_author']), @@ -517,6 +554,7 @@ class Apps { dbesc($created), dbesc($created), intval($darray['app_system']), + dbesc($darray['app_plugin']), intval($darray['app_deleted']) ); if($r) { @@ -569,13 +607,14 @@ class Apps { $darray['app_addr'] = ((x($arr,'addr')) ? escape_tags($arr['addr']) : ''); $darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : ''); $darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : ''); + $darray['app_plugin'] = ((x($arr,'plugin')) ? escape_tags($arr['plugin']) : ''); $darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : ''); $darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0); $darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0); $edited = datetime_convert(); - $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s', app_system = %d, app_deleted = %d where app_id = '%s' and app_channel = %d", + $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s', app_system = %d, app_plugin = '%s', app_deleted = %d where app_id = '%s' and app_channel = %d", dbesc($darray['app_sig']), dbesc($darray['app_author']), dbesc($darray['app_name']), @@ -589,6 +628,7 @@ class Apps { dbesc($darray['app_requires']), dbesc($edited), intval($darray['app_system']), + dbesc($darray['app_plugin']), intval($darray['app_deleted']), dbesc($darray['app_id']), intval($darray['app_channel']) @@ -673,6 +713,9 @@ class Apps { if($app['app_system']) $ret['system'] = $app['app_system']; + if($app['app_plugin']) + $ret['plugin'] = $app['app_plugin']; + if($app['app_deleted']) $ret['deleted'] = $app['app_deleted']; diff --git a/Zotlabs/Lib/Config.php b/Zotlabs/Lib/Config.php index d4ee1aeda..5625a3f79 100644 --- a/Zotlabs/Lib/Config.php +++ b/Zotlabs/Lib/Config.php @@ -98,13 +98,13 @@ class Config { * @return mixed Return value or false on error or if not set */ - static public function Get($family,$key) { + static public function Get($family,$key,$default = false) { if((! array_key_exists($family, \App::$config)) || (! array_key_exists('config_loaded', \App::$config[$family]))) self::Load($family); if(array_key_exists('config_loaded', \App::$config[$family])) { if(! array_key_exists($key, \App::$config[$family])) { - return false; + return $default; } return ((! is_array(\App::$config[$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$family][$key])) ? unserialize(\App::$config[$family][$key]) @@ -112,7 +112,7 @@ class Config { ); } - return false; + return $default; } /** diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php index b6f4d3351..257687567 100644 --- a/Zotlabs/Lib/Enotify.php +++ b/Zotlabs/Lib/Enotify.php @@ -102,7 +102,7 @@ class Enotify { $title = $params['item']['title']; $body = $params['item']['body']; } - if($item['created'] < datetime_convert('UTC','UTC','now - 1 month')) { + if($params['item']['created'] < datetime_convert('UTC','UTC','now - 1 month')) { logger('notification invoked for an old item which may have been refetched.',LOGGER_DEBUG,LOG_INFO); return; } @@ -217,6 +217,85 @@ class Enotify { $hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>'); } + if ($params['type'] == NOTIFY_LIKE) { +// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG); + + $itemlink = $params['link']; + + // ignore like/unlike activity on posts - they probably require a separate notification preference + + if (array_key_exists('item',$params) && (! activity_match($params['item']['verb'],ACTIVITY_LIKE))) { + logger('notification: not a like activity. Ignoring.'); + pop_lang(); + return; + } + + $parent_mid = $params['parent_mid']; + + // Check to see if there was already a notify for this post. + // If so don't create a second notification + + $p = null; + $p = q("select id from notify where link = '%s' and uid = %d limit 1", + dbesc($params['link']), + intval($recip['channel_id']) + ); + if ($p) { + logger('notification: like already notified'); + pop_lang(); + return; + } + + + // if it's a post figure out who's post it is. + + $p = null; + + if($params['otype'] === 'item' && $parent_mid) { + $p = q("select * from item where mid = '%s' and uid = %d limit 1", + dbesc($parent_mid), + intval($recip['channel_id']) + ); + } + + xchan_query($p); + + + $item_post_type = item_post_type($p[0]); +// $private = $p[0]['item_private']; + $parent_id = $p[0]['id']; + + $parent_item = $p[0]; + + + // "your post" + if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall'])) + $dest_str = sprintf(t('%1$s, %2$s liked [zrl=%3$s]your %4$s[/zrl]'), + $recip['channel_name'], + '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', + $itemlink, + $item_post_type); + else { + pop_lang(); + return; + } + + // Some mail softwares relies on subject field for threading. + // So, we cannot have different subjects for notifications of the same thread. + // Before this we have the name of the replier on the subject rendering + // differents subjects for messages on the same thread. + + $subject = sprintf( t('[$Projectname:Notify] Like received to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']); + $preamble = sprintf( t('%1$s, %2$s liked an item/conversation you created.'), $recip['channel_name'], $sender['xchan_name']); + $epreamble = $dest_str; + + $sitelink = t('Please visit %s to view and/or reply to the conversation.'); + $tsitelink = sprintf( $sitelink, $siteurl ); + $hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>'); + } + + + if($params['type'] == NOTIFY_WALL) { $subject = sprintf( t('[$Projectname:Notify] %s posted to your profile wall') , $sender['xchan_name']); diff --git a/Zotlabs/Lib/IConfig.php b/Zotlabs/Lib/IConfig.php index 28c9ab58e..33d94bd49 100644 --- a/Zotlabs/Lib/IConfig.php +++ b/Zotlabs/Lib/IConfig.php @@ -10,7 +10,7 @@ class IConfig { return; } - static public function Get(&$item, $family, $key) { + static public function Get(&$item, $family, $key, $default = false) { $is_item = false; @@ -28,7 +28,7 @@ class IConfig { $iid = $item; if(! $iid) - return false; + return $default; if(is_array($item) && array_key_exists('iconfig',$item) && is_array($item['iconfig'])) { foreach($item['iconfig'] as $c) { @@ -48,7 +48,7 @@ class IConfig { $item['iconfig'][] = $r[0]; return $r[0]['v']; } - return false; + return $default; } diff --git a/Zotlabs/Lib/PConfig.php b/Zotlabs/Lib/PConfig.php index 3b47a250a..d70697fbc 100644 --- a/Zotlabs/Lib/PConfig.php +++ b/Zotlabs/Lib/PConfig.php @@ -67,16 +67,16 @@ class PConfig { * @return mixed Stored value or false if it does not exist */ - static public function Get($uid,$family,$key,$instore = false) { + static public function Get($uid,$family,$key,$default = false) { if(is_null($uid) || $uid === false) - return false; + return $default; if(! array_key_exists($uid, \App::$config)) self::Load($uid); if((! array_key_exists($family, \App::$config[$uid])) || (! array_key_exists($key, \App::$config[$uid][$family]))) - return false; + return $default; return ((! is_array(\App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$uid][$family][$key])) ? unserialize(\App::$config[$uid][$family][$key]) diff --git a/Zotlabs/Lib/System.php b/Zotlabs/Lib/System.php index 32aaa82a9..306c90f4a 100644 --- a/Zotlabs/Lib/System.php +++ b/Zotlabs/Lib/System.php @@ -42,6 +42,20 @@ class System { } + static public function get_project_link() { + if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['project_link']) + return \App::$config['system']['project_link']; + return 'https://hubzilla.org'; + } + + static public function get_project_srclink() { + if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['project_srclink']) + return \App::$config['system']['project_srclink']; + return 'https://github.com/redmatrix/hubzilla'; + } + + + static public function get_server_role() { if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['server_role']) return \App::$config['system']['server_role']; @@ -54,5 +68,15 @@ class System { return '0.0.0'; } + static public function compatible_project($p) { + if(get_directory_realm() != DIRECTORY_REALM) + return true; + + foreach(['hubzilla','zap'] as $t) { + if(stristr($p,$t)) + return true; + } + return false; + } } diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index 48b50b295..e636e5614 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -44,7 +44,7 @@ class ThreadItem { * Only add those that will be displayed */ - if((! visible_activity($item)) || array_key_exists('author_blocked',$item)) { + if((! visible_activity($item)) || array_key_exists('blocked',$item)) { continue; } @@ -335,6 +335,8 @@ class ThreadItem { 'wall' => t('Wall-to-Wall'), 'vwall' => t('via Wall-To-Wall:'), 'profile_url' => $profile_link, + 'thread_action_menu' => thread_action_menu($item,$conv->get_mode()), + 'thread_author_menu' => thread_author_menu($item,$conv->get_mode()), 'item_photo_menu' => item_photo_menu($item), 'dreport' => $dreport, 'name' => $profile_name, diff --git a/Zotlabs/Lib/XConfig.php b/Zotlabs/Lib/XConfig.php index 7f3d0f2cd..bf78c360f 100644 --- a/Zotlabs/Lib/XConfig.php +++ b/Zotlabs/Lib/XConfig.php @@ -59,16 +59,16 @@ class XConfig { * @return mixed Stored $value or false if it does not exist */ - static public function Get($xchan, $family, $key) { + static public function Get($xchan, $family, $key, $default = false) { if(! $xchan) - return false; + return $default; if(! array_key_exists($xchan, \App::$config)) load_xconfig($xchan); if((! array_key_exists($family, \App::$config[$xchan])) || (! array_key_exists($key, \App::$config[$xchan][$family]))) - return false; + return $default; return ((! is_array(\App::$config[$xchan][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$xchan][$family][$key])) ? unserialize(\App::$config[$xchan][$family][$key]) diff --git a/Zotlabs/Module/Admin/Site.php b/Zotlabs/Module/Admin/Site.php index 251533e68..829ca71e4 100644 --- a/Zotlabs/Module/Admin/Site.php +++ b/Zotlabs/Module/Admin/Site.php @@ -22,6 +22,7 @@ class Site { $banner = ((x($_POST,'banner')) ? trim($_POST['banner']) : false); $admininfo = ((x($_POST,'admininfo')) ? trim($_POST['admininfo']) : false); + $siteinfo = ((x($_POST,'siteinfo')) ? trim($_POST['siteinfo']) : ''); $language = ((x($_POST,'language')) ? notags(trim($_POST['language'])) : ''); $theme = ((x($_POST,'theme')) ? notags(trim($_POST['theme'])) : ''); $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : ''); @@ -97,6 +98,7 @@ class Site { linkify_tags($a, $admininfo, local_channel()); set_config('system', 'admininfo', $admininfo); } + set_config('system','siteinfo',$siteinfo); set_config('system', 'language', $language); set_config('system', 'theme', $theme); if ( $theme_mobile === '---' ) { @@ -273,6 +275,7 @@ class Site { '$banner' => array('banner', t("Banner/Logo"), $banner, ""), '$admininfo' => array('admininfo', t("Administrator Information"), $admininfo, t("Contact information for site administrators. Displayed on siteinfo page. BBCode can be used here")), + '$siteinfo' => array('siteinfo', t('Site Information'), get_config('system','siteinfo'), t("Publicly visible description of this site. Displayed on siteinfo page. BBCode can be used here")), '$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices), '$theme' => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices), '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile), diff --git a/Zotlabs/Module/Appman.php b/Zotlabs/Module/Appman.php index a200e986a..425b2d539 100644 --- a/Zotlabs/Module/Appman.php +++ b/Zotlabs/Module/Appman.php @@ -56,6 +56,7 @@ class Appman extends \Zotlabs\Web\Controller { if($_POST['delete']) { Zlib\Apps::app_destroy(local_channel(),$papp); } + if($_POST['edit']) { return; diff --git a/Zotlabs/Module/Apps.php b/Zotlabs/Module/Apps.php index 4dab621b2..5583f1757 100644 --- a/Zotlabs/Module/Apps.php +++ b/Zotlabs/Module/Apps.php @@ -21,7 +21,7 @@ class Apps extends \Zotlabs\Web\Controller { if(local_channel()) { Zlib\Apps::import_system_apps(); $syslist = array(); - $list = Zlib\Apps::app_list(local_channel(), false, $_GET['cat']); + $list = Zlib\Apps::app_list(local_channel(), (($mode == 'edit') ? true : false), $_GET['cat']); if($list) { foreach($list as $x) { $syslist[] = Zlib\Apps::app_encode($x); diff --git a/Zotlabs/Module/Cal.php b/Zotlabs/Module/Cal.php index 1279a51b1..b982d19a8 100644 --- a/Zotlabs/Module/Cal.php +++ b/Zotlabs/Module/Cal.php @@ -292,8 +292,8 @@ class Cal extends \Zotlabs\Web\Controller { $title = strip_tags(html_entity_decode($title,ENT_QUOTES,'UTF-8')); } $html = format_event_html($rr); - $rr['desc'] = bbcode($rr['desc']); - $rr['location'] = bbcode($rr['location']); + $rr['desc'] = zidify_links(smilies(bbcode($rr['desc']))); + $rr['location'] = zidify_links(smilies(bbcode($rr['location']))); $events[] = array( 'id'=>$rr['id'], 'hash' => $rr['event_hash'], diff --git a/Zotlabs/Module/Chatsvc.php b/Zotlabs/Module/Chatsvc.php index 6a28a7c4d..0f79e3b4c 100644 --- a/Zotlabs/Module/Chatsvc.php +++ b/Zotlabs/Module/Chatsvc.php @@ -111,8 +111,22 @@ class Chatsvc extends \Zotlabs\Web\Controller { intval(\App::$data['chat']['room_id']) ); if($r) { - foreach($r as $rr) { - switch($rr['cp_status']) { + foreach($r as $rv) { + if(! $rv['xchan_name']) { + $rv['xchan_hash'] = $rv['cp_xchan']; + $rv['xchan_name'] = substr($rv['cp_xchan'],strrpos($rv['cp_xchan'],'.')+1); + $rv['xchan_addr'] = ''; + $rv['xchan_network'] = 'unknown'; + $rv['xchan_url'] = z_root(); + $rv['xchan_hidden'] = 1; + $rv['xchan_photo_mimetype'] = 'image/jpeg'; + $rv['xchan_photo_l'] = get_default_profile_photo(300); + $rv['xchan_photo_m'] = get_default_profile_photo(80); + $rv['xchan_photo_s'] = get_default_profile_photo(48); + + } + + switch($rv['cp_status']) { case 'away': $status = t('Away'); $status_class = 'away'; @@ -124,7 +138,7 @@ class Chatsvc extends \Zotlabs\Web\Controller { break; } - $inroom[] = array('img' => zid($rr['xchan_photo_m']), 'img_type' => $rr['xchan_photo_mimetype'],'name' => $rr['xchan_name'], 'status' => $status, 'status_class' => $status_class); + $inroom[] = array('img' => zid($rv['xchan_photo_m']), 'img_type' => $rv['xchan_photo_mimetype'],'name' => $rv['xchan_name'], 'status' => $status, 'status_class' => $status_class); } } @@ -143,7 +157,7 @@ class Chatsvc extends \Zotlabs\Web\Controller { 'name' => $rr['xchan_name'], 'isotime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'c'), 'localtime' => datetime_convert('UTC', date_default_timezone_get(), $rr['created'], 'r'), - 'text' => smilies(bbcode($rr['chat_text'])), + 'text' => zidify_links(smilies(bbcode($rr['chat_text']))), 'self' => ((get_observer_hash() == $rr['chat_xchan']) ? 'self' : '') ); } diff --git a/Zotlabs/Module/Connections.php b/Zotlabs/Module/Connections.php index a412d16ae..950be660d 100644 --- a/Zotlabs/Module/Connections.php +++ b/Zotlabs/Module/Connections.php @@ -228,10 +228,18 @@ class Connections extends \Zotlabs\Web\Controller { $contacts = array(); - if(count($r)) { - + if($r) { + + vcard_query($r); + + foreach($r as $rr) { if($rr['xchan_url']) { + + if(($rr['vcard']) && is_array($rr['vcard']['tels']) && $rr['vcard']['tels'][0]['nr']) + $phone = ((\App::$is_mobile || \App::$is_tablet) ? $rr['vcard']['tels'][0]['nr'] : ''); + else + $phone = ''; $status_str = ''; $status = array( @@ -267,6 +275,8 @@ class Connections extends \Zotlabs\Web\Controller { 'network_label' => t('Network'), 'network' => network_to_name($rr['xchan_network']), 'public_forum' => ((intval($rr['xchan_pubforum'])) ? true : false), + 'call' => t('Call'), + 'phone' => $phone, 'status_label' => t('Status'), 'status' => $status_str, 'connected_label' => t('Connected'), diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 5ab6f814b..d60ffcd56 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -37,15 +37,17 @@ class Connedit extends \Zotlabs\Web\Controller { intval(argv(1)) ); if($r) { - \App::$poi = $r[0]; + \App::$poi = array_shift($r); } } + $channel = \App::get_channel(); if($channel) head_set_icon($channel['xchan_photo_s']); } + /* @brief Evaluate posted values and set changes * @@ -84,6 +86,12 @@ class Connedit extends \Zotlabs\Web\Controller { call_hooks('contact_edit_post', $_POST); + $vc = get_abconfig(local_channel(),$orig_record['abook_xchan'],'system','vcard'); + $vcard = (($vc) ? \Sabre\VObject\Reader::read($vc) : null); + $serialised_vcard = update_vcard($_REQUEST,$vcard); + if($serialised_vcard) + set_abconfig(local_channel(),$orig_record[0]['abook_xchan'],'system','vcard',$serialised_vcard); + if(intval($orig_record[0]['abook_self'])) { $autoperms = intval($_POST['autoperms']); $is_self = true; @@ -365,7 +373,7 @@ class Connedit extends \Zotlabs\Web\Controller { intval(\App::$poi['abook_id']) ); if($r) { - \App::$poi = $r[0]; + \App::$poi = array_shift($r); } $clone = \App::$poi; @@ -396,6 +404,7 @@ class Connedit extends \Zotlabs\Web\Controller { return login(); } + $section = ((array_key_exists('section',$_REQUEST)) ? $_REQUEST['section'] : ''); $channel = \App::get_channel(); $my_perms = get_channel_default_perms(local_channel()); $role = get_pconfig(local_channel(),'system','permissions_role'); @@ -546,9 +555,33 @@ class Connedit extends \Zotlabs\Web\Controller { if(\App::$poi) { + $abook_prev = 0; + $abook_next = 0; + $contact_id = \App::$poi['abook_id']; $contact = \App::$poi; - + + $cn = q("SELECT abook_id, xchan_name from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 order by xchan_name", + intval(local_channel()) + ); + + if($cn) { + $pntotal = count($cn); + + for($x = 0; $x < $pntotal; $x ++) { + if($cn[$x]['abook_id'] == $contact_id) { + if($x === 0) + $abook_prev = 0; + else + $abook_prev = $cn[$x - 1]['abook_id']; + if($x === $pntotal) + $abook_next = 0; + else + $abook_next = $cn[$x +1]['abook_id']; + } + } + } + $tools = array( 'view' => array( @@ -615,20 +648,30 @@ class Connedit extends \Zotlabs\Web\Controller { $self = false; - if(intval($contact['abook_self'])) + if(intval($contact['abook_self'])) { $self = true; + $abook_prev = $abook_next = 0; + } + $vc = get_abconfig(local_channel(),$contact['abook_xchan'],'system','vcard'); + + $vctmp = (($vc) ? \Sabre\VObject\Reader::read($vc) : null); + $vcard = (($vctmp) ? get_vcard_array($vctmp,$contact['abook_id']) : [] ); + if(! $vcard) + $vcard['fn'] = $contact['xchan_name']; + + $tpl = get_markup_template("abook_edit.tpl"); if(feature_enabled(local_channel(),'affinity')) { - $labels = array( + $labels = [ t('Me'), t('Family'), t('Friends'), t('Acquaintances'), t('All') - ); + ]; call_hooks('affinity_labels',$labels); $label_str = ''; @@ -746,11 +789,12 @@ class Connedit extends \Zotlabs\Web\Controller { else $locstr = t('none'); - $o .= replace_macros($tpl,array( - + $o .= replace_macros($tpl, [ '$header' => (($self) ? t('Connection Default Permissions') : sprintf( t('Connection: %s'),$contact['xchan_name'])), '$autoperms' => array('autoperms',t('Apply these permissions automatically'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('Connection requests will be approved without your interaction'), $yes_no), '$addr' => $contact['xchan_addr'], + '$section' => $section, + '$vcard' => $vcard, '$addr_text' => t('This connection\'s primary address is'), '$loc_text' => t('Available locations:'), '$locstr' => $locstr, @@ -788,12 +832,42 @@ class Connedit extends \Zotlabs\Web\Controller { '$permnote_self' => t('Some permissions may be inherited from your channel\'s <a href="settings"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can change those settings here but they wont have any impact unless the inherited setting changes.'), '$lastupdtext' => t('Last update:'), '$last_update' => relative_date($contact['abook_connected']), + '$is_mobile' => ((\App::$is_mobile || \App::$is_tablet) ? true : false), '$profile_select' => contact_profile_assign($contact['abook_profile']), '$multiprofs' => $multiprofs, '$contact_id' => $contact['abook_id'], '$name' => $contact['xchan_name'], - - )); + '$abook_prev' => $abook_prev, + '$abook_next' => $abook_next, + '$vcard_label' => t('Details'), + '$displayname' => $displayname, + '$name_label' => t('Name'), + '$org_label' => t('Organisation'), + '$title_label' => t('Title'), + '$tel_label' => t('Phone'), + '$email_label' => t('Email'), + '$impp_label' => t('Instant messenger'), + '$url_label' => t('Website'), + '$adr_label' => t('Address'), + '$note_label' => t('Note'), + '$mobile' => t('Mobile'), + '$home' => t('Home'), + '$work' => t('Work'), + '$other' => t('Other'), + '$add_card' => t('Add Contact'), + '$add_field' => t('Add Field'), + '$create' => t('Create'), + '$update' => t('Update'), + '$delete' => t('Delete'), + '$cancel' => t('Cancel'), + '$po_box' => t('P.O. Box'), + '$extra' => t('Additional'), + '$street' => t('Street'), + '$locality' => t('Locality'), + '$region' => t('Region'), + '$zip_code' => t('ZIP Code'), + '$country' => t('Country') + ]); $arr = array('contact' => $contact,'output' => $o); diff --git a/Zotlabs/Module/Directory.php b/Zotlabs/Module/Directory.php index da9bb146f..59ae88857 100644 --- a/Zotlabs/Module/Directory.php +++ b/Zotlabs/Module/Directory.php @@ -68,6 +68,7 @@ class Directory extends \Zotlabs\Web\Controller { $observer = get_observer_hash(); $globaldir = get_directory_setting($observer, 'globaldir'); + // override your personal global search pref if we're doing a navbar search of the directory if(intval($_REQUEST['navsearch'])) $globaldir = 1; @@ -262,7 +263,7 @@ class Directory extends \Zotlabs\Web\Controller { $hometown = ((x($profile,'hometown') == 1) ? $profile['hometown'] : False); - $about = ((x($profile,'about') == 1) ? bbcode($profile['about']) : False); + $about = ((x($profile,'about') == 1) ? zidify_links(bbcode($profile['about'])) : False); $keywords = ((x($profile,'keywords')) ? $profile['keywords'] : ''); diff --git a/Zotlabs/Module/Dirsearch.php b/Zotlabs/Module/Dirsearch.php index 927800bbb..e6cf5449a 100644 --- a/Zotlabs/Module/Dirsearch.php +++ b/Zotlabs/Module/Dirsearch.php @@ -12,7 +12,7 @@ class Dirsearch extends \Zotlabs\Web\Controller { } - function get() { + function get() { $ret = array('success' => false); @@ -410,13 +410,13 @@ class Dirsearch extends \Zotlabs\Web\Controller { $rand = db_getfunc('rand'); $realm = get_directory_realm(); if($realm == DIRECTORY_REALM) { - $r = q("select * from site where site_access != 0 and site_register !=0 and ( site_realm = '%s' or site_realm = '') and site_type = %d order by $rand", + $r = q("select * from site where site_access != 0 and site_register !=0 and ( site_realm = '%s' or site_realm = '') and site_type = %d and site_dead = 0 order by $rand", dbesc($realm), intval(SITE_TYPE_ZOT) ); } else { - $r = q("select * from site where site_access != 0 and site_register !=0 and site_realm = '%s' and site_type = %d order by $rand", + $r = q("select * from site where site_access != 0 and site_register !=0 and site_realm = '%s' and site_type = %d and site_dead = 0 order by $rand", dbesc($realm), intval(SITE_TYPE_ZOT) ); @@ -457,6 +457,6 @@ class Dirsearch extends \Zotlabs\Web\Controller { } } return $ret; - } - + } + } diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php index 5c04653b8..d7612b165 100644 --- a/Zotlabs/Module/Editpost.php +++ b/Zotlabs/Module/Editpost.php @@ -78,6 +78,7 @@ class Editpost extends \Zotlabs\Web\Controller { $x = array( 'nickname' => $channel['channel_address'], + 'item' => $itm[0], 'editor_autocomplete'=> true, 'bbco_autocomplete'=> 'bbcode', 'return_path' => $_SESSION['return_url'], diff --git a/Zotlabs/Module/Events.php b/Zotlabs/Module/Events.php index b8910b644..edc6dd3f0 100644 --- a/Zotlabs/Module/Events.php +++ b/Zotlabs/Module/Events.php @@ -43,6 +43,10 @@ class Events extends \Zotlabs\Web\Controller { $adjust = intval($_POST['adjust']); $nofinish = intval($_POST['nofinish']); + $timezone = ((x($_POST,'timezone_select')) ? notags(trim($_POST['timezone_select'])) : ''); + + $tz = (($timezone) ? $timezone : date_default_timezone_get()); + $categories = escape_tags(trim($_POST['category'])); // only allow editing your own events. @@ -71,9 +75,9 @@ class Events extends \Zotlabs\Web\Controller { if($adjust) { - $start = datetime_convert(date_default_timezone_get(),'UTC',$start); + $start = datetime_convert($tz,'UTC',$start); if(! $nofinish) - $finish = datetime_convert(date_default_timezone_get(),'UTC',$finish); + $finish = datetime_convert($tz,'UTC',$finish); } else { $start = datetime_convert('UTC','UTC',$start); @@ -374,11 +378,14 @@ class Events extends \Zotlabs\Web\Controller { $event_xchan = ((x($orig_event)) ? $orig_event['event_xchan'] : $channel['channel_hash']); $mid = ((x($orig_event)) ? $orig_event['mid'] : ''); - if(! x($orig_event)) + if(! x($orig_event)) { $sh_checked = ''; - else + $a_checked = ' checked="checked" '; + } + else { $sh_checked = ((($orig_event['allow_cid'] === '<' . $channel['channel_hash'] . '>' || (! $orig_event['allow_cid'])) && (! $orig_event['allow_gid']) && (! $orig_event['deny_cid']) && (! $orig_event['deny_gid'])) ? '' : ' checked="checked" ' ); - + } + if($orig_event['event_xchan']) $sh_checked .= ' disabled="disabled" '; @@ -478,6 +485,8 @@ class Events extends \Zotlabs\Web\Controller { '$allow_gid' => acl2json($permissions['allow_gid']), '$deny_cid' => acl2json($permissions['deny_cid']), '$deny_gid' => acl2json($permissions['deny_gid']), + '$tz_choose' => feature_enabled(local_channel(),'event_tz_select'), + '$timezone' => array('timezone_select' , t('Timezone:'), date_default_timezone_get(), '', get_timezones()), '$lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'), @@ -625,14 +634,14 @@ class Events extends \Zotlabs\Web\Controller { $drop = array(z_root().'/events/drop/'.$rr['event_hash'],t('Delete event'),'',''); - $title = strip_tags(html_entity_decode(bbcode($rr['summary']),ENT_QUOTES,'UTF-8')); + $title = strip_tags(html_entity_decode(zidify_links(bbcode($rr['summary'])),ENT_QUOTES,'UTF-8')); if(! $title) { list($title, $_trash) = explode("<br",bbcode($rr['desc']),2); $title = strip_tags(html_entity_decode($title,ENT_QUOTES,'UTF-8')); } $html = format_event_html($rr); - $rr['desc'] = bbcode($rr['desc']); - $rr['location'] = bbcode($rr['location']); + $rr['desc'] = zidify_links(smilies(bbcode($rr['desc']))); + $rr['location'] = zidify_links(smilies(bbcode($rr['location']))); $events[] = array( 'id'=>$rr['id'], 'hash' => $rr['event_hash'], diff --git a/Zotlabs/Module/Help.php b/Zotlabs/Module/Help.php index 570e8e0cf..e247416d9 100644 --- a/Zotlabs/Module/Help.php +++ b/Zotlabs/Module/Help.php @@ -44,12 +44,56 @@ class Help extends \Zotlabs\Web\Controller { return $o; } + + + if(argc() > 2 && argv(argc()-2) === 'assets') { + $path = ''; + for($x = 1; $x < argc(); $x ++) { + if(strlen($path)) + $path .= '/'; + $path .= argv($x); + } + $realpath = 'doc/' . $path; + //Set the content-type header as appropriate + $imageInfo = getimagesize($realpath); + switch ($imageInfo[2]) { + case IMAGETYPE_JPEG: + header("Content-Type: image/jpeg"); + break; + case IMAGETYPE_GIF: + header("Content-Type: image/gif"); + break; + case IMAGETYPE_PNG: + header("Content-Type: image/png"); + break; + default: + break; + } + header("Content-Length: " . filesize($realpath)); - $content = get_help_content(); + // dump the picture and stop the script + readfile($realpath); + killme(); + } + + $headings = [ + 'about' => t('About'), + 'member' => t('Members'), + 'admin' => t('Administrators'), + 'developer' => t('Developers'), + 'tutorials' => t('Tutorials') + ]; + + if(array_key_exists(argv(1), $headings)) + $heading = $headings[argv(1)]; + + $content = get_help_content(); return replace_macros(get_markup_template('help.tpl'), array( '$title' => t('$Projectname Documentation'), - '$content' => $content + '$tocHeading' => t('Contents'), + '$content' => $content, + '$heading' => $heading )); } diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 344e839f4..7f2813076 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -21,6 +21,7 @@ require_once('include/crypto.php'); require_once('include/items.php'); require_once('include/attach.php'); require_once('include/bbcode.php'); +require_once('include/security.php'); use \Zotlabs\Lib as Zlib; @@ -34,9 +35,7 @@ class Item extends \Zotlabs\Web\Controller { if((! local_channel()) && (! remote_channel()) && (! x($_REQUEST,'commenter'))) return; - - require_once('include/security.php'); - + $uid = local_channel(); $channel = null; $observer = null; @@ -126,6 +125,8 @@ class Item extends \Zotlabs\Web\Controller { $ret = $this->item_check_service_class($uid,(($_REQUEST['webpage'] == ITEM_TYPE_WEBPAGE) ? true : false)); if (!$ret['success']) { notice( t($ret['message']) . EOL) ; + if($api_source) + return ( [ 'success' => false, 'message' => 'service class exception' ] ); if(x($_REQUEST,'return')) goaway(z_root() . "/" . $return_path ); killme(); @@ -180,6 +181,8 @@ class Item extends \Zotlabs\Web\Controller { if(($r === false) || (! count($r))) { notice( t('Unable to locate original post.') . EOL); + if($api_source) + return ( [ 'success' => false, 'message' => 'invalid post id' ] ); if(x($_REQUEST,'return')) goaway(z_root() . "/" . $return_path ); killme(); @@ -214,6 +217,8 @@ class Item extends \Zotlabs\Web\Controller { if(! $can_comment) { notice( t('Permission denied.') . EOL) ; + if($api_source) + return ( [ 'success' => false, 'message' => 'permission denied' ] ); if(x($_REQUEST,'return')) goaway(z_root() . "/" . $return_path ); killme(); @@ -222,6 +227,8 @@ class Item extends \Zotlabs\Web\Controller { else { if(! perm_is_allowed($profile_uid,$observer['xchan_hash'],($webpage) ? 'write_pages' : 'post_wall')) { notice( t('Permission denied.') . EOL) ; + if($api_source) + return ( [ 'success' => false, 'message' => 'permission denied' ] ); if(x($_REQUEST,'return')) goaway(z_root() . "/" . $return_path ); killme(); @@ -276,6 +283,8 @@ class Item extends \Zotlabs\Web\Controller { if(! $channel) { logger("mod_item: no channel."); + if($api_source) + return ( [ 'success' => false, 'message' => 'no channel' ] ); if(x($_REQUEST,'return')) goaway(z_root() . "/" . $return_path ); killme(); @@ -291,6 +300,8 @@ class Item extends \Zotlabs\Web\Controller { } else { logger("mod_item: no owner."); + if($api_source) + return ( [ 'success' => false, 'message' => 'no owner' ] ); if(x($_REQUEST,'return')) goaway(z_root() . "/" . $return_path ); killme(); @@ -433,6 +444,8 @@ class Item extends \Zotlabs\Web\Controller { if($preview) killme(); info( t('Empty post discarded.') . EOL ); + if($api_source) + return ( [ 'success' => false, 'message' => 'no content' ] ); if(x($_REQUEST,'return')) goaway(z_root() . "/" . $return_path ); killme(); @@ -473,6 +486,8 @@ class Item extends \Zotlabs\Web\Controller { } else { notice( t('Executable content type not permitted to this channel.') . EOL); + if($api_source) + return ( [ 'success' => false, 'message' => 'forbidden content type' ] ); if(x($_REQUEST,'return')) goaway(z_root() . "/" . $return_path ); killme(); @@ -540,42 +555,8 @@ class Item extends \Zotlabs\Web\Controller { if($x) $body .= "\n\n@group+" . $x[0]['abook_id'] . "\n"; } - - /** - * fix naked links by passing through a callback to see if this is a hubzilla site - * (already known to us) which will get a zrl, otherwise link with url, add bookmark tag to both. - * 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\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,]+)/ism", 'nakedoembed', $body); - $body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,]+)/ism", '\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); - - - // fix any img tags that should be zmg - - $body = preg_replace_callback('/\[img(.*?)\](.*?)\[\/img\]/ism','\red_zrlify_img_callback',$body); - - - $body = bb_translate_video($body); - - /** - * Fold multi-line [code] sequences - */ - - $body = preg_replace('/\[\/code\]\s*\[code\]/ism',"\n",$body); - - $body = scale_external_images($body,false); - + $body = cleanup_bbcode($body); // Look for tags and linkify them $results = linkify_tags($a, $body, ($uid) ? $uid : $profile_uid); @@ -863,7 +844,8 @@ class Item extends \Zotlabs\Web\Controller { logger('mod_item: post cancelled by plugin or duplicate suppressed.'); if($return_path) goaway(z_root() . "/" . $return_path); - + if($api_source) + return ( [ 'success' => false, 'message' => 'operation cancelled' ] ); $json = array('cancel' => 1); $json['reload'] = z_root() . '/' . $_REQUEST['jsreload']; echo json_encode($json); @@ -916,6 +898,10 @@ class Item extends \Zotlabs\Web\Controller { if(! $nopush) \Zotlabs\Daemon\Master::Summon(array('Notifier', 'edit_post', $post_id)); + + if($api_source) + return($x); + if((x($_REQUEST,'return')) && strlen($return_path)) { logger('return: ' . $return_path); goaway(z_root() . "/" . $return_path ); @@ -990,8 +976,11 @@ class Item extends \Zotlabs\Web\Controller { else { logger('mod_item: unable to retrieve post that was just stored.'); notice( t('System error. Post not saved.') . EOL); - goaway(z_root() . "/" . $return_path ); - // NOTREACHED + if($return_path) + goaway(z_root() . "/" . $return_path ); + if($api_source) + return ( [ 'success' => false, 'message' => 'system error' ] ); + killme(); } if(($parent) && ($parent != $post_id)) { @@ -1046,9 +1035,7 @@ class Item extends \Zotlabs\Web\Controller { if((! local_channel()) && (! remote_channel())) return; - - require_once('include/security.php'); - + if((argc() == 3) && (argv(1) === 'drop') && intval(argv(2))) { require_once('include/items.php'); @@ -1084,6 +1071,14 @@ class Item extends \Zotlabs\Web\Controller { else { // complex deletion that needs to propagate and be performed in phases drop_item($i[0]['id'],true,DROPITEM_PHASE1); + $r = q("select * from item where id = %d", + intval($i[0]['id']) + ); + if($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + build_sync_packet($i[0]['uid'],array('item' => array(encode_item($sync_item[0],true)))); + } tag_deliver($i[0]['uid'],$i[0]['id']); } } diff --git a/Zotlabs/Module/Mail.php b/Zotlabs/Module/Mail.php index c767c8e56..459ce5acf 100644 --- a/Zotlabs/Module/Mail.php +++ b/Zotlabs/Module/Mail.php @@ -23,7 +23,34 @@ class Mail extends \Zotlabs\Web\Controller { $rstr = ((x($_REQUEST,'messagerecip')) ? notags(trim($_REQUEST['messagerecip'])) : ''); $preview = ((x($_REQUEST,'preview')) ? intval($_REQUEST['preview']) : 0); $expires = ((x($_REQUEST,'expires')) ? datetime_convert(date_default_timezone_get(),'UTC', $_REQUEST['expires']) : NULL_DATE); - + + if($preview) { + + $body = cleanup_bbcode($body); + $results = linkify_tags($a, $body, local_channel()); + + if(preg_match_all('/(\[attachment\](.*?)\[\/attachment\])/',$body,$match)) { + $attachments = array(); + foreach($match[2] as $mtch) { + $hash = substr($mtch,0,strpos($mtch,',')); + $rev = intval(substr($mtch,strpos($mtch,','))); + $r = attach_by_hash_nodata($hash,get_observer_hash(),$rev); + if($r['success']) { + $attachments[] = array( + 'href' => z_root() . '/attach/' . $r['data']['hash'], + 'length' => $r['data']['filesize'], + 'type' => $r['data']['filetype'], + 'title' => urlencode($r['data']['filename']), + 'revision' => $r['data']['revision'] + ); + } + $body = trim(str_replace($match[1],'',$body)); + } + } + echo json_encode(['preview' => zidify_links(smilies(bbcode($body)))]); + killme(); + } + // If we have a raw string for a recipient which hasn't been auto-filled, // it means they probably aren't in our address book, hence we don't know // if we have permission to send them private messages. @@ -82,6 +109,8 @@ class Mail extends \Zotlabs\Web\Controller { require_once('include/text.php'); linkify_tags($a, $body, local_channel()); + // I don't think this is used any more. + if($preview) { $mail = [ 'mailbox' => 'outbox', @@ -90,8 +119,8 @@ class Mail extends \Zotlabs\Web\Controller { 'from_name' => $channel['xchan_name'], 'from_url' => $channel['xchan_url'], 'from_photo' => $channel['xchan_photo_s'], - 'subject' => smilies(bbcode($subject)), - 'body' => smilies(bbcode($body)), + 'subject' => zidify_links(smilies(bbcode($subject))), + 'body' => zidify_links(smilies(bbcode($body))), 'attachments' => '', 'can_recall' => false, 'is_recalled' => '', @@ -341,7 +370,7 @@ class Mail extends \Zotlabs\Web\Controller { 'to_url' => chanlink_hash($message['to_xchan']), 'to_photo' => $message['to']['xchan_photo_s'], 'subject' => $message['title'], - 'body' => smilies(bbcode($message['body'])), + 'body' => zidify_links(smilies(bbcode($message['body']))), 'attachments' => $s, 'delete' => t('Delete message'), 'dreport' => t('Delivery report'), diff --git a/Zotlabs/Module/Message.php b/Zotlabs/Module/Message.php index ea2127a1d..7494f4bf4 100644 --- a/Zotlabs/Module/Message.php +++ b/Zotlabs/Module/Message.php @@ -79,7 +79,7 @@ class Message extends \Zotlabs\Web\Controller { 'to_photo' => $rr['to']['xchan_photo_s'], 'subject' => (($rr['seen']) ? $rr['title'] : '<strong>' . $rr['title'] . '</strong>'), 'delete' => t('Delete conversation'), - 'body' => smilies(bbcode($rr['body'])), + 'body' => zidify_links(smilies(bbcode($rr['body']))), 'date' => datetime_convert('UTC',date_default_timezone_get(),$rr['created'], t('D, d M Y - g:i A')), 'seen' => $rr['seen'] ); diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php index 19a642a83..72a056963 100644 --- a/Zotlabs/Module/Profiles.php +++ b/Zotlabs/Module/Profiles.php @@ -191,7 +191,7 @@ class Profiles extends \Zotlabs\Web\Controller { } } - function post() { + function post() { if(! local_channel()) { notice( t('Permission denied.') . EOL); @@ -243,6 +243,7 @@ class Profiles extends \Zotlabs\Web\Controller { check_form_security_token_redirectOnErr('/profiles', 'profile_edit'); + $is_default = (($orig[0]['is_default']) ? 1 : 0); $profile_name = notags(trim($_POST['profile_name'])); @@ -315,6 +316,15 @@ class Profiles extends \Zotlabs\Web\Controller { $hide_friends = ((intval($_POST['hide_friends'])) ? 1: 0); + + $orig_vcard = (($orig[0]['profile_vcard']) ? \Sabre\VObject\Reader::read($orig[0]['profile_vcard']) : null); + + $_REQUEST['fn'] = $name; + $_REQUEST['title'] = $pdesc; + + $profile_vcard = update_vcard($_REQUEST,$orig_vcard); + + require_once('include/text.php'); linkify_tags($a, $likes, local_channel()); linkify_tags($a, $dislikes, local_channel()); @@ -511,7 +521,8 @@ class Profiles extends \Zotlabs\Web\Controller { romance = '%s', employment = '%s', education = '%s', - hide_friends = %d + hide_friends = %d, + profile_vcard = '%s' WHERE id = %d AND uid = %d", dbesc($profile_name), dbesc($name), @@ -546,6 +557,7 @@ class Profiles extends \Zotlabs\Web\Controller { dbesc($work), dbesc($education), intval($hide_friends), + dbesc($profile_vcard), intval(argv(1)), intval(local_channel()) ); diff --git a/Zotlabs/Module/Pubsites.php b/Zotlabs/Module/Pubsites.php index 1c9cd5121..d87967189 100644 --- a/Zotlabs/Module/Pubsites.php +++ b/Zotlabs/Module/Pubsites.php @@ -36,7 +36,7 @@ class Pubsites extends \Zotlabs\Web\Controller { $o .= '</tr>'; if($j['sites']) { foreach($j['sites'] as $jj) { - if(! $jj['project']) + if(! \Zotlabs\Lib\System::compatible_project($jj['project'])) continue; if(strpos($jj['version'],' ')) { $x = explode(' ', $jj['version']); diff --git a/Zotlabs/Module/Search.php b/Zotlabs/Module/Search.php index b319b19d6..89eaa4ffa 100644 --- a/Zotlabs/Module/Search.php +++ b/Zotlabs/Module/Search.php @@ -211,7 +211,7 @@ class Search extends \Zotlabs\Web\Controller { $result = array(); require_once('include/conversation.php'); foreach($items as $item) { - $item['html'] = bbcode($item['body']); + $item['html'] = zidify_links(bbcode($item['body'])); $x = encode_item($item); $x['html'] = prepare_text($item['body'],$item['mimetype']); $result[] = $x; diff --git a/Zotlabs/Module/Settings/Channel.php b/Zotlabs/Module/Settings/Channel.php index e18416393..a73aa2e60 100644 --- a/Zotlabs/Module/Settings/Channel.php +++ b/Zotlabs/Module/Settings/Channel.php @@ -404,8 +404,11 @@ class Channel { '$desc' => t('Your channel address is'), '$nickname' => $nickname, '$subdir' => $subdir, + '$davdesc' => t('Your files/photos are accessible via WebDAV at'), + '$davpath' => ((get_account_techlevel() > 3) ? z_root() . '/dav/' . $nickname : ''), '$basepath' => \App::get_hostname() )); + $stpl = get_markup_template('settings.tpl'); @@ -515,6 +518,8 @@ class Channel { '$notify7' => array('notify7', t('You are tagged in a post'), ($notify & NOTIFY_TAGSELF), NOTIFY_TAGSELF, '', $yes_no), '$notify8' => array('notify8', t('You are poked/prodded/etc. in a post'), ($notify & NOTIFY_POKE), NOTIFY_POKE, '', $yes_no), + '$notify9' => array('notify9', t('Someone likes your post/comment'), ($notify & NOTIFY_LIKE), NOTIFY_LIKE, '', $yes_no), + '$lbl_vnot' => t('Show visual notifications including:'), diff --git a/Zotlabs/Module/Settings/Tokens.php b/Zotlabs/Module/Settings/Tokens.php index e63fed128..d32a00c95 100644 --- a/Zotlabs/Module/Settings/Tokens.php +++ b/Zotlabs/Module/Settings/Tokens.php @@ -115,6 +115,7 @@ class Tokens { $desc2 = t('You may also provide <em>dropbox</em> style access links to friends and associates by adding the Login Password to any specific site URL as shown. Examples:'); $global_perms = \Zotlabs\Access\Permissions::Perms(); + $their_perms = []; $existing = get_all_perms(local_channel(),(($atoken_xchan) ? $atoken_xchan : '')); @@ -123,7 +124,6 @@ class Tokens { intval(local_channel()), dbesc($atoken_xchan) ); - $their_perms = array(); if($theirs) { foreach($theirs as $t) { $their_perms[$t['k']] = $t['v']; diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php index fde9fe823..9c688af01 100644 --- a/Zotlabs/Module/Setup.php +++ b/Zotlabs/Module/Setup.php @@ -161,13 +161,6 @@ class Setup extends \Zotlabs\Web\Controller { } } - function get_db_errno() { - if(class_exists('mysqli')) - return mysqli_connect_errno(); - else - return mysql_errno(); - } - /** * @brief Get output for the setup page. * @@ -175,6 +168,7 @@ class Setup extends \Zotlabs\Web\Controller { * * @return string parsed HTML output */ + function get() { $o = ''; @@ -401,7 +395,8 @@ class Setup extends \Zotlabs\Web\Controller { if (strlen($phpath)) { $passed = file_exists($phpath); - } else { + } + elseif(function_exists('shell_exec')) { if(is_windows()) $phpath = trim(shell_exec('where php')); else @@ -426,9 +421,13 @@ class Setup extends \Zotlabs\Web\Controller { if($passed) { $str = autoname(8); $cmd = "$phpath install/testargs.php $str"; - $result = trim(shell_exec($cmd)); - $passed2 = $result == $str; $help = ''; + + if(function_exists('shell_exec')) + $result = trim(shell_exec($cmd)); + else + $help .= t('Unable to check command line PHP, as shell_exec() is disabled. This is required.') . EOL; + $passed2 = (($result == $str) ? true : false); if(!$passed2) { $help .= t('The command line version of PHP on your system does not have "register_argc_argv" enabled.'). EOL; $help .= t('This is required for message delivery to work.'); @@ -457,7 +456,7 @@ class Setup extends \Zotlabs\Web\Controller { userReadableSize($result['max_upload_filesize']), $result['max_file_uploads'] ); - $help .= '<br>' . t('You can adjust these settings in the servers php.ini.'); + $help .= '<br>' . t('You can adjust these settings in the server php.ini file.'); $this->check_add($checks, t('PHP upload limits'), true, false, $help); } @@ -497,6 +496,11 @@ class Setup extends \Zotlabs\Web\Controller { function check_funcs(&$checks) { $ck_funcs = array(); + $disabled = explode(',',ini_get('disable_functions')); + if($disabled) + array_walk($disabled,'array_trim'); + + // add check metadata, the real check is done bit later and return values set $this->check_add($ck_funcs, t('libCurl PHP module'), true, true); $this->check_add($ck_funcs, t('GD graphics PHP module'), true, true); @@ -512,11 +516,17 @@ class Setup extends \Zotlabs\Web\Controller { $this->check_add($ck_funcs, t('Apache mod_rewrite module'), true, true); } } - if((! function_exists('proc_open')) || strstr(ini_get('disable_functions'),'proc_open')) { - $this->check_add($ck_funcs, t('proc_open'), false, true, t('Error: proc_open is required but is either not installed or has been disabled in php.ini')); + if((! function_exists('exec')) || in_array('exec',$disabled)) { + $this->check_add($ck_funcs, t('exec'), false, true, t('Error: exec is required but is either not installed or has been disabled in php.ini')); + } + else { + $this->check_add($ck_funcs, t('exec'), true, true); + } + if((! function_exists('shell_exec')) || in_array('shell_exec',$disabled)) { + $this->check_add($ck_funcs, t('shell_exec'), false, true, t('Error: shell_exec is required but is either not installed or has been disabled in php.ini')); } else { - $this->check_add($ck_funcs, t('proc_open'), true, true); + $this->check_add($ck_funcs, t('shell_exec'), true, true); } if(! function_exists('curl_init')) { @@ -579,7 +589,7 @@ class Setup extends \Zotlabs\Web\Controller { if(! is_writable(TEMPLATE_BUILD_PATH) ) { $status = false; - $help = t('Red uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') .EOL; + $help = t('This software uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') .EOL; $help .= sprintf( t('In order to store these compiled templates, the web server needs to have write access to the directory %s under the top level web folder.'), TEMPLATE_BUILD_PATH) . EOL; $help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL; $help .= sprintf( t('Note: as a security measure, you should give the web server write access to %s only--not the template files (.tpl) that it contains.'), TEMPLATE_BUILD_PATH) . EOL; @@ -601,7 +611,7 @@ class Setup extends \Zotlabs\Web\Controller { if(! is_writable('store')) { $status = false; - $help = t('This software uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the Red top level folder') . EOL; + $help = t('This software uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the top level web folder') . EOL; $help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL; } @@ -716,7 +726,7 @@ class Setup extends \Zotlabs\Web\Controller { // (e.g. NSS used in RedHat) require different syntax, so hopefully // the default curl cipher list will work for most sites. If not, // this can set via config. Many distros are now disabling RC4, - // but many Red sites still use it and are unable to change it. + // but many existing sites still use it and are unable to change it. // We do not use SSL for encryption, only to protect session cookies. // z_fetch_url() is also used to import shared links and other content // so in theory most any cipher could show up and we should do our best diff --git a/Zotlabs/Module/Siteinfo.php b/Zotlabs/Module/Siteinfo.php index a15e2896d..7c3918425 100644 --- a/Zotlabs/Module/Siteinfo.php +++ b/Zotlabs/Module/Siteinfo.php @@ -15,63 +15,33 @@ class Siteinfo extends \Zotlabs\Web\Controller { function get() { - if(! get_config('system','hidden_version_siteinfo')) { - $version = sprintf( t('Version %s'), \Zotlabs\Lib\System::get_project_version()); - if(@is_dir('.git') && function_exists('shell_exec')) { - $commit = @shell_exec('git log -1 --format="%h"'); - $tag = \Zotlabs\Lib\System::get_std_version(); // @shell_exec('git describe --tags --abbrev=0'); - } - if(! isset($commit) || strlen($commit) > 16) - $commit = ''; - } - else { - $version = $commit = ''; - } + $siteinfo = replace_macros(get_markup_template('siteinfo.tpl'), + [ + '$title' => t('About this site'), + '$sitenametxt' => t('Site Name'), + '$sitename' => \Zotlabs\Lib\System::get_site_name(), + '$headline' => t('Site Information'), + '$site_about' => bbcode(get_config('system','siteinfo')), + '$admin_headline' => t('Administrator'), + '$admin_about' => bbcode(get_config('system','admininfo')), + '$terms' => t('Terms of Service'), + '$prj_header' => t('Software and Project information'), + '$prj_name' => t('This site is powered by $Projectname'), + '$prj_transport' => t('Federated and decentralised networking and identity services provided by Zot'), + '$transport_link' => '<a href="https://zotlabs.com">https://zotlabs.com</a>', + '$prj_version' => ((get_config('system','hidden_version_siteinfo')) ? '' : sprintf( t('Version %s'), \Zotlabs\Lib\System::get_project_version())), + '$prj_linktxt' => t('Project homepage'), + '$prj_srctxt' => t('Developer homepage'), + '$prj_link' => \Zotlabs\Lib\System::get_project_link(), + '$prj_src' => \Zotlabs\Lib\System::get_project_srclink(), + ] + ); - $plugins_list = implode(', ',visible_plugin_list()); + call_hooks('about_hook', $siteinfo); + + return $siteinfo; - if($plugins_list) - $plugins_text = t('Installed plugins/addons/apps:'); - else - $plugins_text = t('No installed plugins/addons/apps'); - - $txt = get_config('system','admininfo'); - $admininfo = bbcode($txt); - - if(file_exists('doc/site_donate.html')) - $donate .= file_get_contents('doc/site_donate.html'); - - if(function_exists('sys_getloadavg')) - $loadavg = sys_getloadavg(); - - $o = replace_macros(get_markup_template('siteinfo.tpl'), array( - '$title' => t('$Projectname'), - '$description' => t('This is a hub of $Projectname - a global cooperative network of decentralized privacy enhanced websites.'), - '$version' => $version, - '$tag_txt' => t('Tag: '), - '$tag' => $tag, - '$polled' => t('Last background fetch: '), - '$lastpoll' => get_poller_runtime(), - '$load_average' => t('Current load average: '), - '$loadavg_all' => $loadavg[0] . ', ' . $loadavg[1] . ', ' . $loadavg[2], - '$commit' => $commit, - '$web_location' => t('Running at web location') . ' ' . z_root(), - '$visit' => t('Please visit <a href="http://hubzilla.org">hubzilla.org</a> to learn more about $Projectname.'), - '$bug_text' => t('Bug reports and issues: please visit'), - '$bug_link_url' => 'https://github.com/redmatrix/hubzilla/issues', - '$bug_link_text' => t('$projectname issues'), - '$contact' => t('Suggestions, praise, etc. - please email "redmatrix" at librelist - dot com'), - '$donate' => $donate, - '$adminlabel' => t('Site Administrators'), - '$admininfo' => $admininfo, - '$plugins_text' => $plugins_text, - '$plugins_list' => $plugins_list - )); - - call_hooks('about_hook', $o); - - return $o; - } + } diff --git a/Zotlabs/Module/Sslify.php b/Zotlabs/Module/Sslify.php index db73f85e0..2891f3691 100644 --- a/Zotlabs/Module/Sslify.php +++ b/Zotlabs/Module/Sslify.php @@ -10,21 +10,16 @@ class Sslify extends \Zotlabs\Web\Controller { $h = explode("\n",$x['header']); foreach ($h as $l) { list($k,$v) = array_map("trim", explode(":", trim($l), 2)); - $hdrs[$k] = $v; + $hdrs[strtolower($k)] = $v; } - if (array_key_exists('Content-Type', $hdrs)) - $type = $hdrs['Content-Type']; - - header('Content-Type: ' . $type); + if (array_key_exists('content-type', $hdrs)) { + $type = $hdrs['content-type']; + header('Content-Type: ' . $type); + } + echo $x['body']; killme(); } killme(); - // for some reason when this fallback is in place - it gets triggered - // often, (creating mixed content exceptions) even though there is - // nothing obvious missing on the page when we bypass it. - goaway($_REQUEST['url']); - } - - + } } diff --git a/Zotlabs/Module/Wall_attach.php b/Zotlabs/Module/Wall_attach.php index 9268fbb0a..c6fe7518e 100644 --- a/Zotlabs/Module/Wall_attach.php +++ b/Zotlabs/Module/Wall_attach.php @@ -12,7 +12,7 @@ class Wall_attach extends \Zotlabs\Web\Controller { $using_api = false; - if(\App::$data['api_info'] && array_key_exists('media',$_FILES)) { + if($_REQUEST['api_source'] && array_key_exists('media',$_FILES)) { $using_api = true; } diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php index 0da699c73..46b94f091 100644 --- a/Zotlabs/Module/Webpages.php +++ b/Zotlabs/Module/Webpages.php @@ -173,7 +173,6 @@ class Webpages extends \Zotlabs\Web\Controller { if($_REQUEST['pagetitle']) $x['pagetitle'] = $_REQUEST['pagetitle']; - $editor = status_editor($a,$x); // Get a list of webpages. We can't display all them because endless scroll makes that unusable, // so just list titles and an edit link. @@ -197,6 +196,11 @@ class Webpages extends \Zotlabs\Web\Controller { // intval(ITEM_TYPE_WEBPAGE) // ); + if(! $r) + $x['pagetitle'] = 'home'; + + $editor = status_editor($a,$x); + $pages = null; if($r) { diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index edcd6ec58..95f7c8704 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -34,20 +34,16 @@ class Wiki extends \Zotlabs\Web\Controller { notice( t('Not found') . EOL); return; } - - $tab = 'wiki'; - - + require_once('include/wiki.php'); require_once('include/acl_selectors.php'); require_once('include/conversation.php'); + require_once('include/bbcode.php'); // TODO: Combine the interface configuration into a unified object // Something like $interface = array('new_page_button' => false, 'new_wiki_button' => false, ...) $wiki_owner = false; $showNewWikiButton = false; - $showCommitMsg = false; - $hidePageHistory = false; $pageHistory = array(); $local_observer = null; $resource_id = ''; @@ -90,50 +86,82 @@ class Wiki extends \Zotlabs\Web\Controller { // Not the channel owner $owner_acl = $x = array(); } - + + $is_owner = ((local_channel()) && (local_channel() == \App::$profile['profile_uid']) ? true : false); + $o = profile_tabs($a, $is_owner, \App::$profile['channel_address']); + // Download a wiki - if ((argc() > 3) && (argv(2) === 'download') && (argv(3) === 'wiki')) { - $resource_id = argv(4); - $w = wiki_get_wiki($resource_id); - if (!$w['path']) { - notice(t('Error retrieving wiki') . EOL); - } - $zip_folder_name = random_string(10); - $zip_folderpath = '/tmp/' . $zip_folder_name; - if (!mkdir($zip_folderpath, 0770, false)) { - logger('Error creating zip file export folder: ' . $zip_folderpath, LOGGER_NORMAL); - notice(t('Error creating zip file export folder') . EOL); - } - $zip_filename = $w['urlName']; - $zip_filepath = '/tmp/' . $zip_folder_name . '/' . $zip_filename; - // Generate the zip file - \Zotlabs\Lib\ExtendedZip::zipTree($w['path'], $zip_filepath, \ZipArchive::CREATE); - // Output the file for download - header('Content-disposition: attachment; filename="' . $zip_filename . '.zip"'); - header("Content-Type: application/zip"); - $success = readfile($zip_filepath); - if ($success) { - rrmdir($zip_folderpath); // delete temporary files - } else { - rrmdir($zip_folderpath); // delete temporary files - logger('Error downloading wiki: ' . $resource_id); - } + if((argc() > 3) && (argv(2) === 'download') && (argv(3) === 'wiki')) { + + $resource_id = argv(4); + + $w = wiki_get_wiki($resource_id); + if(!$w['path']) { + notice(t('Error retrieving wiki') . EOL); + } + + $zip_folder_name = random_string(10); + $zip_folderpath = '/tmp/' . $zip_folder_name; + if(!mkdir($zip_folderpath, 0770, false)) { + logger('Error creating zip file export folder: ' . $zip_folderpath, LOGGER_NORMAL); + notice(t('Error creating zip file export folder') . EOL); + } + + $zip_filename = $w['urlName']; + $zip_filepath = '/tmp/' . $zip_folder_name . '/' . $zip_filename; + + // Generate the zip file + \Zotlabs\Lib\ExtendedZip::zipTree($w['path'], $zip_filepath, \ZipArchive::CREATE); + + // Output the file for download + + header('Content-disposition: attachment; filename="' . $zip_filename . '.zip"'); + header('Content-Type: application/zip'); + + $success = readfile($zip_filepath); + + if(!$success) { + logger('Error downloading wiki: ' . $resource_id); + notice(t('Error downloading wiki: ' . $resource_id) . EOL); + } + + // delete temporary files + rrmdir($zip_folderpath); + killme(); + } switch (argc()) { case 2: - // Configure page template - $wikiheaderName = t('Wiki'); - $wikiheaderPage = t('Sandbox'); - require_once('library/markdown.php'); - $content = t('"# Wiki Sandbox\n\nContent you **edit** and **preview** here *will not be saved*."'); - $renderedContent = Markdown(json_decode($content)); - $hide_editor = false; - $showPageControls = false; - $showNewWikiButton = $wiki_owner; - $showNewPageButton = false; - $hidePageHistory = true; - $showCommitMsg = false; + $wikis = wiki_list($owner, get_observer_hash()); + if ($wikis) { + $o .= replace_macros(get_markup_template('wikilist.tpl'), array( + '$header' => t('Wikis'), + '$channel' => $owner['channel_address'], + '$wikis' => $wikis['wikis'], + // If the observer is the local channel owner, show the wiki controls + '$owner' => ((local_channel() && local_channel() === intval(\App::$profile['uid'])) ? true : false), + '$edit' => t('Edit'), + '$download' => t('Download'), + '$view' => t('View'), + '$create' => t('Create New'), + '$submit' => t('Submit'), + '$wikiName' => array('wikiName', t('Wiki name')), + '$mimeType' => array('mimeType', t('Content type'), '', '', ['text/markdown' => 'Markdown', 'text/bbcode' => 'BB Code']), + '$name' => t('Name'), + '$type' => t('Type'), + '$lockstate' => $x['lockstate'], + '$acl' => $x['acl'], + '$allow_cid' => $x['allow_cid'], + '$allow_gid' => $x['allow_gid'], + '$deny_cid' => $x['deny_cid'], + '$deny_gid' => $x['deny_gid'], + '$notify' => array('postVisible', t('Create a status post for this wiki'), '', '', array(t('No'), t('Yes'))) + )); + + return $o; + } + break; case 3: // /wiki/channel/wiki -> No page was specified, so redirect to Home.md @@ -144,10 +172,12 @@ class Wiki extends \Zotlabs\Web\Controller { // Fetch the wiki info and determine observer permissions $wikiUrlName = urlencode(argv(2)); $pageUrlName = urlencode(argv(3)); + $w = wiki_exists_by_name($owner['channel_id'], $wikiUrlName); if(!$w['resource_id']) { notice(t('Wiki not found') . EOL); goaway('/'.argv(0).'/'.argv(1)); + return; //not reached } $resource_id = $w['resource_id']; @@ -158,6 +188,7 @@ class Wiki extends \Zotlabs\Web\Controller { if(!$perms['read']) { notice(t('Permission denied.') . EOL); goaway('/'.argv(0).'/'.argv(1)); + return; //not reached } if($perms['write']) { $wiki_editor = true; @@ -169,70 +200,59 @@ class Wiki extends \Zotlabs\Web\Controller { } $wikiheaderName = urldecode($wikiUrlName); $wikiheaderPage = urldecode($pageUrlName); + $renamePage = (($wikiheaderPage === 'Home') ? '' : t('Rename page')); + $p = wiki_get_page_content(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); if(!$p['success']) { notice(t('Error retrieving page content') . EOL); goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName); + return; //not reached } - $content = ($p['content'] !== '' ? htmlspecialchars_decode($p['content'],ENT_COMPAT) : '"# New page\n"'); + + $mimeType = $p['mimeType']; + + $rawContent = (($p['mimeType'] == 'text/bbcode') ? htmlspecialchars_decode(json_decode($p['content']),ENT_COMPAT) : htmlspecialchars_decode($p['content'],ENT_COMPAT)); + $content = ($p['content'] !== '' ? $rawContent : '"# New page\n"'); // Render the Markdown-formatted page content in HTML - require_once('library/markdown.php'); - $html = wiki_generate_toc(zidify_text(purify_html(Markdown(wiki_bbcode(json_decode($content)))))); - $renderedContent = wiki_convert_links($html,argv(0).'/'.argv(1).'/'.$wikiUrlName); - $hide_editor = false; + if($mimeType == 'text/bbcode') { + $renderedContent = wiki_convert_links(zidify_links(smilies(bbcode($content))),argv(0).'/'.argv(1).'/'.$wikiUrlName); + } + else { + require_once('library/markdown.php'); + $html = wiki_generate_toc(zidify_text(purify_html(Markdown(wiki_bbcode(json_decode($content)))))); + $renderedContent = wiki_convert_links($html,argv(0).'/'.argv(1).'/'.$wikiUrlName); + } $showPageControls = $wiki_editor; - $showNewWikiButton = $wiki_owner; - $showNewPageButton = $wiki_editor; - $hidePageHistory = false; - $showCommitMsg = true; - $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); break; default: // Strip the extraneous URL components - goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName.'/'.$pageUrlName); + goaway('/' . argv(0) . '/' . argv(1) . '/' . $wikiUrlName . '/' . $pageUrlName); + return; //not reached } $wikiModalID = random_string(3); - $wikiModal = replace_macros( - get_markup_template('generic_modal.tpl'), array( - '$id' => $wikiModalID, - '$title' => t('Revision Comparison'), - '$ok' => t('Revert'), - '$cancel' => t('Cancel') - ) - ); - - $is_owner = ((local_channel()) && (local_channel() == \App::$profile['profile_uid']) ? true : false); - - $o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']); - + $wikiModal = replace_macros(get_markup_template('generic_modal.tpl'), array( + '$id' => $wikiModalID, + '$title' => t('Revision Comparison'), + '$ok' => (($showPageControls) ? t('Revert') : ''), + '$cancel' => t('Cancel') + )); + $o .= replace_macros(get_markup_template('wiki.tpl'),array( '$wikiheaderName' => $wikiheaderName, '$wikiheaderPage' => $wikiheaderPage, - '$hideEditor' => $hide_editor, + '$renamePage' => $renamePage, '$showPageControls' => $showPageControls, - '$tools_label' => 'Wiki Tools', - '$showNewWikiButton'=> $showNewWikiButton, - '$showNewPageButton'=> $showNewPageButton, - '$hidePageHistory' => $hidePageHistory, - '$showCommitMsg' => $showCommitMsg, + '$editOrSourceLabel' => (($showPageControls) ? t('Edit') : t('Source')), + '$tools_label' => 'Page Tools', '$channel' => $owner['channel_address'], '$resource_id' => $resource_id, '$page' => $pageUrlName, - '$lockstate' => $x['lockstate'], - '$acl' => $x['acl'], - '$allow_cid' => $x['allow_cid'], - '$allow_gid' => $x['allow_gid'], - '$deny_cid' => $x['deny_cid'], - '$deny_gid' => $x['deny_gid'], - '$bang' => $x['bang'], + '$mimeType' => $mimeType, '$content' => $content, '$renderedContent' => $renderedContent, - '$wikiName' => array('wikiName', t('Enter the name of your new wiki:'), '', ''), - '$pageName' => array('pageName', t('Enter the name of the new page:'), '', ''), - '$pageRename' => array('pageRename', t('Enter the new name:'), '', ''), - '$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="(optional) Enter a custom message when saving the page..."'), - '$pageHistory' => $pageHistory['history'], + '$pageRename' => array('pageRename', t('New page name'), '', ''), + '$commitMsg' => array('commitMsg', '', '', '', '', 'placeholder="Short description of your changes (optional)"'), '$wikiModal' => $wikiModal, '$wikiModalID' => $wikiModalID, '$commit' => 'HEAD', @@ -242,17 +262,21 @@ class Wiki extends \Zotlabs\Web\Controller { '$embedPhotosModalOK' => t('OK'), '$modalchooseimages' => t('Choose images to embed'), '$modalchoosealbum' => t('Choose an album'), - '$modaldiffalbum' => t('Choose a different album...'), + '$modaldiffalbum' => t('Choose a different album'), '$modalerrorlist' => t('Error getting album list'), '$modalerrorlink' => t('Error getting photo link'), '$modalerroralbum' => t('Error getting album'), )); - head_add_js('library/ace/ace.js'); // Ace Code Editor + + if($p['mimeType'] != 'text/bbcode') + head_add_js('library/ace/ace.js'); // Ace Code Editor + return $o; } function post() { require_once('include/wiki.php'); + require_once('include/bbcode.php'); $nick = argv(1); $owner = channelx_by_nick($nick); @@ -268,13 +292,21 @@ class Wiki extends \Zotlabs\Web\Controller { // Render mardown-formatted text in HTML for preview if((argc() > 2) && (argv(2) === 'preview')) { $content = $_POST['content']; - $resource_id = $_POST['resource_id']; - require_once('library/markdown.php'); - $content = wiki_bbcode($content); - $html = wiki_generate_toc(zidify_text(purify_html(Markdown($content)))); + $resource_id = $_POST['resource_id']; $w = wiki_get_wiki($resource_id); $wikiURL = argv(0).'/'.argv(1).'/'.$w['urlName']; - $html = wiki_convert_links($html,$wikiURL); + + $mimeType = $w['mimeType']; + + if($mimeType == 'text/bbcode') { + $html = wiki_convert_links(zidify_links(smilies(bbcode($content))),$wikiURL); + } + else { + require_once('library/markdown.php'); + $content = wiki_bbcode($content); + $html = wiki_generate_toc(zidify_text(purify_html(Markdown($content)))); + $html = wiki_convert_links($html,$wikiURL); + } json_return_and_die(array('html' => $html, 'success' => true)); } @@ -288,17 +320,19 @@ class Wiki extends \Zotlabs\Web\Controller { if (local_channel() !== intval($owner['channel_id'])) { goaway('/' . argv(0) . '/' . $nick . '/'); } - $wiki = array(); // Generate new wiki info from input name $wiki['postVisible'] = ((intval($_POST['postVisible']) === 0) ? 0 : 1); $wiki['rawName'] = $_POST['wikiName']; $wiki['htmlName'] = escape_tags($_POST['wikiName']); $wiki['urlName'] = urlencode($_POST['wikiName']); + $wiki['mimeType'] = $_POST['mimeType']; + if($wiki['urlName'] === '') { notice( t('Error creating wiki. Invalid name.') . EOL); goaway('/wiki'); } + // Get ACL for permissions $acl = new \Zotlabs\Access\AccessList($owner); $acl->set_from_array($_POST); @@ -355,7 +389,18 @@ class Wiki extends \Zotlabs\Web\Controller { } $page = wiki_create_page($name, $resource_id); if ($page['success']) { - json_return_and_die(array('url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki']['urlName'].'/'.urlencode($page['page']['urlName']), 'success' => true)); + $ob = \App::get_observer(); + $commit = wiki_git_commit(array( + 'commit_msg' => t('New page created'), + 'resource_id' => $resource_id, + 'observer' => $ob, + 'files' => array($page['page']['fileName']) + )); + if($commit['success']) { + json_return_and_die(array('url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki']['urlName'].'/'.$page['page']['urlName'], 'success' => true)); + } else { + json_return_and_die(array('message' => 'Error making git commit','url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki']['urlName'].'/'.urlencode($page['page']['urlName']),'success' => false)); + } } else { logger('Error creating page'); json_return_and_die(array('message' => 'Error creating page.', 'success' => false)); @@ -405,7 +450,7 @@ class Wiki extends \Zotlabs\Web\Controller { 'commit_msg' => $commitMsg, 'resource_id' => $resource_id, 'observer' => $ob, - 'files' => array($pageUrlName.'.md') + 'files' => array($saved['fileName']) )); if($commit['success']) { json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true)); @@ -434,8 +479,9 @@ class Wiki extends \Zotlabs\Web\Controller { } $historyHTML = widget_wiki_page_history(array( - 'resource_id' => $resource_id, - 'pageUrlName' => $pageUrlName + 'resource_id' => $resource_id, + 'pageUrlName' => $pageUrlName, + 'permsWrite' => $perms['write'] )); json_return_and_die(array('historyHTML' => $historyHTML, 'message' => '', 'success' => true)); } @@ -544,7 +590,7 @@ class Wiki extends \Zotlabs\Web\Controller { 'commit_msg' => 'Renamed ' . urldecode($pageUrlName) . ' to ' . $renamed['page']['htmlName'], 'resource_id' => $resource_id, 'observer' => $ob, - 'files' => array($pageUrlName . '.md', $renamed['page']['fileName']), + 'files' => array($pageUrlName . substr($renamed['page']['fileName'], -3), $renamed['page']['fileName']), 'all' => true )); if($commit['success']) { diff --git a/Zotlabs/Render/Comanche.php b/Zotlabs/Render/Comanche.php index 562a9f791..8e36f52c2 100644 --- a/Zotlabs/Render/Comanche.php +++ b/Zotlabs/Render/Comanche.php @@ -104,6 +104,8 @@ class Comanche { $x = explode('.',$v); if($x[0] == 'config') return get_config($x[1],$x[2]); + elseif($x[0] === 'request') + return $_SERVER['REQUEST_URI']; elseif($x[0] === 'observer') { if(count($x) > 1) { $y = \App::get_observer(); @@ -125,20 +127,35 @@ class Comanche { function test_condition($s) { // This is extensible. The first version of variable testing supports tests of the forms: + + // [if $config.system.foo ~= baz] which will check if get_config('system','foo') contains the string 'baz'; // [if $config.system.foo == baz] which will check if get_config('system','foo') is the string 'baz'; // [if $config.system.foo != baz] which will check if get_config('system','foo') is not the string 'baz'; - // You may check numeric entries, but these checks are evaluated as strings. + // [if $config.system.foo >= 3] which will check if get_config('system','foo') is greater than or equal to 3; + // [if $config.system.foo > 3] which will check if get_config('system','foo') is greater than 3; + + // [if $config.system.foo <= 3] which will check if get_config('system','foo') is less than or equal to 3; + // [if $config.system.foo < 3] which will check if get_config('system','foo') is less than 3; + // [if $config.system.foo {} baz] which will check if 'baz' is an array element in get_config('system','foo') // [if $config.system.foo {*} baz] which will check if 'baz' is an array key in get_config('system','foo') // [if $config.system.foo] which will check for a return of a true condition for get_config('system','foo'); // The values 0, '', an empty array, and an unset value will all evaluate to false. + if(preg_match('/[\$](.*?)\s\~\=\s(.*?)$/',$s,$matches)) { + $x = $this->get_condition_var($matches[1]); + if(stripos($x,trim($matches[2])) !== false) + return true; + return false; + } + if(preg_match('/[\$](.*?)\s\=\=\s(.*?)$/',$s,$matches)) { $x = $this->get_condition_var($matches[1]); if($x == trim($matches[2])) return true; return false; } + if(preg_match('/[\$](.*?)\s\!\=\s(.*?)$/',$s,$matches)) { $x = $this->get_condition_var($matches[1]); if($x != trim($matches[2])) @@ -146,6 +163,31 @@ class Comanche { return false; } + if(preg_match('/[\$](.*?)\s\>\=\s(.*?)$/',$s,$matches)) { + $x = $this->get_condition_var($matches[1]); + if($x >= trim($matches[2])) + return true; + return false; + } + if(preg_match('/[\$](.*?)\s\<\=\s(.*?)$/',$s,$matches)) { + $x = $this->get_condition_var($matches[1]); + if($x <= trim($matches[2])) + return true; + return false; + } + if(preg_match('/[\$](.*?)\s\>\s(.*?)$/',$s,$matches)) { + $x = $this->get_condition_var($matches[1]); + if($x > trim($matches[2])) + return true; + return false; + } + if(preg_match('/[\$](.*?)\s\>\s(.*?)$/',$s,$matches)) { + $x = $this->get_condition_var($matches[1]); + if($x < trim($matches[2])) + return true; + return false; + } + if(preg_match('/[\$](.*?)\s\{\}\s(.*?)$/',$s,$matches)) { $x = $this->get_condition_var($matches[1]); if(is_array($x) && in_array(trim($matches[2]),$x)) diff --git a/Zotlabs/Web/Router.php b/Zotlabs/Web/Router.php index a3bad29ae..271836ba9 100644 --- a/Zotlabs/Web/Router.php +++ b/Zotlabs/Web/Router.php @@ -137,15 +137,21 @@ class Router { killme(); } - logger("Module {$module} not found.", LOGGER_DEBUG, LOG_WARNING); - - if((x($_SERVER, 'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && \App::$config['system']['dreamhost_error_hack']) { - logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']); + if((x($_SERVER, 'QUERY_STRING')) + && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') + && \App::$config['system']['dreamhost_error_hack']) { + logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI'],LOGGER_DEBUG); goaway(z_root() . $_SERVER['REQUEST_URI']); } - logger('index.php: page not found: ' . $_SERVER['REQUEST_URI'] . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' . $_SERVER['QUERY_STRING'], LOGGER_DEBUG); - header($_SERVER['SERVER_PROTOCOL'] . ' 404 ' . t('Not Found')); + if(get_config('system','log_404',true)) { + logger("Module {$module} not found.", LOGGER_DEBUG, LOG_WARNING); + logger('index.php: page not found: ' . $_SERVER['REQUEST_URI'] + . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' + . $_SERVER['QUERY_STRING'], LOGGER_DEBUG); + } + + header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); $tpl = get_markup_template('404.tpl'); \App::$page['content'] = replace_macros($tpl, array( '$message' => t('Page not found.') diff --git a/Zotlabs/Zot/Auth.php b/Zotlabs/Zot/Auth.php index 0837be21a..d4d3bee1d 100644 --- a/Zotlabs/Zot/Auth.php +++ b/Zotlabs/Zot/Auth.php @@ -149,9 +149,13 @@ class Auth { // The actual channel sending the packet ($c[0]) is not important, but this provides a // generic zot packet with a sender which can be verified + $x = q("select site_crypto from site where site_url = '%s' limit 1", + dbesc($hubloc['hubloc_url']) + ); + $p = zot_build_packet($channel,$type = 'auth_check', array(array('guid' => $hubloc['hubloc_guid'],'guid_sig' => $hubloc['hubloc_guid_sig'])), - $hubloc['hubloc_sitekey'], $this->sec); + $hubloc['hubloc_sitekey'], (($x) ? $x[0]['site_crypto'] : ''), $this->sec); $this->Debug('auth check packet created using sitekey ' . $hubloc['hubloc_sitekey']); $this->Debug('packet contents: ' . $p); |