first commit. dokuwiki.
[h2N7SspZmY.git] / lib / plugins / cloud / syntax.php
blobe540930b520215371c6817a7948ab59eed6c42b8
1 <?php
2 /**
3 * Cloud Plugin: shows a cloud of the most frequently used words
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();
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/');
15 require_once(DOKU_PLUGIN.'syntax.php');
17 class syntax_plugin_cloud extends DokuWiki_Syntax_Plugin {
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',
30 function getType() { return 'substition'; }
31 function getPType() { return 'block'; }
32 function getSort() { return 98; }
34 function connectTo($mode) {
35 $this->Lexer->addSpecialPattern('~~\w*?CLOUD.*?~~', $mode, 'plugin_cloud');
38 function handle($match, $state, $pos, &$handler) {
39 $match = substr($match, 2, -2); // strip markup
40 if (substr($match, 0, 3) == 'TAG') $type = 'tag';
41 else $type = 'word';
43 list($junk, $num) = explode(':', $match, 2);
44 if (!is_numeric($num)) $num = 50;
46 return array($type, $num);
49 function render($mode, &$renderer, $data) {
50 global $conf;
52 list($type, $num) = $data;
54 if ($mode == 'xhtml') {
56 if ($type == 'tag') { // we need the tag helper plugin
57 if (plugin_isdisabled('tag') || (!$tag = plugin_load('helper', 'tag'))) {
58 msg('The Tag Plugin must be installed to display tag clouds.', -1);
59 return false;
61 $cloud = $this->_getTagCloud($num, $min, $max, $tag);
62 } else {
63 $cloud = $this->_getWordCloud($num, $min, $max);
65 if (!is_array($cloud) || empty($cloud)) return false;
66 $delta = ($max-$min)/16;
68 // prevent caching to ensure the included pages are always fresh
69 $renderer->info['cache'] = false;
71 // and render the cloud
72 $renderer->doc .= '<div id="cloud">'.DOKU_LF;
73 foreach ($cloud as $word => $size) {
74 if ($size < $min+round($delta)) $class = 'cloud1';
75 elseif ($size < $min+round(2*$delta)) $class = 'cloud2';
76 elseif ($size < $min+round(4*$delta)) $class = 'cloud3';
77 elseif ($size < $min+round(8*$delta)) $class = 'cloud4';
78 else $class = 'cloud5';
80 $name = $word;
81 if ($type == 'tag') {
82 $id = $word;
83 resolve_pageID($tag->namespace, $id, $exists);
84 if($exists) {
85 $link = wl($id);
86 if($conf['useheading']) {
87 $name = p_get_first_heading($id, false);
89 } else {
90 $link = wl($id, array('do'=>'showtag', 'tag'=>noNS($id)));
92 $title = $id;
93 $class .= ($exists ? '_tag1' : '_tag2');
94 } else {
95 if($conf['userewrite'] == 2) {
96 $link = wl($word, array('do'=>'search', 'id'=>$word));
97 $title = $size;
98 } else {
99 $link = wl($word, 'do=search');
100 $title = $size;
104 $renderer->doc .= DOKU_TAB . '<a href="' . $link . '" class="' . $class .'"'
105 .' title="' . $title . '">' . $name . '</a>' . DOKU_LF;
107 $renderer->doc .= '</div>' . DOKU_LF;
108 return true;
110 return false;
114 * Returns the sorted word cloud array
116 function _getWordCloud($num, &$min, &$max) {
117 global $conf;
119 // load stopwords
120 $swfile = DOKU_INC.'inc/lang/'.$conf['lang'].'/stopwords.txt';
121 if (@file_exists($swfile)) $stopwords = file($swfile);
122 else $stopwords = array();
124 // load extra local stopwords
125 $swfile = DOKU_CONF.'stopwords.txt';
126 if (@file_exists($swfile)) $stopwords = array_merge($stopwords, file($swfile));
128 $cloud = array();
130 if (@file_exists($conf['indexdir'].'/page.idx')) { // new word-lenght based index
131 require_once(DOKU_INC.'inc/indexer.php');
133 $n = 2; // minimum word length
134 $lengths = idx_indexLengths($n);
135 foreach ($lengths as $len) {
136 $idx = idx_getIndex('i', $len);
137 $word_idx = idx_getIndex('w', $len);
139 $this->_addWordsToCloud($cloud, $idx, $word_idx, $stopwords);
142 } else { // old index
143 $idx = file($conf['cachedir'].'/index.idx');
144 $word_idx = file($conf['cachedir'].'/word.idx');
146 $this->_addWordsToCloud($cloud, $idx, $word_idx, $stopwords);
148 return $this->_sortCloud($cloud, $num, $min, $max);
152 * Adds all words in given index as $word => $freq to $cloud array
154 function _addWordsToCloud(&$cloud, $idx, $word_idx, &$stopwords) {
155 $wcount = count($word_idx);
157 // collect the frequency of the words
158 for ($i = 0; $i < $wcount; $i++) {
159 $key = trim($word_idx[$i]);
160 if (!is_int(array_search("$key\n", $stopwords))) {
161 $value = explode(':', $idx[$i]);
162 if (!trim($value[0])) continue;
163 $cloud[$key] = count($value);
169 * Returns the sorted tag cloud array
171 function _getTagCloud($num, &$min, &$max, &$tag) {
172 $cloud = array();
173 if(!is_array($tag->topic_idx)) return;
174 foreach ($tag->topic_idx as $key => $value) {
175 if (!is_array($value) || empty($value) || (!trim($value[0]))) {
176 continue;
177 } else {
178 $pages = array();
179 foreach($value as $page) {
180 if(auth_quickaclcheck($page) < AUTH_READ) continue;
181 array_push($pages, $page);
183 if(!empty($pages)) $cloud[$key] = count($pages);
186 return $this->_sortCloud($cloud, $num, $min, $max);
190 * Sorts and slices the cloud
192 function _sortCloud($cloud, $num, &$min, &$max) {
193 if(empty($cloud)) return;
195 // sort by frequency, then alphabetically
196 arsort($cloud);
197 $cloud = array_chunk($cloud, $num, true);
198 $max = current($cloud[0]);
199 $min = end($cloud[0]);
200 ksort($cloud[0]);
202 return $cloud[0];
205 // vim:ts=4:sw=4:et:enc=utf-8: