OSDN Git Service

Convert character code of the source code to UTF-8 from EUC-JP
[pukiwiki/pukiwiki.git] / plugin / map.inc.php
1 <?php
2 // PukiWiki - Yet another WikiWikiWeb clone.
3 // $Id: map.inc.php,v 1.18 2011/01/25 15:01:01 henoheno Exp $
4 // Copyright (C) 2002-2005, 2007 PukiWiki Developers Team
5 // License: GPL v2 or (at your option) any later version
6 //
7 // Site map plugin
8
9 /*
10  * プラグイン map: サイトマップ(のようなもの)を表示
11  * Usage : http://.../pukiwiki.php?plugin=map
12  * パラメータ
13  *   &refer=ページ名
14  *     起点となるページを指定
15  *   &reverse=true
16  *     あるページがどこからリンクされているかを一覧。
17 */
18
19 // Show $non_list files
20 define('PLUGIN_MAP_SHOW_HIDDEN', 0); // 0, 1
21
22 function plugin_map_action()
23 {
24         global $vars, $whatsnew, $defaultpage, $non_list;
25
26         $reverse = isset($vars['reverse']);
27         $refer   = isset($vars['refer']) ? $vars['refer'] : '';
28         if ($refer == '' || ! is_page($refer))
29                 $vars['refer'] = $refer = $defaultpage;
30
31         $retval['msg']  = $reverse ? 'Relation map (link from)' : 'Relation map, from $1';
32         $retval['body'] = '';
33
34         // Get pages
35         $pages = array_values(array_diff(get_existpages(), array($whatsnew)));
36         if (! PLUGIN_MAP_SHOW_HIDDEN)
37                 $pages = array_diff($pages, preg_grep('/' . $non_list . '/', $pages));
38         if (empty($pages)) {
39                 $retval['body'] = 'No pages.';
40                 return $retval;
41         } else {
42                 $retval['body'] .= '<p>' . "\n" .  'Total: ' . count($pages) .
43                         ' page(s) on this site.' . "\n" . '</p>' . "\n";
44         }
45
46         // Generate a tree
47         $nodes = array();
48         foreach ($pages as $page)
49                 $nodes[$page] = & new MapNode($page, $reverse);
50
51         // Node not found: Because of filtererd by $non_list
52         if (! isset($nodes[$refer])) $vars['refer'] = $refer = $defaultpage;
53
54         if ($reverse) {
55                 $keys = array_keys($nodes);
56                 sort($keys, SORT_STRING);
57                 $alone = array();
58                 $retval['body'] .= '<ul>' . "\n";
59                 foreach ($keys as $page) {
60                         if (! empty($nodes[$page]->rels)) {
61                                 $retval['body'] .= $nodes[$page]->toString($nodes, 1, $nodes[$page]->parent_id);
62                         } else {
63                                 $alone[] = $page;
64                         }
65                 }
66                 $retval['body'] .= '</ul>' . "\n";
67                 if (! empty($alone)) {
68                         $retval['body'] .= '<hr />' . "\n" .
69                                 '<p>No link from anywhere in this site.</p>' . "\n";
70                         $retval['body'] .= '<ul>' . "\n";
71                         foreach ($alone as $page)
72                                 $retval['body'] .= $nodes[$page]->toString($nodes, 1, $nodes[$page]->parent_id);
73                         $retval['body'] .= '</ul>' . "\n";
74                 }
75         } else {
76                 $nodes[$refer]->chain($nodes);
77                 $retval['body'] .= '<ul>' . "\n" . $nodes[$refer]->toString($nodes) . '</ul>' . "\n";
78                 $retval['body'] .= '<hr />' . "\n" .
79                         '<p>Not related from ' . htmlsc($refer) . '</p>' . "\n";
80                 $keys = array_keys($nodes);
81                 sort($keys, SORT_STRING);
82                 $retval['body'] .= '<ul>' . "\n";
83                 foreach ($keys as $page) {
84                         if (! $nodes[$page]->done) {
85                                 $nodes[$page]->chain($nodes);
86                                 $retval['body'] .= $nodes[$page]->toString($nodes, 1, $nodes[$page]->parent_id);
87                         }
88                 }
89                 $retval['body'] .= '</ul>' . "\n";
90         }
91
92         // 終了
93         return $retval;
94 }
95
96 class MapNode
97 {
98         var $page;
99         var $is_page;
100         var $link;
101         var $id;
102         var $rels;
103         var $parent_id = 0;
104         var $done;
105         var $hide_pattern;
106
107         function MapNode($page, $reverse = FALSE)
108         {
109                 global $script, $non_list;
110
111                 static $id = 0;
112
113                 $this->page    = $page;
114                 $this->is_page = is_page($page);
115                 $this->cache   = CACHE_DIR . encode($page);
116                 $this->done    = ! $this->is_page;
117                 $this->link    = make_pagelink($page);
118                 $this->id      = ++$id;
119                 $this->hide_pattern = '/' . $non_list . '/';
120
121                 $this->rels = $reverse ? $this->ref() : $this->rel();
122                 $mark       = $reverse ? '' : '<sup>+</sup>';
123                 $this->mark = '<a id="rel_' . $this->id . '" href="' . $script .
124                         '?plugin=map&amp;refer=' . rawurlencode($this->page) . '">' .
125                         $mark . '</a>';
126         }
127
128         function hide(& $pages)
129         {
130                 if (! PLUGIN_MAP_SHOW_HIDDEN)
131                         $pages = array_diff($pages, preg_grep($this->hide_pattern, $pages));
132                 return $pages;
133         }
134
135         function ref()
136         {
137                 $refs = array();
138                 $file = $this->cache . '.ref';
139                 if (file_exists($file)) {
140                         foreach (file($file) as $line) {
141                                 $ref = explode("\t", $line);
142                                 $refs[] = $ref[0];
143                         }
144                         $this->hide($refs);
145                         sort($refs, SORT_STRING);
146                 }
147                 return $refs;
148         }
149
150         function rel()
151         {
152                 $rels = array();
153                 $file = $this->cache . '.rel';
154                 if (file_exists($file)) {
155                         $data = file($file);
156                         $rels = explode("\t", trim($data[0]));
157                         $this->hide($rels);
158                         sort($rels, SORT_STRING);
159                 }
160                 return $rels;
161         }
162
163         function chain(& $nodes)
164         {
165                 if ($this->done) return;
166
167                 $this->done = TRUE;
168                 if ($this->parent_id == 0) $this->parent_id = -1;
169
170                 foreach ($this->rels as $page) {
171                         if (! isset($nodes[$page])) $nodes[$page] = & new MapNode($page);
172                         if ($nodes[$page]->parent_id == 0)
173                                 $nodes[$page]->parent_id = $this->id;
174                 }
175                 foreach ($this->rels as $page)
176                         $nodes[$page]->chain($nodes);
177         }
178
179         function toString(& $nodes, $level = 1, $parent_id = -1)
180         {
181                 $indent = str_repeat(' ', $level);
182
183                 if (! $this->is_page) {
184                         return $indent . '<li>' . $this->link . '</li>' . "\n";
185                 } else if ($this->parent_id != $parent_id) {
186                         return $indent . '<li>' . $this->link .
187                                 '<a href="#rel_' . $this->id . '">...</a></li>' . "\n";
188                 }
189                 $retval = $indent . '<li>' . $this->mark . $this->link . "\n";
190                 if (! empty($this->rels)) {
191                         $childs = array();
192                         $level += 2;
193                         foreach ($this->rels as $page)
194                                 if (isset($nodes[$page]) && $this->parent_id != $nodes[$page]->id)
195                                         $childs[] = $nodes[$page]->toString($nodes, $level, $this->id);
196
197                         if (! empty($childs))
198                                 $retval .= $indent . ' <ul>' . "\n" .
199                                         join('', $childs) . $indent . ' </ul>' . "\n";
200                 }
201                 $retval .= $indent . '</li>' . "\n";
202
203                 return $retval;
204         }
205 }
206 ?>