Advertisement
Guest User

syntax.php

a guest
Jun 1st, 2011
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 8.93 KB | None | 0 0
  1. <?php
  2. /**
  3.  * Cloud Plugin: shows a cloud of the most frequently used words
  4.  *
  5.  * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
  6.  * @author     Esther Brunner <wikidesign@gmail.com>
  7.  */
  8. // must be run within Dokuwiki
  9. if(!defined('DOKU_INC')) die();
  10.  
  11. if (!defined('DOKU_LF')) define('DOKU_LF', "\n");
  12. if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t");
  13. if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
  14.  
  15. require_once(DOKU_PLUGIN.'syntax.php');
  16.  
  17. class syntax_plugin_cloud extends DokuWiki_Syntax_Plugin {
  18.  
  19.     function getInfo() {
  20.         return array(
  21.                 'author' => 'Gina Häußge, Michael Klier, Esther Brunner',
  22.                 'email'  => 'dokuwiki@chimeric.de',
  23.                 'date'   => @file_get_contents(DOKU_PLUGIN . 'cloud/VERSION'),
  24.                 'name'   => 'Cloud Plugin',
  25.                 'desc'   => 'displays the most used words in a word cloud',
  26.                 'url'    => 'http://wiki.splitbrain.org/plugin:cloud',
  27.                 );
  28.     }
  29.  
  30.     function getType() { return 'substition'; }
  31.     function getPType() { return 'block'; }
  32.     function getSort() { return 98; }
  33.  
  34.     function connectTo($mode) {
  35.         $this->Lexer->addSpecialPattern('~~\w*?CLOUD.*?~~', $mode, 'plugin_cloud');
  36.     }
  37.  
  38.     function handle($match, $state, $pos, &$handler) {
  39.         $match = substr($match, 2, -2); // strip markup
  40.  
  41.         if (substr($match, 0, 3) == 'TAG') {
  42.             $type = 'tag';
  43.         } elseif (substr($match, 0, 6) == 'SEARCH') {
  44.             $type = 'search';
  45.         } else {
  46.             $type = 'word';
  47.         }
  48.  
  49.         list($junk, $num) = explode(':', $match, 2);
  50.         list($num, $ns) = explode('>', $num, 2);
  51.  
  52.         if (!is_numeric($num)) $num = 50;
  53.         if(!is_null($ns)) $namespaces = explode('|', $ns);
  54.        
  55.         return array($type, $num, $namespaces);
  56.     }            
  57.  
  58.     function render($mode, &$renderer, $data) {
  59.         global $conf;
  60.  
  61.         list($type, $num, $namespaces) = $data;
  62.  
  63.         if ($mode == 'xhtml') {
  64.  
  65.             if ($type == 'tag') { // we need the tag helper plugin
  66.                 if (plugin_isdisabled('tag') || (!$tag = plugin_load('helper', 'tag'))) {
  67.                     msg('The Tag Plugin must be installed to display tag clouds.', -1);
  68.                     return false;
  69.                 }
  70.                 $cloud = $this->_getTagCloud($num, $min, $max, $namespaces, $tag);
  71.             } elseif($type == 'search') {
  72.                 $helper = plugin_load('helper', 'searchstats');
  73.                 if($helper) {
  74.                     $cloud = $helper->getSearchWordArray($num);
  75.                 } else {
  76.                     msg('You have to install the searchstats plugin to use this feature.', -1);
  77.                 }
  78.             } else {
  79.                 $cloud = $this->_getWordCloud($num, $min, $max);
  80.             }
  81.             if (!is_array($cloud) || empty($cloud)) return false;
  82.             $delta = ($max-$min)/16;
  83.  
  84.             // prevent caching to ensure the included pages are always fresh
  85.             $renderer->info['cache'] = false;
  86.  
  87.             // and render the cloud
  88.             $renderer->doc .= '<div id="cloud">'.DOKU_LF;
  89.             foreach ($cloud as $word => $size) {
  90.                 if ($size < $min+round($delta)) $class = 'cloud1';
  91.                 elseif ($size < $min+round(2*$delta)) $class = 'cloud2';
  92.                 elseif ($size < $min+round(4*$delta)) $class = 'cloud3';
  93.                 elseif ($size < $min+round(8*$delta)) $class = 'cloud4';
  94.                 else $class = 'cloud5';
  95.  
  96.                 $name = $word;
  97.                 if ($type == 'tag') {
  98.                     $id = $word;
  99.                     resolve_pageID($tag->namespace, $id, $exists);
  100.                     if($exists) {
  101.                         $link = wl($id);
  102.                         if($conf['useheading']) {
  103.                             $name = p_get_first_heading($id, false);
  104.                         } else {
  105.                             $name = $word;
  106.                         }
  107.                     } else {
  108.                         $link = wl($id, array('do'=>'showtag', 'tag'=>$word));
  109.                     }
  110.                     $title = $word;
  111.                     $class .= ($exists ? '_tag1' : '_tag2');
  112.                 } else {
  113.                     if($conf['userewrite'] == 2) {
  114.                         $link = wl($word, array('do'=>'search', 'id'=>$word));
  115.                         $title = $size;
  116.                     } else {
  117.                         $link = wl($word, 'do=search');
  118.                         $title = $size;
  119.                     }
  120.                 }
  121.  
  122.                 $renderer->doc .= DOKU_TAB . '<a href="' . $link . '" class="' . $class .'"'
  123.                                .' title="' . $title . '">' . $name . '</a>' . DOKU_LF;
  124.             }
  125.             $renderer->doc .= '</div>' . DOKU_LF;
  126.             return true;
  127.         }
  128.         return false;
  129.     }
  130.  
  131.     /**
  132.      * Returns the sorted word cloud array
  133.      */
  134.     function _getWordCloud($num, &$min, &$max) {
  135.         global $conf;
  136.  
  137.         // load stopwords
  138.         $swfile   = DOKU_INC.'inc/lang/'.$conf['lang'].'/stopwords.txt';
  139.         if (@file_exists($swfile)) $stopwords = file($swfile);
  140.         else $stopwords = array();
  141.  
  142.         // load extra local stopwords
  143.         $swfile = DOKU_CONF.'stopwords.txt';
  144.         if (@file_exists($swfile)) $stopwords = array_merge($stopwords, file($swfile));
  145.  
  146.         $cloud = array();
  147.  
  148.         if (@file_exists($conf['indexdir'].'/page.idx')) { // new word-length based index
  149.             require_once(DOKU_INC.'inc/indexer.php');
  150.  
  151.             $n = $this->getConf('minimum_word_length'); // minimum word length
  152.             $lengths = idx_indexLengths($n);
  153.             foreach ($lengths as $len) {
  154.                 $idx      = idx_getIndex('i', $len);
  155.                 $word_idx = idx_getIndex('w', $len);
  156.  
  157.                 $this->_addWordsToCloud($cloud, $idx, $word_idx, $stopwords);
  158.             }
  159.  
  160.         } else {                                          // old index
  161.             $idx      = file($conf['cachedir'].'/index.idx');
  162.             $word_idx = file($conf['cachedir'].'/word.idx');
  163.  
  164.             $this->_addWordsToCloud($cloud, $idx, $word_idx, $stopwords);
  165.         }
  166.         return $this->_sortCloud($cloud, $num, $min, $max);
  167.     }
  168.  
  169.     /**
  170.      * Adds all words in given index as $word => $freq to $cloud array
  171.      */
  172.     function _addWordsToCloud(&$cloud, $idx, $word_idx, &$stopwords) {
  173.         $wcount = count($word_idx);
  174.  
  175.         // collect the frequency of the words
  176.         for ($i = 0; $i < $wcount; $i++) {
  177.             $key = trim($word_idx[$i]);
  178.             if (!is_int(array_search("$key\n", $stopwords))) {
  179.                 $value = explode(':', $idx[$i]);
  180.                 if (!trim($value[0])) continue;
  181.                 $cloud[$key] = count($value);
  182.             }
  183.         }
  184.     }
  185.  
  186.     /**
  187.      * Returns the sorted tag cloud array
  188.      */
  189.     function _getTagCloud($num, &$min, &$max, $namespaces = NULL, &$tag) {
  190.         $cloud = array();
  191.        
  192.         if(!is_array($tag->topic_idx)) return;
  193.  
  194.         foreach ($tag->topic_idx as $key => $value) {
  195.             // discard tags which are listed in the blacklist
  196.             $blacklist = $this->getConf('tag_blacklist');
  197.             if(!empty($blacklist)) {
  198.                  $blacklist = explode(',', $blacklist);
  199.                  $blacklist = str_replace(' ', '', $blacklist); // remove spaces
  200.             }
  201.             if(!empty($blacklist) && in_array($key, $blacklist))    continue;
  202.  
  203.             // check if page is in wanted namespace and (explicit check for root namespace, specified with a dot)
  204.             // condition: ( (no ns given) && ( (page not in given namespace and page is not in rootns) )
  205.             if( !is_null($namespaces) && ((!is_null($namespaces) && !in_array(getNS($value[0]), $namespaces) && getNS($value[0]) )) ) continue;
  206.            
  207.             // page not in root namespace
  208.             if( !is_null($namespaces) && (!(getNS($value[0])) && !in_array('.', $namespaces)) ) continue;
  209.  
  210.             if (!is_array($value) || empty($value) || (!trim($value[0]))) {
  211.                 continue;
  212.             } else {
  213.                 $pages = array();
  214.                 foreach($value as $page) {
  215.                     if(auth_quickaclcheck($page) < AUTH_READ) continue;
  216.                     array_push($pages, $page);
  217.                 }
  218.                 if(!empty($pages)) $cloud[$key] = count($pages);
  219.             }
  220.         }
  221.         return $this->_sortCloud($cloud, $num, $min, $max);
  222.     }
  223.  
  224.     /**
  225.      * Sorts and slices the cloud
  226.      */
  227.     function _sortCloud($cloud, $num, &$min, &$max) {
  228.         if(empty($cloud)) return;
  229.  
  230.         // sort by frequency, then alphabetically
  231.         arsort($cloud);
  232.         $cloud = array_chunk($cloud, $num, true);
  233.         $max = current($cloud[0]);
  234.         $min = end($cloud[0]);
  235.         ksort($cloud[0]);
  236.  
  237.         return $cloud[0];
  238.     }
  239. }
  240. // vim:ts=4:sw=4:et:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement