• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

修订版1741629a86cdcda48f751bcf7b3a475d239cb824 (tree)
时间2022-01-24 01:54:05
作者hai-fun <haifun129@gmai...>
Commiterhai-fun

Log Message

ver: rev201, author: sonots, dl:http://pukiwiki.sonots.com/?Plugin%2Ftag.inc.php

更改概述

差异

--- /dev/null
+++ b/tag/tag.inc.php
@@ -0,0 +1,1507 @@
1+<?php
2+/**
3+ * Tag Plugin
4+ *
5+ * @author sonots
6+ * @license http://www.gnu.org/licenses/gpl.html GPL
7+ * @link http://lsx.sourceforge.jp/?Plugin%2Ftag.inc.php
8+ * @version $Id: tag.inc.php,v 1.30 2008-03-19 07:23:17Z sonots $
9+ * @package plugin
10+ */
11+
12+class PluginTag extends Tag
13+{
14+ function PluginTag()
15+ {
16+ parent::Tag();
17+ static $conf = array();
18+ if (empty($conf)) {
19+ $conf['listcmd'] = get_script_uri() . '?cmd=taglist&amp;tag=';
20+ $conf['use_session'] = TRUE;
21+ $conf['through_if_admin'] = TRUE;
22+ }
23+ $this->conf = & $conf;
24+ }
25+
26+ var $conf;
27+ var $plugin = 'tag';
28+
29+ function action() // clean cache
30+ {
31+ global $vars;
32+ if (is_admin($vars['pass'], $this->conf['use_session'], $this->conf['through_if_admin'])) {
33+ $body = $this->clean_cache();
34+ } else {
35+ $body = $this->display_password_form();
36+ }
37+ return array('msg'=>'Clean Tag Caches', 'body'=>$body);
38+ }
39+
40+ /**
41+ * Clean Tag Caches
42+ *
43+ * @return string HTML
44+ */
45+ function clean_cache()
46+ {
47+ set_time_limit(0);
48+ global $vars;
49+
50+ // remove all files
51+ $files = $this->get_items_filenames();
52+ $files = array_merge($files, $this->get_tags_filenames());
53+ $files = array_merge($files, (array)$this->get_tagcloud_filename());
54+ foreach ($files as $file) {
55+ unlink($file);
56+ }
57+ // execute all pages
58+ $exec_pages = exec_existpages('/&tag\([^;]*\);/');
59+ if (empty($exec_pages)) {
60+ $html = '';
61+ } else {
62+ $links = array_map('make_pagelink', $exec_pages);
63+ $html = '<p>Following pages were executed to assure:</p>'
64+ . '<p>' . implode("<br />\n", $links) . '</p>';
65+ }
66+ $html .= $this->display_tagcloud(NULL);
67+ return $html;
68+ }
69+
70+ /**
71+ * Display a password form
72+ *
73+ * @param $msg error message or some messages
74+ * @return string form html
75+ */
76+ function display_password_form($message = "")
77+ {
78+ $cmd = $this->plugin;
79+ $pcmd = 'clean';
80+ $form = array();
81+ $form[] = '<form action="' . get_script_uri() . '?cmd=' . $cmd . '" method="post">';
82+ $form[] = '<div>';
83+ $form[] = ' <input type="hidden" name="pcmd" value="' . $pcmd . '" />';
84+ if (! is_admin(null, $this->conf['use_session'], $this->conf['through_if_admin'])) {
85+ $form[] = ' <input type="password" name="pass" size="24" value="" /> ' . _('Admin Password') . '<br />';
86+ }
87+ $form[] = ' <input type="submit" name="submit" value="Submit" /><br />';
88+ $form[] = '</div>';
89+ $form[] = '</form>';
90+ $form = implode("\n", $form);
91+
92+ if ($message != '') {
93+ $message = '<p><b>' . htmlspecialchars($message) . '</b></p>';
94+ }
95+ return $message . $form;
96+ }
97+
98+ function inline() // tagging
99+ {
100+ static $tagging = FALSE;
101+ if (func_num_args() == 0){
102+ return 'tag(): no argument(s). ';
103+ }
104+ global $vars, $defaultpage;
105+ $page = isset($vars['page']) ? $vars['page'] : $defaultpage;
106+ $args = func_get_args();
107+ array_pop($args); // drop {}
108+ $tags = $args;
109+
110+ if ($tagging) { // 2nd call
111+ $this->add_tags($page, $tags);
112+ } elseif (isset($vars['preview']) || isset($vars['realview']) ||
113+ is_page_newer($page, $this->get_tags_filename($page))) {
114+ $this->save_tags($page, $tags);
115+ $tagging = TRUE;
116+ }
117+ return $this->display_tags($tags);
118+ }
119+
120+ /**
121+ * Experimental: Write After Plugin Main Function
122+ *
123+ * @param string &$page
124+ * @param string &$postdata
125+ * @param boolean &$notimestamp
126+ * @return void or exit
127+ */
128+ function write_after()
129+ {
130+ $args = func_get_args();
131+ $page = $args[0];
132+ $postdata = $args[1];
133+ if ($postdata == "") { // if page is deleted
134+ $this->save_tags($page, array()); // remove tags
135+ }
136+ // ToDo: renew tag cache on write_after, not on read
137+ // Since the whole text must be parsed to find '&tag();',
138+ // it is not realistic.
139+ // Must create a separated form for Tags to avoid this load.
140+ }
141+
142+ /**
143+ * Experimental: Plugin for Rename Plugin Main Function
144+ *
145+ * @param array $pages $oldpage => $newpage
146+ * @return void or exit
147+ */
148+ function rename_plugin()
149+ {
150+ $args = func_get_args();
151+ $pages = $args[0];
152+ foreach ($pages as $oldpage => $newpage) {
153+ $this->rename_item($oldpage, $newpage);
154+ }
155+ }
156+
157+ /**
158+ * Get tag link
159+ *
160+ * @param string $tag
161+ * @return string url
162+ */
163+ function get_taglink($tag)
164+ {
165+ $href = $this->conf['listcmd'] . rawurlencode($tag);
166+ return '<a href="' . $href . '">' . htmlspecialchars($tag) . '</a> ';
167+ }
168+
169+ /**
170+ * Display tags
171+ *
172+ * @param array $tags
173+ * @return string HTML
174+ */
175+ function display_tags($tags)
176+ {
177+ $ret = '<span class="tag">';
178+ $ret .= 'Tag: ';
179+ foreach ($tags as $tag) {
180+ $ret .= $this->get_taglink($tag);
181+ }
182+ $ret .= '</span>';
183+
184+ global $head_tags;
185+ $head_tags[] = ' <meta name="keywords" content="' .
186+ htmlspecialchars(implode(', ', $tags)) . '" />';
187+
188+ return $ret;
189+ }
190+
191+ /**
192+ * Display tags list
193+ *
194+ * @param integer $limit Number to show
195+ * @param string $relate_tag Show only related tags of this
196+ * @param string $cssclass
197+ * @return string HTML
198+ */
199+ function display_taglist($limit = NULL, $relate_tag = NULL, $cssclass = 'taglist tags')
200+ {
201+ $html = '<ul class="' . $cssclass . '">';
202+ $tagcloud = $this->get_tagcloud($limit, $relate_tag);
203+ foreach ($tagcloud as $tag => $count) {
204+ $html .= '<li>' . $this->get_taglink($tag) . '</li>';
205+ }
206+ $html .= '</ul>';
207+ return $html;
208+ }
209+
210+ /**
211+ * Display tagcloud
212+ *
213+ * @param integer $limit Number to show
214+ * @param string $relate_tag Show only related tags of this
215+ * @return string HTML
216+ */
217+ function display_tagcloud($limit = null, $relate_tag = null)
218+ {
219+ $view = new TagCloud();
220+ $tagcloud = $this->get_tagcloud($limit, $relate_tag);
221+ foreach ($tagcloud as $tag => $count) {
222+ $url = $this->conf['listcmd'] . rawurlencode($tag);
223+ $view->add(htmlspecialchars($tag), $url, $count);
224+ }
225+ return $view->html();
226+ }
227+
228+ function get_items_filename($tag)
229+ {
230+ $tag = $this->normalize_tags($tag);
231+ return CACHE_DIR . encode($tag) . '_tag.tag';
232+ }
233+ function get_items_filenames()
234+ {
235+ return get_existfiles(CACHE_DIR, '_tag.tag');
236+ }
237+ function get_tags_filename($page)
238+ {
239+ return CACHE_DIR . encode($page) . '_page.tag';
240+ }
241+ function get_tags_filenames()
242+ {
243+ return get_existfiles(CACHE_DIR, '_page.tag');
244+ }
245+ function get_tagcloud_filename()
246+ {
247+ return CACHE_DIR . 'tagcloud.tag';
248+ }
249+ /**
250+ * Get tagged pages
251+ *
252+ * Syntax Sugar for get_items_by_tagtok
253+ *
254+ * @uses get_items_by_tagtok
255+ */
256+ function get_taggedpages($tagtok)
257+ {
258+ return $this->get_items_by_tagtok($tagtok);
259+ }
260+}
261+
262+//////////////// PukiWiki API Extension
263+if (! function_exists('parse_options')) {
264+ /**
265+ * Parse plugin arguments for options
266+ *
267+ * @param array &$args
268+ * @param array &$options
269+ * @param string $sep key/val separator
270+ * @return void
271+ */
272+ function parse_options(&$args, &$options, $sep = '=')
273+ {
274+ foreach ($args as $arg) {
275+ list($key, $val) = array_pad(explode($sep, $arg, 2), 2, TRUE);
276+ if (array_key_exists($key, $options)) {
277+ $options[$key] = $val;
278+ }
279+ }
280+ }
281+}
282+
283+if (! function_exists('is_admin')) {
284+ /**
285+ * PukiWiki admin login with session
286+ *
287+ * @param string $pass
288+ * @param boolean $use_session Use Session log
289+ * @param boolean $use_basicauth Use BasicAuth log
290+ * @return boolean
291+ */
292+ function is_admin($pass = null, $use_session = false, $use_basicauth = false)
293+ {
294+ $is_admin = FALSE;
295+ if ($use_basicauth) {
296+ if (is_callable(array('auth', 'check_role'))) { // Plus!
297+ $is_admin = ! auth::check_role('role_adm_contents');
298+ }
299+ }
300+ if (! $is_admin && isset($pass)) {
301+ $is_admin = function_exists('pkwk_login') ? pkwk_login($pass) :
302+ md5($pass) === $GLOBALS['adminpass']; // 1.4.3
303+ }
304+ if ($use_session) {
305+ session_start();
306+ if ($is_admin) $_SESSION['is_admin'] = TRUE;
307+ return isset($_SESSION['is_admin']) && $_SESSION['is_admin'];
308+ } else {
309+ return $is_admin;
310+ }
311+ }
312+}
313+
314+if (! function_exists('make_pagelink_nopg')) {
315+ /**
316+ * Make a hyperlink to the page without passage
317+ *
318+ * @param string $page pagename
319+ * @param string $alias string to be displayed on the link
320+ * @param string $anchor anchor
321+ * @param string $refer reference pagename. query '&amp;refer=' is added.
322+ * @param bool $isautolink flag if this link is created via autolink or not
323+ * @return string link html
324+ * @uses make_pagelink
325+ */
326+ function make_pagelink_nopg($page, $alias = '', $anchor = '', $refer = '', $isautolink = FALSE)
327+ {
328+ // no passage
329+ global $show_passage;
330+ $tmp = $show_passage; $show_passage = 0;
331+ $link = make_pagelink($page, $alias, $anchor, $refer, $isautolink);
332+ $show_passage = $tmp;
333+ return $link;
334+ }
335+}
336+
337+if (! function_exists('is_page_newer')) {
338+ /**
339+ * Check if the page timestamp is newer than the file timestamp
340+ *
341+ * PukiWiki API Extension
342+ *
343+ * @param string $page pagename
344+ * @param string $file filename
345+ * @param bool $ignore_notimestamp Ignore notimestamp edit and see the real time editted
346+ * @return boolean
347+ */
348+ function is_page_newer($page, $file, $ignore_notimestamp = TRUE)
349+ {
350+ $filestamp = file_exists($file) ? filemtime($file) : 0;
351+ if ($ignore_notimestamp) { // See the diff file. PukiWiki Trick.
352+ $pagestamp = is_page($page) ? filemtime(DIFF_DIR . encode($page) . '.txt') : 0;
353+ } else {
354+ $pagestamp = is_page($page) ? filemtime(get_filename($page)) : 0;
355+ }
356+ return $pagestamp > $filestamp;
357+ }
358+}
359+
360+if (! function_exists('exec_page')) {
361+ /**
362+ * Execute (convert_html) this page
363+ *
364+ * PukiWiki API Extension
365+ *
366+ * @param string $page
367+ * @param string $regexp execute only matched lines (preg_grep)
368+ * @return boolean executed
369+ */
370+ function exec_page($page, $regexp = null)
371+ {
372+ global $vars, $get, $post;
373+ $lines = get_source($page);
374+ if (isset($regexp)) {
375+ $lines = preg_grep($regexp, $lines);
376+ }
377+ if (empty($lines)) return FALSE;
378+ $tmp_page = $vars['page'];
379+ $tmp_cmd = $vars['cmd'];
380+ $vars['cmd'] = $get['cmd'] = $post['cmd'] = 'read';
381+ $vars['page'] = $get['page'] = $post['page'] = $page;
382+ convert_html($lines);
383+ $vars['page'] = $get['page'] = $post['page'] = $tmp_page;
384+ $vars['cmd'] = $get['cmd'] = $post['cmd'] = $tmp_cmd;
385+ return TRUE;
386+ }
387+}
388+
389+if (! function_exists('exec_existpages')) {
390+ /**
391+ * Execute (convert_html) all pages
392+ *
393+ * PukiWiki API Extension
394+ *
395+ * @param string $regexp execute only matched lines (preg_grep)
396+ * @return array executed pages
397+ */
398+ function exec_existpages($regexp = null)
399+ {
400+ global $vars, $get, $post;
401+ $pages = get_existpages();
402+ $exec_pages = array();
403+ $tmp_page = $vars['page'];
404+ $tmp_cmd = $vars['cmd'];
405+ $vars['cmd'] = $get['cmd'] = $post['cmd'] = 'read';
406+ foreach ($pages as $page) {
407+ $vars['page'] = $get['page'] = $post['page'] = $page;
408+ $lines = get_source($page);
409+ if (isset($regexp)) {
410+ $lines = preg_grep($regexp, $lines);
411+ }
412+ if (empty($lines)) continue;
413+ convert_html($lines);
414+ $exec_pages[] = $page;
415+ }
416+ $vars['page'] = $get['page'] = $post['page'] = $tmp_page;
417+ $vars['cmd'] = $get['cmd'] = $post['cmd'] = $tmp_cmd;
418+ return $exec_pages;
419+ }
420+}
421+
422+/////////////// PHP API Extension ///////////////////////
423+if (! function_exists('ya_array_diff')) {
424+ /**
425+ * Get array diff
426+ *
427+ * @param array $oldarray
428+ * @param array $newarray
429+ * @return array array((array)$minus, (array)$plus)
430+ */
431+ function ya_array_diff($oldarray, $newarray)
432+ {
433+ $common = array_intersect($oldarray, $newarray);
434+ $minus = array_diff($oldarray, $common);
435+ $plus = array_diff($newarray, $common);
436+ return array($minus, $plus);
437+ }
438+}
439+
440+if (! function_exists('file_put_contents')) {
441+ if (! defined('FILE_APPEND')) define('FILE_APPEND', 8);
442+ if (! defined('FILE_USE_INCLUDE_PATH')) define('FILE_USE_INCLUDE_PATH', 1);
443+ /**
444+ * Write a string to a file (PHP5 has this function)
445+ *
446+ * PHP Compat
447+ *
448+ * @param string $filename
449+ * @param string $data
450+ * @param int $flags
451+ * @return int the amount of bytes that were written to the file, or FALSE if failure
452+ */
453+ function file_put_contents($filename, $data, $flags = 0)
454+ {
455+ $mode = ($flags & FILE_APPEND) ? 'a' : 'w';
456+ $fp = fopen($filename, $mode);
457+ if ($fp === false) {
458+ return false;
459+ }
460+ if (is_array($data)) $data = implode('', $data);
461+ if ($flags & LOCK_EX) flock($fp, LOCK_EX);
462+ $bytes = fwrite($fp, $data);
463+ if ($flags & LOCK_EX) flock($fp, LOCK_UN);
464+ fclose($fp);
465+ return $bytes;
466+ }
467+}
468+
469+if (! function_exists('r_strpos')) {
470+ /**
471+ * Find positions of occurrence of a string
472+ *
473+ * PHP Extension
474+ *
475+ * @param string $str
476+ * @param string $substr
477+ * @return array positions
478+ */
479+ function r_strpos($str, $substr)
480+ {
481+ $r_pos = array();
482+ while(true) {
483+ $pos = strpos($str, $substr);
484+ if ($pos === false) break;
485+ array_push($r_pos, $pos);
486+ $str = substr($str, $pos + 1);
487+ }
488+ return $r_pos;
489+ }
490+}
491+
492+if (! function_exists('get_existfiles')) {
493+ /**
494+ * Get list of files in a directory
495+ *
496+ * PHP Extension
497+ *
498+ * @access public
499+ * @param string $dir Directory Name
500+ * @param string $ext File Extension
501+ * @param bool $recursive Traverse Recursively
502+ * @return array array of filenames
503+ * @uses is_dir()
504+ * @uses opendir()
505+ * @uses readdir()
506+ */
507+ function &get_existfiles($dir, $ext = '', $recursive = FALSE)
508+ {
509+ if (($dp = @opendir($dir)) == FALSE)
510+ return FALSE;
511+ $pattern = '/' . preg_quote($ext, '/') . '$/';
512+ $dir = ($dir[strlen($dir)-1] == '/') ? $dir : $dir . '/';
513+ $dir = ($dir == '.' . '/') ? '' : $dir;
514+ $files = array();
515+ while (($file = readdir($dp)) !== false ) {
516+ if($file != '.' && $file != '..' && is_dir($dir . $file) && $recursive) {
517+ $files = array_merge($files, get_existfiles($dir . $file, $ext, $recursive));
518+ } else {
519+ $matches = array();
520+ if (preg_match($pattern, $file, $matches)) {
521+ $files[] = $dir . $file;
522+ }
523+ }
524+ }
525+ closedir($dp);
526+ return $files;
527+ }
528+}
529+
530+if (! function_exists('_')) {
531+ /**
532+ * i18n gettext
533+ *
534+ * PHP Compat
535+ *
536+ * @param string $str
537+ * @return string
538+ */
539+ function _($str)
540+ {
541+ return $str;
542+ }
543+}
544+
545+////////////////////////////////
546+function plugin_tag_init()
547+{
548+ global $plugin_tag_name;
549+ if (class_exists('PluginTagUnitTest')) {
550+ $plugin_tag_name = 'PluginTagUnitTest';
551+ } elseif (class_exists('PluginTagUser')) {
552+ $plugin_tag_name = 'PluginTagUser';
553+ } else {
554+ $plugin_tag_name = 'PluginTag';
555+ }
556+}
557+
558+function plugin_tag_inline()
559+{
560+ global $plugin_tag, $plugin_tag_name;
561+ $plugin_tag = new $plugin_tag_name();
562+ $args = func_get_args();
563+ return call_user_func_array(array(&$plugin_tag, 'inline'), $args);
564+}
565+
566+function plugin_tag_convert()
567+{
568+ global $plugin_tag, $plugin_tag_name;
569+ $plugin_tag = new $plugin_tag_name();
570+ $args = func_get_args();
571+ return call_user_func_array(array(&$plugin_tag, 'convert'), $args);
572+}
573+
574+function plugin_tag_action()
575+{
576+ global $plugin_tag, $plugin_tag_name;
577+ $plugin_tag = new $plugin_tag_name();
578+ return call_user_func(array(&$plugin_tag, 'action'));
579+}
580+
581+function plugin_tag_write_after()
582+{
583+ global $plugin_tag_name;
584+ $plugin_tag = new $plugin_tag_name();
585+ $args = func_get_args();
586+ return call_user_func_array(array(&$plugin_tag, 'write_after'), $args);
587+}
588+
589+function plugin_tag_rename_plugin()
590+{
591+ global $plugin_tag_name;
592+ $plugin_tag = new $plugin_tag_name();
593+ $args = func_get_args();
594+ return call_user_func_array(array(&$plugin_tag, 'rename_plugin'), $args);
595+}
596+
597+/**
598+ * Tag Class
599+ *
600+ * @author sonots
601+ * @license http://www.gnu.org/licenses/gpl.html GPL2
602+ * @link http://lsx.sourceforge.jp/?Plugin%2Ftag.inc.php
603+ */
604+class Tag
605+{
606+ /**
607+ * Items of a tag
608+ *
609+ * Associative array of items whose key is a tag
610+ * and values are an array of items
611+ *
612+ * @var array
613+ *
614+ * [tag] = array(item1, item2, item3, ...)
615+ */
616+ var $items;
617+ /**
618+ * Tags of an item
619+ *
620+ * Associative array of tags whose key is an item
621+ * and values are an array of keys
622+ *
623+ * @var array
624+ *
625+ * [item] = array(tag1, tag2, tag3, ...)
626+ */
627+ var $tags;
628+ /**
629+ * Tagcloud
630+ *
631+ * Associative array whose key is a tag
632+ * and values are the number of items
633+ *
634+ * @var array
635+ */
636+ var $tagcloud;
637+ /**
638+ * Reserved keys
639+ *
640+ * Strings which have special meanings.
641+ * They can not be used for tag strings
642+ *
643+ * @static array
644+ */
645+ var $reserved_keys = array('prod' => '^', 'diff' => '-');
646+
647+ function Tag($items = array(), $tags = array(), $tagcloud = null)
648+ {
649+ $this->items = $items;
650+ $this->tags = $tags;
651+ $this->tagcloud = $tagcloud;
652+ }
653+
654+ /**
655+ * Get filename which stores items by a tag
656+ *
657+ * Overwrite Me!
658+ *
659+ * @param string $tag
660+ * @return string
661+ * @access protected
662+ */
663+ function get_items_filename($tag)
664+ {
665+ $tag = $this->normalize_tags($tag);
666+ return str_replace('%', '', rawurlencode($tag)) . '_items.tag';
667+ }
668+ /**
669+ * Get all items_filename
670+ *
671+ * Overwrite Me!
672+ *
673+ * @return array
674+ * @access protected
675+ */
676+ function get_items_filenames()
677+ {
678+ return get_existfiles('.', '_items.tag');
679+ }
680+ /**
681+ * Get filename which stores tags of an item
682+ *
683+ * Overwrite Me!
684+ *
685+ * @param string $item
686+ * @return string
687+ * @access protected
688+ */
689+ function get_tags_filename($item)
690+ {
691+ return str_replace('%', '', rawurlencode($item)) . '_tags.tag';
692+ }
693+ /**
694+ * Get all tags_filename
695+ *
696+ * Overwrite Me!
697+ *
698+ * @return array
699+ * @access protected
700+ */
701+ function get_tags_filenames()
702+ {
703+ return get_existfiles('.', '_tags.tag');
704+ }
705+ /**
706+ * Get filename which stores tagcloud
707+ *
708+ * Overwrite Me!
709+ *
710+ * @return string
711+ * @access protected
712+ */
713+ function get_tagcloud_filename()
714+ {
715+ return 'tagcloud.tag';
716+ }
717+
718+ /**
719+ * Get tags of an item from a storage (file or db)
720+ *
721+ * Overwrite Me if you don't like the file format
722+ *
723+ * @param string $item
724+ * @param string $filename
725+ * @return array
726+ * @access protected
727+ */
728+ function get_tags_from_storage($item, $filename = null)
729+ {
730+ if ($item === null) return false;
731+ if ($filename === null) $filename = $this->get_tags_filename($item);
732+ if (! file_exists($filename)) return array();
733+ $tags = array_map('rtrim', file($filename));
734+ return $tags;
735+ }
736+
737+ /**
738+ * Get items by a tag from a storage (file or db)
739+ *
740+ * Overwrite Me if you don't like the file format
741+ *
742+ * @param string $tag
743+ * @param string $filename
744+ * @return array
745+ * @access protected
746+ */
747+ function get_items_from_storage($tag, $filename = null)
748+ {
749+ if ($filename === null) $filename = $this->get_items_filename($tag);
750+ if (! file_exists($filename)) return array();
751+ $items = array_map('rtrim', file($filename));
752+ return $items;
753+ }
754+
755+ /**
756+ * Get tagcloud from a storage (file or db)
757+ *
758+ * Overwrite Me if you don't like the file format
759+ *
760+ * @return array
761+ * @access protected
762+ */
763+ function get_tagcloud_from_storage()
764+ {
765+ $filename = $this->get_tagcloud_filename();
766+ $tagcloud = array();
767+ if (file_exists($filename)) {
768+ $lines = file($filename);
769+ if (empty($lines)) return array();
770+ $lines = array_map('rtrim', $lines);
771+ foreach ($lines as $line) {
772+ list($tag, $count) = explode("\t", $line);
773+ $tagcloud[$tag] = $count;
774+ }
775+ }
776+ return $tagcloud;
777+ }
778+
779+ /**
780+ * Set tags into an item, and store into a storage (file or db)
781+ *
782+ * Overwrite Me if you don't like the file format
783+ *
784+ * @param string $item
785+ * @param array $tags
786+ * @param string $filename
787+ * @return boolean
788+ * @access protected
789+ */
790+ function set_tags_into_storage($item, $tags, $filename = null)
791+ {
792+ if ($filename === null) $filename = $this->get_tags_filename($item);
793+ if (empty($tags) && file_exists($filename)) {
794+ return unlink($filename);
795+ }
796+ $contents = implode("\n", $tags) . "\n";
797+ return file_put_contents($filename, $contents);
798+ }
799+
800+ /**
801+ * Set items into a tag, and store into a storage (file or db)
802+ *
803+ * Overwrite Me if you don't like the file format
804+ *
805+ * @param string $tag
806+ * @param array $items
807+ * @param string $filename
808+ * @return boolean
809+ * @access protected
810+ */
811+ function set_items_into_storage($tag, $items, $filename = null)
812+ {
813+ if ($filename === null) $filename = $this->get_items_filename($tag);
814+ if (empty($items) && file_exists($filename)) {
815+ return unlink($filename);
816+ }
817+ $contents = implode("\n", $items) . "\n";
818+ return file_put_contents($filename, $contents);
819+ }
820+
821+ /**
822+ * Store tagcloud into a storage (file or db)
823+ *
824+ * Overwrite Me if you don't like the file format
825+ *
826+ * @param array $tagcloud
827+ * @param string filename
828+ * @return boolean
829+ * @access protected
830+ */
831+ function set_tagcloud_into_storage($tagcloud, $filename = null)
832+ {
833+ if ($filename === null) $filename = $this->get_tagcloud_filename();
834+ $contents = '';
835+ ksort($tagcloud);
836+ foreach ($tagcloud as $tag => $count) {
837+ if ($count === 0) continue;
838+ $contents .= $tag . "\t" . $count . "\n";
839+ }
840+ return file_put_contents($filename, $contents);
841+ }
842+
843+ /**
844+ * Get tags of an item
845+ *
846+ * @param string $item
847+ * @param boolean $cache use memory cache
848+ * @return array
849+ * @uses get_tags_from_storage
850+ * @access public
851+ */
852+ function get_tags($item, $cache = true)
853+ {
854+ if (isset($this->tags[$item]) & $cache) {
855+ return $this->tags[$item];
856+ }
857+ $tags = $this->get_tags_from_storage($item);
858+ if ($cache) $this->tags[$item] = $tags;
859+ return $tags;
860+ }
861+
862+ /**
863+ * Get items by a tag
864+ *
865+ * @param string $tag
866+ * @param boolean $cache use memory cache
867+ * @return array
868+ * @uses get_items_from_storage
869+ * @access public
870+ */
871+ function get_items($tag, $cache = true)
872+ {
873+ if (isset($this->items[$tag]) & $cache) {
874+ return $this->items[$tag];
875+ }
876+ $items = $this->get_items_from_storage($tag);
877+ if ($cache) $this->items[$tag] = $items;
878+ return $items;
879+ }
880+
881+ /**
882+ * Set tags into an item
883+ *
884+ * @param string $item
885+ * @param array $tags
886+ * @param boolean $storage write to storage
887+ * @return boolean
888+ * @uses normalize_tags
889+ * @uses set_tags_into_storage
890+ * @access public
891+ */
892+ function set_tags($item, $tags, $storage = true)
893+ {
894+ $tags = $this->normalize_tags($tags);
895+ // $tags == $this->tags[$item] // key/val pair
896+ list($minus, $plus) = ya_array_diff($this->get_tags($item), $tags);
897+ if (empty($minus) & empty($plus)) {
898+ return true;
899+ }
900+ $this->tags[$item] = $tags;
901+ if ($storage) {
902+ return $this->set_tags_into_storage($item, $tags);
903+ }
904+ return true;
905+ }
906+
907+ /**
908+ * Set items into a tag
909+ *
910+ * @param string $tag
911+ * @param array $items
912+ * @param boolean $storage write to storage
913+ * @return boolean
914+ * @uses set_items_into_storage
915+ * @access public
916+ */
917+ function set_items($tag, $items, $storage = true)
918+ {
919+ // $items == $this->items[$tag] // key/val pair
920+ list($minus, $plus) = ya_array_diff($this->get_items($tag), $items);
921+ if (empty($minus) & empty($plus)) {
922+ return true;
923+ }
924+ $this->items[$tag] = $items;
925+ if ($storage) {
926+ return $this->set_items_into_storage($tag, $items);
927+ }
928+ return true;
929+ }
930+
931+ /**
932+ * Save tags into an item (This does more than set_tags)
933+ *
934+ * @param string $item
935+ * @param mixed $tags string or array of tag(s)
936+ * @return boolean Success or Failure
937+ * @uses normalize_tags
938+ * @uses get_tags
939+ * @uses set_tags
940+ * @uses get_items
941+ * @uses set_items
942+ * @uses update_tagcloud
943+ * @access public
944+ */
945+ function save_tags($item, $new_tags)
946+ {
947+ $new_tags = (array)$new_tags;
948+ $old_tags = $this->get_tags($item);
949+ $new_tags = $this->normalize_tags($new_tags);
950+ $ret = true;
951+ $ret &= $this->set_tags($item, $new_tags);
952+ list($minus, $plus) = ya_array_diff($old_tags, $new_tags);
953+ foreach ($minus as $tag) {
954+ $old_items = $this->get_items($tag);
955+ $new_items = array_diff($old_items, (array)$item);
956+ $ret &= $this->set_items($tag, $new_items);
957+ }
958+ foreach ($plus as $tag) {
959+ $old_items = $this->get_items($tag);
960+ $new_items = array_unique(array_merge($old_items, (array)$item));
961+ $ret &= $this->set_items($tag, $new_items);
962+ }
963+ $ret &= $this->update_tagcloud();
964+ return $ret;
965+ }
966+ /**
967+ * Add tags into an item
968+ *
969+ * @param string $item
970+ * @param mixed $tags string or array of tag(s)
971+ * @return boolean Success or Failure
972+ * @uses normalize_tags
973+ * @uses get_tags
974+ * @uses set_tags
975+ * @uses get_items
976+ * @uses set_items
977+ * @uses update_tagcloud
978+ * @access public
979+ */
980+ function add_tags($item, $tags)
981+ {
982+ $tags = (array)$tags;
983+ $tags = $this->normalize_tags($tags);
984+ $new_tags = array_unique(array_merge($this->get_tags($item), $tags));
985+ // return $this->save_tags($item, $new_tags);
986+ $ret = true;
987+ $ret &= $this->set_tags($item, $new_tags);
988+ foreach ($tags as $tag) {
989+ $old_items = $this->get_items($tag);
990+ $new_items = array_unique(array_merge($old_items, (array)$item));
991+ $ret &= $this->set_items($tag, $new_items);
992+ }
993+ $ret &= $this->update_tagcloud();
994+ return $ret;
995+ }
996+ /**
997+ * Remove tags from an item
998+ *
999+ * @param string $item
1000+ * @param mixed $tags string or array of tag(s)
1001+ * @return boolean Success or Failure
1002+ * @uses normalize_tags
1003+ * @uses get_tags
1004+ * @uses set_tags
1005+ * @uses get_items
1006+ * @uses set_items
1007+ * @uses update_tagcloud
1008+ * @access public
1009+ */
1010+ function remove_tags($item, $tags)
1011+ {
1012+ $tags = (array)$tags;
1013+ $tags = $this->normalize_tags($tags);
1014+ $new_tags = array_diff($this->get_tags($item), $tags);
1015+ // return $this->save_tags($item, $new_tags);
1016+ $ret = true;
1017+ $ret &= $this->set_tags($item, $new_tags);
1018+ foreach ($tags as $tag) {
1019+ $old_items = $this->get_items($tag);
1020+ $new_items = array_diff($old_items, (array)$item);
1021+ $ret &= $this->set_items($tag, $new_items);
1022+ }
1023+ $ret &= $this->update_tagcloud();
1024+ return $ret;
1025+ }
1026+ /**
1027+ * Remove tags from the system
1028+ *
1029+ * @uses Tag::remove_tags()
1030+ *
1031+ * @param mixed $tags string or array of tag(s)
1032+ * @return boolean Success or Failure
1033+ * @uses normalize_tags
1034+ * @uses get_items
1035+ * @uses remove_tags
1036+ * @uses set_items
1037+ * @uses update_tagcloud
1038+ * @access public
1039+ */
1040+ function remove_system_tags($tags)
1041+ {
1042+ $tags = (array)$tags;
1043+ $tags = $this->normalize_tags($tags);
1044+ $ret = true;
1045+ foreach ($tags as $tag) {
1046+ foreach ($this->get_items($tag) as $item) {
1047+ $ret &= $this->remove_tags($item, $tag);
1048+ }
1049+ $ret &= $this->set_items($tag, array());
1050+ }
1051+ $ret &= $this->update_tagcloud();
1052+ return $ret;
1053+ }
1054+ /**
1055+ * Rename a tag
1056+ *
1057+ * @param string $old_tag
1058+ * @param string $new_tag
1059+ * @return boolean Success or Failure
1060+ * @uses normalize_tags
1061+ * @uses get_items
1062+ * @uses set_items
1063+ * @uses remove_tags
1064+ * @uses add_tags
1065+ * @access public
1066+ */
1067+ function rename_tag($old_tag, $new_tag)
1068+ {
1069+ $old_tag = $this->normalize_tags($old_tag);
1070+ $new_tag = $this->normalize_tags($new_tag);
1071+ $items = $this->get_items($old_tag);
1072+ if (empty($items)) return false;
1073+ $ret = true;
1074+ $ret &= $this->set_items($old_tag, array());
1075+ $ret &= $this->set_items($new_tag, $items);
1076+ foreach ($items as $item) {
1077+ $ret &= $this->remove_tags($item, $old_tag);
1078+ $ret &= $this->add_tags($item, $new_tag);
1079+ }
1080+ // $ret &= $this->update_tagcloud();
1081+ return $ret;
1082+ }
1083+
1084+ /**
1085+ * Rename an item
1086+ *
1087+ * @param string $old_item
1088+ * @param string $new_item
1089+ * @return boolean Success or Failure
1090+ * @uses get_tags
1091+ * @uses save_tags
1092+ * @access public
1093+ */
1094+ function rename_item($old_item, $new_item)
1095+ {
1096+ $tags = $this->get_tags($old_item);
1097+ if (empty($tags)) return false;
1098+ $ret = true;
1099+ $ret &= $this->save_tags($old_item, array());
1100+ $ret &= $this->save_tags($new_item, $tags);
1101+ // $ret &= $this->update_tagcloud();
1102+ return $ret;
1103+ }
1104+
1105+ /**
1106+ * Check if a tag exists in a certain item
1107+ *
1108+ * @param string $tag
1109+ * @return boolean
1110+ * @access public
1111+ */
1112+ function has_tag($item, $tag)
1113+ {
1114+ return in_array($tag, $this->get_tags($item));
1115+ }
1116+ /**
1117+ * Check if a tag exists in the system
1118+ *
1119+ * @param string $tag
1120+ * @return boolean
1121+ * @access public
1122+ */
1123+ function has_system_tag($tag)
1124+ {
1125+ $items = $this->get_items($tag);
1126+ return ! empty($items);
1127+ }
1128+ /**
1129+ * Normalize tags
1130+ *
1131+ * @param string or array $tags
1132+ * @return string or array normalized tags
1133+ * @access public
1134+ */
1135+ function normalize_tags($tags)
1136+ {
1137+ $isarray = is_array($tags);
1138+ $tags = (array)$tags;
1139+ // if (extension_loaded('mbstring'))
1140+ //if (function_exists('mb_strtolower')) {
1141+ //foreach ($tags as $i => $tag) {
1142+ //$tags[$i] = mb_strtolower($tag, SOURCE_ENCODING);
1143+ //}
1144+ //}
1145+
1146+ // Reserved keys can not be used for tag strings
1147+ foreach ($tags as $i => $tag) {
1148+ $tags[$i] = str_replace($this->reserved_keys, '', $tag);
1149+ }
1150+ $tags = array_unique($tags);
1151+ if ($isarray) return $tags;
1152+ else return $tags[0];
1153+ }
1154+
1155+ /**
1156+ * Get tagcloud
1157+ *
1158+ * @param integer $limit
1159+ * @param string $relate_tag
1160+ * @param boolean $cache use memory cache
1161+ * @return array
1162+ * @access public
1163+ */
1164+ function get_tagcloud($limit = null, $relate_tag = null, $cache = true)
1165+ {
1166+ if (isset($this->tagcloud) & $cache) {
1167+ $tagcloud = $this->tagcloud;
1168+ } else {
1169+ $tagcloud = $this->get_tagcloud_from_storage();
1170+ }
1171+ if (isset($relate_tag)) {
1172+ $related_tags = $this->get_related_tags($relate_tag);
1173+ $r_tagcloud = array();
1174+ foreach ($related_tags as $tag) {
1175+ $r_tagcloud[$tag] = $tagcloud[$tag];
1176+ }
1177+ $tagcloud = $r_tagcloud;
1178+ }
1179+ if (isset($limit)) {
1180+ arsort($tagcloud);
1181+ $tagcloud = array_slice($tagcloud, 0, $limit);
1182+ ksort($tagcloud);
1183+ }
1184+ return $tagcloud;
1185+ }
1186+
1187+ /**
1188+ * Update tagcloud
1189+ *
1190+ * Excute after set_tags and set_items
1191+ *
1192+ * @param boolean $cache use memory cache
1193+ * @return boolean
1194+ * @access public
1195+ */
1196+ function update_tagcloud($cache = true)
1197+ {
1198+ if (isset($this->tagcloud) & $cache) {
1199+ $tagcloud = $this->tagcloud; // read cache
1200+ } else {
1201+ $tagcloud = $this->get_tagcloud();
1202+ }
1203+ $ret = true;
1204+ if (! empty($this->items)) { // update
1205+ foreach ($this->items as $tag => $items) {
1206+ $count = count($items);
1207+ if ($count === 0) {
1208+ unset($tagcloud[$tag]);
1209+ } else {
1210+ $tagcloud[$tag] = $count;
1211+ }
1212+ }
1213+ ksort($tagcloud);
1214+ $ret &= $this->set_tagcloud_into_storage($tagcloud);
1215+ }
1216+ if ($cache) $this->tagcloud = $tagcloud;
1217+ return $ret;
1218+ }
1219+
1220+ /**
1221+ * Get related tags
1222+ *
1223+ * @param string $tag
1224+ * @return array
1225+ * @access public
1226+ */
1227+ function get_related_tags($tag = null)
1228+ {
1229+ if ($tag === null) return false;
1230+ $items = $this->get_items($tag);
1231+ $tags = array();
1232+ foreach ($items as $item) {
1233+ $tags = array_merge($tags, (array)$this->get_tags($item));
1234+ }
1235+ $tags = array_unique($tags);
1236+ return $tags;
1237+ }
1238+
1239+ /**
1240+ * Get items by a tag token
1241+ *
1242+ * TagA^TagB => intersection
1243+ * TagA-TagB => subtraction
1244+ *
1245+ * @param string $tagtok
1246+ * @return array items
1247+ * @access public
1248+ */
1249+ function get_items_by_tagtok($tagtok)
1250+ {
1251+ // token analysis
1252+ $tags = array();
1253+ $operands = array();
1254+ $tokpos = -1;
1255+
1256+ $token = implode('', $this->reserved_keys);
1257+ $substr = strtok($tagtok, $token);
1258+ array_push($tags, $substr);
1259+ $tokpos = $tokpos + strlen($substr) + 1;
1260+ $substr = strtok($token);
1261+ while ($substr !== false) {
1262+ switch ($tagtok[$tokpos]) {
1263+ case $this->reserved_keys['diff']:
1264+ array_push($operands, $this->reserved_keys['diff']);
1265+ break;
1266+ case $this->reserved_keys['prod']:
1267+ default:
1268+ array_push($operands, $this->reserved_keys['prod']);
1269+ break;
1270+ }
1271+ array_push($tags, $substr);
1272+ $tokpos = $tokpos + strlen($substr) + 1;
1273+ $substr = strtok($token);
1274+ }
1275+
1276+ // narrow items
1277+ $items = $this->get_items(array_shift($tags));
1278+ foreach ($tags as $i => $tag) {
1279+ switch ($operands[$i]) {
1280+ case $this->reserved_keys['diff']:
1281+ $items = array_diff($items, $this->get_items($tag));
1282+ break;
1283+ case $this->reserved_keys['prod']:
1284+ default:
1285+ $items = array_intersect($items, $this->get_items($tag));
1286+ break;
1287+ }
1288+ }
1289+ return $items;
1290+ }
1291+
1292+ /**
1293+ * Display tags
1294+ *
1295+ * Overwrite Me!
1296+ *
1297+ * @param string $item
1298+ * @access public
1299+ */
1300+ function display_tags($tags)
1301+ {
1302+ print_r($tags);
1303+ }
1304+
1305+ /**
1306+ * Display items
1307+ *
1308+ * Overwrite Me!
1309+ *
1310+ * @param string $tag
1311+ * @access public
1312+ */
1313+ function display_items($items)
1314+ {
1315+ print_r($items);
1316+ }
1317+
1318+ /**
1319+ * Display tagcloud
1320+ *
1321+ * Overwrite Me!
1322+ *
1323+ * @param integer $limit
1324+ * @param string $relate_tag
1325+ * @access public
1326+ */
1327+ function display_tagcloud($limit = null, $relate_tag = null)
1328+ {
1329+ $tagcloud = $this->get_tagcloud($limit, $relate_tag);
1330+ print '[Tabcloud]';
1331+ print_r($tagcloud);
1332+ }
1333+}
1334+/*
1335+$tag = new Tag();
1336+$tag->save_tags('Hoge', 'PukiWiki');
1337+$tag->save_tags('Joge', array('PukiWiki', 'Plugin', 'Plugin'));
1338+$tag->save_tags('Moge', array('Plugin', 'Moge'));
1339+$tag->save_tags('Koge', array('Koge'));
1340+$tag->display_tags('Hoge');
1341+$tag->display_tags('Joge');
1342+$tag->display_tags('Moge');
1343+$tag->display_tags('Koge');
1344+$tag->display_items('PukiWiki');
1345+$tag->display_items('Plugin');
1346+$tag->display_tagcloud();
1347+$tag->display_tagcloud(null, 'Plugin');
1348+*/
1349+
1350+/**
1351+ * Generate An HTML Tag Cloud
1352+ *
1353+ * Example
1354+ * <code>
1355+ * $tags = array(
1356+ * array('tag' => 'blog', 'count' => 20),
1357+ * array('tag' => 'ajax', 'count' => 10),
1358+ * array('tag' => 'mysql', 'count' => 5),
1359+ * array('tag' => 'hatena', 'count' => 12),
1360+ * array('tag' => 'bookmark', 'count' => 30),
1361+ * array('tag' => 'rss', 'count' => 1),
1362+ * array('tag' => 'atom', 'count' => 2),
1363+ * array('tag' => 'misc', 'count' => 10),
1364+ * array('tag' => 'javascript', 'count' => 11),
1365+ * array('tag' => 'xml', 'count' => 6),
1366+ * array('tag' => 'perl', 'count' => 32),
1367+ * );
1368+ * $cloud = new TagCloud();
1369+ * foreach ($tags as $t) {
1370+ * $cloud->add($t['tag'], "http://<your.domain>/{$t['tag']}/", $t['count']);
1371+ * }
1372+ * print "<html><body>";
1373+ * print $cloud->htmlAndCSS(20);
1374+ * print "</body></html>";
1375+ * </code>
1376+ *
1377+ * @author astronote
1378+ * @license http://www.gnu.org/licenses/gpl.html GPL2
1379+ * @link http://astronote.jp/
1380+ */
1381+class TagCloud
1382+{
1383+ /**
1384+ * Counts of tags
1385+ *
1386+ * Associative array of integers whose key is a tag and value
1387+ * is its count (number of items associated with the tag)
1388+ *
1389+ * @var array
1390+ *
1391+ * [tag] = count
1392+ */
1393+ var $counts;
1394+ /**
1395+ * Urls of tags
1396+ *
1397+ * Associative array of strings whose key is a tag
1398+ * and value is its link to be displayed in tagcloud
1399+ *
1400+ * @var array
1401+ *
1402+ * [tag] = url
1403+ */
1404+ var $urls;
1405+
1406+ function TagCloud()
1407+ {
1408+ $this->counts = array();
1409+ $this->urls = array();
1410+ }
1411+
1412+ /**
1413+ * Add a tag
1414+ *
1415+ * @param $tag tag
1416+ * @param $url associated url to be displayed in tagcloud
1417+ * @param $count number of items associated with tag.
1418+ * @return void
1419+ * @access public
1420+ */
1421+ function add($tag, $url, $count)
1422+ {
1423+ $this->counts[$tag] = $count;
1424+ $this->urls[$tag] = $url;
1425+ }
1426+
1427+ /**
1428+ * Generate embedded CSS HTML
1429+ *
1430+ * You may create a .css file instead of using this function everytime
1431+ *
1432+ * @return string CSS
1433+ */
1434+ function css()
1435+ {
1436+ $css = '#htmltagcloud { text-align: center; line-height: 16px; }';
1437+ for ($level = 0; $level <= 24; $level++) {
1438+ $font = 12 + $level;
1439+ $css .= "span.tagcloud$level { font-size: ${font}px;}\n";
1440+ $css .= "span.tagcloud$level a {text-decoration: none;}\n";
1441+ }
1442+ return $css;
1443+ }
1444+
1445+ /**
1446+ * Generate tagcloud HTML
1447+ *
1448+ * @param $limit number of limits to be displayed
1449+ * @return string HTML
1450+ * @access public
1451+ */
1452+ function html($limit = NULL)
1453+ {
1454+ $a = $this->counts;
1455+ arsort($a);
1456+ $tags = array_keys($a);
1457+ if (isset($limit)) {
1458+ $tags = array_slice($tags, 0, $limit);
1459+ }
1460+ $n = count($tags);
1461+ if ($n == 0) {
1462+ return '';
1463+ } elseif ($n == 1) {
1464+ $tag = $tags[0];
1465+ $url = $this->urls[$tag];
1466+ return "<div class=\"htmltagcloud\"><span class=\"tagcloud1\"><a href=\"$url\">$tag</a></span></div>\n";
1467+ }
1468+
1469+ $min = sqrt($this->counts[$tags[$n - 1]]);
1470+ $max = sqrt($this->counts[$tags[0]]);
1471+ $factor = 0;
1472+
1473+ // specal case all tags having the same count
1474+ if (($max - $min) == 0) {
1475+ $min -= 24;
1476+ $factor = 1;
1477+ } else {
1478+ $factor = 24 / ($max - $min);
1479+ }
1480+ $html = '';
1481+ sort($tags);
1482+ foreach($tags as $tag) {
1483+ $count = $this->counts[$tag];
1484+ $url = $this->urls[$tag];
1485+ $level = (int)((sqrt($count) - $min) * $factor);
1486+ $html .= "<span class=\"tagcloud$level\"><a href=\"$url\">$tag</a></span>\n";
1487+ }
1488+ $html = "<div class=\"htmltagcloud\">$html</div>";
1489+ return $html;
1490+ }
1491+
1492+ /**
1493+ * Generate tagcloud HTML and embedded CSS HTML concurrently
1494+ *
1495+ * @param $limit number of limits to be displayed in tagcloud
1496+ * @return string HTML
1497+ * @access public
1498+ */
1499+ function htmlAndCSS($limit = NULL)
1500+ {
1501+ $html = "<style type=\"text/css\">\n" . $this->css() . "</style>"
1502+ . $this->html($limit);
1503+ return $html;
1504+ }
1505+}
1506+
1507+?>
--- /dev/null
+++ b/tag/tagcloud.inc.php
@@ -0,0 +1,75 @@
1+<?php
2+/**
3+ * TagCloud Plugin
4+ *
5+ * @author sonots
6+ * @license http://www.gnu.org/licenses/gpl.html GPL
7+ * @link http://lsx.sourceforge.jp/?Plugin%2Ftag.inc.php
8+ * @version $Id: tagcloud.inc.php,v 1.1 2008-03-19 07:23:17Z sonots $
9+ * @uses tag.inc.php
10+ * @package plugin
11+ */
12+
13+exist_plugin('tag') or die_message('tag.inc.php does not exist.');
14+class PluginTagcloud
15+{
16+ var $plugin_tag;
17+
18+ function PluginTagcloud()
19+ {
20+ static $default_options = array();
21+ if (empty($default_options)) {
22+ $default_options['limit'] = NULL;
23+ $default_options['related'] = NULL;
24+ $default_options['cloud'] = TRUE;
25+ }
26+ // static
27+ $this->default_options = & $default_options;
28+ // init
29+ $this->options = $default_options;
30+ global $plugin_tag_name;
31+ $this->plugin_tag = new $plugin_tag_name();
32+ }
33+
34+ function convert() // tagcloud
35+ {
36+ $args = func_get_args();
37+ parse_options($args, $this->options);
38+ if ($this->options['limit'] === "0") {
39+ $this->options['limit'] = NULL;
40+ }
41+ if ($this->options['cloud'] === 'off' ||
42+ $this->options['cloud'] === 'false' ) {
43+ $this->options['cloud'] = FALSE;
44+ }
45+ //print_r($this->options);
46+ if ($this->options['cloud']) {
47+ $html = $this->plugin_tag->display_tagcloud($this->options['limit'], $this->options['related']);
48+ } else {
49+ $html = $this->plugin_tag->display_taglist($this->options['limit'], $this->options['related']);
50+ }
51+ return $html;
52+ }
53+}
54+
55+function plugin_tagcloud_init()
56+{
57+ global $plugin_tagcloud_name;
58+ if (class_exists('PluginTagcloudUnitTest')) {
59+ $plugin_tagcloud_name = 'PluginTagcloudUnitTest';
60+ } elseif (class_exists('PluginTagcloudUser')) {
61+ $plugin_tagcloud_name = 'PluginTagcloudUser';
62+ } else {
63+ $plugin_tagcloud_name = 'PluginTagcloud';
64+ }
65+ plugin_tag_init();
66+}
67+
68+function plugin_tagcloud_convert()
69+{
70+ global $plugin_tagcloud, $plugin_tagcloud_name;
71+ $plugin_tagcloud = new $plugin_tagcloud_name();
72+ $args = func_get_args();
73+ return call_user_func_array(array(&$plugin_tagcloud, 'convert'), $args);
74+}
75+?>
--- /dev/null
+++ b/tag/taglist.inc.php
@@ -0,0 +1,195 @@
1+<?php
2+/**
3+ * List Tagged Pages Plugin
4+ *
5+ * @author sonots
6+ * @license http://www.gnu.org/licenses/gpl.html GPL
7+ * @link http://lsx.sourceforge.jp/?Plugin%2Ftag.inc.php
8+ * @version $Id: taglist.inc.php,v 1.1 2008-03-19 07:23:17Z sonots $
9+ * @uses tag.inc.php
10+ * @package plugin
11+ */
12+
13+exist_plugin('tag') or die_message('tag.inc.php does not exist.');
14+class PluginTaglist
15+{
16+ function PluginTaglist()
17+ {
18+ static $default_options = array();
19+ if (empty($default_options)) {
20+ $default_options['tag'] = '';
21+ $default_options['related'] = NULL;
22+ }
23+ // static
24+ $this->default_options = & $default_options;
25+ // init
26+ $this->options = $default_options;
27+ global $plugin_tag_name;
28+ $this->plugin_tag = new $plugin_tag_name();
29+ }
30+
31+ var $plugin_tag;
32+ var $default_options;
33+ var $options;
34+ var $plugin = 'taglist';
35+
36+ function action() // taglist
37+ {
38+ global $vars;
39+ if (isset($vars['tag'])) {
40+ $this->options['tag'] = $vars['tag'];
41+ $msg = htmlspecialchars($this->options['tag']);
42+ } elseif (isset($vars['related'])) {
43+ $this->options['related'] = $vars['related'];
44+ $msg = htmlspecialchars($this->options['related']);
45+ } else {
46+ $msg = _('Taglist');
47+ }
48+ $body = $this->taglist($this->options['tag'], $this->options['related']);
49+ return array('msg'=>$msg, 'body'=>$body);
50+ }
51+
52+ function convert() // taglist
53+ {
54+ $args = func_get_args();
55+ ///// Support old versions (The 1st arg is tagtok) ///
56+ $fisrtIsOption = FALSE;
57+ foreach ($this->options as $key => $val) {
58+ if (strpos($args[0], $key) === 0) {
59+ $firstIsOption = TRUE; break;
60+ }
61+ }
62+ if (func_num_args() >= 1 && ! $firstIsOption) {
63+ $this->options['tag'] = array_shift($args);
64+ }
65+ //////////////////////////////////////////////////////
66+ parse_options($args, $this->options);
67+ return $this->taglist($this->options['tag'], $this->options['related']);
68+ }
69+
70+ /**
71+ * Body Function of this plugin
72+ */
73+ function taglist($tagtok = '', $relate_tag = NULL)
74+ {
75+ if ($tagtok !== '') {
76+ $pages = $this->plugin_tag->get_taggedpages($tagtok);
77+ $html = $this->display_pagelist($pages);
78+ } else {
79+ $html = $this->display_tagpagelist($relate_tag);
80+ }
81+ return $html;
82+ }
83+
84+ /**
85+ * Display tags and tagged pages
86+ *
87+ * Future Work: Use a common function with lsx.inc.php
88+ *
89+ * @param array $relate_tag Show only related tags of this
90+ * @return string HTML
91+ */
92+ function display_tagpagelist($relate_tag = NULL, $cssclass = 'taglist tags')
93+ {
94+ $tagcloud = $this->plugin_tag->get_tagcloud(NULL, $relate_tag);
95+ $html = '<ul class="' . $cssclass . '">';
96+ foreach ($tagcloud as $tag => $count) {
97+ $html .= '<li>' . $this->plugin_tag->get_taglink($tag);
98+ $pages = $this->plugin_tag->get_taggedpages($tag);
99+ $html .= $this->display_pagelist($pages);
100+ $html .= '</li>';
101+ }
102+ $html .= '</ul>';
103+ return $html;
104+ }
105+
106+ /**
107+ * Display pages
108+ *
109+ * Future Work: Use a common function with lsx.inc.php
110+ *
111+ * @param array $pages pagenames
112+ * @return string HTML
113+ */
114+ function display_pagelist($pages, $cssclass = 'taglist pages')
115+ {
116+ /* PukiWiki standard does listing as <ul><li style="padding-left:16*2px;margin-left:16*2px">.
117+ Since I do no like it, I do as <ul><li style="list-type:none"><ul><li>
118+
119+ <ul> <ul><li>1
120+ <li>1</li> </li><li>1
121+ <li>1 <ul><li>2
122+ <ul> </li></ul></li><li>1
123+ <li>2</li> </li><li>1
124+ </ul> => <ul><li style="list-type:none"><ul><li>3
125+ </li> </li></ul></li></ul></li></ul>
126+ <li>1</li>
127+ <li>1</li>
128+ <ul><li style="list-type:none"><ul>
129+ <li>3</li>
130+ </ul></li></ul>
131+ </li>
132+ </ul>
133+ */
134+ $ul = $pdepth = 0;
135+ foreach ($pages as $i => $page) {
136+ $exist = is_page($page);
137+ $depth = 1;
138+ $link = make_pagelink_nopg($page);
139+ $info = null;
140+ if ($depth > $pdepth) {
141+ $diff = $depth - $pdepth;
142+ $html .= str_repeat('<ul><li style="list-style:none">', $diff - 1);
143+ if ($depth == 1) { // first flag
144+ $html .= '<ul' . (isset($cssclass) ? ' class="' . $cssclass . '"' : '') . '><li>';
145+ } else {
146+ $html .= '<ul><li>';
147+ }
148+ $ul += $diff;
149+ } elseif ($depth == $pdepth) {
150+ $html .= '</li><li>';
151+ } elseif ($depth < $pdepth) {
152+ $diff = $pdepth - $depth;
153+ $html .= str_repeat('</li></ul>', $diff);
154+ $html .= '</li><li>';
155+ $ul -= $diff;
156+ }
157+ $pdepth = $depth;
158+
159+ $html .= $link;
160+ $html .= isset($info) ? $info: '';
161+ }
162+ $html .= str_repeat('</li></ul>', $ul);
163+ return $html;
164+ }
165+}
166+
167+function plugin_taglist_init()
168+{
169+ global $plugin_taglist_name;
170+ if (class_exists('PluginTaglistUnitTest')) {
171+ $plugin_taglist_name = 'PluginTaglistUnitTest';
172+ } elseif (class_exists('PluginTaglistUser')) {
173+ $plugin_taglist_name = 'PluginTaglistUser';
174+ } else {
175+ $plugin_taglist_name = 'PluginTaglist';
176+ }
177+ plugin_tag_init();
178+}
179+
180+function plugin_taglist_convert()
181+{
182+ global $plugin_taglist, $plugin_taglist_name;
183+ $plugin_taglist = new $plugin_taglist_name();
184+ $args = func_get_args();
185+ return call_user_func_array(array(&$plugin_taglist, 'convert'), $args);
186+}
187+
188+function plugin_taglist_action()
189+{
190+ global $plugin_taglist, $plugin_taglist_name;
191+ $plugin_taglist = new $plugin_taglist_name();
192+ return $plugin_taglist->action();
193+}
194+
195+?>