From 58a98a7934b807df33ee11fcc4267f24c0ed8ddc Mon Sep 17 00:00:00 2001 From: Satoshi Sahara Date: Tue, 23 Jun 2020 19:53:32 +0900 Subject: [PATCH 01/14] PSR-12 coding style --- conf/default.php | 4 +- conf/metadata.php | 2 +- syntax.php | 125 +++++++++++++++++++++++----------------------- 3 files changed, 66 insertions(+), 65 deletions(-) diff --git a/conf/default.php b/conf/default.php index 4ea93b8..048d230 100644 --- a/conf/default.php +++ b/conf/default.php @@ -4,10 +4,10 @@ * * @author Matthias Schulte */ -$conf['minimum_word_length'] = 2; // Minimum world length of words inside the cloud +$conf['minimum_word_length'] = 2; // Minimum word length of words inside the cloud $conf['search_blacklist'] = ''; // Specify search words which shouldn't appear on pages $conf['word_blacklist'] = ''; // Specify words which shouldn't appear on pages $conf['tag_blacklist'] = ''; // Specify tags which shouldn't appear on pages $conf['list_tags_of_subns'] = 0; // list also tags in subnamespaces of a specified namespace -//Setup VIM: ex: et ts=2 : +//Setup VIM: ex: et ts=4 enc=utf-8 : diff --git a/conf/metadata.php b/conf/metadata.php index ec69ee9..d29bf2f 100644 --- a/conf/metadata.php +++ b/conf/metadata.php @@ -12,4 +12,4 @@ $meta['tag_blacklist'] = array('string'); $meta['list_tags_of_subns'] = array('onoff'); -//Setup VIM: ex: et ts=2 : +//Setup VIM: ex: et ts=4 enc=utf-8 : diff --git a/syntax.php b/syntax.php index e5d9c9d..1985b87 100644 --- a/syntax.php +++ b/syntax.php @@ -1,20 +1,13 @@ */ -// must be run within Dokuwiki -if(!defined('DOKU_INC')) die(); - -if (!defined('DOKU_LF')) define('DOKU_LF', "\n"); -if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t"); -if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); - -require_once(DOKU_PLUGIN.'syntax.php'); - -class syntax_plugin_cloud extends DokuWiki_Syntax_Plugin { +class syntax_plugin_cloud extends DokuWiki_Syntax_Plugin +{ protected $knownFlags = array('showCount'); protected $stopwords = null; @@ -22,18 +15,26 @@ class syntax_plugin_cloud extends DokuWiki_Syntax_Plugin { * Constructor. Loads stopwords. */ public function __construct() { - $this->stopwords = $this->_getStopwords(); + $this->stopwords = $this->getStopwords(); } - function getType() { return 'substition'; } - function getPType() { return 'block'; } - function getSort() { return 98; } + public function getType() { return 'substition'; } + public function getPType() { return 'block'; } + public function getSort() { return 98; } - function connectTo($mode) { + /** + * Connect pattern to lexer + */ + public function connectTo($mode) + { $this->Lexer->addSpecialPattern('~~\w*?CLOUD.*?~~', $mode, 'plugin_cloud'); } - function handle($match, $state, $pos, Doku_Handler $handler) { + /** + * Handle the match + */ + public function handle($match, $state, $pos, Doku_Handler $handler) + { $match = substr($match, 2, -2); // strip markup if (substr($match, 0, 3) == 'TAG') { @@ -48,30 +49,33 @@ function handle($match, $state, $pos, Doku_Handler $handler) { list($junk, $num) = explode(':', $num, 2); $flags = null; if (preg_match ('/\[.*\]/', $junk, $flags) === 1) { - $flags = trim ($flags [0], '[]'); + $flags = trim ($flags[0], '[]'); $found = explode(',', $flags); $flags = array(); foreach ($found as $flag) { if (in_array($flag, $this->knownFlags)) { // Actually we just set flags as present // Later we might add values to flags like key=value pairs - $flags [$flag] = true; + $flags[$flag] = true; } } } if (!is_numeric($num)) $num = 50; - if(!is_null($ns)) $namespaces = explode('|', $ns); - else $namespaces = null; + $namespaces = is_null($ns) ? null : explode('|', $ns); return array($type, $num, $namespaces, $flags); } - function render($mode, Doku_Renderer $renderer, $data) { + /** + * Create output + */ + public function render($format, Doku_Renderer $renderer, $data) + { global $conf; list($type, $num, $namespaces, $flags) = $data; - if ($mode == 'xhtml') { + if ($format == 'xhtml') { if ($type == 'tag') { // we need the tag helper plugin /** @var helper_plugin_tag $tag */ @@ -79,13 +83,13 @@ function render($mode, Doku_Renderer $renderer, $data) { msg('The Tag Plugin must be installed to display tag clouds.', -1); return false; } - $cloud = $this->_getTagCloud($num, $min, $max, $namespaces, $tag); + $cloud = $this->getTagCloud($num, $min, $max, $namespaces, $tag); } elseif($type == 'search') { /** @var helper_plugin_searchstats $helper */ $helper = plugin_load('helper', 'searchstats'); - if($helper) { + if ($helper) { $cloud = $helper->getSearchWordArray($num); - $this->_filterCloud($cloud, 'search_blacklist'); + $this->filterCloud($cloud, 'search_blacklist'); // calculate min/max values $min = PHP_INT_MAX; $max = 0; @@ -98,10 +102,10 @@ function render($mode, Doku_Renderer $renderer, $data) { return false; } } else { - $cloud = $this->_getWordCloud($num, $min, $max); + $cloud = $this->getWordCloud($num, $min, $max); } if (!is_array($cloud) || empty($cloud)) return false; - $delta = ($max-$min)/16; + $delta = ($max - $min) / 16; // prevent caching to ensure the included pages are always fresh $renderer->info['cache'] = false; @@ -109,10 +113,10 @@ function render($mode, Doku_Renderer $renderer, $data) { // and render the cloud $renderer->doc .= '
'.DOKU_LF; foreach ($cloud as $word => $size) { - if ($size < $min+round($delta)) $class = 'cloud1'; - elseif ($size < $min+round(2*$delta)) $class = 'cloud2'; - elseif ($size < $min+round(4*$delta)) $class = 'cloud3'; - elseif ($size < $min+round(8*$delta)) $class = 'cloud4'; + if ($size < $min + round($delta)) $class = 'cloud1'; + elseif ($size < $min + round(2*$delta)) $class = 'cloud2'; + elseif ($size < $min + round(4*$delta)) $class = 'cloud3'; + elseif ($size < $min + round(8*$delta)) $class = 'cloud4'; else $class = 'cloud5'; $name = $word; @@ -120,13 +124,10 @@ function render($mode, Doku_Renderer $renderer, $data) { $id = $word; $exists = false; resolve_pageID($tag->namespace, $id, $exists); - if($exists) { + if ($exists) { $link = wl($id); - if($conf['useheading']) { - $name = p_get_first_heading($id, false); - if (empty($name)) { - $name = $word; - } + if ($conf['useheading']) { + $name = p_get_first_heading($id, false) ?: $word; } } else { $link = wl($id, array('do'=>'showtag', 'tag'=>$word)); @@ -134,7 +135,7 @@ function render($mode, Doku_Renderer $renderer, $data) { $title = $word; $class .= ($exists ? '_tag1' : '_tag2'); } else { - if($conf['userewrite'] == 2) { + if ($conf['userewrite'] == 2) { $link = wl($word, array('do'=>'search', 'id'=>$word)); $title = $size; } else { @@ -143,7 +144,7 @@ function render($mode, Doku_Renderer $renderer, $data) { } } - if ($flags ['showCount'] === true) { + if ($flags['showCount'] === true) { $name .= '('.$size.')'; } $renderer->doc .= DOKU_TAB . 'getConf('minimum_word_length'); foreach ($cloud as $key => $count) { if (iconv_strlen($key) < $min) @@ -195,8 +198,7 @@ function _filterCloud(&$cloud, $balcklistName) { } // Remove stopwords - if ($this->stopwords != null) - { + if ($this->stopwords != null) { foreach ($this->stopwords as $word) { if (isset($cloud[$word])) unset($cloud[$word]); @@ -205,7 +207,7 @@ function _filterCloud(&$cloud, $balcklistName) { // Remove word which are on the blacklist $blacklist = $this->getConf($balcklistName); - if(!empty($blacklist)) { + if (!empty($blacklist)) { $blacklist = explode(',', $blacklist); $blacklist = str_replace(' ', '', $blacklist); // remove spaces @@ -219,38 +221,35 @@ function _filterCloud(&$cloud, $balcklistName) { /** * Returns the sorted word cloud array */ - function _getWordCloud($num, &$min, &$max) { + protected function getWordCloud($num, &$min, &$max) + { global $conf; $cloud = array(); if (@file_exists($conf['indexdir'].'/page.idx')) { // new word-length based index - require_once(DOKU_INC.'inc/indexer.php'); - $lengths = idx_indexLengths(0); foreach ($lengths as $len) { $idx = idx_getIndex('i', $len); $word_idx = idx_getIndex('w', $len); - - $this->_addWordsToCloud($cloud, $idx, $word_idx); + $this->addWordsToCloud($cloud, $idx, $word_idx); } - } else { // old index $idx = file($conf['cachedir'].'/index.idx'); $word_idx = file($conf['cachedir'].'/word.idx'); - - $this->_addWordsToCloud($cloud, $idx, $word_idx); + $this->addWordsToCloud($cloud, $idx, $word_idx); } - $this->_filterCloud($cloud, 'word_blacklist'); + $this->filterCloud($cloud, 'word_blacklist'); - return $this->_sortCloud($cloud, $num, $min, $max); + return $this->sortCloud($cloud, $num, $min, $max); } /** * Adds all words in given index as $word => $freq to $cloud array */ - function _addWordsToCloud(&$cloud, $idx, $word_idx) { + protected function addWordsToCloud(&$cloud, $idx, $word_idx) + { $wcount = count($word_idx); // collect the frequency of the words @@ -265,19 +264,21 @@ function _addWordsToCloud(&$cloud, $idx, $word_idx) { /** * Returns the sorted tag cloud array */ - function _getTagCloud($num, &$min, &$max, $namespaces = NULL, helper_plugin_tag &$tag) { + protected function getTagCloud($num, &$min, &$max, $namespaces = NULL, helper_plugin_tag &$tag) + { $cloud = $tag->tagOccurrences(NULL, $namespaces, true, $this->getConf('list_tags_of_subns')); - $this->_filterCloud($cloud, 'tag_blacklist'); + $this->filterCloud($cloud, 'tag_blacklist'); - return $this->_sortCloud($cloud, $num, $min, $max); + return $this->sortCloud($cloud, $num, $min, $max); } /** * Sorts and slices the cloud */ - function _sortCloud($cloud, $num, &$min, &$max) { - if(empty($cloud)) return $cloud; + protected function sortCloud($cloud, $num, &$min, &$max) + { + if (empty($cloud)) return $cloud; // sort by frequency, then alphabetically arsort($cloud); @@ -289,4 +290,4 @@ function _sortCloud($cloud, $num, &$min, &$max) { return $cloud[0]; } } -// vim:ts=4:sw=4:et: +//Setup VIM: ex: et ts=4 enc=utf-8 : From d46e537db7cd47898c9ca04849a2d728f671ce4b Mon Sep 17 00:00:00 2001 From: Satoshi Sahara Date: Tue, 23 Jun 2020 20:22:40 +0900 Subject: [PATCH 02/14] refactor getStopwords() set class property stopwords when it is necessary instead of constructor. use idx_get_stopwords() --- syntax.php | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/syntax.php b/syntax.php index 1985b87..d2b5bca 100644 --- a/syntax.php +++ b/syntax.php @@ -11,13 +11,6 @@ class syntax_plugin_cloud extends DokuWiki_Syntax_Plugin protected $knownFlags = array('showCount'); protected $stopwords = null; - /** - * Constructor. Loads stopwords. - */ - public function __construct() { - $this->stopwords = $this->getStopwords(); - } - public function getType() { return 'substition'; } public function getPType() { return 'block'; } public function getSort() { return 98; } @@ -167,20 +160,20 @@ public function render($format, Doku_Renderer $renderer, $data) */ protected function getStopwords() { - // load stopwords - $swfile = DOKU_INC.'inc/lang/'.$conf['lang'].'/stopwords.txt'; - if (@file_exists($swfile)) $stopwords = file($swfile, FILE_IGNORE_NEW_LINES); - else $stopwords = array(); - - // load extra local stopwords - $swfile = DOKU_CONF.'stopwords.txt'; - if (@file_exists($swfile)) $stopwords = array_merge($stopwords, file($swfile, FILE_IGNORE_NEW_LINES)); - - if (count($stopwords) == 0) { - return null; + if ($this->stopwords === null) { + // load DokuWiki stopwords + $this->stopwords = idx_get_stopwords(); + + // load extra local stopwords + $swfile = DOKU_CONF.'stopwords.txt'; + if (file_exists($swfile)) { + $this->stopwords = array_merge( + $this->stopwords, + file($swfile, FILE_IGNORE_NEW_LINES) + ); + } } - - return $stopwords; + return $this->stopwords; } /** @@ -198,18 +191,16 @@ protected function filterCloud(&$cloud, $balcklistName) } // Remove stopwords - if ($this->stopwords != null) { - foreach ($this->stopwords as $word) { - if (isset($cloud[$word])) - unset($cloud[$word]); - } + foreach ($this->getStopwords() as $word) { + if (isset($cloud[$word])) + unset($cloud[$word]); } // Remove word which are on the blacklist $blacklist = $this->getConf($balcklistName); if (!empty($blacklist)) { $blacklist = explode(',', $blacklist); - $blacklist = str_replace(' ', '', $blacklist); // remove spaces + $blacklist = str_replace(' ', '', $blacklist); // remove spaces foreach ($blacklist as $word) { if (isset($cloud[$word])) From 93cd068dee95a1c2219b4b4c215fae00f55d635e Mon Sep 17 00:00:00 2001 From: Satoshi Sahara Date: Tue, 23 Jun 2020 20:50:19 +0900 Subject: [PATCH 03/14] create getSearchCloud() method --- syntax.php | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/syntax.php b/syntax.php index d2b5bca..eb8eb57 100644 --- a/syntax.php +++ b/syntax.php @@ -77,20 +77,9 @@ public function render($format, Doku_Renderer $renderer, $data) return false; } $cloud = $this->getTagCloud($num, $min, $max, $namespaces, $tag); - } elseif($type == 'search') { - /** @var helper_plugin_searchstats $helper */ - $helper = plugin_load('helper', 'searchstats'); - if ($helper) { - $cloud = $helper->getSearchWordArray($num); - $this->filterCloud($cloud, 'search_blacklist'); - // calculate min/max values - $min = PHP_INT_MAX; - $max = 0; - foreach ($cloud as $size) { - $min = min($size, $min); - $max = max($size, $max); - } - } else { + } elseif ($type == 'search') { + $cloud = $this->getSearchCloud($num, $min, $max); + if ($cloud === false) { msg('You have to install the searchstats plugin to use this feature.', -1); return false; } @@ -264,6 +253,32 @@ protected function getTagCloud($num, &$min, &$max, $namespaces = NULL, helper_pl return $this->sortCloud($cloud, $num, $min, $max); } + /** + * Returns the search cloud array + * + * @return array|false + */ + protected function getSearchCloud($num, &$min, &$max) + { + if (!plugin_isdisabled('searchstats')) { + /** @var helper_plugin_searchstats $helper */ + $helper = plugin_load('helper', 'searchstats'); + $cloud = $helper->getSearchWordArray($num); + $this->filterCloud($cloud, 'search_blacklist'); + } else { + return false; + } + + // calculate min/max values + $min = PHP_INT_MAX; + $max = 0; + foreach ($cloud as $size) { + $min = min($size, $min); + $max = max($size, $max); + } + return $cloud; + } + /** * Sorts and slices the cloud */ From f36fa3430e6affe58348d75a4df0a3c6fe732415 Mon Sep 17 00:00:00 2001 From: Satoshi Sahara Date: Tue, 23 Jun 2020 20:58:38 +0900 Subject: [PATCH 04/14] refactor getTagCloud() --- syntax.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/syntax.php b/syntax.php index eb8eb57..6869681 100644 --- a/syntax.php +++ b/syntax.php @@ -71,12 +71,11 @@ public function render($format, Doku_Renderer $renderer, $data) if ($format == 'xhtml') { if ($type == 'tag') { // we need the tag helper plugin - /** @var helper_plugin_tag $tag */ - if (plugin_isdisabled('tag') || (!$tag = plugin_load('helper', 'tag'))) { + $cloud = $this->getTagCloud($num, $min, $max, $namespaces); + if ($cloud === false) { msg('The Tag Plugin must be installed to display tag clouds.', -1); return false; } - $cloud = $this->getTagCloud($num, $min, $max, $namespaces, $tag); } elseif ($type == 'search') { $cloud = $this->getSearchCloud($num, $min, $max); if ($cloud === false) { @@ -102,7 +101,10 @@ public function render($format, Doku_Renderer $renderer, $data) else $class = 'cloud5'; $name = $word; - if ($type == 'tag' && isset($tag)) { + if ($type == 'tag') { + /** @var helper_plugin_tag $tag */ + $tag = plugin_load('helper', 'tag'); + $id = $word; $exists = false; resolve_pageID($tag->namespace, $id, $exists); @@ -244,12 +246,16 @@ protected function addWordsToCloud(&$cloud, $idx, $word_idx) /** * Returns the sorted tag cloud array */ - protected function getTagCloud($num, &$min, &$max, $namespaces = NULL, helper_plugin_tag &$tag) + protected function getTagCloud($num, &$min, &$max, $namespaces = null) { - $cloud = $tag->tagOccurrences(NULL, $namespaces, true, $this->getConf('list_tags_of_subns')); - - $this->filterCloud($cloud, 'tag_blacklist'); - + if (!plugin_isdisabled('tag')) { + /** @var helper_plugin_tag $tag */ + $tag = plugin_load('helper', 'tag'); + $cloud = $tag->tagOccurrences(null, $namespaces, true, $this->getConf('list_tags_of_subns')); + $this->filterCloud($cloud, 'tag_blacklist'); + } else { + return false; + } return $this->sortCloud($cloud, $num, $min, $max); } From 46516ea727f8cc9e1a0550a12c55ad25d0b2e403 Mon Sep 17 00:00:00 2001 From: Satoshi Sahara Date: Wed, 24 Jun 2020 00:01:13 +0900 Subject: [PATCH 05/14] rewite render() using switch statement --- syntax.php | 107 +++++++++++++++++++++++++++-------------------------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/syntax.php b/syntax.php index 6869681..f7734b5 100644 --- a/syntax.php +++ b/syntax.php @@ -67,77 +67,78 @@ public function render($format, Doku_Renderer $renderer, $data) { global $conf; - list($type, $num, $namespaces, $flags) = $data; - if ($format == 'xhtml') { + if (!in_array($format, ['xhtml'])) return false; - if ($type == 'tag') { // we need the tag helper plugin + list($type, $num, $namespaces, $flags) = $data; + switch ($type) { + case 'tag': // require tag plugin $cloud = $this->getTagCloud($num, $min, $max, $namespaces); if ($cloud === false) { msg('The Tag Plugin must be installed to display tag clouds.', -1); return false; } - } elseif ($type == 'search') { + break; + case 'search': // require searchstats plugin $cloud = $this->getSearchCloud($num, $min, $max); if ($cloud === false) { msg('You have to install the searchstats plugin to use this feature.', -1); return false; } - } else { + break; + default: $cloud = $this->getWordCloud($num, $min, $max); - } - if (!is_array($cloud) || empty($cloud)) return false; - $delta = ($max - $min) / 16; - - // prevent caching to ensure the included pages are always fresh - $renderer->info['cache'] = false; - - // and render the cloud - $renderer->doc .= '
'.DOKU_LF; - foreach ($cloud as $word => $size) { - if ($size < $min + round($delta)) $class = 'cloud1'; - elseif ($size < $min + round(2*$delta)) $class = 'cloud2'; - elseif ($size < $min + round(4*$delta)) $class = 'cloud3'; - elseif ($size < $min + round(8*$delta)) $class = 'cloud4'; - else $class = 'cloud5'; - - $name = $word; - if ($type == 'tag') { - /** @var helper_plugin_tag $tag */ - $tag = plugin_load('helper', 'tag'); - - $id = $word; - $exists = false; - resolve_pageID($tag->namespace, $id, $exists); - if ($exists) { - $link = wl($id); - if ($conf['useheading']) { - $name = p_get_first_heading($id, false) ?: $word; - } - } else { - $link = wl($id, array('do'=>'showtag', 'tag'=>$word)); + } + if (!is_array($cloud) || empty($cloud)) return false; + $delta = ($max - $min) / 16; + + // prevent caching to ensure the included pages are always fresh + $renderer->info['cache'] = false; + + // and render the cloud + $renderer->doc .= '' . DOKU_LF; - return true; + + if ($flags['showCount'] === true) { + $name .= '('.$size.')'; + } + $renderer->doc .= DOKU_TAB . '' . hsc($name) . '' . DOKU_LF; } - return false; + $renderer->doc .= '
' . DOKU_LF; + return true; } /** From 538b3d727211ae4739c99976cdfe3451f3192220 Mon Sep 17 00:00:00 2001 From: Satoshi Sahara Date: Wed, 24 Jun 2020 22:31:27 +0900 Subject: [PATCH 06/14] use FulltextIndex and Tokenizer class https://github.com/splitbrain/dokuwiki/pull/2943 --- syntax.php | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/syntax.php b/syntax.php index f7734b5..be94fe3 100644 --- a/syntax.php +++ b/syntax.php @@ -1,5 +1,8 @@ stopwords === null) { // load DokuWiki stopwords - $this->stopwords = idx_get_stopwords(); + if (is_callable('dokuwiki\Search\Tokenizer::getInstance')) { + $this->stopwords = Tokenizer::getInstance()->getStopwords(); + } else { + $this->stopwords = idx_get_stopwords(); + } // load extra local stopwords $swfile = DOKU_CONF.'stopwords.txt'; @@ -210,17 +217,17 @@ protected function getWordCloud($num, &$min, &$max) $cloud = array(); - if (@file_exists($conf['indexdir'].'/page.idx')) { // new word-length based index + if (is_callable('dokuwiki\Search\FulltextIndex::getInstance')) { + $FulltextIndex = FulltextIndex::getInstance(); + $lengths = $FulltextIndex->getIndexLengths(0); + $funcGetIndex = array($FulltextIndex, 'getIndex'); + } else { $lengths = idx_indexLengths(0); - foreach ($lengths as $len) { - $idx = idx_getIndex('i', $len); - $word_idx = idx_getIndex('w', $len); - $this->addWordsToCloud($cloud, $idx, $word_idx); - } - } else { // old index - $idx = file($conf['cachedir'].'/index.idx'); - $word_idx = file($conf['cachedir'].'/word.idx'); - $this->addWordsToCloud($cloud, $idx, $word_idx); + $funcGetIndex = 'idx_getIndex'; + } + + foreach ($lengths as $len) { + $this->addWordsToCloud($cloud, $funcGetIndex('i', $len), $funcGetIndex('w', $len)); } $this->filterCloud($cloud, 'word_blacklist'); From 7ca8a55423d1f950404f0153c086bd2be128f222 Mon Sep 17 00:00:00 2001 From: Satoshi Sahara Date: Fri, 26 Jun 2020 16:52:01 +0900 Subject: [PATCH 07/14] use loadHelper method instead of plugin_load function --- syntax.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/syntax.php b/syntax.php index be94fe3..b09a505 100644 --- a/syntax.php +++ b/syntax.php @@ -75,7 +75,7 @@ public function render($format, Doku_Renderer $renderer, $data) list($type, $num, $namespaces, $flags) = $data; switch ($type) { case 'tag': // require tag plugin - $cloud = $this->getTagCloud($num, $min, $max, $namespaces); + $cloud = $this->getTagCloud($num, $min, $max, $namespaces); if ($cloud === false) { msg('The Tag Plugin must be installed to display tag clouds.', -1); return false; @@ -109,7 +109,7 @@ public function render($format, Doku_Renderer $renderer, $data) $name = $word; if ($type == 'tag') { /** @var helper_plugin_tag $tag */ - isset($tag) || $tag = plugin_load('helper', 'tag'); + isset($tag) || $tag = $this->loadHelper('tag', true); $id = $word; $exists = false; @@ -258,7 +258,7 @@ protected function getTagCloud($num, &$min, &$max, $namespaces = null) { if (!plugin_isdisabled('tag')) { /** @var helper_plugin_tag $tag */ - $tag = plugin_load('helper', 'tag'); + $tag = $this->loadHelper('tag', true); $cloud = $tag->tagOccurrences(null, $namespaces, true, $this->getConf('list_tags_of_subns')); $this->filterCloud($cloud, 'tag_blacklist'); } else { @@ -276,7 +276,7 @@ protected function getSearchCloud($num, &$min, &$max) { if (!plugin_isdisabled('searchstats')) { /** @var helper_plugin_searchstats $helper */ - $helper = plugin_load('helper', 'searchstats'); + $helper = $this->loadHelper('searchstats', true); $cloud = $helper->getSearchWordArray($num); $this->filterCloud($cloud, 'search_blacklist'); } else { From 72505131168dc6dff0b47d582697f4db53768cfd Mon Sep 17 00:00:00 2001 From: Satoshi Sahara Date: Fri, 26 Jun 2020 16:59:22 +0900 Subject: [PATCH 08/14] use array_map to remove spaces from blacklist --- syntax.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/syntax.php b/syntax.php index b09a505..3383216 100644 --- a/syntax.php +++ b/syntax.php @@ -198,9 +198,7 @@ protected function filterCloud(&$cloud, $balcklistName) // Remove word which are on the blacklist $blacklist = $this->getConf($balcklistName); if (!empty($blacklist)) { - $blacklist = explode(',', $blacklist); - $blacklist = str_replace(' ', '', $blacklist); // remove spaces - + $blacklist = array_map('trim', explode(',', $blacklist)); foreach ($blacklist as $word) { if (isset($cloud[$word])) unset($cloud[$word]); From 255df11e6ba596992c60ca20775f7059d4af0b67 Mon Sep 17 00:00:00 2001 From: Satoshi Sahara Date: Fri, 26 Jun 2020 17:27:42 +0900 Subject: [PATCH 09/14] use dokuwiki\Utf8 class methods --- syntax.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/syntax.php b/syntax.php index 3383216..0206a76 100644 --- a/syntax.php +++ b/syntax.php @@ -2,6 +2,7 @@ use dokuwiki\Search\FulltextIndex; use dokuwiki\Search\Tokenizer; +use dokuwiki\Utf8; /** * Cloud Plugin: shows a cloud of the most frequently used words @@ -184,15 +185,19 @@ protected function filterCloud(&$cloud, $balcklistName) { // Remove short words $min = $this->getConf('minimum_word_length'); - foreach ($cloud as $key => $count) { - if (iconv_strlen($key) < $min) - unset($cloud[$key]); + if (is_callable('dokuwiki\Utf8\PhpString::strlen')) { + foreach ($cloud as $key => $count) { + if (Utf8\PhpString::strlen($key) < $min) unset($cloud[$key]); + } + } else { + foreach ($cloud as $key => $count) { + if (utf8_strlen($key) < $min) unset($cloud[$key]); + } } // Remove stopwords foreach ($this->getStopwords() as $word) { - if (isset($cloud[$word])) - unset($cloud[$word]); + if (isset($cloud[$word])) unset($cloud[$word]); } // Remove word which are on the blacklist @@ -200,8 +205,7 @@ protected function filterCloud(&$cloud, $balcklistName) if (!empty($blacklist)) { $blacklist = array_map('trim', explode(',', $blacklist)); foreach ($blacklist as $word) { - if (isset($cloud[$word])) - unset($cloud[$word]); + if (isset($cloud[$word])) unset($cloud[$word]); } } } From b44f62abf889964c6aec73a1c130f5f3dbe23679 Mon Sep 17 00:00:00 2001 From: Satoshi Sahara Date: Sat, 27 Jun 2020 09:58:20 +0900 Subject: [PATCH 10/14] better syntax handling --- syntax.php | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/syntax.php b/syntax.php index 0206a76..d7bd323 100644 --- a/syntax.php +++ b/syntax.php @@ -34,33 +34,31 @@ public function handle($match, $state, $pos, Doku_Handler $handler) { $match = substr($match, 2, -2); // strip markup - if (substr($match, 0, 3) == 'TAG') { + list($prefix, $params) = explode('CLOUD', $match, 2); + if ($prefix === '') { + $type = 'word'; + } elseif ($prefix === 'TAG') { $type = 'tag'; - } elseif (substr($match, 0, 6) == 'SEARCH') { + } elseif ($prefix === 'SEARCH') { $type = 'search'; } else { - $type = 'word'; + return false; } - list($num, $ns) = explode('>', $match, 2); - list($junk, $num) = explode(':', $num, 2); - $flags = null; - if (preg_match ('/\[.*\]/', $junk, $flags) === 1) { - $flags = trim ($flags[0], '[]'); - $found = explode(',', $flags); - $flags = array(); - foreach ($found as $flag) { - if (in_array($flag, $this->knownFlags)) { - // Actually we just set flags as present - // Later we might add values to flags like key=value pairs - $flags[$flag] = true; - } - } + list($params, $ns) = explode('>', $params, 2); + $namespaces = isset($ns) ? array_map('trim', explode('|', $ns)) : array(); + + list($options, $num) = explode(':', $params, 2); + $num = (isset($num) && is_numeric($num)) ? ($num + 0) : 50; + + $flags = array(); + $found = array_map('trim', explode(',', substr($options, 1, -1))); + foreach ($found as $flag) { + // Actually we just set flags as present + // Later we might add values to flags like key=value pairs + $flags[$flag] = true; } - if (!is_numeric($num)) $num = 50; - $namespaces = is_null($ns) ? null : explode('|', $ns); - return array($type, $num, $namespaces, $flags); } @@ -93,13 +91,13 @@ public function render($format, Doku_Renderer $renderer, $data) $cloud = $this->getWordCloud($num, $min, $max); } if (!is_array($cloud) || empty($cloud)) return false; - $delta = ($max - $min) / 16; // prevent caching to ensure the included pages are always fresh $renderer->info['cache'] = false; // and render the cloud $renderer->doc .= '
'.DOKU_LF; + $delta = ($max - $min) / 16; foreach ($cloud as $word => $size) { if ($size < $min + round($delta)) $class = 'cloud1'; elseif ($size < $min + round(2*$delta)) $class = 'cloud2'; @@ -135,13 +133,13 @@ public function render($format, Doku_Renderer $renderer, $data) } } - if ($flags['showCount'] === true) { + if (array_key_exists('showCount', $flags) && $flags['showCount'] === true) { $name .= '('.$size.')'; } $renderer->doc .= DOKU_TAB . '' . hsc($name) . '' . DOKU_LF; } - $renderer->doc .= '
' . DOKU_LF; + $renderer->doc .= '
'.DOKU_LF; return true; } From 71edd97995db5afaed61dfe4efe89d58cc421fa9 Mon Sep 17 00:00:00 2001 From: Gerrit Uitslag Date: Sun, 20 Aug 2023 23:21:50 +0200 Subject: [PATCH 11/14] remove unused, simplify --- syntax.php | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/syntax.php b/syntax.php index fa12349..28fecdb 100644 --- a/syntax.php +++ b/syntax.php @@ -1,8 +1,6 @@ stopwords === null) { // load DokuWiki stopwords if (is_callable('dokuwiki\Search\Tokenizer::getInstance')) { - $this->stopwords = Tokenizer::getInstance()->getStopwords(); + $this->stopwords = dokuwiki\Search\Tokenizer::getInstance()->getStopwords(); } else { $this->stopwords = idx_get_stopwords(); } @@ -226,12 +223,10 @@ protected function filterCloud(&$cloud, $balcklistName) */ protected function getWordCloud($num, &$min, &$max) { - global $conf; - $cloud = array(); if (is_callable('dokuwiki\Search\FulltextIndex::getInstance')) { - $FulltextIndex = FulltextIndex::getInstance(); + $FulltextIndex = dokuwiki\Search\FulltextIndex::getInstance(); $lengths = $FulltextIndex->getIndexLengths(0); $funcGetIndex = array($FulltextIndex, 'getIndex'); } else { From e3ac4e5dce31ecc288780d54f790b87d765bfed5 Mon Sep 17 00:00:00 2001 From: Gerrit Uitslag Date: Sun, 20 Aug 2023 23:27:31 +0200 Subject: [PATCH 12/14] code reformatting --- syntax.php | 74 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/syntax.php b/syntax.php index 28fecdb..1e602a1 100644 --- a/syntax.php +++ b/syntax.php @@ -13,9 +13,20 @@ class syntax_plugin_cloud extends DokuWiki_Syntax_Plugin { protected $stopwords = null; - public function getType() { return 'substition'; } - public function getPType() { return 'block'; } - public function getSort() { return 98; } + public function getType() + { + return 'substition'; + } + + public function getPType() + { + return 'block'; + } + + public function getSort() + { + return 98; + } /** * Connect pattern to lexer @@ -44,12 +55,12 @@ public function handle($match, $state, $pos, Doku_Handler $handler) } list($params, $ns) = explode('>', $params, 2); - $namespaces = isset($ns) ? array_map('trim', explode('|', $ns)) : array(); + $namespaces = isset($ns) ? array_map('trim', explode('|', $ns)) : []; list($options, $num) = explode(':', $params, 2); $num = (isset($num) && is_numeric($num)) ? ($num + 0) : 50; - $flags = array(); + $flags = []; $found = array_map('trim', explode(',', substr($options, 1, -1))); foreach ($found as $flag) { // Actually we just set flags as present @@ -57,7 +68,7 @@ public function handle($match, $state, $pos, Doku_Handler $handler) $flags[$flag] = true; } - return array($type, $num, $namespaces, $flags); + return [$type, $num, $namespaces, $flags]; } /** @@ -94,13 +105,13 @@ public function render($format, Doku_Renderer $renderer, $data) $renderer->nocache(); // and render the cloud - $renderer->doc .= '
'.DOKU_LF; + $renderer->doc .= '
' . DOKU_LF; $delta = ($max - $min) / 16; foreach ($cloud as $word => $size) { if ($size < $min + round($delta)) $class = 'cloud1'; - elseif ($size < $min + round(2*$delta)) $class = 'cloud2'; - elseif ($size < $min + round(4*$delta)) $class = 'cloud3'; - elseif ($size < $min + round(8*$delta)) $class = 'cloud4'; + elseif ($size < $min + round(2 * $delta)) $class = 'cloud2'; + elseif ($size < $min + round(4 * $delta)) $class = 'cloud3'; + elseif ($size < $min + round(8 * $delta)) $class = 'cloud4'; else $class = 'cloud5'; $name = $word; @@ -130,13 +141,13 @@ public function render($format, Doku_Renderer $renderer, $data) } } } else { - $link = wl($id, array('do'=>'showtag', 'tag'=>$word)); + $link = wl($id, ['do' => 'showtag', 'tag' => $word]); } $title = $word; $class .= ($exists ? '_tag1' : '_tag2'); } else { if ($conf['userewrite'] == 2) { - $link = wl($word, array('do'=>'search', 'id'=>$word)); + $link = wl($word, ['do' => 'search', 'id' => $word]); } else { $link = wl($word, 'do=search'); } @@ -144,12 +155,12 @@ public function render($format, Doku_Renderer $renderer, $data) } if (array_key_exists('showCount', $flags) && $flags['showCount'] === true) { - $name .= '('.$size.')'; + $name .= '(' . $size . ')'; } - $renderer->doc .= DOKU_TAB . '' . hsc($name) . '' . DOKU_LF; + $renderer->doc .= DOKU_TAB . '' . hsc($name) . '' . DOKU_LF; } - $renderer->doc .= '
'.DOKU_LF; + $renderer->doc .= '
' . DOKU_LF; return true; } @@ -173,11 +184,11 @@ protected function getStopwords() } // load extra local stopwords - $swfile = DOKU_CONF.'stopwords.txt'; + $swfile = DOKU_CONF . 'stopwords.txt'; if (file_exists($swfile)) { $this->stopwords = array_merge( - $this->stopwords, - file($swfile, FILE_IGNORE_NEW_LINES) + $this->stopwords, + file($swfile, FILE_IGNORE_NEW_LINES) ); } } @@ -195,17 +206,23 @@ protected function filterCloud(&$cloud, $balcklistName) $min = $this->getConf('minimum_word_length'); if (is_callable('dokuwiki\Utf8\PhpString::strlen')) { foreach ($cloud as $key => $count) { - if (Utf8\PhpString::strlen($key) < $min) unset($cloud[$key]); + if (Utf8\PhpString::strlen($key) < $min) { + unset($cloud[$key]); + } } } else { foreach ($cloud as $key => $count) { - if (utf8_strlen($key) < $min) unset($cloud[$key]); + if (utf8_strlen($key) < $min) { + unset($cloud[$key]); + } } } // Remove stopwords foreach ($this->getStopwords() as $word) { - if (isset($cloud[$word])) unset($cloud[$word]); + if (isset($cloud[$word])) { + unset($cloud[$word]); + } } // Remove word which are on the blacklist @@ -213,7 +230,9 @@ protected function filterCloud(&$cloud, $balcklistName) if (!empty($blacklist)) { $blacklist = array_map('trim', explode(',', $blacklist)); foreach ($blacklist as $word) { - if (isset($cloud[$word])) unset($cloud[$word]); + if (isset($cloud[$word])) { + unset($cloud[$word]); + } } } } @@ -223,12 +242,12 @@ protected function filterCloud(&$cloud, $balcklistName) */ protected function getWordCloud($num, &$min, &$max) { - $cloud = array(); + $cloud = []; if (is_callable('dokuwiki\Search\FulltextIndex::getInstance')) { $FulltextIndex = dokuwiki\Search\FulltextIndex::getInstance(); $lengths = $FulltextIndex->getIndexLengths(0); - $funcGetIndex = array($FulltextIndex, 'getIndex'); + $funcGetIndex = [$FulltextIndex, 'getIndex']; } else { $lengths = idx_indexLengths(0); $funcGetIndex = 'idx_getIndex'; @@ -306,7 +325,9 @@ protected function getSearchCloud($num, &$min, &$max) */ protected function sortCloud($cloud, $num, &$min, &$max) { - if (empty($cloud)) return $cloud; + if (empty($cloud)) { + return $cloud; + } // sort by frequency, then alphabetically arsort($cloud); @@ -318,4 +339,3 @@ protected function sortCloud($cloud, $num, &$min, &$max) return $cloud[0]; } } -//Setup VIM: ex: et ts=4 enc=utf-8 : From a59cdf70ebffabfc6101608150da0d506d2b9cb3 Mon Sep 17 00:00:00 2001 From: Gerrit Uitslag Date: Mon, 21 Aug 2023 21:11:35 +0200 Subject: [PATCH 13/14] phpdocs, use Sort, typo --- syntax.php | 52 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/syntax.php b/syntax.php index 1e602a1..44b9e0b 100644 --- a/syntax.php +++ b/syntax.php @@ -2,6 +2,7 @@ use dokuwiki\File\PageResolver; use dokuwiki\Utf8; +use dokuwiki\Utf8\Sort; /** * Cloud Plugin: shows a cloud of the most frequently used words @@ -105,7 +106,7 @@ public function render($format, Doku_Renderer $renderer, $data) $renderer->nocache(); // and render the cloud - $renderer->doc .= '
' . DOKU_LF; + $renderer->doc .= '
'; $delta = ($max - $min) / 16; foreach ($cloud as $word => $size) { if ($size < $min + round($delta)) $class = 'cloud1'; @@ -157,10 +158,10 @@ public function render($format, Doku_Renderer $renderer, $data) if (array_key_exists('showCount', $flags) && $flags['showCount'] === true) { $name .= '(' . $size . ')'; } - $renderer->doc .= DOKU_TAB . '' . hsc($name) . '' . DOKU_LF; + $renderer->doc .= '' . hsc($name) . ' '; } - $renderer->doc .= '
' . DOKU_LF; + $renderer->doc .= '
'; return true; } @@ -172,6 +173,8 @@ public function render($format, Doku_Renderer $renderer, $data) * - conf/stopwords.txt * * If both files exists, then both files are used - the content is merged. + * + * @return array list of stop words */ protected function getStopwords() { @@ -199,8 +202,11 @@ protected function getStopwords() * Applies filters on the cloud: * - removes all short words, see config option 'minimum_word_length' * - removes all words in configured blacklist $balcklistName from $cloud array + * + * @param array $cloud array(word=>count) + * @param string $blacklistName config setting name */ - protected function filterCloud(&$cloud, $balcklistName) + protected function filterCloud(&$cloud, $blacklistName) { // Remove short words $min = $this->getConf('minimum_word_length'); @@ -226,7 +232,7 @@ protected function filterCloud(&$cloud, $balcklistName) } // Remove word which are on the blacklist - $blacklist = $this->getConf($balcklistName); + $blacklist = $this->getConf($blacklistName); if (!empty($blacklist)) { $blacklist = array_map('trim', explode(',', $blacklist)); foreach ($blacklist as $word) { @@ -239,6 +245,11 @@ protected function filterCloud(&$cloud, $balcklistName) /** * Returns the sorted word cloud array + * + * @param int $num number of words shown in cloud + * @param int $min lowest shown count + * @param int $max highest shown count + * @return array(word=>count) */ protected function getWordCloud($num, &$min, &$max) { @@ -264,6 +275,10 @@ protected function getWordCloud($num, &$min, &$max) /** * Adds all words in given index as $word => $freq to $cloud array + * + * @param array $cloud array(word=>count) + * @param array $idx list with per page the frequency of each word in $word_idx + * @param array $word_idx list with words of same length */ protected function addWordsToCloud(&$cloud, $idx, $word_idx) { @@ -272,14 +287,20 @@ protected function addWordsToCloud(&$cloud, $idx, $word_idx) // collect the frequency of the words for ($i = 0; $i < $wcount; $i++) { $key = trim($word_idx[$i]); - $value = explode(':', $idx[$i]); - if (!trim($value[0])) continue; - $cloud[$key] = count($value); + $pages = explode(':', $idx[$i]); + if (!trim($pages[0])) continue; + $cloud[$key] = count($pages); } } /** * Returns the sorted tag cloud array + * + * @param int $num number of words shown in the cloud + * @param int $min lowest shown count + * @param int $max highest shown count + * @param array $namespaces array of namespaces where to count the tags + * @return false|array(word=>count) */ protected function getTagCloud($num, &$min, &$max, $namespaces) { @@ -297,6 +318,9 @@ protected function getTagCloud($num, &$min, &$max, $namespaces) /** * Returns the search cloud array * + * @param int $num number of words shown in the cloud + * @param int $min lowest shown count + * @param int $max highest shown count * @return array|false */ protected function getSearchCloud($num, &$min, &$max) @@ -322,6 +346,12 @@ protected function getSearchCloud($num, &$min, &$max) /** * Sorts and slices the cloud + * + * @param array $cloud array(word=>count) + * @param int $num number of words shown in the cloud + * @param int $min lowest shown count + * @param int $max highest shown count + * @return array(word=>count) */ protected function sortCloud($cloud, $num, &$min, &$max) { @@ -330,11 +360,11 @@ protected function sortCloud($cloud, $num, &$min, &$max) } // sort by frequency, then alphabetically - arsort($cloud); + arsort($cloud, SORT_NUMERIC); $cloud = array_chunk($cloud, $num, true); $max = current($cloud[0]); $min = end($cloud[0]); - ksort($cloud[0]); + Sort::ksort($cloud[0]); return $cloud[0]; } From 98d81fa8e2c9de7447537397ad4871013870f1a5 Mon Sep 17 00:00:00 2001 From: Gerrit Uitslag Date: Tue, 22 Aug 2023 00:10:57 +0200 Subject: [PATCH 14/14] change default for list_tags_of_subns to on Most places subnamespaces are considered with their parent, therefore, this default feels more intuitive --- conf/default.php | 6 ++---- syntax.php | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/conf/default.php b/conf/default.php index 048d230..32a742b 100644 --- a/conf/default.php +++ b/conf/default.php @@ -1,13 +1,11 @@ */ $conf['minimum_word_length'] = 2; // Minimum word length of words inside the cloud $conf['search_blacklist'] = ''; // Specify search words which shouldn't appear on pages $conf['word_blacklist'] = ''; // Specify words which shouldn't appear on pages $conf['tag_blacklist'] = ''; // Specify tags which shouldn't appear on pages -$conf['list_tags_of_subns'] = 0; // list also tags in subnamespaces of a specified namespace - -//Setup VIM: ex: et ts=4 enc=utf-8 : +$conf['list_tags_of_subns'] = 1; // list also tags in subnamespaces of a specified namespace diff --git a/syntax.php b/syntax.php index 44b9e0b..72cf6c2 100644 --- a/syntax.php +++ b/syntax.php @@ -201,7 +201,7 @@ protected function getStopwords() /** * Applies filters on the cloud: * - removes all short words, see config option 'minimum_word_length' - * - removes all words in configured blacklist $balcklistName from $cloud array + * - removes all words in configured blacklist $blacklistName from $cloud array * * @param array $cloud array(word=>count) * @param string $blacklistName config setting name