diff options
Diffstat (limited to 'Zotlabs')
91 files changed, 1489 insertions, 430 deletions
diff --git a/Zotlabs/Access/PermissionLimits.php b/Zotlabs/Access/PermissionLimits.php index 1d15098fc..c11dc95e6 100644 --- a/Zotlabs/Access/PermissionLimits.php +++ b/Zotlabs/Access/PermissionLimits.php @@ -41,10 +41,8 @@ class PermissionLimits { $limits = []; $perms = Permissions::Perms(); - $anon_comments = get_config('system','anonymous_comments',true); - foreach($perms as $k => $v) { - if(strstr($k, 'view') || ($k === 'post_comments' && $anon_comments)) + if(strstr($k, 'view')) $limits[$k] = PERMS_PUBLIC; else $limits[$k] = PERMS_SPECIFIC; @@ -74,13 +72,13 @@ class PermissionLimits { * @param int $channel_id * @param string $perm (optional) * @return - * * \b boolean false if no perm_limits set for this channel - * * \b int if $perm is set, return one of PERMS_* constants for this permission + * * \b false if no perm_limits set for this channel + * * \b int if $perm is set, return one of PERMS_* constants for this permission, default 0 * * \b array with all permission limits, if $perm is not set */ static public function Get($channel_id, $perm = '') { if($perm) { - return PConfig::Get($channel_id, 'perm_limits', $perm); + return intval(PConfig::Get($channel_id, 'perm_limits', $perm)); } PConfig::Load($channel_id); diff --git a/Zotlabs/Access/PermissionRoles.php b/Zotlabs/Access/PermissionRoles.php index b335bf825..9855a05c4 100644 --- a/Zotlabs/Access/PermissionRoles.php +++ b/Zotlabs/Access/PermissionRoles.php @@ -41,6 +41,24 @@ class PermissionRoles { break; + case 'social_federation': + $ret['perms_auto'] = false; + $ret['default_collection'] = false; + $ret['directory_publish'] = true; + $ret['online'] = true; + $ret['perms_connect'] = [ + 'view_stream', 'view_profile', 'view_contacts', 'view_storage', + 'view_pages', 'view_wiki', 'send_stream', 'post_wall', 'post_comments', + 'post_mail', 'chat', 'post_like', 'republish' + ]; + $ret['limits'] = PermissionLimits::Std_Limits(); + $ret['limits']['post_comments'] = PERMS_AUTHED; + $ret['limits']['post_mail'] = PERMS_AUTHED; + $ret['limits']['post_like'] = PERMS_AUTHED; + $ret['limits']['chat'] = PERMS_AUTHED; + break; + + case 'social_restricted': $ret['perms_auto'] = false; $ret['default_collection'] = true; @@ -263,6 +281,7 @@ class PermissionRoles { static public function roles() { $roles = [ t('Social Networking') => [ + 'social_federation' => t('Social - Federation'), 'social' => t('Social - Mostly Public'), 'social_restricted' => t('Social - Restricted'), 'social_private' => t('Social - Private') diff --git a/Zotlabs/Daemon/Expire.php b/Zotlabs/Daemon/Expire.php index 215513e87..398425861 100644 --- a/Zotlabs/Daemon/Expire.php +++ b/Zotlabs/Daemon/Expire.php @@ -34,7 +34,8 @@ class Expire { logger('expire: start', LOGGER_DEBUG); - $site_expire = get_config('system', 'default_expire_days'); + $site_expire = intval(get_config('system', 'default_expire_days')); + $commented_days = intval(get_config('system','active_expire_days')); logger('site_expire: ' . $site_expire); @@ -64,7 +65,7 @@ class Expire { // if the site or service class expiration is non-zero and less than person expiration, use that logger('Expire: ' . $rr['channel_address'] . ' interval: ' . $expire_days, LOGGER_DEBUG); - item_expire($rr['channel_id'], $expire_days); + item_expire($rr['channel_id'], $expire_days, $commented_days); } } @@ -85,7 +86,7 @@ class Expire { logger('Expire: sys interval: ' . $expire_days, LOGGER_DEBUG); if ($expire_days) - item_expire($x['channel_id'], $expire_days); + item_expire($x['channel_id'], $expire_days, $commented_days); logger('Expire: sys: done', LOGGER_DEBUG); } diff --git a/Zotlabs/Lib/ActivityStreams.php b/Zotlabs/Lib/ActivityStreams.php index 2e9bb0703..3a99e7b49 100644 --- a/Zotlabs/Lib/ActivityStreams.php +++ b/Zotlabs/Lib/ActivityStreams.php @@ -9,6 +9,7 @@ namespace Zotlabs\Lib; */ class ActivityStreams { + public $raw = null; public $data; public $valid = false; public $id = ''; @@ -33,6 +34,7 @@ class ActivityStreams { */ function __construct($string) { + $this->raw = $string; $this->data = json_decode($string, true); if($this->data) { $this->valid = true; diff --git a/Zotlabs/Lib/Apps.php b/Zotlabs/Lib/Apps.php index f91dc8e49..24cb4a626 100644 --- a/Zotlabs/Lib/Apps.php +++ b/Zotlabs/Lib/Apps.php @@ -785,6 +785,7 @@ class Apps { dbesc($darray['app_plugin']), intval($darray['app_deleted']) ); + if($r) { $ret['success'] = true; $ret['app_id'] = $darray['app_id']; @@ -871,6 +872,12 @@ class Apps { dbesc($darray['app_id']), intval($darray['app_channel']) ); + + // if updating an embed app, don't mess with any existing categories. + + if(array_key_exists('embed',$arr) && intval($arr['embed'])) + return $ret; + if($x) { q("delete from term where otype = %d and oid = %d", intval(TERM_OBJ_APP), diff --git a/Zotlabs/Lib/Chatroom.php b/Zotlabs/Lib/Chatroom.php index e762620ae..882c846cd 100644 --- a/Zotlabs/Lib/Chatroom.php +++ b/Zotlabs/Lib/Chatroom.php @@ -266,7 +266,7 @@ class Chatroom { intval($room_id), dbesc($xchan), dbesc(datetime_convert()), - dbesc($arr['chat_text']) + dbesc(str_rot47(base64url_encode($arr['chat_text']))) ); $ret['success'] = true; diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php index 61c98c881..cfb0bd344 100644 --- a/Zotlabs/Lib/Enotify.php +++ b/Zotlabs/Lib/Enotify.php @@ -115,6 +115,9 @@ class Enotify { $always_show_in_notices = get_pconfig($recip['channel_id'],'system','always_show_in_notices'); + $vnotify = get_pconfig($recip['channel_id'],'system','vnotify'); + + $salutation = $recip['channel_name']; // e.g. "your post", "David's photo", etc. $possess_desc = t('%s <!item_type!>'); @@ -123,7 +126,7 @@ class Enotify { logger('notification: mail'); $subject = sprintf( t('[$Projectname:Notify] New mail received at %s'),$sitename); - $preamble = sprintf( t('%1$s, %2$s sent you a new private message at %3$s.'),$recip['channel_name'], $sender['xchan_name'],$sitename); + $preamble = sprintf( t('%1$s sent you a new private message at %2$s.'), $sender['xchan_name'],$sitename); $epreamble = sprintf( t('%1$s sent you %2$s.'),'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]'); $sitelink = t('Please visit %s to view and/or reply to your private messages.'); $tsitelink = sprintf( $sitelink, $siteurl . '/mail/' . $params['item']['id'] ); @@ -142,7 +145,7 @@ class Enotify { if(array_key_exists('item',$params) && in_array($params['item']['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) { - if(! $always_show_in_notices) { + if(! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE)) { logger('notification: not a visible activity. Ignoring.'); pop_lang(); return; @@ -195,8 +198,7 @@ class Enotify { //$possess_desc = str_replace('<!item_type!>',$possess_desc); // "a post" - $dest_str = sprintf(t('%1$s, %2$s %3$s [zrl=%4$s]a %5$s[/zrl]'), - $recip['channel_name'], + $dest_str = sprintf(t('%1$s %2$s [zrl=%3$s]a %4$s[/zrl]'), '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $action, $itemlink, @@ -204,8 +206,7 @@ class Enotify { // "George Bull's post" if($p) - $dest_str = sprintf(t('%1$s, %2$s %3$s [zrl=%4$s]%5$s\'s %6$s[/zrl]'), - $recip['channel_name'], + $dest_str = sprintf(t('%1$s %2$s [zrl=%3$s]%4$s\'s %5$s[/zrl]'), '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $action, $itemlink, @@ -214,8 +215,7 @@ class Enotify { // "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 %3$s [zrl=%4$s]your %5$s[/zrl]'), - $recip['channel_name'], + $dest_str = sprintf(t('%1$s %2$s [zrl=%3$s]your %4$s[/zrl]'), '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $action, $itemlink, @@ -230,7 +230,7 @@ class Enotify { $subject = sprintf( t('[$Projectname:Notify] Moderated Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']); else $subject = sprintf( t('[$Projectname:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']); - $preamble = sprintf( t('%1$s, %2$s commented on an item/conversation you have been following.'), $recip['channel_name'], $sender['xchan_name']); + $preamble = sprintf( t('%1$s commented on an item/conversation you have been following.'), $sender['xchan_name']); $epreamble = $dest_str; $sitelink = t('Please visit %s to view and/or reply to the conversation.'); @@ -249,7 +249,7 @@ class Enotify { $itemlink = $params['link']; if (array_key_exists('item',$params) && (! activity_match($params['item']['verb'],ACTIVITY_LIKE))) { - if(! $always_show_in_notices) { + if(! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE)) { logger('notification: not a visible activity. Ignoring.'); pop_lang(); return; @@ -296,8 +296,7 @@ class Enotify { // "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'], + $dest_str = sprintf(t('%1$s liked [zrl=%2$s]your %3$s[/zrl]'), '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $itemlink, $item_post_type); @@ -312,7 +311,7 @@ class Enotify { // 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']); + $preamble = sprintf( t('%1$s liked an item/conversation you created.'), $sender['xchan_name']); $epreamble = $dest_str; $sitelink = t('Please visit %s to view and/or reply to the conversation.'); @@ -325,10 +324,9 @@ class Enotify { if($params['type'] == NOTIFY_WALL) { $subject = sprintf( t('[$Projectname:Notify] %s posted to your profile wall') , $sender['xchan_name']); - $preamble = sprintf( t('%1$s, %2$s posted to your profile wall at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename); + $preamble = sprintf( t('%1$s posted to your profile wall at %2$s') , $sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s, %2$s posted to [zrl=%3$s]your wall[/zrl]') , - $recip['channel_name'], + $epreamble = sprintf( t('%1$s posted to [zrl=%2$s]your wall[/zrl]') , '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $params['link']); @@ -352,9 +350,8 @@ class Enotify { } $subject = sprintf( t('[$Projectname:Notify] %s tagged you') , $sender['xchan_name']); - $preamble = sprintf( t('%1$s, %2$s tagged you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s, %2$s [zrl=%3$s]tagged you[/zrl].') , - $recip['channel_name'], + $preamble = sprintf( t('%1$s tagged you at %2$s') , $sender['xchan_name'], $sitename); + $epreamble = sprintf( t('%1$s [zrl=%2$s]tagged you[/zrl].') , '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $params['link']); @@ -366,9 +363,8 @@ class Enotify { if ($params['type'] == NOTIFY_POKE) { $subject = sprintf( t('[$Projectname:Notify] %1$s poked you') , $sender['xchan_name']); - $preamble = sprintf( t('%1$s, %2$s poked you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s, %2$s [zrl=%2$s]poked you[/zrl].') , - $recip['channel_name'], + $preamble = sprintf( t('%1$s poked you at %2$s') , $sender['xchan_name'], $sitename); + $epreamble = sprintf( t('%1$s [zrl=%2$s]poked you[/zrl].') , '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $params['link']); @@ -384,9 +380,8 @@ class Enotify { if ($params['type'] == NOTIFY_TAGSHARE) { $subject = sprintf( t('[$Projectname:Notify] %s tagged your post') , $sender['xchan_name']); - $preamble = sprintf( t('%1$s, %2$s tagged your post at %3$s') , $recip['channel_name'],$sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s, %2$s tagged [zrl=%3$s]your post[/zrl]') , - $recip['channel_name'], + $preamble = sprintf( t('%1$s tagged your post at %2$s'),$sender['xchan_name'], $sitename); + $epreamble = sprintf( t('%1$s tagged [zrl=%2$s]your post[/zrl]') , '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', $itemlink); @@ -398,9 +393,8 @@ class Enotify { if ($params['type'] == NOTIFY_INTRO) { $subject = sprintf( t('[$Projectname:Notify] Introduction received')); - $preamble = sprintf( t('%1$s, you\'ve received an new connection request from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a new connection request[/zrl] from %3$s.'), - $recip['channel_name'], + $preamble = sprintf( t('You\'ve received an new connection request from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename); + $epreamble = sprintf( t('You\'ve received [zrl=%1$s]a new connection request[/zrl] from %2$s.'), $siteurl . '/connections/ifpending', '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]'); $body = sprintf( t('You may visit their profile at %s'),$sender['xchan_url']); @@ -413,9 +407,8 @@ class Enotify { if ($params['type'] == NOTIFY_SUGGEST) { $subject = sprintf( t('[$Projectname:Notify] Friend suggestion received')); - $preamble = sprintf( t('%1$s, you\'ve received a friend suggestion from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename); - $epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a friend suggestion[/zrl] for %3$s from %4$s.'), - $recip['channel_name'], + $preamble = sprintf( t('You\'ve received a friend suggestion from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename); + $epreamble = sprintf( t('You\'ve received [zrl=%1$s]a friend suggestion[/zrl] for %2$s from %3$s.'), $itemlink, '[zrl=' . $params['item']['url'] . ']' . $params['item']['name'] . '[/zrl]', '[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]'); @@ -664,7 +657,7 @@ class Enotify { '$banner' => $datarray['banner'], '$notify_icon' => \Zotlabs\Lib\System::get_notify_icon(), '$product' => $datarray['product'], - '$preamble' => $datarray['preamble'], + '$preamble' => $salutation . '<br><br>' . $datarray['preamble'], '$sitename' => $datarray['sitename'], '$siteurl' => $datarray['siteurl'], '$source_name' => $datarray['source_name'], @@ -686,7 +679,7 @@ class Enotify { $email_text_body = replace_macros($tpl, array( '$banner' => $datarray['banner'], '$product' => $datarray['product'], - '$preamble' => $datarray['preamble'], + '$preamble' => $salutation . "\n\n" . $datarray['preamble'], '$sitename' => $datarray['sitename'], '$siteurl' => $datarray['siteurl'], '$source_name' => $datarray['source_name'], @@ -754,8 +747,8 @@ class Enotify { // generate a mime boundary $mimeBoundary = rand(0, 9) . "-" - .rand(10000000000, 9999999999) . "-" - .rand(10000000000, 9999999999) . "=:" + .rand(100000000, 999999999) . "-" + .rand(100000000, 999999999) . "=:" .rand(10000, 99999); // generate a multipart/alternative message header diff --git a/Zotlabs/Lib/NativeWiki.php b/Zotlabs/Lib/NativeWiki.php index 7642dbb3e..6f916216e 100644 --- a/Zotlabs/Lib/NativeWiki.php +++ b/Zotlabs/Lib/NativeWiki.php @@ -171,16 +171,23 @@ class NativeWiki { dbesc(NWIKI_ITEM_RESOURCE_TYPE), dbesc($resource_id) ); + if($r) { $q = q("select * from item where resource_type = 'nwikipage' and resource_id = '%s'", - dbesc($r[0]['resource_type']) + dbesc($r[0]['resource_id']) ); if($q) { $r = array_merge($r,$q); } xchan_query($r); $sync_item = fetch_post_tags($r); - build_sync_packet($uid,array('wiki' => array(encode_item($sync_item[0],true)))); + if($sync_item) { + $pkt = []; + foreach($sync_item as $w) { + $pkt[] = encode_item($w,true); + } + build_sync_packet($uid,array('wiki' => $pkt)); + } } } diff --git a/Zotlabs/Lib/Share.php b/Zotlabs/Lib/Share.php index b5341e662..e9e4d23c4 100644 --- a/Zotlabs/Lib/Share.php +++ b/Zotlabs/Lib/Share.php @@ -123,11 +123,13 @@ class Share { $bb = substr($this->item['body'], $pos); } else { $bb = "[share author='".urlencode($this->item['author']['xchan_name']). - "' profile='".$this->item['author']['xchan_url'] . - "' avatar='".$this->item['author']['xchan_photo_s']. - "' link='".$this->item['plink']. - "' posted='".$this->item['created']. - "' message_id='".$this->item['mid']."']"; + "' profile='" . $this->item['author']['xchan_url'] . + "' avatar='" . $this->item['author']['xchan_photo_s'] . + "' link='" . $this->item['plink'] . + "' auth='" . (($this->item['author']['network'] === 'zot') ? 'true' : 'false') . + "' posted='" . $this->item['created'] . + "' message_id='" . $this->item['mid'] . + "']"; if($this->item['title']) $bb .= '[b]'.$this->item['title'].'[/b]'."\r\n"; $bb .= (($is_photo) ? $photo_bb . "\r\n" . $this->item['body'] : $this->item['body']); diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index d35d4732a..61a012f9d 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -238,9 +238,9 @@ class ThreadItem { 'do' => t("Add Star"), 'undo' => t("Remove Star"), 'toggle' => t("Toggle Star Status"), - 'classdo' => (intval($item['item_starred']) ? "hidden" : ""), - 'classundo' => (intval($item['item_starred']) ? "" : "hidden"), - 'isstarred' => (intval($item['item_starred']) ? "starred fa-star" : "unstarred fa-star-o"), + 'classdo' => ((intval($item['item_starred'])) ? "hidden" : ""), + 'classundo' => ((intval($item['item_starred'])) ? "" : "hidden"), + 'isstarred' => ((intval($item['item_starred'])) ? true : false), 'starred' => t('starred'), ); @@ -733,6 +733,8 @@ class ThreadItem { $arr = array('comment_buttons' => '','id' => $this->get_id()); call_hooks('comment_buttons',$arr); $comment_buttons = $arr['comment_buttons']; + + $feature_auto_save_draft = ((feature_enabled($conv->get_profile_owner(), 'auto_save_draft')) ? "true" : "false"); $comment_box = replace_macros($template,array( '$return_path' => '', @@ -768,7 +770,8 @@ class ThreadItem { '$anoncomments' => ((($conv->get_mode() === 'channel' || $conv->get_mode() === 'display') && perm_is_allowed($conv->get_profile_owner(),'','post_comments')) ? true : false), '$anonname' => [ 'anonname', t('Your full name (required)') ], '$anonmail' => [ 'anonmail', t('Your email address (required)') ], - '$anonurl' => [ 'anonurl', t('Your website URL (optional)') ] + '$anonurl' => [ 'anonurl', t('Your website URL (optional)') ], + '$auto_save_draft' => $feature_auto_save_draft, )); return $comment_box; diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php index fae7e2e44..2678aeb7a 100644 --- a/Zotlabs/Module/Acl.php +++ b/Zotlabs/Module/Acl.php @@ -24,7 +24,7 @@ class Acl extends \Zotlabs\Web\Controller { function init() { - logger('mod_acl: ' . print_r($_REQUEST,true)); + logger('mod_acl: ' . print_r($_REQUEST,true),LOGGER_DATA); $start = (x($_REQUEST,'start') ? $_REQUEST['start'] : 0); $count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 500); @@ -82,7 +82,7 @@ class Acl extends \Zotlabs\Web\Controller { if($search) { $sql_extra = " AND groups.gname LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " "; - $sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc($search) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") "; + $sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc(punify($search)) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") "; // This horrible mess is needed because position also returns 0 if nothing is found. // Would be MUCH easier if it instead returned a very large value @@ -92,10 +92,10 @@ class Acl extends \Zotlabs\Web\Controller { $order_extra2 = "CASE WHEN xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " then POSITION('" . protect_sprintf(dbesc($search)) - . "' IN xchan_name) else position('" . protect_sprintf(dbesc($search)) . "' IN xchan_addr) end, "; + . "' IN xchan_name) else position('" . protect_sprintf(dbesc(punify($search))) . "' IN xchan_addr) end, "; $col = ((strpos($search,'@') !== false) ? 'xchan_addr' : 'xchan_name' ); - $sql_extra3 = "AND $col like " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " "; + $sql_extra3 = "AND $col like " . protect_sprintf( "'%" . dbesc(($col === 'xchan_addr') ? punify($search) : $search) . "%'" ) . " "; } else { @@ -268,15 +268,15 @@ class Acl extends \Zotlabs\Web\Controller { }); } } - if(intval(get_config('system','taganyone')) || intval(get_pconfig(local_channel(),'system','taganyone'))) { - if((count($r) < 100) && $type == 'c') { - $r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self - FROM xchan - WHERE xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" - ); - if($r2) - $r = array_merge($r,$r2); - } + if((count($r) < 100) && $type == 'c') { + $r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self + FROM xchan + WHERE xchan_deleted = 0 and not xchan_network in ('rss','anon','unknown') $sql_extra2 order by $order_extra2 xchan_name asc" + ); + if($r2) { + $r = array_merge($r,$r2); + $r = unique_multidim_array($r,'hash'); + } } } elseif($type == 'm') { @@ -337,24 +337,23 @@ class Acl extends \Zotlabs\Web\Controller { if($r) { foreach($r as $g) { - if(($g['network'] === 'rss') && ($type != 'a')) + if(in_array($g['network'],['rss','anon','unknown']) && ($type != 'a')) continue; $g['hash'] = urlencode($g['hash']); if(! $g['nick']) { - $t = explode(' ',strtolower($g['name'])); - $g['nick'] = $t[0] . '@'; + $g['nick'] = $g['url']; } - if(in_array($g['hash'],$permitted) && in_array($type, [ 'c', 'f' ]) && (! $noforums)) { + if(in_array($g['hash'],$permitted) && $type === 'f' && (! $noforums)) { $contacts[] = array( "type" => "c", "photo" => "images/twopeople.png", - "name" => $g['name'] . (($type === 'f') ? '' : '+'), - "id" => urlencode($g['id']) . (($type === 'f') ? '' : '+'), + "name" => $g['name'], + "id" => urlencode($g['id']), "xid" => $g['hash'], - "link" => $g['nick'], + "link" => (($g['nick']) ? $g['nick'] : $g['url']), "nick" => substr($g['nick'],0,strpos($g['nick'],'@')), "self" => (intval($g['abook_self']) ? 'abook-self' : ''), "taggable" => 'taggable', @@ -368,8 +367,8 @@ class Acl extends \Zotlabs\Web\Controller { "name" => $g['name'], "id" => urlencode($g['id']), "xid" => $g['hash'], - "link" => $g['nick'], - "nick" => (($g['nick']) ? substr($g['nick'],0,strpos($g['nick'],'@')) : $g['nick']), + "link" => (($g['nick']) ? $g['nick'] : $g['url']), + "nick" => ((strpos($g['nick'],'@')) ? substr($g['nick'],0,strpos($g['nick'],'@')) : $g['nick']), "self" => (intval($g['abook_self']) ? 'abook-self' : ''), "taggable" => '', "label" => '', @@ -435,7 +434,7 @@ class Acl extends \Zotlabs\Web\Controller { $count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 100); if($url) { $query = $url . '?f=' . (($token) ? '&t=' . urlencode($token) : ''); - $query .= '&name=' . urlencode($search) . "&limit=$count" . (($address) ? '&address=' . urlencode($search) : ''); + $query .= '&name=' . urlencode($search) . "&limit=$count" . (($address) ? '&address=' . urlencode(punify($search)) : ''); $x = z_fetch_url($query); if($x['success']) { diff --git a/Zotlabs/Module/Admin/Accounts.php b/Zotlabs/Module/Admin/Accounts.php index 2e417edd1..0c7e089be 100644 --- a/Zotlabs/Module/Admin/Accounts.php +++ b/Zotlabs/Module/Admin/Accounts.php @@ -133,12 +133,13 @@ class Accounts { $base = z_root() . '/admin/accounts?f='; $odir = (($dir === 'asc') ? '0' : '1'); - + $users = q("SELECT account_id , account_email, account_lastlog, account_created, account_expires, account_service_class, ( account_flags & %d ) > 0 as blocked, (SELECT %s FROM channel as ch WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as channels FROM account as ac - where true $serviceclass order by $key $dir limit %d offset %d ", + where true $serviceclass and account_flags != %d order by $key $dir limit %d offset %d ", intval(ACCOUNT_BLOCKED), db_concat('ch.channel_address', ' '), + intval(ACCOUNT_BLOCKED | ACCOUNT_PENDING), intval(\App::$pager['itemspage']), intval(\App::$pager['start']) ); @@ -203,4 +204,4 @@ class Accounts { } -}
\ No newline at end of file +} diff --git a/Zotlabs/Module/Admin/Profs.php b/Zotlabs/Module/Admin/Profs.php index b3da09cb7..eb2501d43 100644 --- a/Zotlabs/Module/Admin/Profs.php +++ b/Zotlabs/Module/Admin/Profs.php @@ -9,17 +9,37 @@ class Profs { if(array_key_exists('basic',$_REQUEST)) { $arr = explode(',',$_REQUEST['basic']); - for($x = 0; $x < count($arr); $x ++) - if(trim($arr[$x])) - $arr[$x] = trim($arr[$x]); - set_config('system','profile_fields_basic',$arr); - + array_walk($arr,'array_trim'); + $narr = []; + if(count($arr)) { + foreach($arr as $a) { + if(strlen($a)) { + $narr[] = $a; + } + } + } + if(! $narr) + del_config('system','profile_fields_basic'); + else + set_config('system','profile_fields_basic',$narr); + + if(array_key_exists('advanced',$_REQUEST)) { $arr = explode(',',$_REQUEST['advanced']); - for($x = 0; $x < count($arr); $x ++) - if(trim($arr[$x])) - $arr[$x] = trim($arr[$x]); - set_config('system','profile_fields_advanced',$arr); + array_walk($arr,'array_trim'); + $narr = []; + if(count($arr)) { + foreach($arr as $a) { + if(strlen($a)) { + $narr[] = $a; + } + } + } + if(! $narr) + del_config('system','profile_fields_advanced'); + else + set_config('system','profile_fields_advanced',$narr); + } goaway(z_root() . '/admin/profs'); } @@ -98,6 +118,7 @@ class Profs { $basic = ''; $barr = array(); $fields = get_profile_fields_basic(); + if(! $fields) $fields = get_profile_fields_basic(1); if($fields) { diff --git a/Zotlabs/Module/Admin/Site.php b/Zotlabs/Module/Admin/Site.php index 880dbbe4b..656770ad9 100644 --- a/Zotlabs/Module/Admin/Site.php +++ b/Zotlabs/Module/Admin/Site.php @@ -24,7 +24,7 @@ class Site { $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'])) : ''); +// $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : ''); // $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : ''); $maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0); @@ -38,7 +38,12 @@ class Site { $site_sellpage = ((x($_POST,'site_sellpage')) ? notags(trim($_POST['site_sellpage'])) : ''); $site_location = ((x($_POST,'site_location')) ? notags(trim($_POST['site_location'])) : ''); $frontpage = ((x($_POST,'frontpage')) ? notags(trim($_POST['frontpage'])) : ''); - $firstpage = ((x(trim($_POST,'firstpage'))) ? notags(trim($_POST['firstpage'])) : 'profiles'); + $firstpage = ((x($_POST,'firstpage')) ? notags(trim($_POST['firstpage'])) : 'profiles'); + $first_page = ((x($_POST,'first_page')) ? notags(trim($_POST['first_page'])) : 'profiles'); + // check value after trim + if(! $first_page) { + $first_page = 'profiles'; + } $mirror_frontpage = ((x($_POST,'mirror_frontpage')) ? intval(trim($_POST['mirror_frontpage'])) : 0); $directory_server = ((x($_POST,'directory_server')) ? trim($_POST['directory_server']) : ''); $allowed_sites = ((x($_POST,'allowed_sites')) ? notags(trim($_POST['allowed_sites'])) : ''); @@ -51,6 +56,7 @@ class Site { $global_directory = ((x($_POST,'directory_submit_url')) ? notags(trim($_POST['directory_submit_url'])) : ''); $no_community_page = !((x($_POST,'no_community_page')) ? True : False); $default_expire_days = ((array_key_exists('default_expire_days',$_POST)) ? intval($_POST['default_expire_days']) : 0); + $active_expire_days = ((array_key_exists('active_expire_days',$_POST)) ? intval($_POST['active_expire_days']) : 7); $reply_address = ((array_key_exists('reply_address',$_POST) && trim($_POST['reply_address'])) ? trim($_POST['reply_address']) : 'noreply@' . \App::get_hostname()); $from_email = ((array_key_exists('from_email',$_POST) && trim($_POST['from_email'])) ? trim($_POST['from_email']) : 'Administrator@' . \App::get_hostname()); @@ -82,7 +88,7 @@ class Site { set_config('system', 'maxloadavg', $maxloadavg); set_config('system', 'frontpage', $frontpage); set_config('system', 'sellpage', $site_sellpage); - set_config('system', 'workflow_channel_next', $firstpage); + set_config('system', 'workflow_channel_next', $first_page); set_config('system', 'site_location', $site_location); set_config('system', 'mirror_frontpage', $mirror_frontpage); set_config('system', 'sitename', $sitename); @@ -90,6 +96,7 @@ class Site { set_config('system', 'enable_context_help', $enable_context_help); set_config('system', 'verify_email', $verify_email); set_config('system', 'default_expire_days', $default_expire_days); + set_config('system', 'active_expire_days', $active_expire_days); set_config('system', 'reply_address', $reply_address); set_config('system', 'from_email', $from_email); set_config('system', 'from_email_name' , $from_email_name); @@ -122,11 +129,11 @@ class Site { set_config('system','siteinfo',$siteinfo); set_config('system', 'language', $language); set_config('system', 'theme', $theme); - if ( $theme_mobile === '---' ) { - del_config('system', 'mobile_theme'); - } else { - set_config('system', 'mobile_theme', $theme_mobile); - } +// if ( $theme_mobile === '---' ) { +// del_config('system', 'mobile_theme'); +// } else { +// set_config('system', 'mobile_theme', $theme_mobile); +// } // set_config('system','site_channel', $site_channel); set_config('system','maximagesize', $maximagesize); @@ -305,7 +312,7 @@ class Site { '$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), +// '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile), // '$site_channel' => array('site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel")), '$feed_contacts' => array('feed_contacts', t('Allow Feeds as Connections'),get_config('system','feed_contacts'),t('(Heavy system resource usage)')), '$maximagesize' => array('maximagesize', t("Maximum image size"), intval(get_config('system','maximagesize')), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")), @@ -343,9 +350,10 @@ class Site { '$thumbnail_security' => array('thumbnail_security', t("Allow SVG thumbnails in file browser"), get_config('system','thumbnail_security',0), t("WARNING: SVG images may contain malicious code.")), '$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")), '$default_expire_days' => array('default_expire_days', t('Expiration period in days for imported (grid/network) content'), intval(get_config('system','default_expire_days')), t('0 for no expiration of imported content')), + '$active_expire_days' => array('active_expire_days', t('Do not expire any posts which have comments less than this many days ago'), intval(get_config('system','active_expire_days',7)), ''), '$sellpage' => array('site_sellpage', t('Public servers: Optional landing (marketing) webpage for new registrants'), get_config('system','sellpage',''), sprintf( t('Create this page first. Default is %s/register'),z_root())), - '$firstpage' => array('firstpage', t('Page to display after creating a new channel'), get_config('system','workflow_channel_next','profiles'), t('Recommend: profiles, go, or settings')), + '$first_page' => array('first_page', t('Page to display after creating a new channel'), get_config('system','workflow_channel_next','profiles'), t('Recommend: profiles, go, or settings')), '$location' => array('site_location', t('Optional: site location'), get_config('system','site_location',''), t('Region or country')), diff --git a/Zotlabs/Module/Appman.php b/Zotlabs/Module/Appman.php index 64d4628ae..3ebafafa4 100644 --- a/Zotlabs/Module/Appman.php +++ b/Zotlabs/Module/Appman.php @@ -25,6 +25,7 @@ class Appman extends \Zotlabs\Web\Controller { 'photo' => escape_tags($_REQUEST['photo']), 'version' => escape_tags($_REQUEST['version']), 'price' => escape_tags($_REQUEST['price']), + 'page' => escape_tags($_REQUEST['page']), 'requires' => escape_tags($_REQUEST['requires']), 'system' => intval($_REQUEST['system']), 'plugin' => escape_tags($_REQUEST['plugin']), diff --git a/Zotlabs/Module/Articles.php b/Zotlabs/Module/Articles.php index e2e0fed5d..284868241 100644 --- a/Zotlabs/Module/Articles.php +++ b/Zotlabs/Module/Articles.php @@ -127,21 +127,26 @@ class Articles extends \Zotlabs\Web\Controller { $editor = ''; } + $itemspage = get_pconfig(local_channel(),'system','itemspage'); + \App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20)); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start'])); + $sql_extra = item_permissions_sql($owner); + $sql_item = ''; if($selected_card) { $r = q("select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and iconfig.v = '%s' limit 1", dbesc($selected_card) ); if($r) { - $sql_extra .= "and item.id = " . intval($r[0]['iid']) . " "; + $sql_item = "and item.id = " . intval($r[0]['iid']) . " "; } } $r = q("select * from item where item.uid = %d and item_type = %d - $sql_extra order by item.created desc", + $sql_extra $sql_item order by item.created desc $pager_sql", intval($owner), intval(ITEM_TYPE_ARTICLE) ); @@ -152,6 +157,8 @@ class Articles extends \Zotlabs\Web\Controller { if($r) { + $pager_total = count($r); + $parents_str = ids_to_querystr($r,'id'); $items = q("SELECT item.*, item.id AS item_id @@ -173,13 +180,18 @@ class Articles extends \Zotlabs\Web\Controller { $mode = 'articles'; - $content = conversation($items,$mode,false,'traditional'); + if(get_pconfig(local_channel(),'system','articles_list_mode') && (! $selected_card)) + $page_mode = 'pager_list'; + else + $page_mode = 'traditional'; + + $content = conversation($items,$mode,false,$page_mode); $o = replace_macros(get_markup_template('cards.tpl'), [ '$title' => t('Articles'), '$editor' => $editor, '$content' => $content, - '$pager' => alt_pager($a,count($items)) + '$pager' => alt_pager($pager_total) ]); return $o; diff --git a/Zotlabs/Module/Authorize.php b/Zotlabs/Module/Authorize.php index 254700b4e..bfb76150f 100644 --- a/Zotlabs/Module/Authorize.php +++ b/Zotlabs/Module/Authorize.php @@ -4,60 +4,89 @@ namespace Zotlabs\Module; use Zotlabs\Identity\OAuth2Storage; - class Authorize extends \Zotlabs\Web\Controller { - function init() { - - // workaround for HTTP-auth in CGI mode - if (x($_SERVER, 'REDIRECT_REMOTE_USER')) { - $userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"], 6)) ; - if(strlen($userpass)) { - list($name, $password) = explode(':', $userpass); - $_SERVER['PHP_AUTH_USER'] = $name; - $_SERVER['PHP_AUTH_PW'] = $password; - } + function get() { + if (!local_channel()) { + return login(); + } else { + // TODO: Fully implement the dynamic client registration protocol: + // OpenID Connect Dynamic Client Registration 1.0 Client Metadata + // http://openid.net/specs/openid-connect-registration-1_0.html + $app = array( + 'name' => (x($_REQUEST, 'client_name') ? urldecode($_REQUEST['client_name']) : t('Unknown App')), + 'icon' => (x($_REQUEST, 'logo_uri') ? urldecode($_REQUEST['logo_uri']) : z_root() . '/images/icons/plugin.png'), + 'url' => (x($_REQUEST, 'client_uri') ? urldecode($_REQUEST['client_uri']) : ''), + ); + $o .= replace_macros(get_markup_template('oauth_authorize.tpl'), array( + '$title' => t('Authorize'), + '$authorize' => sprintf( t('Do you authorize the app %s to access your channel data?'), '<a style="float: none;" href="' . $app['url'] . '">' . $app['name'] . '</a> '), + '$app' => $app, + '$yes' => t('Allow'), + '$no' => t('Deny'), + '$client_id' => (x($_REQUEST, 'client_id') ? $_REQUEST['client_id'] : ''), + '$redirect_uri' => (x($_REQUEST, 'redirect_uri') ? $_REQUEST['redirect_uri'] : ''), + '$state' => (x($_REQUEST, 'state') ? $_REQUEST['state'] : ''), + )); + return $o; } + } - if (x($_SERVER, 'HTTP_AUTHORIZATION')) { - $userpass = base64_decode(substr($_SERVER["HTTP_AUTHORIZATION"], 6)) ; - if(strlen($userpass)) { - list($name, $password) = explode(':', $userpass); - $_SERVER['PHP_AUTH_USER'] = $name; - $_SERVER['PHP_AUTH_PW'] = $password; - } + function post() { + if (! local_channel()) { + return; } - $s = new \Zotlabs\Identity\OAuth2Server(new OAuth2Storage(\DBA::$dba->db)); + $storage = new OAuth2Storage(\DBA::$dba->db); + $s = new \Zotlabs\Identity\OAuth2Server($storage); + + // TODO: The automatic client registration protocol below should adhere more + // closely to "OAuth 2.0 Dynamic Client Registration Protocol" defined + // at https://tools.ietf.org/html/rfc7591 + + // If no client_id was provided, generate a new one. + if (x($_POST, 'client_id')) { + $client_id = $_POST['client_id']; + } else { + $client_id = $_POST['client_id'] = random_string(16); + } + // If no redirect_uri was provided, generate a fake one. + if (x($_POST, 'redirect_uri')) { + $redirect_uri = $_POST['redirect_uri']; + } else { + $redirect_uri = $_POST['redirect_uri'] = 'https://fake.example.com/oauth'; + } $request = \OAuth2\Request::createFromGlobals(); $response = new \OAuth2\Response(); - // validate the authorize request - if (! $s->validateAuthorizeRequest($request, $response)) { + // If the client is not registered, add to the database + if (!$client = $storage->getClientDetails($client_id)) { + $client_secret = random_string(16); + // Client apps are registered per channel + $user_id = local_channel(); + $storage->setClientDetails($client_id, $client_secret, $redirect_uri, 'authorization_code', null, $user_id); + + } + if (!$client = $storage->getClientDetails($client_id)) { + // There was an error registering the client. $response->send(); killme(); } + $response->setParameter('client_secret', $client['client_secret']); - // display an authorization form - if (empty($_POST)) { - - return ' -<form method="post"> - <label>Do You Authorize TestClient?</label><br /> - <input type="submit" name="authorized" value="yes"> - <input type="submit" name="authorized" value="no"> -</form>'; + // validate the authorize request + if (!$s->validateAuthorizeRequest($request, $response)) { + $response->send(); + killme(); } // print the authorization code if the user has authorized your client - $is_authorized = ($_POST['authorized'] === 'yes'); + $is_authorized = ($_POST['authorize'] === 'allow'); $s->handleAuthorizeRequest($request, $response, $is_authorized, local_channel()); if ($is_authorized) { - // this is only here so that you get to see your code in the cURL request. Otherwise, - // we'd redirect back to the client - $code = substr($response->getHttpHeader('Location'), strpos($response->getHttpHeader('Location'), 'code=')+5, 40); - echo("SUCCESS! Authorization Code: $code"); + $code = substr($response->getHttpHeader('Location'), strpos($response->getHttpHeader('Location'), 'code=') + 5, 40); + logger('Authorization Code: ' . $code); } $response->send(); diff --git a/Zotlabs/Module/Cards.php b/Zotlabs/Module/Cards.php index f87988183..f196988a2 100644 --- a/Zotlabs/Module/Cards.php +++ b/Zotlabs/Module/Cards.php @@ -131,20 +131,26 @@ class Cards extends \Zotlabs\Web\Controller { } + $itemspage = get_pconfig(local_channel(),'system','itemspage'); + \App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20)); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start'])); + + $sql_extra = item_permissions_sql($owner); + $sql_item = ''; if($selected_card) { $r = q("select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.v = '%s' limit 1", dbesc($selected_card) ); if($r) { - $sql_extra .= "and item.id = " . intval($r[0]['iid']) . " "; + $sql_item = "and item.id = " . intval($r[0]['iid']) . " "; } } $r = q("select * from item where uid = %d and item_type = %d - $sql_extra order by item.created desc", + $sql_extra $sql_item order by item.created desc $pager_sql", intval($owner), intval(ITEM_TYPE_CARD) ); @@ -156,6 +162,8 @@ class Cards extends \Zotlabs\Web\Controller { $items_result = []; if($r) { + $pager_total = count($r); + $parents_str = ids_to_querystr($r, 'id'); $items = q("SELECT item.*, item.id AS item_id @@ -175,13 +183,18 @@ class Cards extends \Zotlabs\Web\Controller { $mode = 'cards'; - $content = conversation($items_result, $mode, false, 'traditional'); + if(get_pconfig(local_channel(),'system','articles_list_mode') && (! $selected_card)) + $page_mode = 'pager_list'; + else + $page_mode = 'traditional'; + + $content = conversation($items_result, $mode, false, $page_mode); $o = replace_macros(get_markup_template('cards.tpl'), [ '$title' => t('Cards'), '$editor' => $editor, '$content' => $content, - '$pager' => alt_pager($a, count($items_result)) + '$pager' => alt_pager($pager_total) ]); return $o; diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index 3d3eb2a85..953f87f11 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -204,7 +204,7 @@ class Channel extends \Zotlabs\Web\Controller { $_SESSION['loadtime'] = datetime_convert(); } else { - $r = q("SELECT distinct parent AS item_id from item + $r = q("SELECT parent AS item_id from item left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids ) WHERE uid = %d $item_normal_update AND item_wall = 1 $simple_update @@ -380,7 +380,7 @@ class Channel extends \Zotlabs\Web\Controller { } if((! $update) || ($checkjs->disabled())) { - $o .= alt_pager($a,count($items)); + $o .= alt_pager(count($items)); if ($mid && $items[0]['title']) \App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title']; } diff --git a/Zotlabs/Module/Chanview.php b/Zotlabs/Module/Chanview.php index 24ab9b022..779c7e646 100644 --- a/Zotlabs/Module/Chanview.php +++ b/Zotlabs/Module/Chanview.php @@ -19,7 +19,7 @@ class Chanview extends \Zotlabs\Web\Controller { } if($_REQUEST['address']) { $r = q("select * from xchan where xchan_addr = '%s' limit 1", - dbesc($_REQUEST['address']) + dbesc(punify($_REQUEST['address'])) ); } elseif(local_channel() && intval($_REQUEST['cid'])) { diff --git a/Zotlabs/Module/Chatsvc.php b/Zotlabs/Module/Chatsvc.php index 0f79e3b4c..b4657e84d 100644 --- a/Zotlabs/Module/Chatsvc.php +++ b/Zotlabs/Module/Chatsvc.php @@ -60,7 +60,7 @@ class Chatsvc extends \Zotlabs\Web\Controller { intval(\App::$data['chat']['room_id']), dbesc(get_observer_hash()), dbesc(datetime_convert()), - dbesc($arr['chat_text']) + dbesc(str_rot47(base64url_encode($arr['chat_text']))) ); $ret['success'] = true; @@ -157,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' => zidify_links(smilies(bbcode($rr['chat_text']))), + 'text' => zidify_links(smilies(bbcode(base64url_decode(str_rot47($rr['chat_text']))))), 'self' => ((get_observer_hash() == $rr['chat_xchan']) ? 'self' : '') ); } diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index 8b5476efc..34397d275 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -60,6 +60,12 @@ class Cloud extends \Zotlabs\Web\Controller { // if we arrived at this path with any query parameters in the url, build a clean url without // them and redirect. + if(! array_key_exists('cloud_sort',$_SESSION)) { + $_SESSION['cloud_sort'] = 'name'; + } + + $_SESSION['cloud_sort'] = (($_REQUEST['sort']) ? trim(notags($_REQUEST['sort'])) : $_SESSION['cloud_sort']); + $x = clean_query_string(); if($x !== \App::$query_string) goaway(z_root() . '/' . $x); diff --git a/Zotlabs/Module/Connections.php b/Zotlabs/Module/Connections.php index 55e716ace..3bbdbf326 100644 --- a/Zotlabs/Module/Connections.php +++ b/Zotlabs/Module/Connections.php @@ -32,6 +32,7 @@ class Connections extends \Zotlabs\Web\Controller { nav_set_selected('Connections'); + $active = false; $blocked = false; $hidden = false; $ignored = false; @@ -44,11 +45,16 @@ class Connections extends \Zotlabs\Web\Controller { if(! $_REQUEST['aj']) $_SESSION['return_url'] = \App::$query_string; - $search_flags = ''; + $search_flags = ""; $head = ''; if(argc() == 2) { switch(argv(1)) { + case 'active': + $search_flags = " and abook_blocked = 0 and abook_ignored = 0 and abook_hidden = 0 and abook_archived = 0 AND abook_not_here = 0 "; + $head = t('Active'); + $active = true; + break; case 'blocked': $search_flags = " and abook_blocked = 1 "; $head = t('Blocked'); @@ -101,8 +107,9 @@ class Connections extends \Zotlabs\Web\Controller { case 'all': $head = t('All'); default: - $search_flags = ''; - $all = true; + $search_flags = " and abook_blocked = 0 and abook_ignored = 0 and abook_hidden = 0 and abook_archived = 0 and abook_not_here = 0 "; + $active = true; + $head = t('Active'); break; } @@ -129,6 +136,13 @@ class Connections extends \Zotlabs\Web\Controller { ), */ + 'active' => array( + 'label' => t('Active Connections'), + 'url' => z_root() . '/connections/active', + 'sel' => ($active) ? 'active' : '', + 'title' => t('Show active connections'), + ), + 'pending' => array( 'label' => t('New Connections'), 'url' => z_root() . '/connections/pending', @@ -136,12 +150,6 @@ class Connections extends \Zotlabs\Web\Controller { 'title' => t('Show pending (new) connections'), ), - 'all' => array( - 'label' => t('All Connections'), - 'url' => z_root() . '/connections/all', - 'sel' => ($all) ? 'active' : '', - 'title' => t('Show all connections'), - ), /* array( @@ -187,6 +195,13 @@ class Connections extends \Zotlabs\Web\Controller { // 'title' => t('Only show one-way connections'), // ), + + 'all' => array( + 'label' => t('All Connections'), + 'url' => z_root() . '/connections', + 'sel' => ($all) ? 'active' : '', + 'title' => t('Show all connections'), + ), ); @@ -238,6 +253,7 @@ class Connections extends \Zotlabs\Web\Controller { $status_str = ''; $status = array( + ((intval($rr['abook_active'])) ? t('Active') : ''), ((intval($rr['abook_pending'])) ? t('Pending approval') : ''), ((intval($rr['abook_archived'])) ? t('Archived') : ''), ((intval($rr['abook_hidden'])) ? t('Hidden') : ''), diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index f359175c1..cb9c19cf0 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -828,7 +828,7 @@ class Connedit extends \Zotlabs\Web\Controller { $locstr = locations_by_netid($contact['xchan_hash']); if(! $locstr) - $locstr = $contact['xchan_url']; + $locstr = unpunify($contact['xchan_url']); $clone_warn = ''; $clonable = (in_array($contact['xchan_network'],['zot','rss']) ? true : false); @@ -852,8 +852,8 @@ class Connedit extends \Zotlabs\Web\Controller { '$permcat' => [ 'permcat', t('Permission role'), '', '<span class="loading invisible">' . t('Loading') . '<span class="jumping-dots"><span class="dot-1">.</span><span class="dot-2">.</span><span class="dot-3">.</span></span></span>',$permcats ], '$permcat_new' => t('Add permission role'), '$permcat_enable' => feature_enabled(local_channel(),'permcats'), - '$addr' => $contact['xchan_addr'], - '$primeurl' => $contact['xchan_url'], + '$addr' => unpunify($contact['xchan_addr']), + '$primeurl' => unpunify($contact['xchan_url']), '$section' => $section, '$sections' => $sections, '$vcard' => $vcard, diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php index 047bcf3d4..d76c1b408 100644 --- a/Zotlabs/Module/Cover_photo.php +++ b/Zotlabs/Module/Cover_photo.php @@ -207,7 +207,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { } } - $imagedata = (($os_storage) ? @file_get_contents($imagedata) : $imagedata); + $imagedata = (($os_storage) ? @file_get_contents(dbunescbin($imagedata)) : dbunescbin($imagedata)); $ph = photo_factory($imagedata, $filetype); if(! $ph->is_valid()) { @@ -355,6 +355,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { $o .= replace_macros($tpl,array( '$user' => \App::$channel['channel_address'], + '$existing' => get_cover_photo(local_channel(),'array',PHOTO_RES_COVER_850), '$lbl_upfile' => t('Upload File:'), '$lbl_profiles' => t('Select a profile:'), '$title' => t('Change Cover Photo'), @@ -364,6 +365,12 @@ class Cover_photo extends \Zotlabs\Web\Controller { '$embedPhotosModalTitle' => t('Use a photo from your albums'), '$embedPhotosModalCancel' => t('Cancel'), '$embedPhotosModalOK' => t('OK'), + '$modalchooseimages' => t('Choose images to embed'), + '$modalchoosealbum' => t('Choose an album'), + '$modaldiffalbum' => t('Choose a different album'), + '$modalerrorlist' => t('Error getting album list'), + '$modalerrorlink' => t('Error getting photo link'), + '$modalerroralbum' => t('Error getting album'), '$form_security_token' => get_form_security_token("cover_photo"), /// @FIXME - yuk '$select' => t('Select existing photo'), diff --git a/Zotlabs/Module/Directory.php b/Zotlabs/Module/Directory.php index b1552a694..f2673fa1a 100644 --- a/Zotlabs/Module/Directory.php +++ b/Zotlabs/Module/Directory.php @@ -17,7 +17,7 @@ class Directory extends \Zotlabs\Web\Controller { intval(local_channel()), dbesc($_GET['ignore']) ); - goaway(z_root() . '/directory?suggest=1'); + goaway(z_root() . '/directory?f=&suggest=1'); } $observer = get_observer_hash(); @@ -101,6 +101,11 @@ class Directory extends \Zotlabs\Web\Controller { if($suggest) { $r = suggestion_query(local_channel(),get_observer_hash()); + + if(! $r) { + notice( t('No default suggestions were found.') . EOL); + return; + } // Remember in which order the suggestions were $addresses = array(); @@ -294,9 +299,9 @@ class Directory extends \Zotlabs\Web\Controller { if(strlen($out)) $out .= ', '; if($marr && in_arrayi($k,$marr)) - $out .= '<strong>' . $k . '</strong>'; + $out .= '<a href="' . z_root() . '/directory/f=&keywords=' . urlencode($k) .'"><strong>' . $k . '</strong></a>'; else - $out .= $k; + $out .= '<a href="' . z_root() . '/directory/f=&keywords=' . urlencode($k) .'">' . $k . '</a>'; } } @@ -399,7 +404,7 @@ class Directory extends \Zotlabs\Web\Controller { '$entries' => $entries, '$dirlbl' => $suggest ? t('Channel Suggestions') : $dirtitle, '$submit' => t('Find'), - '$next' => alt_pager($a,$j['records'], t('next page'), t('previous page')), + '$next' => alt_pager($j['records'], t('next page'), t('previous page')), '$sort' => t('Sort options'), '$normal' => t('Alphabetic'), '$reverse' => t('Reverse Alphabetic'), diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php index 8e8a1ed24..06c9479b2 100644 --- a/Zotlabs/Module/Display.php +++ b/Zotlabs/Module/Display.php @@ -102,7 +102,7 @@ class Display extends \Zotlabs\Web\Controller { if($decoded) $item_hash = $decoded; - $r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where mid like '%s' limit 1", + $r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, author_xchan, item_blocked from item where mid like '%s' limit 1", dbesc($item_hash . '%') ); @@ -110,6 +110,14 @@ class Display extends \Zotlabs\Web\Controller { $target_item = $r[0]; } + $x = q("select * from xchan where xchan_hash = '%s' limit 1", + dbesc($target_item['author_xchan']) + ); + if($x) { +// not yet ready for prime time +// \App::$poi = $x[0]; + } + //if the item is to be moderated redirect to /moderate if($target_item['item_blocked'] == ITEM_MODERATED) { goaway(z_root() . '/moderate/' . $target_item['id']); @@ -124,7 +132,7 @@ class Display extends \Zotlabs\Web\Controller { $y = q("select * from iconfig left join item on iconfig.iid = item.id where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item.id = %d limit 1", intval($target_item['uid']), - intval($target_item['id']) + intval($target_item['parent']) ); if($x && $y) { goaway(z_root() . '/page/' . $x[0]['channel_address'] . '/' . $y[0]['v']); @@ -134,6 +142,41 @@ class Display extends \Zotlabs\Web\Controller { return ''; } } + if($target_item['item_type'] == ITEM_TYPE_ARTICLE) { + $x = q("select * from channel where channel_id = %d limit 1", + intval($target_item['uid']) + ); + $y = q("select * from iconfig left join item on iconfig.iid = item.id + where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and item.id = %d limit 1", + intval($target_item['uid']), + intval($target_item['parent']) + ); + if($x && $y) { + goaway(z_root() . '/articles/' . $x[0]['channel_address'] . '/' . $y[0]['v']); + } + else { + notice( t('Page not found.') . EOL); + return ''; + } + } + if($target_item['item_type'] == ITEM_TYPE_CARD) { + $x = q("select * from channel where channel_id = %d limit 1", + intval($target_item['uid']) + ); + $y = q("select * from iconfig left join item on iconfig.iid = item.id + where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'CARD' and item.id = %d limit 1", + intval($target_item['uid']), + intval($target_item['parent']) + ); + if($x && $y) { + goaway(z_root() . '/cards/' . $x[0]['channel_address'] . '/' . $y[0]['v']); + } + else { + notice( t('Page not found.') . EOL); + return ''; + } + } + $static = ((array_key_exists('static',$_REQUEST)) ? intval($_REQUEST['static']) : 0); diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php index a54c42e7f..57a4cb97f 100644 --- a/Zotlabs/Module/Editpost.php +++ b/Zotlabs/Module/Editpost.php @@ -82,7 +82,7 @@ class Editpost extends \Zotlabs\Web\Controller { 'editor_autocomplete'=> true, 'bbco_autocomplete'=> 'bbcode', 'return_path' => $_SESSION['return_url'], - 'button' => t('Edit'), + 'button' => t('Submit'), 'hide_voting' => true, 'hide_future' => true, 'hide_location' => true, diff --git a/Zotlabs/Module/Follow.php b/Zotlabs/Module/Follow.php index d8a86d0ce..cbf9d62c5 100644 --- a/Zotlabs/Module/Follow.php +++ b/Zotlabs/Module/Follow.php @@ -14,21 +14,26 @@ class Follow extends \Zotlabs\Web\Controller { } $uid = local_channel(); - $url = notags(trim($_REQUEST['url'])); + $url = notags(trim(punify($_REQUEST['url']))); $return_url = $_SESSION['return_url']; $confirm = intval($_REQUEST['confirm']); - + $interactive = (($_REQUEST['interactive']) ? intval($_REQUEST['interactive']) : 1); $channel = \App::get_channel(); - $result = new_contact($uid,$url,$channel,true,$confirm); + $result = new_contact($uid,$url,$channel,$interactive,$confirm); if($result['success'] == false) { if($result['message']) notice($result['message']); - goaway($return_url); + if($interactive) { + goaway($return_url); + } + else { + json_return_and_die($result); + } } - info( t('Channel added.') . EOL); + info( t('Connection added.') . EOL); $clone = array(); foreach($result['abook'] as $k => $v) { @@ -53,7 +58,12 @@ class Follow extends \Zotlabs\Web\Controller { if(($can_view_stream) || ($result['abook']['xchan_network'] === 'rss')) \Zotlabs\Daemon\Master::Summon(array('Onepoll',$result['abook']['abook_id'])); - goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?f=&follow=1'); + if($interactive) { + goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?f=&follow=1'); + } + else { + json_return_and_die([ 'success' => true ]); + } } diff --git a/Zotlabs/Module/Hashtags.php b/Zotlabs/Module/Hashtags.php new file mode 100644 index 000000000..300485196 --- /dev/null +++ b/Zotlabs/Module/Hashtags.php @@ -0,0 +1,27 @@ +<?php + +namespace Zotlabs\Module; + + +class Hashtags extends \Zotlabs\Web\Controller { + + function init() { + $result = []; + + $t = escape_tags($_REQUEST['t']); + if(! $t) + json_return_and_die($result); + + $r = q("select distinct(term) from term where term like '%s' and ttype = %d order by term", + dbesc($t . '%'), + intval(TERM_HASHTAG) + ); + if($r) { + foreach($r as $rv) { + $result[] = [ 'text' => $rv['term'] ]; + } + } + + json_return_and_die($result); + } +}
\ No newline at end of file diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php index 36bd72310..81c405f00 100644 --- a/Zotlabs/Module/Import.php +++ b/Zotlabs/Module/Import.php @@ -114,15 +114,16 @@ class Import extends \Zotlabs\Web\Controller { return; } - if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) { - $v1 = substr($data['compatibility']['database'],-4); - $v2 = substr(DB_UPDATE_VERSION,-4); - if($v2 > $v1) { - $t = sprintf( t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1 ); - notice($t); - } - - } +// This is only an info message but it is alarming to folks who then report failure with this as the cause, when in fact we ignore this completely. +// if(array_key_exists('compatibility',$data) && array_key_exists('database',$data['compatibility'])) { +// $v1 = substr($data['compatibility']['database'],-4); +// $v2 = substr(DB_UPDATE_VERSION,-4); +// if($v2 > $v1) { +// $t = sprintf( t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1 ); +// notice($t); +// } +// +// } if($moving) $seize = 1; diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 3f857030b..bba1dc02d 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -468,6 +468,7 @@ class Item extends \Zotlabs\Web\Controller { $private = intval($acl->is_private() || $parent_item['item_private']); $public_policy = $parent_item['public_policy']; $owner_hash = $parent_item['owner_xchan']; + $webpage = $parent_item['item_type']; } if((! $allow_empty) && (! strlen($body))) { @@ -542,7 +543,7 @@ class Item extends \Zotlabs\Web\Controller { // Look for tags and linkify them $results = linkify_tags($a, $body, ($uid) ? $uid : $profile_uid); - + if($results) { // Set permissions based on tag replacements @@ -830,6 +831,12 @@ class Item extends \Zotlabs\Web\Controller { $datarray['plink'] = $plink; $datarray['route'] = $route; + + // A specific ACL over-rides public_policy completely + + if(! empty_acl($datarray)) + $datarray['public_policy'] = ''; + if($iconfig) $datarray['iconfig'] = $iconfig; diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php index 6d9fde17c..4e216f08b 100644 --- a/Zotlabs/Module/Like.php +++ b/Zotlabs/Module/Like.php @@ -296,10 +296,11 @@ class Like extends \Zotlabs\Web\Controller { notice( t('Permission denied') . EOL); killme(); } - + $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($item['owner_xchan']) ); + if($r) $thread_owner = $r[0]; else @@ -418,6 +419,7 @@ class Like extends \Zotlabs\Web\Controller { $arr['item_origin'] = 1; $arr['item_notshown'] = 1; + $arr['item_type'] = $item['item_type']; if(intval($item['item_wall'])) $arr['item_wall'] = 1; diff --git a/Zotlabs/Module/Logout.php b/Zotlabs/Module/Logout.php index f06e7278b..d11ce54ac 100644 --- a/Zotlabs/Module/Logout.php +++ b/Zotlabs/Module/Logout.php @@ -5,7 +5,12 @@ namespace Zotlabs\Module; class Logout extends \Zotlabs\Web\Controller { function init() { - \App::$session->nuke(); + if($_SESSION['delegate'] && $_SESSION['delegate_push']) { + $_SESSION = $_SESSION['delegate_push']; + } + else { + \App::$session->nuke(); + } goaway(z_root()); } diff --git a/Zotlabs/Module/Magic.php b/Zotlabs/Module/Magic.php index 15e5cedcf..4b3a223ba 100644 --- a/Zotlabs/Module/Magic.php +++ b/Zotlabs/Module/Magic.php @@ -112,6 +112,8 @@ class Magic extends \Zotlabs\Web\Controller { if($r && intval($r[0]['channel_id'])) { $allowed = perm_is_allowed($r[0]['channel_id'],get_observer_hash(),'delegate'); if($allowed) { + $tmp = $_SESSION; + $_SESSION['delegate_push'] = $tmp; $_SESSION['delegate_channel'] = $r[0]['channel_id']; $_SESSION['delegate'] = get_observer_hash(); $_SESSION['account_id'] = intval($r[0]['channel_account_id']); diff --git a/Zotlabs/Module/Mail.php b/Zotlabs/Module/Mail.php index b58b169d0..ca183f644 100644 --- a/Zotlabs/Module/Mail.php +++ b/Zotlabs/Module/Mail.php @@ -67,14 +67,14 @@ class Mail extends \Zotlabs\Web\Controller { if(! $recipient) { $channel = \App::get_channel(); - $j = \Zotlabs\Zot\Finger::run($rstr,$channel); + $j = \Zotlabs\Zot\Finger::run(punify($rstr),$channel); if(! $j['success']) { notice( t('Unable to lookup recipient.') . EOL); return; } - logger('message_post: lookup: ' . $url . ' ' . print_r($j,true)); + logger('message_post: lookup: ' . $rstr . ' ' . print_r($j,true)); if(! $j['guid']) { notice( t('Unable to communicate with requested channel.')); diff --git a/Zotlabs/Module/Message.php b/Zotlabs/Module/Message.php index 7494f4bf4..5856bfbdf 100644 --- a/Zotlabs/Module/Message.php +++ b/Zotlabs/Module/Message.php @@ -93,7 +93,7 @@ class Message extends \Zotlabs\Web\Controller { )); - $o .= alt_pager($a,count($r)); + $o .= alt_pager(count($r)); return $o; diff --git a/Zotlabs/Module/Moderate.php b/Zotlabs/Module/Moderate.php index cf1625a6b..a7c98e05e 100644 --- a/Zotlabs/Module/Moderate.php +++ b/Zotlabs/Module/Moderate.php @@ -14,9 +14,12 @@ class Moderate extends \Zotlabs\Web\Controller { return; } + \App::set_pager_itemspage(60); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start'])); + //show all items if(argc() == 1) { - $r = q("select item.id as item_id, item.* from item where item.uid = %d and item_blocked = %d and item_deleted = 0 order by created desc limit 60", + $r = q("select item.id as item_id, item.* from item where item.uid = %d and item_blocked = %d and item_deleted = 0 order by created desc $pager_sql", intval(local_channel()), intval(ITEM_MODERATED) ); @@ -26,7 +29,7 @@ class Moderate extends \Zotlabs\Web\Controller { if(argc() == 2) { $post_id = intval(argv(1)); - $r = q("select item.id as item_id, item.* from item where item.id = %d and item.uid = %d and item_blocked = %d and item_deleted = 0 order by created desc limit 60", + $r = q("select item.id as item_id, item.* from item where item.id = %d and item.uid = %d and item_blocked = %d and item_deleted = 0 order by created desc $pager_sql", intval($post_id), intval(local_channel()), intval(ITEM_MODERATED) @@ -47,17 +50,26 @@ class Moderate extends \Zotlabs\Web\Controller { ); if($r) { + $item = $r[0]; + if($action === 'approve') { q("update item set item_blocked = 0 where uid = %d and id = %d", intval(local_channel()), intval($post_id) ); + + $item['item_blocked'] = 0; + + item_update_parent_commented($item); + notice( t('Comment approved') . EOL); } elseif($action === 'drop') { drop_item($post_id,false); notice( t('Comment deleted') . EOL); } + + // refetch the item after changes have been made $r = q("select * from item where id = %d", intval($post_id) @@ -83,6 +95,7 @@ class Moderate extends \Zotlabs\Web\Controller { } $o = conversation($items,'moderate',false,'traditional'); + $o .= alt_pager(count($items)); return $o; } diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index 6e961dc36..e97ebf1d0 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -210,26 +210,22 @@ class Network extends \Zotlabs\Web\Controller { $sql_nets = ''; - $distinct = ''; $item_thread_top = ' AND item_thread_top = 1 '; - $sql_extra = $sql_options; + $sql_extra = ''; if($group) { $contact_str = ''; $contacts = group_get_members($group); if($contacts) { - foreach($contacts as $c) { - if($contact_str) - $contact_str .= ','; - $contact_str .= "'" . $c['xchan'] . "'"; - } + $contact_str = ids_to_querystr($contacts,'xchan',true); } else { - $contact_str = ' 0 '; - info( t('Privacy group is empty')); + $contact_str = " '0' "; + if(! $update) { + info( t('Privacy group is empty')); + } } - $distinct = ' distinct '; $item_thread_top = ''; $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str )) or allow_gid like '" . protect_sprintf('%<' . dbesc($group_hash) . '>%') . "' ) and id = parent $item_normal ) "; @@ -254,7 +250,6 @@ class Network extends \Zotlabs\Web\Controller { intval(local_channel()) ); if($r) { - $distinct = ' distinct '; $item_thread_top = ''; $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($r[0]['abook_xchan']) . "' or owner_xchan = '" . dbesc($r[0]['abook_xchan']) . "' ) $item_normal ) "; $title = replace_macros(get_markup_template("section_title.tpl"),array( @@ -274,7 +269,6 @@ class Network extends \Zotlabs\Web\Controller { dbesc($xchan) ); if($r) { - $distinct = ' distinct '; $item_thread_top = ''; $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($xchan) . "' or owner_xchan = '" . dbesc($xchan) . "' ) $item_normal ) "; $title = replace_macros(get_markup_template("section_title.tpl"),array( @@ -381,7 +375,6 @@ class Network extends \Zotlabs\Web\Controller { } if($conv) { - $distinct = ' distinct '; $item_thread_top = ''; $sql_extra .= sprintf(" AND parent IN (SELECT distinct(parent) from item where ( author_xchan like '%s' or item_mentionsme = 1 )) ", dbesc(protect_sprintf($channel['channel_hash'])) @@ -464,7 +457,7 @@ class Network extends \Zotlabs\Web\Controller { WHERE true $uids $item_normal and (abook.abook_blocked = 0 or abook.abook_flags is null) $simple_update - $sql_extra $sql_nets + $sql_extra $sql_options $sql_nets $net_query2 ORDER BY item.received DESC $pager_sql " ); @@ -485,15 +478,14 @@ class Network extends \Zotlabs\Web\Controller { $ordering = "commented"; if($load) { - // Fetch a page full of parent items for this page - $r = q("SELECT $distinct item.parent AS item_id FROM item + $r = q("SELECT item.parent AS item_id FROM item left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids ) $net_query WHERE true $uids $item_thread_top $item_normal AND item.mid = item.parent_mid and (abook.abook_blocked = 0 or abook.abook_flags is null) - $sql_extra3 $sql_extra $sql_nets + $sql_extra3 $sql_extra $sql_options $sql_nets $net_query2 ORDER BY $ordering DESC $pager_sql " ); @@ -506,7 +498,7 @@ class Network extends \Zotlabs\Web\Controller { $net_query WHERE true $uids $item_normal_update $simple_update and (abook.abook_blocked = 0 or abook.abook_flags is null) - $sql_extra3 $sql_extra $sql_nets $net_query2" + $sql_extra3 $sql_extra $sql_options $sql_nets $net_query2" ); $_SESSION['loadtime'] = datetime_convert(); } @@ -570,7 +562,7 @@ class Network extends \Zotlabs\Web\Controller { $o .= conversation($items,$mode,$update,$page_mode); if(($items) && (! $update)) - $o .= alt_pager($a,count($items)); + $o .= alt_pager(count($items)); return $o; } diff --git a/Zotlabs/Module/New_channel.php b/Zotlabs/Module/New_channel.php index 548f28c4f..d9becbc22 100644 --- a/Zotlabs/Module/New_channel.php +++ b/Zotlabs/Module/New_channel.php @@ -16,8 +16,15 @@ class New_channel extends \Zotlabs\Web\Controller { require_once('library/urlify/URLify.php'); $result = array('error' => false, 'message' => ''); $n = trim($_REQUEST['name']); - - $x = strtolower(\URLify::transliterate($n)); + + $x = false; + + if(get_config('system','unicode_usernames')) { + $x = punify(mb_strtolower($n)); + } + + if((! $x) || strlen($x) > 64) + $x = strtolower(\URLify::transliterate($n)); $test = array(); @@ -43,7 +50,14 @@ class New_channel extends \Zotlabs\Web\Controller { $result = array('error' => false, 'message' => ''); $n = trim($_REQUEST['nick']); - $x = strtolower(\URLify::transliterate($n)); + $x = false; + + if(get_config('system','unicode_usernames')) { + $x = punify(mb_strtolower($n)); + } + + if((! $x) || strlen($x) > 64) + $x = strtolower(\URLify::transliterate($n)); $test = array(); @@ -132,14 +146,14 @@ class New_channel extends \Zotlabs\Web\Controller { $name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"'), "*"); $nickhub = '@' . \App::get_hostname(); $nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub), "*"); - $role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/member/member_guide#Account_Permission_Roles" target="_blank">' . t('Read more about roles') . '</a>',$perm_roles); + $role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/member/member_guide#Channel_Permission_Roles" target="_blank">' . t('Read more about roles') . '</a>',$perm_roles); $o = replace_macros(get_markup_template('new_channel.tpl'), array( '$title' => t('Create Channel'), - '$desc' => t('A channel is your identity on this network. It can represent a person, a blog, or a forum to name a few. Channels can make connections with other channels to share information with highly detailed permissions.'), + '$desc' => t('A channel is a unique network identity. It can represent a person (social network profile), a forum (group), a business or celebrity page, a newsfeed, and many other things. Channels can make connections with other channels to share information with each other.') . ' ' . t('The type of channel you create affects the basic privacy settings, the permissions that are granted to connections/friends, and also the channel\'s visibility across the network.'), '$label_import' => t('or <a href="import">import an existing channel</a> from another location.'), '$name' => $name, - '$role' => $role, + '$role' => $role, '$default_role' => $default_role, '$nickname' => $nickname, '$validate' => t('Validate'), diff --git a/Zotlabs/Module/Oauth2testvehicle.php b/Zotlabs/Module/Oauth2testvehicle.php new file mode 100644 index 000000000..5ae278e8c --- /dev/null +++ b/Zotlabs/Module/Oauth2testvehicle.php @@ -0,0 +1,151 @@ +<?php + +namespace Zotlabs\Module; + +/** + * The OAuth2TestVehicle class is a way to test the registration of an OAuth2 + * client app. It allows you to walk through the steps of registering a client, + * requesting an authorization code for that client, and then requesting an + * access token for use in authentication against the Hubzilla API endpoints. + */ +class OAuth2TestVehicle extends \Zotlabs\Web\Controller { + + function init() { + + killme(); + + // If there is a 'code' and 'state' parameter then this is a client app + // callback issued after the authorization code request + // TODO: Check state value and compare to original sent value + // "You should first compare this state value to ensure it matches the + // one you started with. You can typically store the state value in a + // cookie, and compare it when the user comes back. This ensures your + // redirection endpoint isn't able to be tricked into attempting to + // exchange arbitrary authorization codes." + $_SESSION['redirect_uri'] = z_root() . '/oauth2testvehicle'; + $_SESSION['authorization_code'] = (x($_REQUEST, 'code') ? $_REQUEST['code'] : $_SESSION['authorization_code']); + $_SESSION['state'] = (x($_REQUEST, 'state') ? $_REQUEST['state'] : $_SESSION['state'] ); + $_SESSION['client_id'] = (x($_REQUEST, 'client_id') ? $_REQUEST['client_id'] : $_SESSION['client_id'] ); + $_SESSION['client_secret'] = (x($_REQUEST, 'client_secret') ? $_REQUEST['client_secret'] : $_SESSION['client_secret']); + $_SESSION['access_token'] = (x($_REQUEST, 'access_token') ? $_REQUEST['access_token'] : $_SESSION['access_token'] ); + $_SESSION['api_response'] = (x($_SESSION, 'api_response') ? $_SESSION['api_response'] : ''); + } + function get() { + + $o .= replace_macros(get_markup_template('oauth2testvehicle.tpl'), array( + '$baseurl' => z_root(), + '$api_response' => $_SESSION['api_response'], + /* + endpoints => array( + array( + 'path_to_endpoint', + array( + array('field_name_1', 'value'), + array('field_name_2', 'value'), + ... + ), + 'submit_button_name', + 'Description of API action' + ) + ) + */ + '$endpoints' => array( + array( + 'authorize', + array( + array('response_type', 'code'), + array('client_id', (x($_REQUEST, 'client_id') ? $_REQUEST['client_id'] : 'oauth2_test_app')), + array('redirect_uri', $_SESSION['redirect_uri']), + array('state', 'xyz'), + // OpenID Connect Dynamic Client Registration 1.0 Client Metadata + // http://openid.net/specs/openid-connect-registration-1_0.html + array('client_name', 'OAuth2 Test App'), + array('logo_uri', urlencode(z_root() . '/images/icons/plugin.png')), + array('client_uri', urlencode('https://client.example.com/website')), + array('application_type', 'web'), // would be 'native' for mobile app + ), + 'oauth_authorize', + 'Authorize a test client app', + 'GET', + (($_REQUEST['code'] && $_REQUEST['state']) ? true : false), + ), + array( + 'oauth2testvehicle', + array( + array('action', 'request_token'), + array('grant_type', 'authorization_code'), + array('code', $_SESSION['authorization_code']), + array('redirect_uri', $_SESSION['redirect_uri']), + array('client_id', ($_SESSION['client_id'] ? $_SESSION['client_id'] : 'oauth2_test_app')), + array('client_secret', $_SESSION['client_secret']), + ), + 'oauth_token_request', + 'Request a token', + 'POST', + ($_SESSION['success'] === 'request_token'), + ), + array( + 'oauth2testvehicle', + array( + array('action', 'api_files'), + array('access_token', $_SESSION['access_token']), + ), + 'oauth_api_files', + 'API: Get channel files', + 'POST', + ($_SESSION['success'] === 'api_files'), + ) + ) + )); + $_SESSION['success'] = ''; + return $o; + } + + function post() { + + switch ($_POST['action']) { + case 'api_files': + $access_token = $_SESSION['access_token']; + $url = z_root() . '/api/z/1.0/files/'; + $headers = []; + $headers[] = 'Authorization: Bearer ' . $access_token; + $post = z_fetch_url($url, false, 0, array( + 'custom' => 'GET', + 'headers' => $headers, + )); + logger(json_encode($post, JSON_PRETTY_PRINT), LOGGER_DEBUG); + $response = json_decode($post['body'], true); + $_SESSION['api_response'] = json_encode($response, JSON_PRETTY_PRINT); + break; + case 'request_token': + $grant_type = (x($_POST, 'grant_type') ? $_POST['grant_type'] : ''); + $redirect_uri = (x($_POST, 'redirect_uri') ? $_POST['redirect_uri'] : ''); + $client_id = (x($_POST, 'client_id') ? $_POST['client_id'] : ''); + $code = (x($_POST, 'code') ? $_POST['code'] : ''); + $client_secret = (x($_POST, 'client_secret') ? $_POST['client_secret'] : ''); + $url = z_root() . '/token/'; + $params = http_build_query(array( + 'grant_type' => $grant_type, + 'redirect_uri' => urlencode($redirect_uri), + 'client_id' => $client_id, + 'code' => $code, + )); + $post = z_post_url($url, $params, 0, array( + 'http_auth' => $client_id . ':' . $client_secret, + )); + logger(json_encode($post, JSON_PRETTY_PRINT), LOGGER_DEBUG); + $response = json_decode($post['body'], true); + logger(json_encode($response, JSON_PRETTY_PRINT), LOGGER_DEBUG); + if($response['access_token']) { + info('Access token received: ' . $response['access_token'] . EOL); + $_SESSION['success'] = 'request_token'; + $_SESSION['access_token'] = $response['access_token']; + } + break; + + default: + break; + } + } + +} diff --git a/Zotlabs/Module/Ochannel.php b/Zotlabs/Module/Ochannel.php new file mode 100644 index 000000000..508be1408 --- /dev/null +++ b/Zotlabs/Module/Ochannel.php @@ -0,0 +1,69 @@ +<?php + +namespace Zotlabs\Module; + +require_once('include/contact_widgets.php'); +require_once('include/items.php'); +require_once("include/bbcode.php"); +require_once('include/security.php'); +require_once('include/conversation.php'); +require_once('include/acl_selectors.php'); +require_once('include/permissions.php'); + +/** + * @brief Channel Controller for broken OStatus implementations + * + */ +class Ochannel extends \Zotlabs\Web\Controller { + + function init() { + + $which = null; + if(argc() > 1) + $which = argv(1); + if(! $which) { + if(local_channel()) { + $channel = \App::get_channel(); + if($channel && $channel['channel_address']) + $which = $channel['channel_address']; + } + } + if(! $which) { + notice( t('You must be logged in to see this page.') . EOL ); + return; + } + + $profile = 0; + $channel = \App::get_channel(); + + if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { + $which = $channel['channel_address']; + $profile = argv(1); + } + + head_add_link( [ + 'rel' => 'alternate', + 'type' => 'application/atom+xml', + 'href' => z_root() . '/ofeed/' . $which + ]); + + + // Run profile_load() here to make sure the theme is set before + // we start loading content + + profile_load($which,$profile); + } + + function get($update = 0, $load = false) { + + if(argc() < 2) + return; + + if($load) + $_SESSION['loadtime'] = datetime_convert(); + + return '<script>window.location.href = "' . z_root() . '/' . str_replace('ochannel/','channel/',\App::$query_string) . '";</script>'; + + } + +} diff --git a/Zotlabs/Module/Oep.php b/Zotlabs/Module/Oep.php index bb3a13b56..ec40bf9db 100644 --- a/Zotlabs/Module/Oep.php +++ b/Zotlabs/Module/Oep.php @@ -125,6 +125,7 @@ class Oep extends \Zotlabs\Web\Controller { "' profile='".$p[0]['author']['xchan_url'] . "' avatar='".$p[0]['author']['xchan_photo_s']. "' link='".$p[0]['plink']. + "' auth='".(($p[0]['author']['network'] === 'zot') ? 'true' : 'false') . "' posted='".$p[0]['created']. "' message_id='".$p[0]['mid']."']"; if($p[0]['title']) @@ -209,6 +210,7 @@ class Oep extends \Zotlabs\Web\Controller { "' profile='".$p[0]['author']['xchan_url'] . "' avatar='".$p[0]['author']['xchan_photo_s']. "' link='".$p[0]['plink']. + "' auth='".(($p[0]['author']['network'] === 'zot') ? 'true' : 'false') . "' posted='".$p[0]['created']. "' message_id='".$p[0]['mid']."']"; if($p[0]['title']) @@ -292,6 +294,7 @@ class Oep extends \Zotlabs\Web\Controller { "' profile='".$p[0]['author']['xchan_url'] . "' avatar='".$p[0]['author']['xchan_photo_s']. "' link='".$p[0]['plink']. + "' auth='".(($p[0]['author']['network'] === 'zot') ? 'true' : 'false') . "' posted='".$p[0]['created']. "' message_id='".$p[0]['mid']."']"; if($p[0]['title']) @@ -366,6 +369,7 @@ class Oep extends \Zotlabs\Web\Controller { "' profile='".$p[0]['author']['xchan_url'] . "' avatar='".$p[0]['author']['xchan_photo_s']. "' link='".$p[0]['plink']. + "' auth='".(($p[0]['author']['network'] === 'zot') ? 'true' : 'false') . "' posted='".$p[0]['created']. "' message_id='".$p[0]['mid']."']"; if($p[0]['title']) diff --git a/Zotlabs/Module/Owa.php b/Zotlabs/Module/Owa.php index e62fc9592..da26748b3 100644 --- a/Zotlabs/Module/Owa.php +++ b/Zotlabs/Module/Owa.php @@ -34,6 +34,15 @@ class Owa extends \Zotlabs\Web\Controller { where hubloc_addr = '%s' ", dbesc(str_replace('acct:','',$keyId)) ); + if(! $r) { + $found = discover_by_webbie(str_replace('acct:','',$keyId)); + if($found) { + $r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash + where hubloc_addr = '%s' ", + dbesc(str_replace('acct:','',$keyId)) + ); + } + } if($r) { foreach($r as $hubloc) { $verified = \Zotlabs\Web\HTTPSig::verify('',$hubloc['xchan_pubkey']); diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index 81af607ec..a143c4d4c 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -695,8 +695,8 @@ class Photos extends \Zotlabs\Web\Controller { '$newalbum_label' => t('Enter an album name'), '$newalbum_placeholder' => t('or select an existing album (doubleclick)'), '$visible' => array('visible', t('Create a status post for this upload'), 0,'', array(t('No'), t('Yes')), 'onclick="showHideBodyTextarea();"'), - '$caption' => array('description', t('Caption (optional):')), - '$body' => array('body', t('Description (optional):'),'', 'Description will only appear in the status post'), + '$caption' => array('description', t('Title (optional)')), + '$body' => array('body', t('Description (optional)'),'', 'Description will only appear in the status post'), '$albums' => $albums['albums'], '$selname' => $selname, '$permissions' => t('Permissions'), @@ -841,7 +841,7 @@ class Photos extends \Zotlabs\Web\Controller { '$album_id' => $datum, '$album_edit' => array(t('Edit Album'), $album_edit), '$can_post' => $can_post, - '$upload' => array(t('Upload'), z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/upload/' . $datum), + '$upload' => array(t('Add Photos'), z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/upload/' . $datum), '$order' => $order, '$upload_form' => $upload_form, '$usage' => $usage_message @@ -1065,7 +1065,7 @@ class Photos extends \Zotlabs\Web\Controller { 'newalbum_placeholder' => t('or select an existing one (doubleclick)'), 'nickname' => \App::$data['channel']['channel_address'], 'resource_id' => $ph[0]['resource_id'], - 'capt_label' => t('Caption'), + 'capt_label' => t('Title (optional)'), 'caption' => $caption_e, 'tag_label' => t('Add a Tag'), 'permissions' => t('Permissions'), @@ -1148,10 +1148,10 @@ class Photos extends \Zotlabs\Web\Controller { builtin_activity_puller($item, $conv_responses); } - $like_count = ((x($alike,$link_item['mid'])) ? $alike[$link_item['mid']] : ''); $like_list = ((x($alike,$link_item['mid'])) ? $alike[$link_item['mid'] . '-l'] : ''); - if (count($like_list) > MAX_LIKERS) { + + if(is_array($like_list) && (count($like_list) > MAX_LIKERS)) { $like_list_part = array_slice($like_list, 0, MAX_LIKERS); array_push($like_list_part, '<a href="#" data-toggle="modal" data-target="#likeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>'); } else { @@ -1163,7 +1163,7 @@ class Photos extends \Zotlabs\Web\Controller { $dislike_count = ((x($dlike,$link_item['mid'])) ? $dlike[$link_item['mid']] : ''); $dislike_list = ((x($dlike,$link_item['mid'])) ? $dlike[$link_item['mid'] . '-l'] : ''); $dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun'); - if (count($dislike_list) > MAX_LIKERS) { + if (is_array($dislike_list) && (count($dislike_list) > MAX_LIKERS)) { $dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS); array_push($dislike_list_part, '<a href="#" data-toggle="modal" data-target="#dislikeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>'); } else { @@ -1378,7 +1378,7 @@ class Photos extends \Zotlabs\Web\Controller { '$title' => t('Recent Photos'), '$album_id' => bin2hex(t('Recent Photos')), '$can_post' => $can_post, - '$upload' => array(t('Upload'), z_root().'/photos/'.\App::$data['channel']['channel_address'].'/upload'), + '$upload' => array(t('Add Photos'), z_root().'/photos/'.\App::$data['channel']['channel_address'].'/upload'), '$photos' => $photos, '$upload_form' => $upload_form, '$usage' => $usage_message diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php index eab49d69e..206b8c3d1 100644 --- a/Zotlabs/Module/Ping.php +++ b/Zotlabs/Module/Ping.php @@ -140,7 +140,13 @@ class Ping extends \Zotlabs\Web\Controller { db_utcnow(), db_quoteinterval('3 MINUTE') ); - $discover_tab_on = ((get_config('system','disable_discover_tab') || get_config('system','disable_discover_tab') === false) ? false : true); + + $sql_extra = ''; + if(! ($vnotify & VNOTIFY_LIKE)) + $sql_extra = " AND verb NOT IN ('" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') "; + + $discover_tab_on = can_view_public_stream(); + $notify_pubs = ((local_channel()) ? ($vnotify & VNOTIFY_PUBS) && $discover_tab_on : $discover_tab_on); if($notify_pubs) { @@ -151,7 +157,8 @@ class Ping extends \Zotlabs\Web\Controller { AND item_unseen = 1 AND author_xchan != '%s' AND created > '" . datetime_convert('UTC','UTC',$_SESSION['static_loadtime']) . "' - $item_normal", + $item_normal + $sql_extra", intval($sys['channel_id']), dbesc(get_observer_hash()) ); @@ -160,6 +167,8 @@ class Ping extends \Zotlabs\Web\Controller { $result['pubs'] = intval($pubs[0]['total']); } + + if((argc() > 1) && (argv(1) === 'pubs') && ($notify_pubs)) { $sys = get_sys_channel(); $result = array(); @@ -170,6 +179,7 @@ class Ping extends \Zotlabs\Web\Controller { AND author_xchan != '%s' AND created > '" . datetime_convert('UTC','UTC',$_SESSION['static_loadtime']) . "' $item_normal + $sql_extra ORDER BY created DESC LIMIT 300", intval($sys['channel_id']), @@ -275,10 +285,10 @@ class Ping extends \Zotlabs\Web\Controller { intval(local_channel()) ); - $b64mid = ((strpos($r[0]['thr_parent'], 'b64.' === 0)) ? $r[0]['thr_parent'] : 'b64.' . base64url_encode($r[0]['thr_parent'])); + $b64mid = ((strpos($r[0]['thr_parent'], 'b64.') === 0) ? $r[0]['thr_parent'] : 'b64.' . base64url_encode($r[0]['thr_parent'])); } else { - $b64mid = ((strpos($mid, 'b64.' === 0)) ? $mid : 'b64.' . base64url_encode($mid)); + $b64mid = ((strpos($mid, 'b64.') === 0) ? $mid : 'b64.' . base64url_encode($mid)); } $notifs[] = array( @@ -334,6 +344,7 @@ class Ping extends \Zotlabs\Web\Controller { AND item_unseen = 1 AND author_xchan != '%s' $item_normal + $sql_extra ORDER BY created DESC LIMIT 300", intval(local_channel()), @@ -508,6 +519,7 @@ class Ping extends \Zotlabs\Web\Controller { $r = q("SELECT id, item_wall FROM item WHERE uid = %d and item_unseen = 1 $item_normal + $sql_extra AND author_xchan != '%s'", intval(local_channel()), dbesc($ob_hash) diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php index 44b7c18c6..2ce8686b9 100644 --- a/Zotlabs/Module/Profile_photo.php +++ b/Zotlabs/Module/Profile_photo.php @@ -463,6 +463,12 @@ class Profile_photo extends \Zotlabs\Web\Controller { '$embedPhotosModalTitle' => t('Use a photo from your albums'), '$embedPhotosModalCancel' => t('Cancel'), '$embedPhotosModalOK' => t('OK'), + '$modalchooseimages' => t('Choose images to embed'), + '$modalchoosealbum' => t('Choose an album'), + '$modaldiffalbum' => t('Choose a different album'), + '$modalerrorlist' => t('Error getting album list'), + '$modalerrorlink' => t('Error getting photo link'), + '$modalerroralbum' => t('Error getting album'), '$form_security_token' => get_form_security_token("profile_photo"), '$select' => t('Select existing photo'), )); diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php index b1cf9596c..202ee462a 100644 --- a/Zotlabs/Module/Profiles.php +++ b/Zotlabs/Module/Profiles.php @@ -655,7 +655,7 @@ class Profiles extends \Zotlabs\Web\Controller { intval($id), intval(local_channel()) ); - if(! count($r)) { + if(! $r) { notice( t('Profile not found.') . EOL); return; } @@ -712,13 +712,10 @@ class Profiles extends \Zotlabs\Web\Controller { $tpl = get_markup_template("profile_edit.tpl"); $o .= replace_macros($tpl,array( - + '$multi_profiles' => ((feature_enabled(local_channel(),'multi_profiles')) ? true : false), '$form_security_token' => get_form_security_token("profile_edit"), - '$profile_clone_link' => ((feature_enabled(local_channel(),'multi_profiles')) ? 'profiles/clone/' . $r[0]['id'] . '?t=' - . get_form_security_token("profile_clone") : ''), - '$profile_drop_link' => 'profiles/drop/' . $r[0]['id'] . '?t=' - . get_form_security_token("profile_drop"), - + '$profile_clone_link' => 'profiles/clone/' . $r[0]['id'] . '?t=' . get_form_security_token("profile_clone"), + '$profile_drop_link' => 'profiles/drop/' . $r[0]['id'] . '?t=' . get_form_security_token("profile_drop"), '$fields' => $fields, '$vcard' => $vcard, '$guid' => $r[0]['profile_guid'], @@ -735,7 +732,7 @@ class Profiles extends \Zotlabs\Web\Controller { '$addthing' => t('Add profile things'), '$personal' => t('Personal'), '$location' => t('Location'), - '$relation' => t('Relation'), + '$relation' => t('Relationship'), '$miscellaneous'=> t('Miscellaneous'), '$exportable' => feature_enabled(local_channel(),'profile_export'), '$lbl_import' => t('Import profile from file'), @@ -786,22 +783,22 @@ class Profiles extends \Zotlabs\Web\Controller { '$channels' => array('channels', t('My other channels'), $r[0]['channels']), '$extra_fields' => $extra_fields, '$comms' => t('Communications'), - '$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'), + '$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'), )); $arr = array('profile' => $r[0], 'entry' => $o); diff --git a/Zotlabs/Module/Pubstream.php b/Zotlabs/Module/Pubstream.php index 79f205a22..571118201 100644 --- a/Zotlabs/Module/Pubstream.php +++ b/Zotlabs/Module/Pubstream.php @@ -34,6 +34,8 @@ class Pubstream extends \Zotlabs\Web\Controller { } $mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : ''); + $hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : ''); + if(strpos($mid,'b64.') === 0) $decoded = @base64url_decode(substr($mid,4)); @@ -133,7 +135,7 @@ class Pubstream extends \Zotlabs\Web\Controller { '$order' => 'comment', '$file' => '', '$cats' => '', - '$tags' => '', + '$tags' => $hashtags, '$dend' => '', '$mid' => $mid, '$verb' => '', @@ -170,6 +172,10 @@ class Pubstream extends \Zotlabs\Web\Controller { $page_mode = 'client'; + if(x($hashtags)) { + $sql_extra .= protect_sprintf(term_query('item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG)); + } + $net_query = (($net) ? " left join xchan on xchan_hash = author_xchan " : ''); $net_query2 = (($net) ? " and xchan_network = '" . protect_sprintf(dbesc($net)) . "' " : ''); @@ -224,7 +230,7 @@ class Pubstream extends \Zotlabs\Web\Controller { ); } else { - $r = q("SELECT distinct parent AS item_id, $ordering FROM item + $r = q("SELECT parent AS item_id FROM item left join abook on item.author_xchan = abook.abook_xchan $net_query WHERE true $uids $item_normal_update @@ -273,7 +279,7 @@ class Pubstream extends \Zotlabs\Web\Controller { $o .= '<div id="content-complete"></div>'; if(($items) && (! $update)) - $o .= alt_pager($a,count($items)); + $o .= alt_pager(count($items)); return $o; diff --git a/Zotlabs/Module/React.php b/Zotlabs/Module/React.php index 6473317c7..fbb760786 100644 --- a/Zotlabs/Module/React.php +++ b/Zotlabs/Module/React.php @@ -49,6 +49,7 @@ class React extends \Zotlabs\Web\Controller { $n['aid'] = $channel['channel_account_id']; $n['uid'] = $channel['channel_id']; $n['item_origin'] = true; + $n['item_type'] = $i[0]['item_type']; $n['parent'] = $postid; $n['parent_mid'] = $i[0]['mid']; $n['mid'] = item_message_id(); diff --git a/Zotlabs/Module/Regmod.php b/Zotlabs/Module/Regmod.php index c7e5c44aa..70635d707 100644 --- a/Zotlabs/Module/Regmod.php +++ b/Zotlabs/Module/Regmod.php @@ -35,6 +35,8 @@ class Regmod extends \Zotlabs\Web\Controller { if($cmd === 'allow') { if (! account_allow($hash)) killme(); } + + goaway('/admin/accounts'); } } diff --git a/Zotlabs/Module/Rpost.php b/Zotlabs/Module/Rpost.php index 5d2f0d7e8..f0c4a06b9 100644 --- a/Zotlabs/Module/Rpost.php +++ b/Zotlabs/Module/Rpost.php @@ -45,7 +45,9 @@ class Rpost extends \Zotlabs\Web\Controller { $url = get_rpost_path(\App::get_observer()); // make sure we're not looping to our own hub if(($url) && (! stristr($url, \App::get_hostname()))) { - foreach($_REQUEST as $key => $arg) { + foreach($_GET as $key => $arg) { + if($key === 'q') + continue; $url .= '&' . $key . '=' . $arg; } goaway($url); @@ -111,43 +113,7 @@ class Rpost extends \Zotlabs\Web\Controller { } if($_REQUEST['post_id']) { - $r = q("SELECT * from item WHERE id = %d LIMIT 1", - intval($_REQUEST['post_id']) - ); - if(($r) && (! intval($r[0]['item_private']))) { - $sql_extra = item_permissions_sql($r[0]['uid']); - - $r = q("select * from item where id = %d $sql_extra", - intval($_REQUEST['post_id']) - ); - if($r && $r[0]['mimetype'] === 'text/bbcode') { - - xchan_query($r); - - $is_photo = (($r[0]['obj_type'] === ACTIVITY_OBJ_PHOTO) ? true : false); - if($is_photo) { - $object = json_decode($r[0]['obj'],true); - $photo_bb = $object['body']; - } - - if (strpos($r[0]['body'], "[/share]") !== false) { - $pos = strpos($r[0]['body'], "[share"); - $i = substr($r[0]['body'], $pos); - } else { - $i = "[share author='".urlencode($r[0]['author']['xchan_name']). - "' profile='".$r[0]['author']['xchan_url'] . - "' avatar='".$r[0]['author']['xchan_photo_s']. - "' link='".$r[0]['plink']. - "' posted='".$r[0]['created']. - "' message_id='".$r[0]['mid']."']"; - if($r[0]['title']) - $i .= '[b]'.$r[0]['title'].'[/b]'."\r\n"; - $i .= (($is_photo) ? $photo_bb . "\r\n" . $r[0]['body'] : $r[0]['body']); - $i .= "[/share]"; - } - } - } - $_REQUEST['body'] = $_REQUEST['body'] . $i; + $_REQUEST['body'] .= '[share=' . intval($_REQUEST['post_id']) . '][/share]'; } $x = array( diff --git a/Zotlabs/Module/Search.php b/Zotlabs/Module/Search.php index 55e0e746f..43464ad8b 100644 --- a/Zotlabs/Module/Search.php +++ b/Zotlabs/Module/Search.php @@ -66,6 +66,10 @@ class Search extends \Zotlabs\Web\Controller { $search = substr($search,1); goaway(z_root() . '/directory' . '?f=1&navsearch=1&search=' . $search); } + if(strpos($search,'!') === 0) { + $search = substr($search,1); + goaway(z_root() . '/directory' . '?f=1&navsearch=1&search=' . $search); + } if(strpos($search,'?') === 0) { $search = substr($search,1); goaway(z_root() . '/help' . '?f=1&navsearch=1&search=' . $search); diff --git a/Zotlabs/Module/Settings/Channel.php b/Zotlabs/Module/Settings/Channel.php index fb8284d2e..65b9b197e 100644 --- a/Zotlabs/Module/Settings/Channel.php +++ b/Zotlabs/Module/Settings/Channel.php @@ -21,6 +21,10 @@ class Channel { $role = ((x($_POST,'permissions_role')) ? notags(trim($_POST['permissions_role'])) : ''); $oldrole = get_pconfig(local_channel(),'system','permissions_role'); + // This mapping can be removed after 3.4 release + if($oldrole === 'social_party') { + $oldrole = 'social_federation'; + } if(($role != $oldrole) || ($role === 'custom')) { @@ -202,12 +206,14 @@ class Channel { $vnotify += intval($_POST['vnotify9']); if(x($_POST,'vnotify10')) $vnotify += intval($_POST['vnotify10']); - if(x($_POST,'vnotify11')) + if(x($_POST,'vnotify11') && is_site_admin()) $vnotify += intval($_POST['vnotify11']); if(x($_POST,'vnotify12')) $vnotify += intval($_POST['vnotify12']); if(x($_POST,'vnotify13')) $vnotify += intval($_POST['vnotify13']); + if(x($_POST,'vnotify14')) + $vnotify += intval($_POST['vnotify14']); $always_show_in_notices = x($_POST,'always_show_in_notices') ? 1 : 0; @@ -412,12 +418,16 @@ class Channel { )); $subdir = ((strlen(\App::get_path())) ? '<br />' . t('or') . ' ' . z_root() . '/channel/' . $nickname : ''); + + $webbie = $nickname . '@' . \App::get_hostname(); + $intl_nickname = unpunify($nickname) . '@' . unpunify(\App::get_hostname()); + $tpl_addr = get_markup_template("settings_nick_set.tpl"); $prof_addr = replace_macros($tpl_addr,array( '$desc' => t('Your channel address is'), - '$nickname' => $nickname, + '$nickname' => (($intl_nickname === $webbie) ? $webbie : $intl_nickname . ' (' . $webbie . ')'), '$subdir' => $subdir, '$davdesc' => t('Your files/photos are accessible via WebDAV at'), '$davpath' => ((get_account_techlevel() > 3) ? z_root() . '/dav/' . $nickname : ''), @@ -465,6 +475,10 @@ class Channel { $permissions_role = get_pconfig(local_channel(),'system','permissions_role'); if(! $permissions_role) $permissions_role = 'custom'; + // compatibility mapping - can be removed after 3.4 release + if($permissions_role === 'social_party') + $permissions_role = 'social_federation'; + $permissions_set = (($permissions_role != 'custom') ? true : false); @@ -480,7 +494,8 @@ class Channel { $plugin = [ 'basic' => '', 'security' => '', 'notify' => '', 'misc' => '' ]; call_hooks('channel_settings',$plugin); - $disable_discover_tab = get_config('system','disable_discover_tab') || get_config('system','disable_discover_tab') === false; + $disable_discover_tab = intval(get_config('system','disable_discover_tab',1)) == 1; + $site_firehose = intval(get_config('system','site_firehose',0)) == 1; $o .= replace_macros($stpl,array( '$ptitle' => t('Channel Settings'), @@ -529,7 +544,7 @@ class Channel { '$deny_gid' => acl2json($perm_defaults['deny_gid']), '$suggestme' => $suggestme, '$group_select' => $group_select, - '$role' => array('permissions_role' , t('Channel permissions category:'), $permissions_role, '', $perm_roles), + '$role' => array('permissions_role' , t('Channel role and privacy'), $permissions_role, '', $perm_roles), '$defpermcat' => [ 'defpermcat', t('Default Permissions Group'), $default_permcat, '', $permcats ], '$permcat_enable' => feature_enabled(local_channel(),'permcats'), '$profile_in_dir' => $profile_in_dir, @@ -569,11 +584,12 @@ class Channel { '$vnotify8' => array('vnotify8', t('System info messages'), ($vnotify & VNOTIFY_INFO), VNOTIFY_INFO, t('Recommended'), $yes_no), '$vnotify9' => array('vnotify9', t('System critical alerts'), ($vnotify & VNOTIFY_ALERT), VNOTIFY_ALERT, t('Recommended'), $yes_no), '$vnotify10' => array('vnotify10', t('New connections'), ($vnotify & VNOTIFY_INTRO), VNOTIFY_INTRO, t('Recommended'), $yes_no), - '$vnotify11' => array('vnotify11', t('System Registrations'), ($vnotify & VNOTIFY_REGISTER), VNOTIFY_REGISTER, '', $yes_no), + '$vnotify11' => ((is_site_admin()) ? array('vnotify11', t('System Registrations'), ($vnotify & VNOTIFY_REGISTER), VNOTIFY_REGISTER, '', $yes_no) : array()), '$vnotify12' => array('vnotify12', t('Unseen shared files'), ($vnotify & VNOTIFY_FILES), VNOTIFY_FILES, '', $yes_no), - '$vnotify13' => (($disable_discover_tab) ? array() : array('vnotify13', t('Unseen public activity'), ($vnotify & VNOTIFY_PUBS), VNOTIFY_PUBS, '', $yes_no)), + '$vnotify13' => (($disable_discover_tab && !$site_firehose) ? array() : array('vnotify13', t('Unseen public activity'), ($vnotify & VNOTIFY_PUBS), VNOTIFY_PUBS, '', $yes_no)), + '$vnotify14' => array('vnotify14', t('Unseen likes and dislikes'), ($vnotify & VNOTIFY_LIKE), VNOTIFY_LIKE, '', $yes_no), '$mailhost' => [ 'mailhost', t('Email notification hub (hostname)'), get_pconfig(local_channel(),'system','email_notify_host',\App::get_hostname()), sprintf( t('If your channel is mirrored to multiple hubs, set this to your preferred location. This will prevent duplicate email notifications. Example: %s'),\App::get_hostname()) ], - '$always_show_in_notices' => array('always_show_in_notices', t('Also show new wall posts, private messages and connections under Notices'), $always_show_in_notices, 1, '', $yes_no), + '$always_show_in_notices' => array('always_show_in_notices', t('Show new wall posts, private messages and connections under Notices'), $always_show_in_notices, 1, '', $yes_no), '$evdays' => array('evdays', t('Notify me of events this many days in advance'), $evdays, t('Must be greater than 0')), '$basic_addon' => $plugin['basic'], diff --git a/Zotlabs/Module/Settings/Featured.php b/Zotlabs/Module/Settings/Featured.php index 1da139206..542a05363 100644 --- a/Zotlabs/Module/Settings/Featured.php +++ b/Zotlabs/Module/Settings/Featured.php @@ -57,7 +57,10 @@ class Featured { } call_hooks('feature_settings', $settings_addons); - + + $this->sortpanels($settings_addons); + + $tpl = get_markup_template("settings_addons.tpl"); $o .= replace_macros($tpl, array( '$form_security_token' => get_form_security_token("settings_featured"), @@ -67,5 +70,15 @@ class Featured { )); return $o; } - -}
\ No newline at end of file + + function sortpanels(&$s) { + $a = explode('<div class="panel">',$s); + if($a) { + usort($a,'featured_sort'); + $s = implode('<div class="panel">',$a); + } + } + +} + + diff --git a/Zotlabs/Module/Settings/Features.php b/Zotlabs/Module/Settings/Features.php index 5b642acc3..888032c28 100644 --- a/Zotlabs/Module/Settings/Features.php +++ b/Zotlabs/Module/Settings/Features.php @@ -8,43 +8,75 @@ class Features { function post() { check_form_security_token_redirectOnErr('/settings/features', 'settings_features'); - // Build list of features and check which are set - // We will not create any settings for features that are above our techlevel - - $features = get_features(); - $all_features = array(); - foreach($features as $k => $v) { - foreach($v as $f) - $all_features[] = $f[0]; - } - foreach($all_features as $k) { - if(x($_POST,"feature_$k")) - set_pconfig(local_channel(),'feature',$k, 1); - else - set_pconfig(local_channel(),'feature',$k, 0); + $features = get_features(false); + + foreach($features as $fname => $fdata) { + foreach(array_slice($fdata,1) as $f) { + $k = $f[0]; + if(array_key_exists("feature_$k",$_POST)) + set_pconfig(local_channel(),'feature',$k, (string) $_POST["feature_$k"]); + else + set_pconfig(local_channel(),'feature', $k, ''); + } } build_sync_packet(); return; } function get() { - $arr = array(); - $features = get_features(); - + + $arr = []; + $harr = []; + + if(intval($_REQUEST['techlevel'])) + $level = intval($_REQUEST['techlevel']); + else { + $level = get_account_techlevel(); + } + + if(! intval($level)) { + notice( t('Permission denied.') . EOL); + return; + } + + $techlevels = \Zotlabs\Lib\Techlevels::levels(); + + // This page isn't accessible at techlevel 0 + + unset($techlevels[0]); + + $def_techlevel = (($level > 0) ? $level : 1); + $techlock = get_config('system','techlevel_lock'); + + $all_features_raw = get_features(false); + + foreach($all_features_raw as $fname => $fdata) { + foreach(array_slice($fdata,1) as $f) { + $harr[$f[0]] = ((intval(feature_enabled(local_channel(),$f[0]))) ? "1" : ''); + } + } + + $features = get_features(true,$level); + foreach($features as $fname => $fdata) { $arr[$fname] = array(); $arr[$fname][0] = $fdata[0]; foreach(array_slice($fdata,1) as $f) { - $arr[$fname][1][] = array('feature_' .$f[0],$f[1],((intval(feature_enabled(local_channel(),$f[0]))) ? "1" : ''),$f[2],array(t('Off'),t('On'))); + $arr[$fname][1][] = array('feature_' . $f[0],$f[1],((intval(feature_enabled(local_channel(),$f[0]))) ? "1" : ''),$f[2],array(t('Off'),t('On'))); + unset($harr[$f[0]]); } } $tpl = get_markup_template("settings_features.tpl"); $o .= replace_macros($tpl, array( '$form_security_token' => get_form_security_token("settings_features"), - '$title' => t('Additional Features'), - '$features' => $arr, - '$submit' => t('Submit'), + '$title' => t('Additional Features'), + '$techlevel' => [ 'techlevel', t('Your technical skill level'), $def_techlevel, t('Used to provide a member experience and additional features consistent with your comfort level'), $techlevels ], + '$techlock' => $techlock, + '$features' => $arr, + '$hiddens' => $harr, + '$baseurl' => z_root(), + '$submit' => t('Submit'), )); return $o; diff --git a/Zotlabs/Module/Settings/Oauth.php b/Zotlabs/Module/Settings/Oauth.php index c612c7667..d6576c6de 100644 --- a/Zotlabs/Module/Settings/Oauth.php +++ b/Zotlabs/Module/Settings/Oauth.php @@ -23,11 +23,12 @@ class Oauth { check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth'); - $name = ((x($_POST,'name')) ? $_POST['name'] : ''); - $key = ((x($_POST,'key')) ? $_POST['key'] : ''); - $secret = ((x($_POST,'secret')) ? $_POST['secret'] : ''); - $redirect = ((x($_POST,'redirect')) ? $_POST['redirect'] : ''); - $icon = ((x($_POST,'icon')) ? $_POST['icon'] : ''); + $name = ((x($_POST,'name')) ? escape_tags($_POST['name']) : ''); + $key = ((x($_POST,'key')) ? escape_tags($_POST['key']) : ''); + $secret = ((x($_POST,'secret')) ? escape_tags($_POST['secret']) : ''); + $redirect = ((x($_POST,'redirect')) ? escape_tags($_POST['redirect']) : ''); + $icon = ((x($_POST,'icon')) ? escape_tags($_POST['icon']) : ''); + $oauth2 = ((x($_POST,'oauth2')) ? intval($_POST['oauth2']) : 0); $ok = true; if($name == '') { $ok = false; diff --git a/Zotlabs/Module/Settings/Oauth2.php b/Zotlabs/Module/Settings/Oauth2.php new file mode 100644 index 000000000..88bbea3b8 --- /dev/null +++ b/Zotlabs/Module/Settings/Oauth2.php @@ -0,0 +1,160 @@ +<?php + +namespace Zotlabs\Module\Settings; + + +class Oauth2 { + + + function post() { + + if(x($_POST,'remove')){ + check_form_security_token_redirectOnErr('/settings/oauth2', 'settings_oauth2'); + + $key = $_POST['remove']; + q("DELETE FROM tokens WHERE id='%s' AND uid=%d", + dbesc($key), + local_channel()); + goaway(z_root()."/settings/oauth2/"); + return; + } + + if((argc() > 2) && (argv(2) === 'edit' || argv(2) === 'add') && x($_POST,'submit')) { + + check_form_security_token_redirectOnErr('/settings/oauth2', 'settings_oauth2'); + + $name = ((x($_POST,'name')) ? escape_tags(trim($_POST['name'])) : ''); + $secret = ((x($_POST,'secret')) ? escape_tags(trim($_POST['secret'])) : ''); + $redirect = ((x($_POST,'redirect')) ? escape_tags(trim($_POST['redirect'])) : ''); + $grant = ((x($_POST,'grant')) ? escape_tags(trim($_POST['grant'])) : ''); + $scope = ((x($_POST,'scope')) ? escape_tags(trim($_POST['scope'])) : ''); + + $ok = true; + if($name == '' || $secret == '') { + $ok = false; + notice( t('Name and Secret are required') . EOL); + } + + if($ok) { + if ($_POST['submit']==t("Update")){ + $r = q("UPDATE oauth_clients SET + client_id = '%s', + client_secret = '%s', + redirect_uri = '%s', + grant_types = '%s', + scope = '%s', + user_id = '%s' + WHERE client_id='%s'", + dbesc($name), + dbesc($secret), + dbesc($redirect), + dbesc($grant), + dbesc($scope), + dbesc(local_channel()), + dbesc($name)); + } else { + $r = q("INSERT INTO oauth_clients (client_id, client_secret, redirect_uri, grant_types, scope, user_id) + VALUES ('%s','%s','%s','%s','%s','%s')", + dbesc($name), + dbesc($secret), + dbesc($redirect), + dbesc($grant), + dbesc($scope), + dbesc(local_channel()) + ); + $r = q("INSERT INTO xperm (xp_client, xp_channel, xp_perm) VALUES ('%s', %d, '%s') ", + dbesc($name), + intval(local_channel()), + dbesc('all') + ); + } + } + goaway(z_root()."/settings/oauth2/"); + return; + } + } + + function get() { + + if((argc() > 2) && (argv(2) === 'add')) { + $tpl = get_markup_template("settings_oauth2_edit.tpl"); + $o .= replace_macros($tpl, array( + '$form_security_token' => get_form_security_token("settings_oauth2"), + '$title' => t('Add OAuth2 application'), + '$submit' => t('Submit'), + '$cancel' => t('Cancel'), + '$name' => array('name', t('Name'), '', t('Name of application')), + '$secret' => array('secret', t('Consumer Secret'), random_string(16), t('Automatically generated - change if desired. Max length 20')), + '$redirect' => array('redirect', t('Redirect'), '', t('Redirect URI - leave blank unless your application specifically requires this')), + '$grant' => array('grant', t('Grant Types'), '', t('leave blank unless your application sepcifically requires this')), + '$scope' => array('scope', t('Authorization scope'), '', t('leave blank unless your application sepcifically requires this')), + )); + return $o; + } + + if((argc() > 3) && (argv(2) === 'edit')) { + $r = q("SELECT * FROM oauth_clients WHERE client_id='%s' AND user_id= '%s'", + dbesc(argv(3)), + dbesc(local_channel()) + ); + + if (! $r){ + notice(t('OAuth2 Application not found.')); + return; + } + + $app = $r[0]; + + $tpl = get_markup_template("settings_oauth2_edit.tpl"); + $o .= replace_macros($tpl, array( + '$form_security_token' => get_form_security_token("settings_oauth2"), + '$title' => t('Add application'), + '$submit' => t('Update'), + '$cancel' => t('Cancel'), + '$name' => array('name', t('Name'), $app['client_id'], t('Name of application')), + '$secret' => array('secret', t('Consumer Secret'), $app['client_secret'], t('Automatically generated - change if desired. Max length 20')), + '$redirect' => array('redirect', t('Redirect'), $app['redirect_uri'], t('Redirect URI - leave blank unless your application specifically requires this')), + '$grant' => array('grant', t('Grant Types'), $app['grant_types'], t('leave blank unless your application sepcifically requires this')), + '$scope' => array('scope', t('Authorization scope'), $app['scope'], t('leave blank unless your application sepcifically requires this')), + )); + return $o; + } + + if((argc() > 3) && (argv(2) === 'delete')) { + check_form_security_token_redirectOnErr('/settings/oauth2', 'settings_oauth2', 't'); + + $r = q("DELETE FROM oauth_clients WHERE client_id = '%s' AND user_id = '%s'", + dbesc(argv(3)), + dbesc(local_channel()) + ); + goaway(z_root()."/settings/oauth2/"); + return; + } + + + $r = q("SELECT oauth_clients.*, oauth_access_tokens.access_token as oauth_token, (oauth_clients.user_id = '%s') AS my + FROM oauth_clients + LEFT JOIN oauth_access_tokens ON oauth_clients.client_id=oauth_access_tokens.client_id + WHERE oauth_clients.user_id IN ('%s',0)", + dbesc(local_channel()), + dbesc(local_channel()) + ); + + $tpl = get_markup_template("settings_oauth2.tpl"); + $o .= replace_macros($tpl, array( + '$form_security_token' => get_form_security_token("settings_oauth2"), + '$baseurl' => z_root(), + '$title' => t('Connected OAuth2 Apps'), + '$add' => t('Add application'), + '$edit' => t('Edit'), + '$delete' => t('Delete'), + '$consumerkey' => t('Client key starts with'), + '$noname' => t('No name'), + '$remove' => t('Remove authorization'), + '$apps' => $r, + )); + return $o; + + } + +}
\ No newline at end of file diff --git a/Zotlabs/Module/Settings/Permcats.php b/Zotlabs/Module/Settings/Permcats.php index 535399083..40641c3f2 100644 --- a/Zotlabs/Module/Settings/Permcats.php +++ b/Zotlabs/Module/Settings/Permcats.php @@ -19,6 +19,11 @@ class Permcats { $all_perms = \Zotlabs\Access\Permissions::Perms(); $name = escape_tags(trim($_POST['name'])); + if(! $name) { + notice( t('Permission Name is required.') . EOL); + return; + } + $pcarr = []; diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php index 8e7fbbddf..a3832d156 100644 --- a/Zotlabs/Module/Setup.php +++ b/Zotlabs/Module/Setup.php @@ -563,16 +563,20 @@ class Setup extends \Zotlabs\Web\Controller { $status = true; $help = ''; - if( (file_exists('.htconfig.php') && !is_writable('.htconfig.php')) || - (!file_exists('.htconfig.php') && !is_writable('.')) ) { - $status = false; - $help = t('The web installer needs to be able to create a file called ".htconfig.php" in the top folder of your web server and it is unable to do so.') .EOL; - $help .= t('This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.').EOL; - $help .= t('At the end of this procedure, we will give you a text to save in a file named .htconfig.php in your Red top folder.').EOL; - $help .= t('You can alternatively skip this procedure and perform a manual installation. Please see the file "install/INSTALL.txt" for instructions.').EOL; + $fname = '.htconfig.php'; + + if((file_exists($fname) && is_writable($fname)) || + (! (file_exists($fname) && is_writable('.')))) { + $this->check_add($checks, t('.htconfig.php is writable'), $status, true, $help); + return; } - $this->check_add($checks, t('.htconfig.php is writable'), $status, false, $help); + $status = false; + $help = t('The web installer needs to be able to create a file called ".htconfig.php" in the top folder of your web server and it is unable to do so.') .EOL; + $help .= t('This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.').EOL; + $help .= t('Please see install/INSTALL.txt for additional information.'); + + $this->check_add($checks, t('.htconfig.php is writable'), $status, true, $help); } /** diff --git a/Zotlabs/Module/Share.php b/Zotlabs/Module/Share.php index 7f4d8b1eb..c6d0be051 100644 --- a/Zotlabs/Module/Share.php +++ b/Zotlabs/Module/Share.php @@ -14,10 +14,15 @@ class Share extends \Zotlabs\Web\Controller { if(! $post_id) killme(); - echo '[share=' . $post_id . '][/share]'; killme(); + + /** + * The remaining code is deprecated and handled in Zotlabs/Lib/Share.php at post + * submission time. + */ + if(! (local_channel() || remote_channel())) killme(); @@ -60,12 +65,14 @@ class Share extends \Zotlabs\Web\Controller { $pos = strpos($r[0]['body'], "[share"); $o = substr($r[0]['body'], $pos); } else { - $o = "[share author='".urlencode($r[0]['author']['xchan_name']). - "' profile='".$r[0]['author']['xchan_url'] . - "' avatar='".$r[0]['author']['xchan_photo_s']. - "' link='".$r[0]['plink']. - "' posted='".$r[0]['created']. - "' message_id='".$r[0]['mid']."']"; + $o = "[share author='" . urlencode($r[0]['author']['xchan_name']) . + "' profile='" . $r[0]['author']['xchan_url'] . + "' avatar='" . $r[0]['author']['xchan_photo_s'] . + "' link='" . $r[0]['plink'] . + "' auth='" . (($r[0]['author']['network'] === 'zot') ? 'true' : 'false') . + "' posted='" . $r[0]['created'] . + "' message_id='" . $r[0]['mid'] . + "']"; if($r[0]['title']) $o .= '[b]'.$r[0]['title'].'[/b]'."\r\n"; $o .= (($is_photo) ? $photo_bb . "\r\n" . $r[0]['body'] : $r[0]['body']); diff --git a/Zotlabs/Module/Sitelist.php b/Zotlabs/Module/Sitelist.php index e7d4187b7..2ac5ed1b8 100644 --- a/Zotlabs/Module/Sitelist.php +++ b/Zotlabs/Module/Sitelist.php @@ -32,7 +32,7 @@ class Sitelist extends \Zotlabs\Web\Controller { $result = array('success' => false); - $r = q("select count(site_url) as total from site where site_type = %d $sql_extra ", + $r = q("select count(site_url) as total from site where site_type = %d and site_dead = 0 $sql_extra ", intval(SITE_TYPE_ZOT) ); @@ -42,7 +42,7 @@ class Sitelist extends \Zotlabs\Web\Controller { $result['start'] = $start; $result['limit'] = $limit; - $r = q("select * from site where site_type = %d $sql_extra $sql_order $sql_limit", + $r = q("select * from site where site_type = %d and site_dead = 0 $sql_extra $sql_order $sql_limit", intval(SITE_TYPE_ZOT) ); diff --git a/Zotlabs/Module/Tagger.php b/Zotlabs/Module/Tagger.php index 603a95f2b..24adf1bde 100644 --- a/Zotlabs/Module/Tagger.php +++ b/Zotlabs/Module/Tagger.php @@ -80,6 +80,8 @@ class Tagger extends \Zotlabs\Web\Controller { break; } + + $clean_term = trim($term,'"\' '); $links = array(array('rel' => 'alternate','type' => 'text/html', 'href' => z_root() . '/display/' . gen_link_id($item['mid']))); @@ -103,15 +105,15 @@ class Tagger extends \Zotlabs\Web\Controller { ), )); - $tagid = z_root() . '/search?tag=' . $term; + $tagid = z_root() . '/search?tag=' . $clean_term; $objtype = ACTIVITY_OBJ_TAGTERM; $obj = json_encode(array( 'type' => $objtype, 'id' => $tagid, 'link' => array(array('rel' => 'alternate','type' => 'text/html', 'href' => $tagid)), - 'title' => $term, - 'content' => $term + 'title' => $clean_term, + 'content' => $clean_term )); $bodyverb = t('%1$s tagged %2$s\'s %3$s with %4$s'); @@ -119,7 +121,7 @@ class Tagger extends \Zotlabs\Web\Controller { // saving here for reference // also check out x22d5 and x2317 and x0d6b and x0db8 and x24d0 and xff20 !!! - $termlink = html_entity_decode('⋕') . '[zrl=' . z_root() . '/search?tag=' . urlencode($term) . ']'. $term . '[/zrl]'; + $termlink = html_entity_decode('⋕') . '[zrl=' . z_root() . '/search?tag=' . urlencode($clean_term) . ']'. $clean_term . '[/zrl]'; $channel = \App::get_channel(); @@ -143,8 +145,7 @@ class Tagger extends \Zotlabs\Web\Controller { $arr['obj_type'] = $objtype; $arr['obj'] = $obj; $arr['parent_mid'] = $item['mid']; - - store_item_tag($item['uid'],$item['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$term,$tagid); + store_item_tag($item['uid'],$item['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$clean_term,$tagid); $ret = post_activity_item($arr); if($ret['success']) { diff --git a/Zotlabs/Module/Thing.php b/Zotlabs/Module/Thing.php index f816632ab..c3d8ff802 100644 --- a/Zotlabs/Module/Thing.php +++ b/Zotlabs/Module/Thing.php @@ -20,6 +20,11 @@ class Thing extends \Zotlabs\Web\Controller { $channel = \App::get_channel(); + if($_SERVER['REQUEST_METHOD'] === 'GET' && argc() < 2) { + profile_load($channel['channel_address']); + } + + $term_hash = (($_REQUEST['term_hash']) ? $_REQUEST['term_hash'] : ''); $name = escape_tags($_REQUEST['term']); diff --git a/Zotlabs/Module/Token.php b/Zotlabs/Module/Token.php index f7c074233..32cf95c61 100644 --- a/Zotlabs/Module/Token.php +++ b/Zotlabs/Module/Token.php @@ -29,7 +29,8 @@ class Token extends \Zotlabs\Web\Controller { } $s = new \Zotlabs\Identity\OAuth2Server(new OAuth2Storage(\DBA::$dba->db)); - $s->handleTokenRequest(\OAuth2\Request::createFromGlobals())->send(); + $request = \OAuth2\Request::createFromGlobals(); + $s->handleTokenRequest($request)->send(); killme(); } diff --git a/Zotlabs/Module/Uexport.php b/Zotlabs/Module/Uexport.php index 28c840ceb..9af1887dc 100644 --- a/Zotlabs/Module/Uexport.php +++ b/Zotlabs/Module/Uexport.php @@ -22,8 +22,8 @@ class Uexport extends \Zotlabs\Web\Controller { $month = intval(argv(2)); } - header('content-type: application/octet_stream'); - header('content-disposition: attachment; filename="' . $channel['channel_address'] . (($year) ? '-' . $year : '') . (($month) ? '-' . $month : '') . '.json"' ); + header('content-type: application/json'); + header('content-disposition: attachment; filename="' . $channel['channel_address'] . (($year) ? '-' . $year : '') . (($month) ? '-' . $month : '') . (($_REQUEST['sections']) ? '-' . $_REQUEST['sections'] : '') . '.json"' ); if($year) { echo json_encode(identity_export_year(local_channel(),$year,$month)); diff --git a/Zotlabs/Module/Webfinger.php b/Zotlabs/Module/Webfinger.php index c50680de7..0dafae23c 100644 --- a/Zotlabs/Module/Webfinger.php +++ b/Zotlabs/Module/Webfinger.php @@ -17,33 +17,15 @@ class Webfinger extends \Zotlabs\Web\Controller { $o .= '<br /><br />'; - $old = false; if(x($_GET,'addr')) { $addr = trim($_GET['addr']); - // if(strpos($addr,'@') !== false) { - $res = webfinger_rfc7033($addr,true); - if(! $res) { - $res = old_webfinger($addr); - $old = true; - } - // } - // else { - // if(function_exists('lrdd')) - // $res = lrdd($addr); - // } - - if($res && $old) { - foreach($res as $r) { - if($r['@attributes']['rel'] === 'http://microformats.org/profile/hcard') { - $hcard = unamp($r['@attributes']['href']); - require_once('library/HTML5/Parser.php'); - $res['vcard'] = scrape_vcard($hcard); - break; - } - } + + $res = webfinger_rfc7033($addr,true); + if(! $res) { + $res = old_webfinger($addr); } - + $o .= '<pre>'; $o .= str_replace("\n",'<br />',print_r($res,true)); $o .= '</pre>'; diff --git a/Zotlabs/Module/Well_known.php b/Zotlabs/Module/Well_known.php index b57666bff..177de2323 100644 --- a/Zotlabs/Module/Well_known.php +++ b/Zotlabs/Module/Well_known.php @@ -26,7 +26,6 @@ class Well_known extends \Zotlabs\Web\Controller { killme(); } - switch(argv(1)) { case 'zot-info': \App::$argc -= 1; @@ -52,6 +51,10 @@ class Well_known extends \Zotlabs\Web\Controller { $module->init(); break; + case 'dnt-policy.txt': + echo file_get_contents('doc/dnt-policy.txt'); + killme(); + default: if(file_exists(\App::$cmd)) { echo file_get_contents(\App::$cmd); diff --git a/Zotlabs/Module/Wfinger.php b/Zotlabs/Module/Wfinger.php index 753721d27..81d4beaed 100644 --- a/Zotlabs/Module/Wfinger.php +++ b/Zotlabs/Module/Wfinger.php @@ -123,7 +123,8 @@ class Wfinger extends \Zotlabs\Web\Controller { $result['properties'] = [ 'http://webfinger.net/ns/name' => $r[0]['channel_name'], 'http://xmlns.com/foaf/0.1/name' => $r[0]['channel_name'], - 'https://w3id.org/security/v1#publicKeyPem' => $r[0]['xchan_pubkey'] + 'https://w3id.org/security/v1#publicKeyPem' => $r[0]['xchan_pubkey'], + 'http://purl.org/zot/federation' => 'zot' ]; foreach($aliases as $alias) diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index ae543eb98..7dc8eb1bc 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -284,6 +284,8 @@ class Wiki extends \Zotlabs\Web\Controller { $wikiheaderPage = urldecode($pageUrlName); $renamePage = (($wikiheaderPage === 'Home') ? '' : t('Rename page')); + $sharePage = t('Share'); + $p = []; if(! $ignore_language) { @@ -354,6 +356,8 @@ class Wiki extends \Zotlabs\Web\Controller { '$wikiheaderName' => $wikiheaderName, '$wikiheaderPage' => $wikiheaderPage, '$renamePage' => $renamePage, + '$sharePage' => $sharePage, + '$shareLink' => urlencode('#^[zrl=' . z_root() . '/wiki/' . argv(1) . '/' . $wikiUrlName . '/' . $pageUrlName . ']' . '[ ' . $owner['channel_name'] . ' ] ' . $wikiheaderName . ' - ' . $wikiheaderPage . '[/zrl]'), '$showPageControls' => $showPageControls, '$editOrSourceLabel' => (($showPageControls) ? t('Edit') : t('Source')), '$tools_label' => 'Page Tools', diff --git a/Zotlabs/Storage/Browser.php b/Zotlabs/Storage/Browser.php index f1c95802b..508c39d22 100644 --- a/Zotlabs/Storage/Browser.php +++ b/Zotlabs/Storage/Browser.php @@ -274,7 +274,7 @@ class Browser extends DAV\Browser\Plugin { '$actionspanel' => $output, '$shared' => t('Shared'), '$create' => t('Create'), - '$upload' => t('Upload'), + '$upload' => t('Add Files'), '$is_owner' => $is_owner, '$parentpath' => $parentpath, '$cpath' => bin2hex(\App::$query_string), diff --git a/Zotlabs/Storage/Directory.php b/Zotlabs/Storage/Directory.php index 510d463c1..d063eed40 100644 --- a/Zotlabs/Storage/Directory.php +++ b/Zotlabs/Storage/Directory.php @@ -389,8 +389,12 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo ); if ($r) { + + // When initiated from DAV, set the 'force' flag on attach_mkdir(). This will cause the operation to report success even if the + // folder already exists. + require_once('include/attach.php'); - $result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash)); + $result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash, 'force' => true)); if($result['success']) { $sync = attach_export_data($r[0],$result['data']['hash']); @@ -680,7 +684,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo throw new DAV\Exception\Forbidden('Permission denied.'); } else { - throw new DAV\Exception\NotFound('A component of the request file path could not be found.'); + throw new DAV\Exception\NotFound('A component of the requested file path could not be found.'); } } @@ -691,7 +695,23 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo } $prefix = ''; - $suffix = ' order by is_dir desc, filename asc '; + + if(! array_key_exists('cloud_sort',$_SESSION)) + $_SESSION['cloud_sort'] = 'name'; + + switch($_SESSION['cloud_sort']) { + case 'size': + $suffix = ' order by is_dir desc, filesize asc '; + break; + // The following provides inconsistent results for directories because we re-calculate the date for directories based on the most recent change + case 'date': + $suffix = ' order by is_dir desc, edited asc '; + break; + case 'name': + default: + $suffix = ' order by is_dir desc, filename asc '; + break; + } $r = q("select $prefix id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, created, edited from attach where folder = '%s' and uid = %d $perms $suffix", dbesc($folder), diff --git a/Zotlabs/Storage/ZotOauth2Pdo.php b/Zotlabs/Storage/ZotOauth2Pdo.php new file mode 100644 index 000000000..b2c3ce228 --- /dev/null +++ b/Zotlabs/Storage/ZotOauth2Pdo.php @@ -0,0 +1,10 @@ +<?php + +namespace Zotlabs\Storage; + +class ZotOauth2Pdo extends \OAuth2\Storage\Pdo { + public function getConfig() + { + return $this->config; + } +} diff --git a/Zotlabs/Update/_1204.php b/Zotlabs/Update/_1204.php index 93c2e4e3f..0b9204b9b 100644 --- a/Zotlabs/Update/_1204.php +++ b/Zotlabs/Update/_1204.php @@ -8,11 +8,11 @@ class _1204 { if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { $r1 = q("ALTER TABLE poll ADD poll_guid text NOT NULL"); - $r2 = q("create index \"poll_guid_idx\" on poll \"poll_guid\""); + $r2 = q("create index \"poll_guid_idx\" on poll (\"poll_guid\")"); $r3 = q("ALTER TABLE poll_elm ADD pelm_guid text NOT NULL"); - $r4 = q("create index \"pelm_guid_idx\" on poll_elm \"pelm_guid\""); + $r4 = q("create index \"pelm_guid_idx\" on poll_elm (\"pelm_guid\")"); $r5 = q("ALTER TABLE vote ADD vote_guid text NOT NULL"); - $r6 = q("create index \"vote_guid_idx\" on vote \"vote_guid\""); + $r6 = q("create index \"vote_guid_idx\" on vote (\"vote_guid\")"); $r = ($r1 && $r2 && $r3 && $r4 && $r5 && $r6); } diff --git a/Zotlabs/Update/_1205.php b/Zotlabs/Update/_1205.php index 5384f183e..968833726 100644 --- a/Zotlabs/Update/_1205.php +++ b/Zotlabs/Update/_1205.php @@ -7,6 +7,17 @@ class _1205 { function run() { if(ACTIVE_DBTYPE == DBTYPE_MYSQL) { + + q("ALTER TABLE item DROP INDEX title"); + q("ALTER TABLE item DROP INDEX body"); + q("ALTER TABLE item DROP INDEX allow_cid"); + q("ALTER TABLE item DROP INDEX allow_gid"); + q("ALTER TABLE item DROP INDEX deny_cid"); + q("ALTER TABLE item DROP INDEX deny_gid"); + q("ALTER TABLE item DROP INDEX item_flags"); + q("ALTER TABLE item DROP INDEX item_restrict"); + q("ALTER TABLE item DROP INDEX aid"); + $r = q("ALTER TABLE item DROP INDEX item_private, ADD INDEX uid_item_private (uid, item_private), diff --git a/Zotlabs/Update/_1207.php b/Zotlabs/Update/_1207.php new file mode 100644 index 000000000..f53bc46ae --- /dev/null +++ b/Zotlabs/Update/_1207.php @@ -0,0 +1,24 @@ +<?php + +namespace Zotlabs\Update; + +class _1207 { + + function run() { + + if(ACTIVE_DBTYPE == DBTYPE_MYSQL) { + $r = q("ALTER TABLE item + DROP INDEX resource_type + "); + + if($r) + return UPDATE_SUCCESS; + return UPDATE_FAILED; + } + else { + return UPDATE_SUCCESS; + } + + } + +} diff --git a/Zotlabs/Update/_1208.php b/Zotlabs/Update/_1208.php new file mode 100644 index 000000000..4cbcf4322 --- /dev/null +++ b/Zotlabs/Update/_1208.php @@ -0,0 +1,26 @@ +<?php + +namespace Zotlabs\Update; + +class _1208 { + + function run() { + + if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { + $r1 = q("ALTER TABLE poll ADD poll_author text NOT NULL"); + $r2 = q("create index \"poll_author_idx\" on poll \"poll_author\""); + + $r = ($r1 && $r2); + } + else { + $r = q("ALTER TABLE `poll` ADD `poll_author` VARCHAR(191) NOT NULL AFTER `poll_votes`, + ADD INDEX `poll_author` (`poll_author`)"); + } + + if($r) + return UPDATE_SUCCESS; + return UPDATE_FAILED; + + } + +} diff --git a/Zotlabs/Update/_1209.php b/Zotlabs/Update/_1209.php new file mode 100644 index 000000000..5ec449395 --- /dev/null +++ b/Zotlabs/Update/_1209.php @@ -0,0 +1,26 @@ +<?php + +namespace Zotlabs\Update; + +class _1209 { + + function run() { + + if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { + $r1 = q("ALTER TABLE poll_elm ADD pelm_order numeric(6) NOT NULL DEFAULT '0' "); + $r2 = q("create index \"pelm_order_idx\" on poll_elm \"pelm_order\""); + + $r = ($r1 && $r2); + } + else { + $r = q("ALTER TABLE `poll_elm` ADD `pelm_order` int(11) NOT NULL DEFAULT 0, + ADD INDEX `pelm_order` (`pelm_order`)"); + } + + if($r) + return UPDATE_SUCCESS; + return UPDATE_FAILED; + + } + +} diff --git a/Zotlabs/Update/_1210.php b/Zotlabs/Update/_1210.php new file mode 100644 index 000000000..813e3fe82 --- /dev/null +++ b/Zotlabs/Update/_1210.php @@ -0,0 +1,78 @@ +<?php + +namespace Zotlabs\Update; + +class _1210 { + + function run() { + + $sql = "CREATE TABLE oauth_clients ( + client_id VARCHAR(80) NOT NULL, + client_secret VARCHAR(80), + redirect_uri VARCHAR(2000), + grant_types VARCHAR(80), + scope VARCHAR(4000), + user_id VARCHAR(80), + PRIMARY KEY (client_id) +); + +CREATE TABLE oauth_access_tokens ( + access_token VARCHAR(40) NOT NULL, + client_id VARCHAR(80) NOT NULL, + user_id VARCHAR(255), + expires TIMESTAMP NOT NULL, + scope VARCHAR(4000), + PRIMARY KEY (access_token) +); + +CREATE TABLE oauth_authorization_codes ( + authorization_code VARCHAR(40) NOT NULL, + client_id VARCHAR(80) NOT NULL, + user_id VARCHAR(255), + redirect_uri VARCHAR(2000), + expires TIMESTAMP NOT NULL, + scope VARCHAR(4000), + id_token VARCHAR(1000), + PRIMARY KEY (authorization_code) +); + +CREATE TABLE oauth_refresh_tokens ( + refresh_token VARCHAR(40) NOT NULL, + client_id VARCHAR(80) NOT NULL, + user_id VARCHAR(255), + expires TIMESTAMP NOT NULL, + scope VARCHAR(4000), + PRIMARY KEY (refresh_token) +); + +CREATE TABLE oauth_scopes ( + scope VARCHAR(191) NOT NULL, + is_default SMALLINT, + PRIMARY KEY (scope) +); + +CREATE TABLE oauth_jwt ( + client_id VARCHAR(80) NOT NULL, + subject VARCHAR(80), + public_key VARCHAR(2000) NOT NULL +); +"; + + $arr = explode(';', $sql); + $errors = 0; + foreach($arr as $a) { + if(strlen(trim($a))) { + $r = dbq(trim($a)); + if(! $r) { + $errors ++; + } + } + } + + if(! $errors) + return UPDATE_SUCCESS; + return UPDATE_FAILED; + + } + +} diff --git a/Zotlabs/Update/_1211.php b/Zotlabs/Update/_1211.php new file mode 100644 index 000000000..739a5670d --- /dev/null +++ b/Zotlabs/Update/_1211.php @@ -0,0 +1,26 @@ +<?php + +namespace Zotlabs\Update; + +class _1211 { + + function run() { + + if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { + $r1 = q("ALTER TABLE channel ADD channel_active timestamp NOT NULL DEFAULT '0001-01-01 00:00:00' "); + $r2 = q("create index \"channel_active\" on channel_active \"channel_active\""); + + $r = ($r1 && $r2); + } + else { + $r = q("ALTER TABLE `channel` ADD `channel_active` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' , + ADD INDEX `channel_active` (`channel_active`)"); + } + + if($r) + return UPDATE_SUCCESS; + return UPDATE_FAILED; + + } + +} diff --git a/Zotlabs/Update/_1212.php b/Zotlabs/Update/_1212.php new file mode 100644 index 000000000..f15ba8a71 --- /dev/null +++ b/Zotlabs/Update/_1212.php @@ -0,0 +1,26 @@ +<?php + +namespace Zotlabs\Update; + +class _1212 { + + function run() { + + $r = q("select channel_id from channel where true"); + if($r) { + foreach($r as $rv) { + $role = get_pconfig($rv['channel_id'],'system','permissions_role'); + if($role !== 'custom') { + $role_permissions = \Zotlabs\Access\PermissionRoles::role_perms($role); + if(array_key_exists('limits',$role_permissions) && array_key_exists('post_comments',$role_permissions['limits'])) { + set_pconfig($rv['channel_id'],'perm_limits','post_comments',$role_permissions['limits']['post_comments']); + } + } + } + } + + return UPDATE_SUCCESS; + + } + +} diff --git a/Zotlabs/Web/HTTPSig.php b/Zotlabs/Web/HTTPSig.php index 9bcc2e5ec..df66ecf5c 100644 --- a/Zotlabs/Web/HTTPSig.php +++ b/Zotlabs/Web/HTTPSig.php @@ -59,6 +59,8 @@ class HTTPSig { $headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']; + $headers['content-type'] = $_SERVER['CONTENT_TYPE']; + foreach($_SERVER as $k => $v) { if(strpos($k,'HTTP_') === 0) { $field = str_replace('_','-',strtolower(substr($k,5))); @@ -67,6 +69,10 @@ class HTTPSig { } } + // logger('SERVER: ' . print_r($_SERVER,true), LOGGER_ALL); + + // logger('headers: ' . print_r($headers,true), LOGGER_ALL); + $sig_block = null; if(array_key_exists('signature',$headers)) { @@ -189,15 +195,17 @@ class HTTPSig { if($x && $x[0]['xchan_pubkey']) { return ($x[0]['xchan_pubkey']); } - $r = as_fetch($id); + + if(function_exists('as_fetch')) + $r = as_fetch($id); if($r) { $j = json_decode($r,true); - if($j['id'] !== $id) - return false; - if(array_key_exists('publicKey',$j) && array_key_exists('publicKeyPem',$j['publicKey'])) { + if((array_key_exists('id',$j['publicKey']) && $j['publicKey']['id'] !== $id) && $j['id'] !== $id) + return false; + return($j['publicKey']['publicKeyPem']); } } diff --git a/Zotlabs/Web/WebServer.php b/Zotlabs/Web/WebServer.php index 5183fb2b0..1c3ea29d0 100644 --- a/Zotlabs/Web/WebServer.php +++ b/Zotlabs/Web/WebServer.php @@ -44,9 +44,9 @@ class WebServer { * We have to do it here because the session was just now opened. */ - if(array_key_exists('system_language',$_POST)) { - if(strlen($_POST['system_language'])) - $_SESSION['language'] = $_POST['system_language']; + if(array_key_exists('system_language',$_REQUEST)) { + if(strlen($_REQUEST['system_language'])) + $_SESSION['language'] = $_REQUEST['system_language']; else unset($_SESSION['language']); } diff --git a/Zotlabs/Widget/Catcloud.php b/Zotlabs/Widget/Catcloud.php new file mode 100644 index 000000000..c53f9bbf6 --- /dev/null +++ b/Zotlabs/Widget/Catcloud.php @@ -0,0 +1,46 @@ +<?php + +namespace Zotlabs\Widget; + +class Catcloud { + + function widget($arr) { + + if((! \App::$profile['profile_uid']) || (! \App::$profile['channel_hash'])) + return ''; + + $limit = ((array_key_exists('limit',$arr)) ? intval($arr['limit']) : 50); + + if(array_key_exists('type',$arr)) { + switch($arr['type']) { + + case 'cards': + + if(! perm_is_allowed(\App::$profile['profile_uid'], get_observer_hash(), 'view_pages')) + return ''; + + return card_catblock(\App::$profile['profile_uid'], $limit, '', \App::$profile['channel_hash']); + + case 'articles': + + if(! perm_is_allowed(\App::$profile['profile_uid'], get_observer_hash(), 'view_pages')) + return ''; + + return article_catblock(\App::$profile['profile_uid'], $limit, '', \App::$profile['channel_hash']); + + + default: + break; + } + } + + + if(! perm_is_allowed(\App::$profile['profile_uid'], get_observer_hash(), 'view_stream')) + return ''; + + return catblock(\App::$profile['profile_uid'], $limit, '', \App::$profile['channel_hash']); + + + } + +} diff --git a/Zotlabs/Widget/Design_tools.php b/Zotlabs/Widget/Design_tools.php index 8ab6a235d..a15c0c98d 100644 --- a/Zotlabs/Widget/Design_tools.php +++ b/Zotlabs/Widget/Design_tools.php @@ -6,16 +6,9 @@ class Design_tools { function widget($arr) { - // mod menu doesn't load a profile. For any modules which load a profile, check it. - // otherwise local_channel() is sufficient for permissions. + if(perm_is_allowed(\App::$profile['profile_uid'],get_observer_hash(),'write_pages') || (\App::$is_sys && is_site_admin())) + return design_tools(); - if(\App::$profile['profile_uid']) - if((\App::$profile['profile_uid'] != local_channel()) && (! \App::$is_sys)) - return ''; - - if(! local_channel()) - return ''; - - return design_tools(); + return EMPTY_STR; } }
\ No newline at end of file diff --git a/Zotlabs/Widget/Forums.php b/Zotlabs/Widget/Forums.php index f65a639ff..7415c0f0a 100644 --- a/Zotlabs/Widget/Forums.php +++ b/Zotlabs/Widget/Forums.php @@ -66,8 +66,8 @@ class Forums { for($x = 0; $x < count($r1); $x ++) { $r = q("select sum(item_unseen) as unseen from item where uid = %d and owner_xchan = '%s' and item_unseen = 1 $perms_sql ", - dbesc($r1[$x]['xchan_hash']), - intval(local_channel()) + intval(local_channel()), + dbesc($r1[$x]['xchan_hash']) ); if($r) $r1[$x]['unseen'] = $r[0]['unseen']; diff --git a/Zotlabs/Widget/Newmember.php b/Zotlabs/Widget/Newmember.php index 898942ccc..1a4b575b9 100644 --- a/Zotlabs/Widget/Newmember.php +++ b/Zotlabs/Widget/Newmember.php @@ -13,22 +13,13 @@ class Newmember { if(! $c) return EMPTY_STR; - $a = \App::get_account(); if(! $a) return EMPTY_STR; - - if(datetime_convert('UTC','UTC',$a['account_created']) < datetime_convert('UTC','UTC', 'now - 60 days')) - return EMPTY_STR; - - // This could be a new account that was used to clone a very old channel - - $ob = \App::get_observer(); - if($ob && array_key_exists('xchan_name_date',$ob) && $ob['xchan_name_date'] < datetime_convert('UTC','UTC','now - 60 days')) + if(! feature_enabled(local_channel(),'start_menu')) return EMPTY_STR; - $options = [ t('Profile Creation'), [ @@ -39,14 +30,14 @@ class Newmember { t('Find and Connect with others'), [ - 'directory' => t('View the channel directory'), - 'suggest' => t('View friend suggestions'), - 'connections' => t('Manage your connections'), + 'directory' => t('View the directory'), + 'directory?f=&suggest=1' => t('View friend suggestions'), + 'connections' => t('Manage your connections'), ], t('Communicate'), [ - 'channel/' . $channel['channel_address'] => t('View your channel homepage'), + 'channel/' . $c['channel_address'] => t('View your channel homepage'), 'network' => t('View your network stream'), ], @@ -64,7 +55,7 @@ class Newmember { // hack to put this in the correct spot of the array if($site_firehose || $net_firehose) { - $options[5]['pubstream'] = t('View public stream. Warning: not moderated'); + $options[5]['pubstream'] = t('View public stream'); } $o = replace_macros(get_markup_template('new_member.tpl'), [ diff --git a/Zotlabs/Widget/Notifications.php b/Zotlabs/Widget/Notifications.php index f2619c5cf..fc78a2a39 100644 --- a/Zotlabs/Widget/Notifications.php +++ b/Zotlabs/Widget/Notifications.php @@ -123,7 +123,7 @@ class Notifications { ]; } - if(get_config('system', 'disable_discover_tab') != 1) { + if(can_view_public_stream()) { $notifications[] = [ 'type' => 'pubs', 'icon' => 'globe', diff --git a/Zotlabs/Widget/Pubtagcloud.php b/Zotlabs/Widget/Pubtagcloud.php new file mode 100644 index 000000000..826e3e6ae --- /dev/null +++ b/Zotlabs/Widget/Pubtagcloud.php @@ -0,0 +1,41 @@ +<?php + +namespace Zotlabs\Widget; + +class Pubtagcloud { + + function widget($arr) { + + $trending = ((array_key_exists('trending',$arr)) ? intval($arr['trending']) : 0); + if((observer_prohibited(true))) { + return EMPTY_STR; + } + + if(! intval(get_config('system','open_pubstream',1))) { + if(! get_observer_hash()) { + return EMPTY_STR; + } + } + + $site_firehose = ((intval(get_config('system','site_firehose',0))) ? true : false); + $net_firehose = ((get_config('system','disable_discover_tab',1)) ? false : true); + + if(! ($site_firehose || $net_firehose)) { + return EMPTY_STR; + } + + if($net_firehose) { + $site_firehose = false; + } + + $safemode = get_xconfig(get_observer_hash(),'directory','safemode',1); + + + + $limit = ((array_key_exists('limit', $arr)) ? intval($arr['limit']) : 75); + + return pubtagblock($net_firehose,$site_firehose, $limit, $trending, $safemode); + + return ''; + } +} diff --git a/Zotlabs/Widget/Settings_menu.php b/Zotlabs/Widget/Settings_menu.php index 455fdcb9b..9574becc3 100644 --- a/Zotlabs/Widget/Settings_menu.php +++ b/Zotlabs/Widget/Settings_menu.php @@ -81,12 +81,20 @@ class Settings_menu { if(feature_enabled(local_channel(),'oauth_clients')) { $tabs[] = array( - 'label' => t('Connected apps'), + 'label' => t('OAuth1 apps'), 'url' => z_root() . '/settings/oauth', 'selected' => ((argv(1) === 'oauth') ? 'active' : ''), ); } + if(feature_enabled(local_channel(),'oauth2_clients')) { + $tabs[] = array( + 'label' => t('OAuth2 apps'), + 'url' => z_root() . '/settings/oauth2', + 'selected' => ((argv(1) === 'oauth2') ? 'active' : ''), + ); + } + if(feature_enabled(local_channel(),'access_tokens')) { $tabs[] = array( 'label' => t('Guest Access Tokens'), diff --git a/Zotlabs/Widget/Tagcloud.php b/Zotlabs/Widget/Tagcloud.php index cf7a4932e..f79bd59ad 100644 --- a/Zotlabs/Widget/Tagcloud.php +++ b/Zotlabs/Widget/Tagcloud.php @@ -2,9 +2,6 @@ namespace Zotlabs\Widget; -// @FIXME The problem with this widget is that we don't have a search function for webpages -// that we can send the links to. Then we should also provide an option to search webpages -// and conversations. class Tagcloud { @@ -14,15 +11,15 @@ class Tagcloud { $uid = \App::$profile_uid; $count = ((x($args,'count')) ? intval($args['count']) : 24); $flags = 0; - $type = TERM_CATEGORY; + $type = TERM_HASHTAG; // @FIXME there exists no $authors variable - $r = tagadelic($uid, $count, $authors, $owner, $flags, ITEM_TYPE_WEBPAGE, $type); + $r = tagadelic($uid, $count, $authors, $owner, $flags, 0, $type); // @FIXME this should use a template if($r) { - $o = '<div class="tagblock widget"><h3>' . t('Categories') . '</h3><div class="tags" align="center">'; + $o = '<div class="tagblock widget"><h3>' . t('Tags') . '</h3><div class="tags" align="center">'; foreach($r as $rv) { $o .= '<span class="tag' . $rv[2] . '">' . $rv[0] .' </span> ' . "\r\n"; } |