From 9402f537b62e80939d09ad602f96460e8ab66b1c Mon Sep 17 00:00:00 2001 From: "M.Dent" Date: Sun, 12 Aug 2018 19:02:11 -0400 Subject: [PATCH 01/14] Fix root not added to internationalized template search --- Zotlabs/Render/SmartyTemplate.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Zotlabs/Render/SmartyTemplate.php b/Zotlabs/Render/SmartyTemplate.php index ffe58e286..f14d63064 100755 --- a/Zotlabs/Render/SmartyTemplate.php +++ b/Zotlabs/Render/SmartyTemplate.php @@ -64,17 +64,20 @@ class SmartyTemplate implements TemplateEngine { public function get_intltext_template($file, $root='') { $lang = \App::$language; - - if(file_exists("view/$lang/$file")) - $template_file = "view/$lang/$file"; - elseif(file_exists("view/en/$file")) - $template_file = "view/en/$file"; - else - $template_file = theme_include($file,$root); + if ($root != '' && substr($root,-1) != '/' ) { + $root .= '/'; + } + foreach (Array( + $root."view/$lang/$file", + $root."view/en/$file", + '' + ) as $template_file) { + if (is_file($template_file)) { break; } + } + if ($template_file=='') {$template_file = theme_include($file,$root);} if($template_file) { $template = new SmartyInterface(); $template->filename = $template_file; - return $template; } return ""; From b436c4a94c86a7b346872b4c92f3c803b1582ed0 Mon Sep 17 00:00:00 2001 From: "M.Dent" Date: Sun, 12 Aug 2018 19:47:10 -0400 Subject: [PATCH 02/14] Add support for overriding the default template location and individual templates via .htconfig.php --- boot.php | 3 +++ include/plugin.php | 51 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/boot.php b/boot.php index fca184555..6816187cb 100755 --- a/boot.php +++ b/boot.php @@ -728,6 +728,9 @@ class App { private static $perms = null; // observer permissions private static $widgets = array(); // widgets for this page public static $config = array(); // config cache + public static $override_intltext_templates = array(); + public static $override_markup_templates = array(); + public static $override_templateroot = null; public static $session = null; public static $groups; diff --git a/include/plugin.php b/include/plugin.php index 13652c620..23cb2b5f6 100755 --- a/include/plugin.php +++ b/include/plugin.php @@ -959,9 +959,8 @@ function format_js_if_exists($source) { function theme_include($file, $root = '') { // Make sure $root ends with a slash / if it's not blank - if($root !== '' && $root[strlen($root)-1] !== '/') + if($root !== '' && substr($root,-1) !== '/') $root = $root . '/'; - $theme_info = App::$theme_info; if(array_key_exists('extends',$theme_info)) @@ -992,21 +991,51 @@ function theme_include($file, $root = '') { return ''; } - function get_intltext_template($s, $root = '') { + $testroot = ($root=='') ? $testroot = "ROOT" : $root; + $t = App::template_engine(); - $t = App::template_engine(); - - $template = $t->get_intltext_template($s, $root); - return $template; + if (isset(\App::$override_intltext_templates[$testroot][$s]["content"])) { + return \App::$override_intltext_templates[$testroot][$s]["content"]; + } else { + if (isset(\App::$override_intltext_templates[$testroot][$s]["root"]) && + isset(\App::$override_intltext_templates[$testroot][$s]["file"])) { + $s = \App::$override_intltext_templates[$testroot][$s]["file"]; + $root = \App::$override_intltext_templates[$testroot][$s]["root"]; + } elseif (\App::$override_templateroot) { + $newroot = \App::$override_templateroot.$root; + if ($newroot != '' && substr($newroot,-1) != '/' ) { + $newroot .= '/'; + } + $template = $t->get_intltext_template($s, $newroot); + } + $template = $t->get_intltext_template($s, $root); + return $template; + } } - function get_markup_template($s, $root = '') { + $testroot = ($root=='') ? $testroot = "ROOT" : $root; - $t = App::template_engine(); - $template = $t->get_markup_template($s, $root); - return $template; + $t = App::template_engine(); + + if (isset(\App::$override_markup_templates[$testroot][$s]["content"])) { + return \App::$override_markup_templates[$testroot][$s]["content"]; + } else { + if (isset(\App::$override_markup_templates[$testroot][$s]["root"]) && + isset(\App::$override_markup_templates[$testroot][$s]["file"])) { + $s = \App::$override_markup_templates[$testroot][$s]["file"]; + $root = \App::$override_markup_templates[$testroot][$s]["root"]; + } elseif (\App::$override_templateroot) { + $newroot = \App::$override_templateroot.$root; + if ($newroot != '' && substr($newroot,-1) != '/' ) { + $newroot .= '/'; + } + $template = $t->get_markup_template($s, $newroot); + } + $template = $t->get_markup_template($s, $root); + return $template; + } } /** From f15c1c4e54a49d1e76747ca5e3034ca2cef909aa Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 13 Aug 2018 21:18:20 -0700 Subject: [PATCH 03/14] hubloc DB changes needed for z6 --- Zotlabs/Update/_1218.php | 31 +++++++++++++++++++++++++++++++ boot.php | 2 +- include/hubloc.php | 2 ++ install/schema_mysql.sql | 6 +++++- install/schema_postgres.sql | 5 +++++ 5 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 Zotlabs/Update/_1218.php diff --git a/Zotlabs/Update/_1218.php b/Zotlabs/Update/_1218.php new file mode 100644 index 000000000..67d8b49a5 --- /dev/null +++ b/Zotlabs/Update/_1218.php @@ -0,0 +1,31 @@ + ((array_key_exists('hubloc_status',$arr)) ? $arr['hubloc_status'] : 0), 'hubloc_url' => ((array_key_exists('hubloc_url',$arr)) ? $arr['hubloc_url'] : ''), 'hubloc_url_sig' => ((array_key_exists('hubloc_url_sig',$arr)) ? $arr['hubloc_url_sig'] : ''), + 'hubloc_id_url' => ((array_key_exists('hubloc_id_url',$arr)) ? $arr['hubloc_id_url'] : ''), + 'hubloc_site_id' => ((array_key_exists('hubloc_site_id',$arr)) ? $arr['hubloc_site_id'] : ''), 'hubloc_host' => ((array_key_exists('hubloc_host',$arr)) ? $arr['hubloc_host'] : ''), 'hubloc_callback' => ((array_key_exists('hubloc_callback',$arr)) ? $arr['hubloc_callback'] : ''), 'hubloc_connect' => ((array_key_exists('hubloc_connect',$arr)) ? $arr['hubloc_connect'] : ''), diff --git a/install/schema_mysql.sql b/install/schema_mysql.sql index b556b15cd..7fd2cfea8 100644 --- a/install/schema_mysql.sql +++ b/install/schema_mysql.sql @@ -501,10 +501,12 @@ CREATE TABLE IF NOT EXISTS `hook` ( KEY `hook_version` (`hook_version`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + CREATE TABLE IF NOT EXISTS `hubloc` ( `hubloc_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `hubloc_guid` char(191) NOT NULL DEFAULT '', `hubloc_guid_sig` text NOT NULL, + `hubloc_id_url` char(191) NOT NULL DEFAULT '0', `hubloc_hash` char(191) NOT NULL DEFAULT '', `hubloc_addr` char(191) NOT NULL DEFAULT '', `hubloc_network` char(32) NOT NULL DEFAULT '', @@ -512,6 +514,7 @@ CREATE TABLE IF NOT EXISTS `hubloc` ( `hubloc_status` int(10) unsigned NOT NULL DEFAULT 0 , `hubloc_url` char(191) NOT NULL DEFAULT '', `hubloc_url_sig` text NOT NULL, + `hubloc_site_id` char(191) NOT NULL DEFAULT '', `hubloc_host` char(191) NOT NULL DEFAULT '', `hubloc_callback` char(191) NOT NULL DEFAULT '', `hubloc_connect` char(191) NOT NULL DEFAULT '', @@ -524,7 +527,9 @@ CREATE TABLE IF NOT EXISTS `hubloc` ( `hubloc_deleted` tinyint(1) NOT NULL DEFAULT 0 , PRIMARY KEY (`hubloc_id`), KEY `hubloc_url` (`hubloc_url`), + KEY `hubloc_site_id` (`hubloc_site_id`), KEY `hubloc_guid` (`hubloc_guid`), + KEY `hubloc_id_url` (`hubloc_id_url`), KEY `hubloc_hash` (`hubloc_hash`), KEY `hubloc_flags` (`hubloc_flags`), KEY `hubloc_connect` (`hubloc_connect`), @@ -540,7 +545,6 @@ CREATE TABLE IF NOT EXISTS `hubloc` ( KEY `hubloc_error` (`hubloc_error`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; - CREATE TABLE IF NOT EXISTS `iconfig` ( `id` int(11) NOT NULL AUTO_INCREMENT, `iid` int(11) NOT NULL DEFAULT 0 , diff --git a/install/schema_postgres.sql b/install/schema_postgres.sql index 8db0eb8be..68c65c830 100644 --- a/install/schema_postgres.sql +++ b/install/schema_postgres.sql @@ -474,10 +474,12 @@ create index "hook_idx" on hook ("hook"); create index "hook_version_idx" on hook ("hook_version"); create index "hook_priority_idx" on hook ("priority"); + CREATE TABLE "hubloc" ( "hubloc_id" serial NOT NULL, "hubloc_guid" text NOT NULL DEFAULT '', "hubloc_guid_sig" text NOT NULL DEFAULT '', + "hubloc_id_url" text NOT NULL DEFAULT '', "hubloc_hash" text NOT NULL, "hubloc_addr" text NOT NULL DEFAULT '', "hubloc_network" text NOT NULL DEFAULT '', @@ -485,6 +487,7 @@ CREATE TABLE "hubloc" ( "hubloc_status" bigint NOT NULL DEFAULT '0', "hubloc_url" text NOT NULL DEFAULT '', "hubloc_url_sig" text NOT NULL DEFAULT '', + "hubloc_site_id" text NOT NULL DEFAULT '', "hubloc_host" text NOT NULL DEFAULT '', "hubloc_callback" text NOT NULL DEFAULT '', "hubloc_connect" text NOT NULL DEFAULT '', @@ -498,7 +501,9 @@ CREATE TABLE "hubloc" ( PRIMARY KEY ("hubloc_id") ); create index "hubloc_url" on hubloc ("hubloc_url"); +create index "hubloc_site_id" on hubloc ("hubloc_site_id"); create index "hubloc_guid" on hubloc ("hubloc_guid"); +create index "hubloc_id_url" on hubloc ("hubloc_id_url"); create index "hubloc_flags" on hubloc ("hubloc_flags"); create index "hubloc_connect" on hubloc ("hubloc_connect"); create index "hubloc_host" on hubloc ("hubloc_host"); From 12f4787b67561be8afc78620823b81e290cddfaa Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 13 Aug 2018 23:11:10 -0700 Subject: [PATCH 04/14] issue with mdpost addon and archive.org links which contain a full url as a path/query component --- Zotlabs/Module/Item.php | 2 +- include/bbcode.php | 2 ++ include/markdown.php | 4 ++-- include/text.php | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index ef1eb3700..640b4fa5c 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -533,7 +533,7 @@ class Item extends \Zotlabs\Web\Controller { // Look for tags and linkify them $results = linkify_tags($a, $body, ($uid) ? $uid : $profile_uid); -logger('linkify: ' . print_r($results,true)); + if($results) { // Set permissions based on tag replacements diff --git a/include/bbcode.php b/include/bbcode.php index 345b5b025..6f22509e6 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -953,12 +953,14 @@ function bbcode($Text, $options = []) { $Text = preg_replace_callback("/[^\^]\[url\]([$URLSearchString]*)\[\/url\]/ism", 'tryoembed', $Text); } } + if (strpos($Text,'[/url]') !== false) { $Text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '#^$1', $Text); $Text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '#^$2', $Text); $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '$1', $Text); $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$2', $Text); } + if (strpos($Text,'[/zrl]') !== false) { $Text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '#^$1', $Text); $Text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '#^$2', $Text); diff --git a/include/markdown.php b/include/markdown.php index 1b3538306..f4944e2cc 100644 --- a/include/markdown.php +++ b/include/markdown.php @@ -82,10 +82,10 @@ function markdown_to_bb($s, $use_zrl = false, $options = []) { $s = preg_replace_callback("/\[img\](.*?)\[\/img\]/ism", 'use_zrl_cb_img', $s); $s = preg_replace_callback("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", 'use_zrl_cb_img_x', $s); } - $s = preg_replace_callback("/([^\]\=\{]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", 'use_zrl_cb_link',$s); + $s = preg_replace_callback("/([^\]\=\{\/]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", 'use_zrl_cb_link',$s); } else { - $s = preg_replace("/([^\]\=\{]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", '$1[url=$2$3]$2$3[/url]',$s); + $s = preg_replace("/([^\]\=\{\/]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", '$1[url=$2$3]$2$3[/url]',$s); } // remove duplicate adjacent code tags diff --git a/include/text.php b/include/text.php index e894c5ce5..e57450020 100644 --- a/include/text.php +++ b/include/text.php @@ -3251,17 +3251,17 @@ function cleanup_bbcode($body) { * First protect any url inside certain bbcode tags so we don't double link it. */ - $body = preg_replace_callback('/\[code(.*?)\[\/(code)\]/ism','\red_escape_codeblock',$body); $body = preg_replace_callback('/\[url(.*?)\[\/(url)\]/ism','\red_escape_codeblock',$body); $body = preg_replace_callback('/\[zrl(.*?)\[\/(zrl)\]/ism','\red_escape_codeblock',$body); - $body = preg_replace_callback("/([^\]\='".'"'."\/\{]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\ +\,\(\)]+)/ismu", '\nakedoembed', $body); + $body = preg_replace_callback("/([^\]\='".'"'."\/\{]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\ +\,\(\)]+)/ismu", '\red_zrl_callback', $body); + $body = preg_replace_callback('/\[\$b64zrl(.*?)\[\/(zrl)\]/ism','\red_unescape_codeblock',$body); $body = preg_replace_callback('/\[\$b64url(.*?)\[\/(url)\]/ism','\red_unescape_codeblock',$body); $body = preg_replace_callback('/\[\$b64code(.*?)\[\/(code)\]/ism','\red_unescape_codeblock',$body); From 94393d27c8f39cc409f60078af6241d9eab21fc2 Mon Sep 17 00:00:00 2001 From: "M. Dent" Date: Tue, 14 Aug 2018 13:03:26 +0200 Subject: [PATCH 05/14] Override helpfiles --- boot.php | 2 + include/help.php | 99 +++++++++++++++++++++++++++++------------------- 2 files changed, 63 insertions(+), 38 deletions(-) diff --git a/boot.php b/boot.php index 6816187cb..e3dbbec75 100755 --- a/boot.php +++ b/boot.php @@ -731,6 +731,8 @@ class App { public static $override_intltext_templates = array(); public static $override_markup_templates = array(); public static $override_templateroot = null; + public static $override_helproot = null; + public static $override_helpfiles = array(); public static $session = null; public static $groups; diff --git a/include/help.php b/include/help.php index ce389b4db..3b56a7238 100644 --- a/include/help.php +++ b/include/help.php @@ -2,6 +2,50 @@ use \Michelf\MarkdownExtra; + +/** + * @brief + * + * @param string $path + * @return string|unknown + */ +function get_help_fullpath($path,$suffix=null) { + + $docroot = (\App::$override_helproot) ? \App::$override_helproot : 'doc/'; + $docroot = (substr($docroot,-1)!='/') ? $docroot .= '/' : $docroot; + + // Determine the language and modify the path accordingly + $x = determine_help_language(); + $lang = $x['language']; + $url_idx = ($x['from_url'] ? 1 : 0); + // The English translation is at the root of /doc/. Other languages are in + // subfolders named by the language code such as "de", "es", etc. + if($lang !== 'en') { + $langpath = $lang . '/' . $path; + } else { + $langpath = $path; + } + + $newpath = (isset(\App::$override_helpfiles[$langpath])) ? \App::$override_helpfiles[$langpath] : $langpath; + $newpath = ($newpath == $langpath) ? $docroot . $newpath : $newpath; + + if ($suffix) { + if (file_exists($newpath . $suffix)) { + return $newpath; + } + } elseif (file_exists($newpath . '.md') || + file_exists($newpath . '.bb') || + file_exists($newpath . '.html')) { + return $newpath; + } + + $newpath = (isset(\App::$override_helpfiles[$path])) ? \App::$override_helpfiles[$path] : null; + + $newpath = (!$newpath) ? $docroot.$path : $newpath; + return $newpath; +} + + /** * @brief * @@ -9,7 +53,6 @@ use \Michelf\MarkdownExtra; * @return string|unknown */ function get_help_content($tocpath = false) { - global $lang; $doctype = 'markdown'; @@ -17,6 +60,8 @@ function get_help_content($tocpath = false) { $text = ''; $path = (($tocpath !== false) ? $tocpath : ''); + $docroot = (\App::$override_helproot) ? \App::$override_helproot : 'doc/'; + $docroot = (substr($docroot,-1)!='/') ? $docroot .= '/' : $docroot; if($tocpath === false && argc() > 1) { $path = ''; @@ -27,8 +72,9 @@ function get_help_content($tocpath = false) { } } - if($path) { + if($path) { + $fullpath = get_help_fullpath($path); $title = basename($path); if(! $tocpath) \App::$page['title'] = t('Help:') . ' ' . ucwords(str_replace('-',' ',notags($title))); @@ -39,21 +85,22 @@ function get_help_content($tocpath = false) { // TODO: This is incompatible with the hierarchical TOC construction // defined in /Zotlabs/Widget/Helpindex.php. if($tocpath !== false && - load_doc_file('doc/' . $path . '.md') === '' && - load_doc_file('doc/' . $path . '.bb') === '' && - load_doc_file('doc/' . $path . '.html') === '' + load_doc_file($fullpath . '.md') === '' && + load_doc_file($fullpath . '.bb') === '' && + load_doc_file($fullpath . '.html') === '' ) { $path = $title; } - $text = load_doc_file('doc/' . $path . '.md'); + $fullpath = get_help_fullpath($path); + $text = load_doc_file($fullpath . '.md'); if(! $text) { - $text = load_doc_file('doc/' . $path . '.bb'); + $text = load_doc_file($fullpath . '.bb'); if($text) $doctype = 'bbcode'; } if(! $text) { - $text = load_doc_file('doc/' . $path . '.html'); + $text = load_doc_file($fullpath . '.html'); if($text) $doctype = 'html'; } @@ -64,12 +111,16 @@ function get_help_content($tocpath = false) { if($tocpath === false) { if(! $text) { - $text = load_doc_file('doc/Site.md'); + $path = 'Site'; + $fullpath = get_help_fullpath($path,'.md'); + $text = load_doc_file($fullpath . '.md'); \App::$page['title'] = t('Help'); } if(! $text) { $doctype = 'bbcode'; - $text = load_doc_file('doc/main.bb'); + $path = 'main'; + $fullpath = get_help_fullpath($path,'.md'); + $text = load_doc_file($fullpath . '.bb'); goaway('/help/about/about'); \App::$page['title'] = t('Help'); } @@ -146,35 +197,7 @@ function determine_help_language() { } function load_doc_file($s) { - $path = 'doc'; - // Determine the language and modify the path accordingly - $x = determine_help_language(); - $lang = $x['language']; - $url_idx = ($x['from_url'] ? 1 : 0); - // The English translation is at the root of /doc/. Other languages are in - // subfolders named by the language code such as "de", "es", etc. - if($lang !== 'en') { - $path .= '/' . $lang; - } - $b = basename($s); - - for($i=1+$url_idx; $i Date: Tue, 14 Aug 2018 18:19:34 -0700 Subject: [PATCH 06/14] more backporting for zot6 --- include/channel.php | 3 +++ include/text.php | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/include/channel.php b/include/channel.php index 2d0231bba..82d500e83 100644 --- a/include/channel.php +++ b/include/channel.php @@ -2797,3 +2797,6 @@ function pchan_to_chan($pchan) { return $chan; } +function channel_url($channel) { + return (($channel) ? z_root() . '/channel/' . $channel['channel_address'] : z_root()); +} diff --git a/include/text.php b/include/text.php index e57450020..c4f253a27 100644 --- a/include/text.php +++ b/include/text.php @@ -3412,3 +3412,41 @@ function get_forum_channels($uid) { return $r; } + +function print_array($arr, $level = 0) { + + $o = EMPTY_STR; + $tabs = EMPTY_STR; + + if(is_array($arr)) { + for($x = 0; $x <= $level; $x ++) { + $tabs .= "\t"; + } + $o .= '[' . "\n"; + if(count($arr)) { + foreach($arr as $k => $v) { + if(is_array($v)) { + $o .= $tabs . '[' . $k . '] => ' . print_array($v, $level + 1) . "\n"; + } + else { + $o .= $tabs . '[' . $k . '] => ' . print_val($v) . ",\n"; + } + } + } + $o .= substr($tabs,0,-1) . ']' . (($level) ? ',' : ';' ). "\n"; + return $o; + } + +} + +function print_val($v) { + if(is_bool($v)) { + if($v) return 'true'; + return 'false'; + } + if(is_string($v)) { + return "'" . $v . "'"; + } + return $v; + +} From f230c07ba5ed71c0491c6fd109c0789d2cc341c1 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 15 Aug 2018 17:00:37 -0700 Subject: [PATCH 07/14] possible fixes for can_comment_on_post(), provide wiki_list on wiki sidebar --- Zotlabs/Lib/ThreadStream.php | 1 - Zotlabs/Widget/Wiki_list.php | 6 +++++- include/items.php | 40 ++++++++++++++++++++++++------------ view/pdl/mod_wiki.pdl | 1 + 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/Zotlabs/Lib/ThreadStream.php b/Zotlabs/Lib/ThreadStream.php index d0c964149..020e8729b 100644 --- a/Zotlabs/Lib/ThreadStream.php +++ b/Zotlabs/Lib/ThreadStream.php @@ -196,7 +196,6 @@ class ThreadStream { $item->set_commentable(false); } - require_once('include/channel.php'); $item->set_conversation($this); $this->threads[] = $item; diff --git a/Zotlabs/Widget/Wiki_list.php b/Zotlabs/Widget/Wiki_list.php index 62f32dbf0..c8d83cbe8 100644 --- a/Zotlabs/Widget/Wiki_list.php +++ b/Zotlabs/Widget/Wiki_list.php @@ -6,13 +6,17 @@ class Wiki_list { function widget($arr) { + if(argc() < 3) { + return; + } + $channel = channelx_by_n(\App::$profile_uid); $wikis = \Zotlabs\Lib\NativeWiki::listwikis($channel,get_observer_hash()); if($wikis) { return replace_macros(get_markup_template('wikilist_widget.tpl'), array( - '$header' => t('Wiki List'), + '$header' => t('Wikis'), '$channel' => $channel['channel_address'], '$wikis' => $wikis['wikis'] )); diff --git a/include/items.php b/include/items.php index 9dd5d005b..ee7bfd5bc 100755 --- a/include/items.php +++ b/include/items.php @@ -234,10 +234,11 @@ function can_comment_on_post($observer_xchan, $item) { // logger('Comment_policy: ' . $item['comment_policy'], LOGGER_DEBUG); $x = [ - 'observer_hash' => $observer_xchan, - 'item' => $item, - 'allowed' => 'unset' + 'observer_hash' => $observer_xchan, + 'item' => $item, + 'allowed' => 'unset' ]; + /** * @hooks can_comment_on_post * Called when deciding whether or not to present a comment box for a post. @@ -245,26 +246,34 @@ function can_comment_on_post($observer_xchan, $item) { * * \e array \b item * * \e boolean \b allowed - return value */ + call_hooks('can_comment_on_post', $x); - if($x['allowed'] !== 'unset') + + if($x['allowed'] !== 'unset') { return $x['allowed']; + } - if(! $observer_xchan) + if(! $observer_xchan) { return false; + } - if($item['comment_policy'] === 'none') + if($item['comment_policy'] === 'none') { return false; + } - if(comments_are_now_closed($item)) + if(comments_are_now_closed($item)) { return false; + } - if($observer_xchan === $item['author_xchan'] || $observer_xchan === $item['owner_xchan']) + if($observer_xchan === $item['author_xchan'] || $observer_xchan === $item['owner_xchan']) { return true; + } switch($item['comment_policy']) { case 'self': - if($observer_xchan === $item['author_xchan'] || $observer_xchan === $item['owner_xchan']) + if($observer_xchan === $item['author_xchan'] || $observer_xchan === $item['owner_xchan']) { return true; + } break; case 'public': case 'authenticated': @@ -276,17 +285,22 @@ function can_comment_on_post($observer_xchan, $item) { case 'any connections': case 'contacts': case '': - if(array_key_exists('owner',$item) && get_abconfig($item['uid'],$item['owner']['abook_xchan'],'their_perms','post_comments')) { - return true; + if(local_channel() && get_abconfig(local_channel(),$item['owner_xchan'],'their_perms','post_comments')) { + return true; + } + if(intval($item['item_wall']) && perm_is_allowed($item['uid'],$observer_xchan,'post_comments')) { + return true; } break; default: break; } - if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'red')) + if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'red')) { return true; - if(strstr($item['comment_policy'],'site:') && strstr($item['comment_policy'],App::get_hostname())) + } + if(strstr($item['comment_policy'],'site:') && strstr($item['comment_policy'],App::get_hostname())) { return true; + } return false; } diff --git a/view/pdl/mod_wiki.pdl b/view/pdl/mod_wiki.pdl index be86be7e3..2e99ea36b 100644 --- a/view/pdl/mod_wiki.pdl +++ b/view/pdl/mod_wiki.pdl @@ -1,5 +1,6 @@ [region=aside] [widget=vcard][/widget] +[widget=wiki_list][/widget] [widget=wiki_pages][/widget] [/region] [region=right_aside] From 32acb0ff01b8fde3801fafbd7953aa36b5933f96 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 15 Aug 2018 21:33:11 -0700 Subject: [PATCH 08/14] missing files --- Zotlabs/Module/Zot_probe.php | 47 ++++ Zotlabs/Zot6/HTTPSig.php | 507 +++++++++++++++++++++++++++++++++++ 2 files changed, 554 insertions(+) create mode 100644 Zotlabs/Module/Zot_probe.php create mode 100644 Zotlabs/Zot6/HTTPSig.php diff --git a/Zotlabs/Module/Zot_probe.php b/Zotlabs/Module/Zot_probe.php new file mode 100644 index 000000000..d0c7e688f --- /dev/null +++ b/Zotlabs/Module/Zot_probe.php @@ -0,0 +1,47 @@ +Zot6 Probe Diagnostic'; + + $o .= '
'; + $o .= 'Lookup URI:
'; + $o .= '
'; + + $o .= '

'; + + if(x($_GET,'addr')) { + $addr = $_GET['addr']; + + + $x = Zotfinger::exec($addr); + + $o .= '
' . htmlspecialchars(print_array($x)) . '
'; + + $headers = 'Accept: application/x-zot+json, application/jrd+json, application/json'; + + $redirects = 0; + $x = z_fetch_url($addr,true,$redirects, [ 'headers' => [ $headers ]]); + + if($x['success']) { + + $o .= '
' . htmlspecialchars($x['header']) . '
' . EOL; + + $o .= 'verify returns: ' . str_replace("\n",EOL,print_r(HTTPSig::verify($x),true)) . EOL; + + $o .= '
' . htmlspecialchars(json_encode(json_decode($x['body']),JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)) . '
' . EOL; + + } + + } + return $o; + } + +} diff --git a/Zotlabs/Zot6/HTTPSig.php b/Zotlabs/Zot6/HTTPSig.php new file mode 100644 index 000000000..a0f0d3500 --- /dev/null +++ b/Zotlabs/Zot6/HTTPSig.php @@ -0,0 +1,507 @@ +fetcharr(); + $body = $data['body']; + } + + else { + $headers = []; + $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))); + $headers[$field] = $v; + } + } + } + + //logger('SERVER: ' . print_r($_SERVER,true), LOGGER_ALL); + + //logger('headers: ' . print_r($headers,true), LOGGER_ALL); + + return $headers; + } + + + // See draft-cavage-http-signatures-10 + + static function verify($data,$key = '') { + + $body = $data; + $headers = null; + + $result = [ + 'signer' => '', + 'portable_id' => '', + 'header_signed' => false, + 'header_valid' => false, + 'content_signed' => false, + 'content_valid' => false + ]; + + + $headers = self::find_headers($data,$body); + + if(! $headers) + return $result; + + $sig_block = null; + + if(array_key_exists('signature',$headers)) { + $sig_block = self::parse_sigheader($headers['signature']); + } + elseif(array_key_exists('authorization',$headers)) { + $sig_block = self::parse_sigheader($headers['authorization']); + } + + if(! $sig_block) { + logger('no signature provided.', LOGGER_DEBUG); + return $result; + } + + // Warning: This log statement includes binary data + // logger('sig_block: ' . print_r($sig_block,true), LOGGER_DATA); + + $result['header_signed'] = true; + + $signed_headers = $sig_block['headers']; + if(! $signed_headers) + $signed_headers = [ 'date' ]; + + $signed_data = ''; + foreach($signed_headers as $h) { + if(array_key_exists($h,$headers)) { + $signed_data .= $h . ': ' . $headers[$h] . "\n"; + } + } + $signed_data = rtrim($signed_data,"\n"); + + $algorithm = null; + if($sig_block['algorithm'] === 'rsa-sha256') { + $algorithm = 'sha256'; + } + if($sig_block['algorithm'] === 'rsa-sha512') { + $algorithm = 'sha512'; + } + + if(! array_key_exists('keyId',$sig_block)) + return $result; + + $result['signer'] = $sig_block['keyId']; + + $key = self::get_key($key,$result['signer']); + + if(! ($key && $key['public_key'])) { + return $result; + } + + $x = rsa_verify($signed_data,$sig_block['signature'],$key['public_key'],$algorithm); + + logger('verified: ' . $x, LOGGER_DEBUG); + + if(! $x) + return $result; + + $result['portable_id'] = $key['portable_id']; + $result['header_valid'] = true; + + if(in_array('digest',$signed_headers)) { + $result['content_signed'] = true; + $digest = explode('=', $headers['digest'], 2); + if($digest[0] === 'SHA-256') + $hashalg = 'sha256'; + if($digest[0] === 'SHA-512') + $hashalg = 'sha512'; + + if(base64_encode(hash($hashalg,$body,true)) === $digest[1]) { + $result['content_valid'] = true; + } + + logger('Content_Valid: ' . (($result['content_valid']) ? 'true' : 'false')); + } + + return $result; + } + + static function get_key($key,$id) { + + if($key) { + if(function_exists($key)) { + return $key($id); + } + return [ 'public_key' => $key ]; + } + + $key = self::get_webfinger_key($id); + + if(! $key) { + $key = self::get_activitystreams_key($id); + } + + return $key; + + } + + + function convertKey($key) { + + if(strstr($key,'RSA ')) { + return rsatopem($key); + } + elseif(substr($key,0,5) === 'data:') { + return convert_salmon_key($key); + } + else { + return $key; + } + + } + + + /** + * @brief + * + * @param string $id + * @return boolean|string + * false if no pub key found, otherwise return the pub key + */ + + function get_activitystreams_key($id) { + + $x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_addr = '%s' or hubloc_id_url = '%s' limit 1", + dbesc(str_replace('acct:','',$id)), + dbesc($id) + ); + + if($x && $x[0]['xchan_pubkey']) { + return [ 'portable_id' => $x[0]['xchan_hash'], 'public_key' => $x[0]['xchan_pubkey'] , 'hubloc' => $x[0] ]; + } + + $r = ActivityStreams::fetch_property($id); + + if($r) { + if(array_key_exists('publicKey',$j) && array_key_exists('publicKeyPem',$j['publicKey']) && array_key_exists('id',$j['publicKey'])) { + if($j['publicKey']['id'] === $id || $j['id'] === $id) { + return [ 'public_key' => self::convertKey($j['publicKey']['publicKeyPem']), 'portable_id' => '', 'hubloc' => [] ]; + } + } + } + + return false; + } + + + function get_webfinger_key($id) { + + $x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_addr = '%s' or hubloc_id_url = '%s' limit 1", + dbesc(str_replace('acct:','',$id)), + dbesc($id) + ); + + if($x && $x[0]['xchan_pubkey']) { + return [ 'portable_id' => $x[0]['xchan_hash'], 'public_key' => $x[0]['xchan_pubkey'] , 'hubloc' => $x[0] ]; + } + + $wf = Webfinger::exec($id); + $key = [ 'portable_id' => '', 'public_key' => '', 'hubloc' => [] ]; + + if($wf) { + if(array_key_exists('properties',$wf) && array_key_exists('https://w3id.org/security/v1#publicKeyPem',$wf['properties'])) { + $key['public_key'] = self::convertKey($wf['properties']['https://w3id.org/security/v1#publicKeyPem']); + } + if(array_key_exists('links', $wf) && is_array($wf['links'])) { + foreach($wf['links'] as $l) { + if(! (is_array($l) && array_key_exists('rel',$l))) { + continue; + } + if($l['rel'] === 'magic-public-key' && array_key_exists('href',$l) && $key['public_key'] === EMPTY_STR) { + $key['public_key'] = self::convertKey($l['href']); + } + } + } + } + + return (($key['public_key']) ? $key : false); + } + + + function get_zotfinger_key($id) { + + $x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_addr = '%s' or hubloc_id_url = '%s' limit 1", + dbesc(str_replace('acct:','',$id)), + dbesc($id) + ); + if($x && $x[0]['xchan_pubkey']) { + return [ 'portable_id' => $x[0]['xchan_hash'], 'public_key' => $x[0]['xchan_pubkey'] , 'hubloc' => $x[0] ]; + } + + $wf = Webfinger::exec($id); + $key = [ 'portable_id' => '', 'public_key' => '', 'hubloc' => [] ]; + + if($wf) { + if(array_key_exists('properties',$wf) && array_key_exists('https://w3id.org/security/v1#publicKeyPem',$wf['properties'])) { + $key['public_key'] = self::convertKey($wf['properties']['https://w3id.org/security/v1#publicKeyPem']); + } + if(array_key_exists('links', $wf) && is_array($wf['links'])) { + foreach($wf['links'] as $l) { + if(! (is_array($l) && array_key_exists('rel',$l))) { + continue; + } + if($l['rel'] === 'http://purl.org/zot/protocol/6.0' && array_key_exists('href',$l) && $l['href'] !== EMPTY_STR) { + $z = \Zotlabs\Lib\Zotfinger::exec($l['href']); + if($z) { + $i = Zotlabs\Lib\Libzot::import_xchan($z['data']); + if($i['success']) { + $key['portable_id'] = $i['hash']; + + $x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s' limit 1", + dbesc($l['href']) + ); + if($x) { + $key['hubloc'] = $x[0]; + } + } + } + } + if($l['rel'] === 'magic-public-key' && array_key_exists('href',$l) && $key['public_key'] === EMPTY_STR) { + $key['public_key'] = self::convertKey($l['href']); + } + } + } + } + + return (($key['public_key']) ? $key : false); + } + + + /** + * @brief + * + * @param array $head + * @param string $prvkey + * @param string $keyid (optional, default '') + * @param boolean $auth (optional, default false) + * @param string $alg (optional, default 'sha256') + * @param array $encryption [ 'key', 'algorithm' ] or false + * @return array + */ + static function create_sig($head, $prvkey, $keyid = EMPTY_STR, $auth = false, $alg = 'sha256', $encryption = false ) { + + $return_headers = []; + + if($alg === 'sha256') { + $algorithm = 'rsa-sha256'; + } + if($alg === 'sha512') { + $algorithm = 'rsa-sha512'; + } + + $x = self::sign($head,$prvkey,$alg); + + $headerval = 'keyId="' . $keyid . '",algorithm="' . $algorithm . '",headers="' . $x['headers'] . '",signature="' . $x['signature'] . '"'; + + if($encryption) { + $x = crypto_encapsulate($headerval,$encryption['key'],$encryption['algorithm']); + if(is_array($x)) { + $headerval = 'iv="' . $x['iv'] . '",key="' . $x['key'] . '",alg="' . $x['alg'] . '",data="' . $x['data'] . '"'; + } + } + + if($auth) { + $sighead = 'Authorization: Signature ' . $headerval; + } + else { + $sighead = 'Signature: ' . $headerval; + } + + if($head) { + foreach($head as $k => $v) { + // strip the request-target virtual header from the output headers + if($k === '(request-target)') { + continue; + } + $return_headers[] = $k . ': ' . $v; + } + } + $return_headers[] = $sighead; + + return $return_headers; + } + + /** + * @brief set headers + * + * @param array $headers + * @return void + */ + + + static function set_headers($headers) { + if($headers && is_array($headers)) { + foreach($headers as $h) { + header($h); + } + } + } + + + /** + * @brief + * + * @param array $head + * @param string $prvkey + * @param string $alg (optional) default 'sha256' + * @return array + */ + + static function sign($head, $prvkey, $alg = 'sha256') { + + $ret = []; + + $headers = ''; + $fields = ''; + + if($head) { + foreach($head as $k => $v) { + $headers .= strtolower($k) . ': ' . trim($v) . "\n"; + if($fields) + $fields .= ' '; + + $fields .= strtolower($k); + } + // strip the trailing linefeed + $headers = rtrim($headers,"\n"); + } + + $sig = base64_encode(rsa_sign($headers,$prvkey,$alg)); + + $ret['headers'] = $fields; + $ret['signature'] = $sig; + + return $ret; + } + + /** + * @brief + * + * @param string $header + * @return array associate array with + * - \e string \b keyID + * - \e string \b algorithm + * - \e array \b headers + * - \e string \b signature + */ + + static function parse_sigheader($header) { + + $ret = []; + $matches = []; + + // if the header is encrypted, decrypt with (default) site private key and continue + + if(preg_match('/iv="(.*?)"/ism',$header,$matches)) + $header = self::decrypt_sigheader($header); + + if(preg_match('/keyId="(.*?)"/ism',$header,$matches)) + $ret['keyId'] = $matches[1]; + if(preg_match('/algorithm="(.*?)"/ism',$header,$matches)) + $ret['algorithm'] = $matches[1]; + if(preg_match('/headers="(.*?)"/ism',$header,$matches)) + $ret['headers'] = explode(' ', $matches[1]); + if(preg_match('/signature="(.*?)"/ism',$header,$matches)) + $ret['signature'] = base64_decode(preg_replace('/\s+/','',$matches[1])); + + if(($ret['signature']) && ($ret['algorithm']) && (! $ret['headers'])) + $ret['headers'] = [ 'date' ]; + + return $ret; + } + + + /** + * @brief + * + * @param string $header + * @param string $prvkey (optional), if not set use site private key + * @return array|string associative array, empty string if failue + * - \e string \b iv + * - \e string \b key + * - \e string \b alg + * - \e string \b data + */ + + static function decrypt_sigheader($header, $prvkey = null) { + + $iv = $key = $alg = $data = null; + + if(! $prvkey) { + $prvkey = get_config('system', 'prvkey'); + } + + $matches = []; + + if(preg_match('/iv="(.*?)"/ism',$header,$matches)) + $iv = $matches[1]; + if(preg_match('/key="(.*?)"/ism',$header,$matches)) + $key = $matches[1]; + if(preg_match('/alg="(.*?)"/ism',$header,$matches)) + $alg = $matches[1]; + if(preg_match('/data="(.*?)"/ism',$header,$matches)) + $data = $matches[1]; + + if($iv && $key && $alg && $data) { + return crypto_unencapsulate([ 'encrypted' => true, 'iv' => $iv, 'key' => $key, 'alg' => $alg, 'data' => $data ] , $prvkey); + } + + return ''; + } + +} From e5529938ea029ac0f416f96fbdc481f66001d0eb Mon Sep 17 00:00:00 2001 From: zotlabs Date: Thu, 16 Aug 2018 12:35:57 -0700 Subject: [PATCH 09/14] Suppress duplicate info() messages. This was done long for notice(), but info() was overlooked at that time. --- boot.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/boot.php b/boot.php index 3bea050dd..955e616eb 100755 --- a/boot.php +++ b/boot.php @@ -1785,6 +1785,10 @@ function info($s) { return; if(! x($_SESSION, 'sysmsg_info')) $_SESSION['sysmsg_info'] = array(); + + if(in_array($s, $_SESSION['sysmsg_info'])) + return; + if(App::$interactive) $_SESSION['sysmsg_info'][] = $s; } From df26fec1b3eff35179543bfdbaf51b3124390fc1 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Fri, 17 Aug 2018 21:21:02 -0700 Subject: [PATCH 10/14] hubzilla core issue #1262 --- include/text.php | 1 + 1 file changed, 1 insertion(+) diff --git a/include/text.php b/include/text.php index c4f253a27..8a07dc113 100644 --- a/include/text.php +++ b/include/text.php @@ -2047,6 +2047,7 @@ function undo_post_tagging($s) { $cnt = preg_match_all('/([@#])(\!*)\[zrl=(.*?)\](.*?)\[\/zrl\]/ism',$s,$matches,PREG_SET_ORDER); if($cnt) { foreach($matches as $mtch) { + $x = false; if($mtch[1] === '@') { $x = q("select xchan_addr, xchan_url from xchan where xchan_url = '%s' limit 1", dbesc($mtch[3]) From d95735deaf321eb560b3fdc0b88d25bca4be3b48 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 20 Aug 2018 17:22:49 -0700 Subject: [PATCH 11/14] channel page performance improvement: don't use "checkjs" with an associated page reload. Wrap a static copy of the content in noscript tags instead. --- Zotlabs/Module/Channel.php | 88 +++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index b5e6b3aee..f1ae2f507 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -2,6 +2,8 @@ namespace Zotlabs\Module; +use \App; + require_once('include/contact_widgets.php'); require_once('include/items.php'); require_once("include/bbcode.php"); @@ -26,7 +28,7 @@ class Channel extends \Zotlabs\Web\Controller { $which = argv(1); if(! $which) { if(local_channel()) { - $channel = \App::get_channel(); + $channel = App::get_channel(); if($channel && $channel['channel_address']) $which = $channel['channel_address']; } @@ -37,7 +39,7 @@ class Channel extends \Zotlabs\Web\Controller { } $profile = 0; - $channel = \App::get_channel(); + $channel = App::get_channel(); if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { $which = $channel['channel_address']; @@ -70,8 +72,6 @@ class Channel extends \Zotlabs\Web\Controller { if($load) $_SESSION['loadtime'] = datetime_convert(); - $checkjs = new \Zotlabs\Web\CheckJS(1); - $category = $datequery = $datequery2 = ''; $mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : ''); @@ -95,22 +95,22 @@ class Channel extends \Zotlabs\Web\Controller { if($update) { // Ensure we've got a profile owner if updating. - \App::$profile['profile_uid'] = \App::$profile_uid = $update; + App::$profile['profile_uid'] = App::$profile_uid = $update; } - $is_owner = (((local_channel()) && (\App::$profile['profile_uid'] == local_channel())) ? true : false); + $is_owner = (((local_channel()) && (App::$profile['profile_uid'] == local_channel())) ? true : false); - $channel = \App::get_channel(); - $observer = \App::get_observer(); + $channel = App::get_channel(); + $observer = App::get_observer(); $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); - $perms = get_all_perms(\App::$profile['profile_uid'],$ob_hash); + $perms = get_all_perms(App::$profile['profile_uid'],$ob_hash); if(! $perms['view_stream']) { // We may want to make the target of this redirect configurable if($perms['view_profile']) { notice( t('Insufficient permissions. Request redirected to profile page.') . EOL); - goaway (z_root() . "/profile/" . \App::$profile['channel_address']); + goaway (z_root() . "/profile/" . App::$profile['channel_address']); } notice( t('Permission denied.') . EOL); return; @@ -121,7 +121,7 @@ class Channel extends \Zotlabs\Web\Controller { nav_set_selected('Channel Home'); - $static = channel_manual_conv_update(\App::$profile['profile_uid']); + $static = channel_manual_conv_update(App::$profile['profile_uid']); // search terms header if($search) { @@ -147,16 +147,16 @@ class Channel extends \Zotlabs\Web\Controller { $x = array( 'is_owner' => $is_owner, - 'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(\App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false), - 'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''), - 'nickname' => \App::$profile['channel_address'], - 'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'), + 'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false), + 'default_location' => (($is_owner) ? App::$profile['channel_location'] : ''), + 'nickname' => App::$profile['channel_address'], + 'lockstate' => (((strlen(App::$profile['channel_allow_cid'])) || (strlen(App::$profile['channel_allow_gid'])) || (strlen(App::$profile['channel_deny_cid'])) || (strlen(App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'), 'acl' => (($is_owner) ? populate_acl($channel_acl,true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''), 'permissions' => $channel_acl, 'showacl' => (($is_owner) ? 'yes' : ''), 'bang' => '', 'visitor' => (($is_owner || $observer) ? true : false), - 'profile_uid' => \App::$profile['profile_uid'], + 'profile_uid' => App::$profile['profile_uid'], 'editor_autocomplete' => true, 'bbco_autocomplete' => 'bbcode', 'bbcode' => true, @@ -176,14 +176,14 @@ class Channel extends \Zotlabs\Web\Controller { $item_normal = item_normal(); $item_normal_update = item_normal_update(); - $sql_extra = item_permissions_sql(\App::$profile['profile_uid']); + $sql_extra = item_permissions_sql(App::$profile['profile_uid']); - if(get_pconfig(\App::$profile['profile_uid'],'system','channel_list_mode') && (! $mid)) + if(get_pconfig(App::$profile['profile_uid'],'system','channel_list_mode') && (! $mid)) $page_mode = 'list'; else $page_mode = 'client'; - $abook_uids = " and abook.abook_channel = " . intval(\App::$profile['profile_uid']) . " "; + $abook_uids = " and abook.abook_channel = " . intval(App::$profile['profile_uid']) . " "; $simple_update = (($update) ? " AND item_unseen = 1 " : ''); @@ -203,7 +203,7 @@ class Channel extends \Zotlabs\Web\Controller { head_add_link([ 'rel' => 'alternate', 'type' => 'application/json+oembed', - 'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string), + 'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string), 'title' => 'oembed' ]); @@ -221,7 +221,7 @@ class Channel extends \Zotlabs\Web\Controller { $r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal_update AND item_wall = 1 $simple_update $sql_extra limit 1", dbesc($mid . '%'), - intval(\App::$profile['profile_uid']) + intval(App::$profile['profile_uid']) ); $_SESSION['loadtime'] = datetime_convert(); } @@ -233,7 +233,7 @@ class Channel extends \Zotlabs\Web\Controller { AND (abook.abook_blocked = 0 or abook.abook_flags is null) $sql_extra ORDER BY created DESC", - intval(\App::$profile['profile_uid']) + intval(App::$profile['profile_uid']) ); $_SESSION['loadtime'] = datetime_convert(); } @@ -242,10 +242,10 @@ class Channel extends \Zotlabs\Web\Controller { else { if(x($category)) { - $sql_extra2 .= protect_sprintf(term_item_parent_query(\App::$profile['profile_uid'],'item', $category, TERM_CATEGORY)); + $sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'],'item', $category, TERM_CATEGORY)); } if(x($hashtags)) { - $sql_extra2 .= protect_sprintf(term_item_parent_query(\App::$profile['profile_uid'],'item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG)); + $sql_extra2 .= protect_sprintf(term_item_parent_query(App::$profile['profile_uid'],'item', $hashtags, TERM_HASHTAG, TERM_COMMUNITYTAG)); } if($datequery) { @@ -267,15 +267,15 @@ class Channel 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'])); + App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20)); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); - if($load || ($checkjs->disabled())) { + if((! $update) || ($load)) { if($mid) { $r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal AND item_wall = 1 $sql_extra limit 1", dbesc($mid . '%'), - intval(\App::$profile['profile_uid']) + intval(App::$profile['profile_uid']) ); if (! $r) { notice( t('Permission denied.') . EOL); @@ -289,7 +289,7 @@ class Channel extends \Zotlabs\Web\Controller { AND item.item_wall = 1 AND item.item_thread_top = 1 $sql_extra $sql_extra2 ORDER BY $ordering DESC $pager_sql ", - intval(\App::$profile['profile_uid']) + intval(App::$profile['profile_uid']) ); } } @@ -306,7 +306,7 @@ class Channel extends \Zotlabs\Web\Controller { WHERE item.uid = %d $item_normal AND item.parent IN ( %s ) $sql_extra ", - intval(\App::$profile['profile_uid']), + intval(App::$profile['profile_uid']), dbesc($parents_str) ); @@ -329,19 +329,19 @@ class Channel extends \Zotlabs\Web\Controller { // This is ugly, but we can't pass the profile_uid through the session to the ajax updater, // because browser prefetching might change it on us. We have to deliver it with the page. - $maxheight = get_pconfig(\App::$profile['profile_uid'],'system','channel_divmore_height'); + $maxheight = get_pconfig(App::$profile['profile_uid'],'system','channel_divmore_height'); if(! $maxheight) $maxheight = 400; $o .= '
' . "\r\n"; - $o .= "\r\n"; - \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( + App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( '$baseurl' => z_root(), '$pgtype' => 'channel', - '$uid' => ((\App::$profile['profile_uid']) ? \App::$profile['profile_uid'] : '0'), + '$uid' => ((App::$profile['profile_uid']) ? App::$profile['profile_uid'] : '0'), '$gid' => '0', '$cid' => '0', '$cmin' => '(-1)', @@ -354,7 +354,7 @@ class Channel extends \Zotlabs\Web\Controller { '$wall' => '1', '$fh' => '0', '$static' => $static, - '$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1), + '$page' => ((App::$pager['page'] != 1) ? App::$pager['page'] : 1), '$search' => $search, '$xchan' => '', '$order' => $order, @@ -405,17 +405,19 @@ class Channel extends \Zotlabs\Web\Controller { $mode = (($search) ? 'search' : 'channel'); - if($checkjs->disabled()) { - $o .= conversation($items,$mode,$update,'traditional'); - } - else { + if($update) { $o .= conversation($items,$mode,$update,$page_mode); } - - if((! $update) || ($checkjs->disabled())) { + else { + $o .= ''; + $o .= conversation($items,$mode,$update,$page_mode); + if ($mid && $items[0]['title']) - \App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title']; + App::$page['title'] = $items[0]['title'] . " - " . App::$page['title']; + } if($mid) From a9bbfe9c4f0b783433ceb6c586022093e74aa718 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 20 Aug 2018 17:38:38 -0700 Subject: [PATCH 12/14] Only show cover photos once per login session. After that they can get annoying. If there is pushback on this, then it should perhaps be optional. --- Zotlabs/Widget/Cover_photo.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Zotlabs/Widget/Cover_photo.php b/Zotlabs/Widget/Cover_photo.php index d2eb1be92..af1ae5c7f 100644 --- a/Zotlabs/Widget/Cover_photo.php +++ b/Zotlabs/Widget/Cover_photo.php @@ -20,6 +20,16 @@ class Cover_photo { if(! $channel_id) return ''; + // only show cover photos once per login session + + if(array_key_exists('channels_visited',$_SESSION) && is_array($_SESSION['channels_visited']) && in_array($channel_id,$_SESSION['channels_visited'])) { + return EMPTY_STR; + } + if(! array_key_exists('channels_visited',$_SESSION)) { + $_SESSION['channels_visited'] = []; + } + $_SESSION['channels_visited'][] = $channel_id; + $channel = channelx_by_n($channel_id); if(array_key_exists('style', $arr) && isset($arr['style'])) From 9b620b2a35e256c905b6e3bd0e6f0228a0426e07 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 20 Aug 2018 20:07:54 -0700 Subject: [PATCH 13/14] remove checkjs reloader from mod_display also --- Zotlabs/Module/Display.php | 90 ++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php index fe0408c6f..bdaed0933 100644 --- a/Zotlabs/Module/Display.php +++ b/Zotlabs/Module/Display.php @@ -21,8 +21,6 @@ class Display extends \Zotlabs\Web\Controller { $module_format = 'html'; } - $checkjs = new \Zotlabs\Web\CheckJS(1); - if($load) $_SESSION['loadtime'] = datetime_convert(); @@ -253,53 +251,44 @@ class Display extends \Zotlabs\Web\Controller { $sql_extra = public_permissions_sql($observer_hash); - if(($update && $load) || ($checkjs->disabled()) || ($module_format !== 'html')) { + if((! $update) || ($load)) { - $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']),intval(\App::$pager['start'])); + $r = null; - if($load || ($checkjs->disabled()) || ($module_format !== 'html')) { + require_once('include/channel.php'); + $sys = get_sys_channel(); + $sysid = $sys['channel_id']; - $r = null; - - require_once('include/channel.php'); - $sys = get_sys_channel(); - $sysid = $sys['channel_id']; - - if(local_channel()) { - $r = q("SELECT item.id as item_id from item - WHERE uid = %d - and mid = '%s' - $item_normal - limit 1", - intval(local_channel()), - dbesc($target_item['parent_mid']) - ); - if($r) { - $updateable = true; - } + if(local_channel()) { + $r = q("SELECT item.id as item_id from item WHERE uid = %d and mid = '%s' $item_normal limit 1", + intval(local_channel()), + dbesc($target_item['parent_mid']) + ); + if($r) { + $updateable = true; } + } - if(! $r) { + if(! $r) { - // in case somebody turned off public access to sys channel content using permissions - // make that content unsearchable by ensuring the owner uid can't match + // in case somebody turned off public access to sys channel content using permissions + // make that content unsearchable by ensuring the owner uid can't match - if(! perm_is_allowed($sysid,$observer_hash,'view_stream')) - $sysid = 0; + if(! perm_is_allowed($sysid,$observer_hash,'view_stream')) + $sysid = 0; - $r = q("SELECT item.id as item_id from item - WHERE mid = '%s' - AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = '' - AND item.deny_gid = '' AND item_private = 0 ) - and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " )) - OR uid = %d ) - $sql_extra ) - $item_normal - limit 1", - dbesc($target_item['parent_mid']), - intval($sysid) - ); - } + $r = q("SELECT item.id as item_id from item + WHERE mid = '%s' + AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = '' + AND item.deny_gid = '' AND item_private = 0 ) + and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " )) + OR uid = %d ) + $sql_extra ) + $item_normal + limit 1", + dbesc($target_item['parent_mid']), + intval($sysid) + ); } } @@ -373,14 +362,19 @@ class Display extends \Zotlabs\Web\Controller { case 'html': - if ($checkjs->disabled()) { - $o .= conversation($items, 'display', $update, 'traditional'); - if ($items[0]['title']) - \App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title']; - } - else { + if ($update) { $o .= conversation($items, 'display', $update, 'client'); } + else { + $o .= ''; + + if ($items[0]['title']) + \App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title']; + + $o .= conversation($items, 'display', $update, 'client'); + } break; @@ -435,7 +429,7 @@ class Display extends \Zotlabs\Web\Controller { $o .= '
'; - if((($update && $load) || $checkjs->disabled()) && (! $items)) { + if(((! $update) || ($load)) && (! $items)) { $r = q("SELECT id, item_deleted FROM item WHERE mid = '%s' LIMIT 1", dbesc($item_hash) From 8bf1e3a9449b95307d6d991284dce1addade813a Mon Sep 17 00:00:00 2001 From: zotlabs Date: Mon, 20 Aug 2018 22:02:08 -0700 Subject: [PATCH 14/14] more code optimisation --- Zotlabs/Module/Channel.php | 14 ++++++++------ Zotlabs/Module/Network.php | 22 ++++++++++++---------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index f1ae2f507..9d4c23e4c 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -2,21 +2,23 @@ namespace Zotlabs\Module; -use \App; -require_once('include/contact_widgets.php'); +use App; +use Zotlabs\Web\Controller; +use Zotlabs\Lib\PermissionDescription; + 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 * */ -class Channel extends \Zotlabs\Web\Controller { + +class Channel extends Controller { function init() { @@ -151,7 +153,7 @@ class Channel extends \Zotlabs\Web\Controller { 'default_location' => (($is_owner) ? App::$profile['channel_location'] : ''), 'nickname' => App::$profile['channel_address'], 'lockstate' => (((strlen(App::$profile['channel_allow_cid'])) || (strlen(App::$profile['channel_allow_gid'])) || (strlen(App::$profile['channel_deny_cid'])) || (strlen(App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'), - 'acl' => (($is_owner) ? populate_acl($channel_acl,true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''), + 'acl' => (($is_owner) ? populate_acl($channel_acl,true, PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post') : ''), 'permissions' => $channel_acl, 'showacl' => (($is_owner) ? 'yes' : ''), 'bang' => '', diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index 77a08585b..ca0ec7844 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -1,6 +1,8 @@ \App::$query_string); + $arr = array('query' => App::$query_string); call_hooks('network_content_init', $arr); - $channel = \App::get_channel(); + $channel = App::get_channel(); $item_normal = item_normal(); $item_normal_update = item_normal_update(); @@ -326,10 +328,10 @@ class Network extends \Zotlabs\Web\Controller { $o .= '
' . "\r\n"; $o .= "\r\n"; - \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( + App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array( '$baseurl' => z_root(), '$pgtype' => 'network', '$uid' => ((local_channel()) ? local_channel() : '0'), @@ -346,7 +348,7 @@ class Network extends \Zotlabs\Web\Controller { '$wall' => '0', '$static' => $static, '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0), - '$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1), + '$page' => ((App::$pager['page'] != 1) ? App::$pager['page'] : 1), '$search' => (($search) ? $search : ''), '$xchan' => $xchan, '$order' => $order, @@ -417,8 +419,8 @@ class Network extends \Zotlabs\Web\Controller { } else { $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'])); + App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20)); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start'])); } // cmin and cmax are both -1 when the affinity tool is disabled