Revision | 4a24baeea36ba75c6bb4963919c87614f956d792 (tree) |
---|---|
Time | 2022-01-24 01:58:20 |
Author | hai-fun <haifun129@gmai...> |
Commiter | hai-fun |
PHP8
@@ -8,1176 +8,1185 @@ | ||
8 | 8 | * @version $Id: contentsx.inc.php,v 1.11 2007-08-03 07:23:17Z sonots $ |
9 | 9 | * @package plugin |
10 | 10 | */ |
11 | + // v1.12 PHP8.0対応 2021-12-15 byはいふん | |
11 | 12 | |
12 | 13 | class PluginContentsx |
13 | 14 | { |
14 | - function PluginContentsx() | |
15 | - { | |
16 | - // Message | |
17 | - static $msg = array(); | |
18 | - if (empty($msg)) $msg = array( | |
19 | - 'toctitle' => _('Table of Contents'), | |
20 | - ); | |
21 | - // Modify here for default option values | |
22 | - static $default_options = array( | |
23 | - 'page' => array('string', ''), | |
24 | - 'fromhere' => array('bool', true), | |
25 | - 'hierarchy' => array('bool', true), | |
26 | - 'compact' => array('bool', true), | |
27 | - 'num' => array('number', ''), | |
28 | - 'depth' => array('number', ''), | |
29 | - 'except' => array('string', ''), | |
30 | - 'filter' => array('string', ''), | |
31 | - 'include' => array('bool', true), | |
32 | - 'cache' => array('enum', 'on', array('on', 'off', 'reset')), | |
33 | - 'link' => array('enum', 'on', array('on', 'off', 'anchor', 'page')), | |
34 | - ); | |
35 | - // Definitions | |
36 | - static $conf = array( | |
37 | - 'def_headline' => '/^(\*{1,3})/', | |
38 | - 'max_depth' => 3, | |
39 | - 'def_include' => '/^#include.*\((.+)\)/', | |
40 | - 'def_title' => '/^TITLE:(.+)/', | |
41 | - 'use_session' => TRUE, // action | |
42 | - 'through_if_admin' => TRUE, // action | |
43 | - ); | |
44 | - $this->msg = &$msg; | |
45 | - $this->default_options = &$default_options; | |
46 | - $this->conf = &$conf; | |
15 | + function __construct() | |
16 | + { | |
17 | + // Message | |
18 | + static $msg = array(); | |
19 | + if (empty($msg)) $msg = array( | |
20 | + 'toctitle' => _('Table of Contents'), | |
21 | + ); | |
22 | + // Modify here for default option values | |
23 | + static $default_options = array( | |
24 | + 'page' => array('string', ''), | |
25 | + 'fromhere' => array('bool', true), | |
26 | + 'hierarchy' => array('bool', true), | |
27 | + 'compact' => array('bool', true), | |
28 | + 'num' => array('number', ''), | |
29 | + 'depth' => array('number', ''), | |
30 | + 'except' => array('string', ''), | |
31 | + 'filter' => array('string', ''), | |
32 | + 'include' => array('bool', true), | |
33 | + 'cache' => array('enum', 'on', array('on', 'off', 'reset')), | |
34 | + 'link' => array('enum', 'on', array('on', 'off', 'anchor', 'page')), | |
35 | + ); | |
36 | + // Definitions | |
37 | + static $conf = array( | |
38 | + 'def_headline' => '/^(\*{1,3})/', | |
39 | + 'max_depth' => 3, | |
40 | + 'def_include' => '/^#include.*\((.+)\)/', | |
41 | + 'def_title' => '/^TITLE:(.+)/', | |
42 | + 'use_session' => TRUE, // action | |
43 | + 'through_if_admin' => TRUE, // action | |
44 | + ); | |
45 | + $this->msg = &$msg; | |
46 | + $this->default_options = &$default_options; | |
47 | + $this->conf = &$conf; | |
47 | 48 | |
48 | - // init | |
49 | - $this->options = $this->default_options; | |
50 | - } | |
49 | + // init | |
50 | + $this->options = $this->default_options; | |
51 | + } | |
51 | 52 | |
52 | - // static | |
53 | - var $msg; | |
54 | - var $default_options; | |
55 | - var $conf; | |
56 | - // var | |
57 | - var $args; | |
58 | - var $options; | |
59 | - var $error = ""; | |
60 | - var $plugin = "contentsx"; | |
61 | - var $metalines; | |
62 | - var $visited = array(); // page => title(alias) | |
53 | + function PluginContentsx() { | |
54 | + $this->__construct(); | |
55 | + } | |
63 | 56 | |
64 | - function action() // clean cache | |
65 | - { | |
66 | - global $vars; | |
57 | + // static | |
58 | + var $msg; | |
59 | + var $default_options; | |
60 | + var $conf; | |
61 | + // var | |
62 | + var $args; | |
63 | + var $options; | |
64 | + var $error = ""; | |
65 | + var $plugin = "contentsx"; | |
66 | + var $metalines; | |
67 | + var $visited = array(); // page => title(alias) | |
67 | 68 | |
68 | - if (is_admin($vars['pass'], $this->conf['use_session'], $this->conf['through_if_admin']) && | |
69 | - $vars['pcmd'] == 'clean') { | |
70 | - $body = $this->clean_cache(); | |
71 | - } else { | |
72 | - $body = $this->display_password_form(); | |
73 | - } | |
74 | - return array('msg'=>'Clean Contentsx Caches', 'body'=>$body); | |
75 | - } | |
76 | - | |
77 | - function clean_cache() | |
78 | - { | |
79 | - set_time_limit(0); | |
80 | - global $vars; | |
69 | + function action() // clean cache | |
70 | + { | |
71 | + global $vars; | |
81 | 72 | |
82 | - $page = isset($vars['page']) ? $vars['page'] : ''; | |
83 | - if ($page != '') { | |
84 | - $file = $this->get_cache_filename($page); | |
85 | - @unlink($file); | |
86 | - if (exec_page($page, '/^#contentsx/')) { | |
87 | - $body = 'Recreated a cache of '; | |
88 | - } else { | |
89 | - $body = 'No #contentsx in '; | |
90 | - } | |
91 | - $body .= make_pagelink($page); | |
92 | - } else { | |
93 | - // remove all files | |
94 | - $files = $this->get_cache_filenames(); | |
95 | - foreach ($files as $file) { | |
96 | - unlink($file); | |
97 | - } | |
98 | - // execute all pages | |
99 | - $exec_pages = exec_existpages('/^#contentsx/'); | |
100 | - if (empty($exec_pages)) { | |
101 | - $body = ''; | |
102 | - } else { | |
103 | - $links = array_map('make_pagelink', $exec_pages); | |
104 | - $body = '<p>Following pages were executed to assure:</p>' | |
105 | - . '<p>' . implode("<br />\n", $links) . '</p>'; | |
106 | - } | |
107 | - } | |
108 | - return $body; | |
109 | - } | |
73 | + if (is_admin($vars['pass'], $this->conf['use_session'], $this->conf['through_if_admin']) && | |
74 | + $vars['pcmd'] == 'clean') { | |
75 | + $body = $this->clean_cache(); | |
76 | + } else { | |
77 | + $body = $this->display_password_form(); | |
78 | + } | |
79 | + return array('msg'=>'Clean Contentsx Caches', 'body'=>$body); | |
80 | + } | |
81 | + | |
82 | + function clean_cache() | |
83 | + { | |
84 | + set_time_limit(0); | |
85 | + global $vars; | |
110 | 86 | |
111 | - /** | |
112 | - * Display a password form | |
113 | - * | |
114 | - * @param $msg error message or some messages | |
115 | - * @return string form html | |
116 | - */ | |
117 | - function display_password_form($message = "") | |
118 | - { | |
119 | - $cmd = $this->plugin; | |
120 | - $pcmd = 'clean'; | |
121 | - $form = array(); | |
122 | - $form[] = '<form action="' . get_script_uri() . '?cmd=' . $cmd . '" method="post">'; | |
123 | - $form[] = '<div>'; | |
124 | - $form[] = ' <input type="hidden" name="pcmd" value="' . $pcmd . '" />'; | |
125 | - $form[] = ' <input type="text" name="page" size="24" value="" /> ' . _('A Page (Blank if All)') . '<br />'; | |
126 | - if (! is_admin(null, $this->conf['use_session'], $this->conf['through_if_admin'])) { | |
127 | - $form[] = ' <input type="password" name="pass" size="24" value="" /> ' . _('Admin Password') . '<br />'; | |
128 | - } else { | |
129 | - $form[] = ' <input type="password" name="pass" size="24" value="" style="background-color:#ddd;" disabled="disabled" /> ' . _('Admin Password') . '<br />'; | |
130 | - } | |
131 | - $form[] = ' <input type="submit" name="submit" value="Submit" /><br />'; | |
132 | - $form[] = '</div>'; | |
133 | - $form[] = '</form>'; | |
134 | - $form = implode("\n", $form); | |
135 | - | |
136 | - if ($message != '') { | |
137 | - $message = '<p><b>' . htmlspecialchars($message) . '</b></p>'; | |
138 | - } | |
139 | - return $message . $form; | |
140 | - } | |
87 | + $page = isset($vars['page']) ? $vars['page'] : ''; | |
88 | + if ($page != '') { | |
89 | + $file = $this->get_cache_filename($page); | |
90 | + @unlink($file); | |
91 | + if (exec_page($page, '/^#contentsx/')) { | |
92 | + $body = 'Recreated a cache of '; | |
93 | + } else { | |
94 | + $body = 'No #contentsx in '; | |
95 | + } | |
96 | + $body .= make_pagelink($page); | |
97 | + } else { | |
98 | + // remove all files | |
99 | + $files = $this->get_cache_filenames(); | |
100 | + foreach ($files as $file) { | |
101 | + unlink($file); | |
102 | + } | |
103 | + // execute all pages | |
104 | + $exec_pages = exec_existpages('/^#contentsx/'); | |
105 | + if (empty($exec_pages)) { | |
106 | + $body = ''; | |
107 | + } else { | |
108 | + $links = array_map('make_pagelink', $exec_pages); | |
109 | + $body = '<p>Following pages were executed to assure:</p>' | |
110 | + . '<p>' . implode("<br />\n", $links) . '</p>'; | |
111 | + } | |
112 | + } | |
113 | + return $body; | |
114 | + } | |
141 | 115 | |
142 | - function convert() | |
143 | - { | |
144 | - $args = func_get_args(); | |
145 | - if ($GLOBALS['vars']['cmd'] != 'read') { | |
146 | - return ''; | |
147 | - } | |
148 | - $body = $this->body($args); | |
149 | - if ($body != '') { | |
150 | - $body = '<table border="0" class="toc"><tbody>' . "\n" | |
151 | - . '<tr><td class="toctitle">' . "\n" | |
152 | - . '<span>' . $this->msg['toctitle'] . "</span>\n" | |
153 | - . "</td></tr>\n" | |
154 | - . '<tr><td class="toclist">' . "\n" | |
155 | - . $body | |
156 | - . "</td></tr>\n" | |
157 | - . "</tbody></table>\n"; | |
158 | - } | |
159 | - if ($this->error != "" ) { | |
160 | - return "<p>#$this->plugin(): $this->error</p>"; | |
161 | - } | |
162 | - return $body; | |
163 | - } | |
164 | - | |
165 | - function body($args) | |
166 | - { | |
167 | - global $vars; | |
116 | + /** | |
117 | + * Display a password form | |
118 | + * | |
119 | + * @param $msg error message or some messages | |
120 | + * @return string form html | |
121 | + */ | |
122 | + function display_password_form($message = "") | |
123 | + { | |
124 | + $cmd = $this->plugin; | |
125 | + $pcmd = 'clean'; | |
126 | + $form = array(); | |
127 | + $form[] = '<form action="' . get_script_uri() . '?cmd=' . $cmd . '" method="post">'; | |
128 | + $form[] = '<div>'; | |
129 | + $form[] = ' <input type="hidden" name="pcmd" value="' . $pcmd . '" />'; | |
130 | + $form[] = ' <input type="text" name="page" size="24" value="" /> ' . _('A Page (Blank if All)') . '<br />'; | |
131 | + if (! is_admin(null, $this->conf['use_session'], $this->conf['through_if_admin'])) { | |
132 | + $form[] = ' <input type="password" name="pass" size="24" value="" /> ' . _('Admin Password') . '<br />'; | |
133 | + } else { | |
134 | + $form[] = ' <input type="password" name="pass" size="24" value="" style="background-color:#ddd;" disabled="disabled" /> ' . _('Admin Password') . '<br />'; | |
135 | + } | |
136 | + $form[] = ' <input type="submit" name="submit" value="Submit" /><br />'; | |
137 | + $form[] = '</div>'; | |
138 | + $form[] = '</form>'; | |
139 | + $form = implode("\n", $form); | |
140 | + | |
141 | + if ($message != '') { | |
142 | + $message = '<p><b>' . htmlsc($message) . '</b></p>'; | |
143 | + } | |
144 | + return $message . $form; | |
145 | + } | |
168 | 146 | |
169 | - $parser = new PluginContentsxOptionParser(); | |
170 | - $this->options = $parser->parse_options($args, $this->options); | |
171 | - if ($parser->error != "") { $this->error = $parser->error; return; } | |
147 | + function convert() | |
148 | + { | |
149 | + $args = func_get_args(); | |
150 | + if ($GLOBALS['vars']['cmd'] != 'read') { | |
151 | + return ''; | |
152 | + } | |
153 | + $body = $this->body($args); | |
154 | + if ($body != '') { | |
155 | + $body = '<table border="0" class="toc"><tbody>' . "\n" | |
156 | + . '<tr><td class="toctitle">' . "\n" | |
157 | + . '<span>' . $this->msg['toctitle'] . "</span>\n" | |
158 | + . "</td></tr>\n" | |
159 | + . '<tr><td class="toclist">' . "\n" | |
160 | + . $body | |
161 | + . "</td></tr>\n" | |
162 | + . "</tbody></table>\n"; | |
163 | + } | |
164 | + if ($this->error != "" ) { | |
165 | + return "<p>#$this->plugin(): $this->error</p>"; | |
166 | + } | |
167 | + return $body; | |
168 | + } | |
169 | + | |
170 | + function body($args) | |
171 | + { | |
172 | + global $vars; | |
172 | 173 | |
173 | - $this->options['page'][1] = $this->check_page($this->options['page'][1]); | |
174 | - if ($this->error !== "") { return; } | |
174 | + $parser = new PluginContentsxOptionParser(); | |
175 | + $this->options = $parser->parse_options($args, $this->options); | |
176 | + if ($parser->error != "") { $this->error = $parser->error; return; } | |
175 | 177 | |
176 | - $this->init_metalines($this->options['page'][1]); | |
177 | - if ($this->error !== "") { return; } | |
178 | - | |
179 | - $this->narrow_metalines(); | |
180 | - if ($this->error !== "") { return; } | |
178 | + $this->options['page'][1] = $this->check_page($this->options['page'][1]); | |
179 | + if ($this->error !== "") { return; } | |
181 | 180 | |
182 | - $body = $this->frontend(); | |
183 | - if ($this->error !== "") { return; } | |
184 | - return $body; | |
185 | - } | |
181 | + $this->init_metalines($this->options['page'][1]); | |
182 | + if ($this->error !== "") { return; } | |
183 | + | |
184 | + $this->narrow_metalines(); | |
185 | + if ($this->error !== "") { return; } | |
186 | 186 | |
187 | - function get_title($page) | |
188 | - { | |
189 | - $page = $this->check_page($page); | |
190 | - $this->init_metalines($page); | |
191 | - $title = $this->visited[$page]; | |
192 | - // FYI: $title = strip_htmltag(make_link($title)); | |
193 | - // $link = make_pagelink($page, $title); | |
194 | - return $title; | |
195 | - } | |
187 | + $body = $this->frontend(); | |
188 | + if ($this->error !== "") { return; } | |
189 | + return $body; | |
190 | + } | |
196 | 191 | |
197 | - function get_visited($page) | |
198 | - { | |
199 | - $page = $this->check_page($page); | |
200 | - $this->init_metalines($page); | |
201 | - return array_keys($this->visited); | |
202 | - } | |
192 | + function get_title($page) | |
193 | + { | |
194 | + $page = $this->check_page($page); | |
195 | + $this->init_metalines($page); | |
196 | + $title = $this->visited[$page]; | |
197 | + // FYI: $title = strip_htmltag(make_link($title)); | |
198 | + // $link = make_pagelink($page, $title); | |
199 | + return $title; | |
200 | + } | |
203 | 201 | |
204 | - function get_metalines($page) | |
205 | - { | |
206 | - $page = $this->check_page($page); | |
207 | - $this->init_metalines($page); | |
208 | - return $this->metalines; | |
209 | - } | |
202 | + function get_visited($page) | |
203 | + { | |
204 | + $page = $this->check_page($page); | |
205 | + $this->init_metalines($page); | |
206 | + return array_keys($this->visited); | |
207 | + } | |
210 | 208 | |
211 | - function narrow_metalines() | |
212 | - { | |
213 | - $this->fromhere_metalines(); | |
214 | - $this->include_metalines(); | |
215 | - $this->filter_metalines(); | |
216 | - $this->except_metalines(); | |
217 | - | |
218 | - $parser = new PluginContentsxOptionParser(); | |
219 | - $this->options['depth'][1] = $parser->parse_numoption($this->options['depth'][1], 0, $this->conf['max_depth']); | |
220 | - if ($parser->error != "") { $this->error = $parser->error; return; } | |
221 | - $this->depth_filter_metalines(); | |
222 | - | |
223 | - $num = sizeof($this->metalines); | |
224 | - $this->options['num'][1] = $parser->parse_numoption($this->options['num'][1], 1, $num); | |
225 | - if ($parser->error != "") { $this->error = $parser->error; return; } | |
226 | - $this->num_filter_metalines(); | |
227 | - } | |
209 | + function get_metalines($page) | |
210 | + { | |
211 | + $page = $this->check_page($page); | |
212 | + $this->init_metalines($page); | |
213 | + return $this->metalines; | |
214 | + } | |
228 | 215 | |
229 | - function frontend() | |
230 | - { | |
231 | - $this->hierarchy_metalines(); | |
232 | - $this->compact_metalines(); | |
233 | - $this->makelink_metalines(); | |
234 | - | |
235 | - return $this->list_metalines(); | |
236 | - } | |
216 | + function narrow_metalines() | |
217 | + { | |
218 | + $this->fromhere_metalines(); | |
219 | + $this->include_metalines(); | |
220 | + $this->filter_metalines(); | |
221 | + $this->except_metalines(); | |
222 | + | |
223 | + $parser = new PluginContentsxOptionParser(); | |
224 | + $this->options['depth'][1] = $parser->parse_numoption($this->options['depth'][1], 0, $this->conf['max_depth']); | |
225 | + if ($parser->error != "") { $this->error = $parser->error; return; } | |
226 | + $this->depth_filter_metalines(); | |
227 | + | |
228 | + $num = sizeof($this->metalines); | |
229 | + $this->options['num'][1] = $parser->parse_numoption($this->options['num'][1], 1, $num); | |
230 | + if ($parser->error != "") { $this->error = $parser->error; return; } | |
231 | + $this->num_filter_metalines(); | |
232 | + } | |
237 | 233 | |
238 | - function list_metalines() | |
239 | - { | |
240 | - if (sizeof($this->metalines) == 0) { | |
241 | - return; | |
242 | - } | |
243 | - | |
244 | - /* HTML validate (without <ul><li style="list-type:none"><ul><li>, we have to do as | |
245 | - <ul><li style="padding-left:16*2px;margin-left:16*2px"> as pukiwiki standard. I did not like it) | |
246 | - | |
247 | - <ul> <ul><li>1 | |
248 | - <li>1</li> </li><li>1 | |
249 | - <li>1 <ul><li>2 | |
250 | - <ul> </li></ul></li><li>1 | |
251 | - <li>2</li> </li><li>1 | |
252 | - </ul> => <ul><li style="list-type:none"><ul><li>3 | |
253 | - </li> </li></ul></li></ul></li></ul> | |
254 | - <li>1</li> | |
255 | - <li>1</li> | |
256 | - <ul><li style="list-type:none"><ul> | |
257 | - <li>3</li> | |
258 | - </ul></li></ul> | |
259 | - </li> | |
260 | - </ul> | |
261 | - */ | |
262 | - | |
263 | - $ul = $pdepth = 0; | |
264 | - foreach ($this->metalines as $metaline) { | |
265 | - $display = $metaline['display']; | |
266 | - $depth = $metaline['listdepth']; | |
267 | - if ($depth > $pdepth) { | |
268 | - $diff = $depth - $pdepth; | |
269 | - $html .= str_repeat('<ul><li style="list-style:none">', $diff - 1); | |
270 | - if ($depth == 1) { // or $first flag | |
271 | - $html .= '<ul class="' . $this->plugin . '"><li>'; | |
272 | - } else { | |
273 | - $html .= '<ul><li>'; | |
274 | - } | |
275 | - $ul += $diff; | |
276 | - } elseif ($depth == $pdepth) { | |
277 | - $html .= '</li><li>'; | |
278 | - } elseif ($depth < $pdepth) { | |
279 | - $diff = $pdepth - $depth; | |
280 | - $html .= str_repeat('</li></ul>', $diff); | |
281 | - $html .= '</li><li>'; | |
282 | - $ul -= $diff; | |
283 | - } | |
284 | - $html .= $display; | |
285 | - $html .= "\n"; | |
286 | - $pdepth = $depth; | |
287 | - } | |
288 | - $html .= str_repeat('</li></ul>', $ul); | |
289 | - return $html; | |
290 | - } | |
291 | - | |
292 | - function makelink_metalines() | |
293 | - { | |
294 | - $metalines = array(); | |
295 | - foreach ($this->metalines as $metaline) { | |
296 | - $anchor = $metaline['anchor']; | |
297 | - $headline = $metaline['headline']; | |
298 | - $headline = strip_htmltag(make_link($headline)); // convert inline plugin | |
299 | - $metaline['display'] = $this->make_pagelink($this->options['page'][1], $headline, $anchor); | |
300 | - $metalines[] = $metaline; | |
301 | - } | |
302 | - $this->metalines = $metalines; | |
303 | - } | |
304 | - | |
305 | - function make_pagelink($page, $alias, $anchor) | |
306 | - { | |
307 | - global $vars; | |
308 | - if ($this->options['link'][1] == 'off' || $anchor =='') { | |
309 | - return htmlspecialchars($alias); | |
310 | - } | |
311 | - if (($this->options['link'][1] == 'on' && $page == $vars['page']) | |
312 | - || $this->options['link'][1] == 'anchor') { | |
313 | - $page = ''; | |
314 | - } | |
315 | - global $show_passage; | |
316 | - $tmp = $show_passage; $show_passage = 0; | |
317 | - $link = make_pagelink($page, $alias, $anchor); | |
318 | - $show_passage = $tmp; | |
319 | - return $link; | |
320 | - } | |
234 | + function frontend() | |
235 | + { | |
236 | + $this->hierarchy_metalines(); | |
237 | + $this->compact_metalines(); | |
238 | + $this->makelink_metalines(); | |
239 | + | |
240 | + return $this->list_metalines(); | |
241 | + } | |
321 | 242 | |
322 | - function compact_metalines() | |
323 | - { | |
324 | - // Hmmmmm, complex | |
325 | - if (!$this->options['compact'][1]) { | |
326 | - return; | |
327 | - } | |
328 | - if (! $this->options['hierarchy'][1]) { | |
329 | - return; | |
330 | - } | |
331 | - // 1) fill in list spaces for each page | |
332 | - // 1 3 1 1 3 3 1 => 1 2 1 1 2 2 1 (2 was none, move 3 to 2) | |
333 | - // 2 2 2 => 1 1 1 | |
334 | - $listdepthstack = array(); | |
335 | - foreach ($this->metalines as $metaline) { | |
336 | - $page = $metaline['page']; | |
337 | - $listdepth = $metaline['listdepth']; | |
338 | - if(! in_array($listdepth, $listdepthstack[$page])) { | |
339 | - $listdepthstack[$page][] = $listdepth; | |
340 | - } | |
341 | - } | |
342 | - foreach (array_keys($listdepthstack) as $page) { | |
343 | - sort($listdepthstack[$page]); | |
344 | - } | |
345 | - // 1 2 4 == (0=>1, 1=>2, 2=>4) -> (1=>1, 1=>2, 3=>4) -exchange keys and values-> (1=>1, 2=>1, 4=>3) | |
346 | - $listdepthfill = array(); | |
347 | - foreach ($listdepthstack as $page => $stack) { | |
348 | - foreach($stack as $i => $listdepth) { | |
349 | - $listdepthfill[$page][$listdepth] = $i + 1; | |
350 | - } | |
351 | - } | |
352 | - $metalines = array(); | |
353 | - foreach ($this->metalines as $metaline) { | |
354 | - $page = $metaline['page']; | |
355 | - $listdepth = $metaline['listdepth']; | |
356 | - $metaline['listdepth'] = $listdepthfill[$page][$listdepth]; | |
357 | - $metalines[] = $metaline; | |
358 | - } | |
359 | - $this->metalines = $metalines; | |
243 | + function list_metalines() | |
244 | + { | |
245 | + if (sizeof($this->metalines) == 0) { | |
246 | + return; | |
247 | + } | |
248 | + | |
249 | + /* HTML validate (without <ul><li style="list-type:none"><ul><li>, we have to do as | |
250 | + <ul><li style="padding-left:16*2px;margin-left:16*2px"> as pukiwiki standard. I did not like it) | |
251 | + | |
252 | + <ul> <ul><li>1 | |
253 | + <li>1</li> </li><li>1 | |
254 | + <li>1 <ul><li>2 | |
255 | + <ul> </li></ul></li><li>1 | |
256 | + <li>2</li> </li><li>1 | |
257 | + </ul> => <ul><li style="list-type:none"><ul><li>3 | |
258 | + </li> </li></ul></li></ul></li></ul> | |
259 | + <li>1</li> | |
260 | + <li>1</li> | |
261 | + <ul><li style="list-type:none"><ul> | |
262 | + <li>3</li> | |
263 | + </ul></li></ul> | |
264 | + </li> | |
265 | + </ul> | |
266 | + */ | |
267 | + | |
268 | + $html = ""; | |
269 | + $ul = $pdepth = 0; | |
270 | + foreach ($this->metalines as $metaline) { | |
271 | + $display = $metaline['display']; | |
272 | + $depth = $metaline['listdepth']; | |
273 | + if ($depth > $pdepth) { | |
274 | + $diff = $depth - $pdepth; | |
275 | + $html .= str_repeat('<ul><li style="list-style:none">', $diff - 1); | |
276 | + if ($depth == 1) { // or $first flag | |
277 | + $html .= '<ul class="' . $this->plugin . '"><li>'; | |
278 | + } else { | |
279 | + $html .= '<ul><li>'; | |
280 | + } | |
281 | + $ul += $diff; | |
282 | + } elseif ($depth == $pdepth) { | |
283 | + $html .= '</li><li>'; | |
284 | + } elseif ($depth < $pdepth) { | |
285 | + $diff = $pdepth - $depth; | |
286 | + $html .= str_repeat('</li></ul>', $diff); | |
287 | + $html .= '</li><li>'; | |
288 | + $ul -= $diff; | |
289 | + } | |
290 | + $html .= $display; | |
291 | + $html .= "\n"; | |
292 | + $pdepth = $depth; | |
293 | + } | |
294 | + $html .= str_repeat('</li></ul>', $ul); | |
295 | + return $html; | |
296 | + } | |
297 | + | |
298 | + function makelink_metalines() | |
299 | + { | |
300 | + $metalines = array(); | |
301 | + foreach ($this->metalines as $metaline) { | |
302 | + $anchor = $metaline['anchor']; | |
303 | + $headline = $metaline['headline']; | |
304 | + $headline = strip_htmltag(make_link($headline)); // convert inline plugin | |
305 | + $metaline['display'] = $this->make_pagelink($this->options['page'][1], $headline, $anchor); | |
306 | + $metalines[] = $metaline; | |
307 | + } | |
308 | + $this->metalines = $metalines; | |
309 | + } | |
310 | + | |
311 | + function make_pagelink($page, $alias, $anchor) | |
312 | + { | |
313 | + global $vars; | |
314 | + if ($this->options['link'][1] == 'off' || $anchor =='') { | |
315 | + return htmlsc($alias); | |
316 | + } | |
317 | + if (($this->options['link'][1] == 'on' && $page == $vars['page']) | |
318 | + || $this->options['link'][1] == 'anchor') { | |
319 | + $page = ''; | |
320 | + } | |
321 | + global $show_passage; | |
322 | + $tmp = $show_passage; $show_passage = 0; | |
323 | + $link = make_pagelink($page, $alias, $anchor); | |
324 | + $show_passage = $tmp; | |
325 | + return $link; | |
326 | + } | |
360 | 327 | |
361 | - // 2) fill in previous list space, seperately for each page | |
362 | - // 1 3 2 => 1 2 2 | |
363 | - $pdepth = array(); $plistdepth = array(); | |
364 | - foreach (array_keys($listdepthstack) as $page) { | |
365 | - $pdepth[$page] = -1; | |
366 | - $plistdepth[$page] = 0; | |
367 | - } | |
368 | - $metalines = array(); | |
369 | - $this->hoge = array(); | |
370 | - foreach ($this->metalines as $metaline) { | |
371 | - $page = $metaline['page']; | |
372 | - if ($metaline['depth'] > $pdepth[$page]) { | |
373 | - $metaline['listdepth'] = $plistdepth[$page] + 1; | |
374 | - } elseif($metaline['depth'] == $pdepth[$page]) { | |
375 | - $metaline['listdepth'] = $plistdepth[$page]; | |
376 | - } else { | |
377 | - $metaline['listdepth'] = ($plistdepth[$page] < $metaline['listdepth']) ? $plistdepth[$page]: $metaline['listdepth']; | |
378 | - } | |
379 | - $pdepth[$page] = $metaline['depth']; | |
380 | - $plistdepth[$page] = $metaline['listdepth']; | |
381 | - $metalines[] = $metaline; | |
382 | - } | |
383 | - $this->metalines = $metalines; | |
384 | - } | |
385 | - | |
386 | - function hierarchy_metalines() | |
387 | - { | |
388 | - $include = 0; | |
389 | - if ($this->options['include'][1] && sizeof($this->visited) >= 2) { // include (0,1,2,3...) -> (1,2,3,4...) | |
390 | - $include = 1; | |
391 | - } | |
392 | - $metalines = array(); | |
393 | - foreach($this->metalines as $metaline) { | |
394 | - if ($this->options['hierarchy'][1]) { | |
395 | - $metaline['listdepth'] = $metaline['depth'] + $include; | |
396 | - } else { | |
397 | - $metaline['listdepth'] = 1; | |
398 | - } | |
399 | - $metalines[] = $metaline; | |
400 | - } | |
401 | - $this->metalines = $metalines; | |
402 | - } | |
403 | - | |
404 | - function num_filter_metalines() | |
405 | - { | |
406 | - if ($this->options['num'][1] === '') { | |
407 | - return; | |
408 | - } | |
409 | - $metalines = array(); | |
410 | - foreach ($this->options['num'][1] as $num) { | |
411 | - $metalines[] = $this->metalines[$num - 1]; | |
412 | - } | |
413 | - $this->metalines = $metalines; | |
414 | - } | |
328 | + function compact_metalines() | |
329 | + { | |
330 | + // Hmmmmm, complex | |
331 | + if (!$this->options['compact'][1]) { | |
332 | + return; | |
333 | + } | |
334 | + if (! $this->options['hierarchy'][1]) { | |
335 | + return; | |
336 | + } | |
337 | + // 1) fill in list spaces for each page | |
338 | + // 1 3 1 1 3 3 1 => 1 2 1 1 2 2 1 (2 was none, move 3 to 2) | |
339 | + // 2 2 2 => 1 1 1 | |
340 | + $listdepthstack = array(); | |
341 | + foreach ($this->metalines as $metaline) { | |
342 | + $page = $metaline['page']; | |
343 | + $listdepth = $metaline['listdepth']; | |
344 | + if (empty($listdepthstack[$page])) { | |
345 | + $listdepthstack[$page][] = $listdepth; | |
346 | + } | |
347 | + else if(! in_array($listdepth, $listdepthstack[$page])) { | |
348 | + $listdepthstack[$page][] = $listdepth; | |
349 | + } | |
350 | + } | |
351 | + foreach (array_keys($listdepthstack) as $page) { | |
352 | + sort($listdepthstack[$page]); | |
353 | + } | |
354 | + // 1 2 4 == (0=>1, 1=>2, 2=>4) -> (1=>1, 1=>2, 3=>4) -exchange keys and values-> (1=>1, 2=>1, 4=>3) | |
355 | + $listdepthfill = array(); | |
356 | + foreach ($listdepthstack as $page => $stack) { | |
357 | + foreach($stack as $i => $listdepth) { | |
358 | + $listdepthfill[$page][$listdepth] = $i + 1; | |
359 | + } | |
360 | + } | |
361 | + $metalines = array(); | |
362 | + foreach ($this->metalines as $metaline) { | |
363 | + $page = $metaline['page']; | |
364 | + $listdepth = $metaline['listdepth']; | |
365 | + $metaline['listdepth'] = $listdepthfill[$page][$listdepth]; | |
366 | + $metalines[] = $metaline; | |
367 | + } | |
368 | + $this->metalines = $metalines; | |
415 | 369 | |
416 | - function depth_filter_metalines() | |
417 | - { | |
418 | - if ($this->options['depth'][1] === '') { | |
419 | - return; | |
420 | - } | |
421 | - $metalines = array(); | |
422 | - foreach ($this->metalines as $metaline) { | |
423 | - $depth = $metaline['depth']; | |
424 | - if (in_array($depth, $this->options['depth'][1])) { | |
425 | - $metalines[] = $metaline; | |
426 | - } | |
427 | - } | |
428 | - $this->metalines = $metalines; | |
429 | - } | |
430 | - | |
431 | - function filter_metalines() | |
432 | - { | |
433 | - if ($this->options['filter'][1] === "") { | |
434 | - return; | |
435 | - } | |
436 | - $metalines = array(); | |
437 | - foreach ($this->metalines as $metaline) { | |
438 | - $headline = $metaline['headline']; | |
439 | - if (ereg($this->options['filter'][1], $headline)) { | |
440 | - $metalines[] = $metaline; | |
441 | - } | |
442 | - } | |
443 | - $this->metalines = $metalines; | |
444 | - } | |
370 | + // 2) fill in previous list space, seperately for each page | |
371 | + // 1 3 2 => 1 2 2 | |
372 | + $pdepth = array(); $plistdepth = array(); | |
373 | + foreach (array_keys($listdepthstack) as $page) { | |
374 | + $pdepth[$page] = -1; | |
375 | + $plistdepth[$page] = 0; | |
376 | + } | |
377 | + $metalines = array(); | |
378 | + $this->hoge = array(); | |
379 | + foreach ($this->metalines as $metaline) { | |
380 | + $page = $metaline['page']; | |
381 | + if ($metaline['depth'] > $pdepth[$page]) { | |
382 | + $metaline['listdepth'] = $plistdepth[$page] + 1; | |
383 | + } elseif($metaline['depth'] == $pdepth[$page]) { | |
384 | + $metaline['listdepth'] = $plistdepth[$page]; | |
385 | + } else { | |
386 | + $metaline['listdepth'] = ($plistdepth[$page] < $metaline['listdepth']) ? $plistdepth[$page]: $metaline['listdepth']; | |
387 | + } | |
388 | + $pdepth[$page] = $metaline['depth']; | |
389 | + $plistdepth[$page] = $metaline['listdepth']; | |
390 | + $metalines[] = $metaline; | |
391 | + } | |
392 | + $this->metalines = $metalines; | |
393 | + } | |
394 | + | |
395 | + function hierarchy_metalines() | |
396 | + { | |
397 | + $include = 0; | |
398 | + if ($this->options['include'][1] && sizeof($this->visited) >= 2) { // include (0,1,2,3...) -> (1,2,3,4...) | |
399 | + $include = 1; | |
400 | + } | |
401 | + $metalines = array(); | |
402 | + foreach($this->metalines as $metaline) { | |
403 | + if ($this->options['hierarchy'][1]) { | |
404 | + $metaline['listdepth'] = $metaline['depth'] + $include; | |
405 | + } else { | |
406 | + $metaline['listdepth'] = 1; | |
407 | + } | |
408 | + $metalines[] = $metaline; | |
409 | + } | |
410 | + $this->metalines = $metalines; | |
411 | + } | |
412 | + | |
413 | + function num_filter_metalines() | |
414 | + { | |
415 | + if ($this->options['num'][1] === '') { | |
416 | + return; | |
417 | + } | |
418 | + $metalines = array(); | |
419 | + foreach ($this->options['num'][1] as $num) { | |
420 | + $metalines[] = $this->metalines[$num - 1]; | |
421 | + } | |
422 | + $this->metalines = $metalines; | |
423 | + } | |
445 | 424 | |
446 | - function except_metalines() | |
447 | - { | |
448 | - if ($this->options['except'][1] === "") { | |
449 | - return; | |
450 | - } | |
451 | - $metalines = array(); | |
452 | - foreach ($this->metalines as $metaline) { | |
453 | - $headline = $metaline['headline']; | |
454 | - if (!ereg($this->options['except'][1], $headline)) { | |
455 | - $metalines[] = $metaline; | |
456 | - } | |
457 | - } | |
458 | - $this->metalines = $metalines; | |
459 | - } | |
460 | - | |
461 | - function include_metalines() | |
462 | - { | |
463 | - if ($this->options['include'][1]) { | |
464 | - return; | |
465 | - } | |
466 | - $metalines = array(); | |
467 | - foreach ($this->metalines as $metaline) { | |
468 | - if ($metaline['page'] == $this->options['page'][1]) { | |
469 | - $metalines[] = $metaline; | |
470 | - } | |
471 | - } | |
472 | - $this->metalines = $metalines; | |
473 | - } | |
425 | + function depth_filter_metalines() | |
426 | + { | |
427 | + if ($this->options['depth'][1] === '') { | |
428 | + return; | |
429 | + } | |
430 | + $metalines = array(); | |
431 | + foreach ($this->metalines as $metaline) { | |
432 | + $depth = $metaline['depth']; | |
433 | + if (in_array($depth, $this->options['depth'][1])) { | |
434 | + $metalines[] = $metaline; | |
435 | + } | |
436 | + } | |
437 | + $this->metalines = $metalines; | |
438 | + } | |
439 | + | |
440 | + function filter_metalines() | |
441 | + { | |
442 | + if ($this->options['filter'][1] === "") { | |
443 | + return; | |
444 | + } | |
445 | + $metalines = array(); | |
446 | + foreach ($this->metalines as $metaline) { | |
447 | + $headline = $metaline['headline']; | |
448 | + if (ereg($this->options['filter'][1], $headline)) { | |
449 | + $metalines[] = $metaline; | |
450 | + } | |
451 | + } | |
452 | + $this->metalines = $metalines; | |
453 | + } | |
474 | 454 | |
475 | - function fromhere_metalines() | |
476 | - { | |
477 | - if (! $this->options['fromhere'][1]) { | |
478 | - return; | |
479 | - } | |
480 | - $metalines = array(); | |
481 | - foreach ($this->metalines as $metaline) { | |
482 | - if ($metaline['fromhere']) { | |
483 | - $metalines[] = $metaline; | |
484 | - } | |
485 | - } | |
486 | - $this->metalines = $metalines; | |
487 | - } | |
455 | + function except_metalines() | |
456 | + { | |
457 | + if ($this->options['except'][1] === "") { | |
458 | + return; | |
459 | + } | |
460 | + $metalines = array(); | |
461 | + foreach ($this->metalines as $metaline) { | |
462 | + $headline = $metaline['headline']; | |
463 | + if (!ereg($this->options['except'][1], $headline)) { | |
464 | + $metalines[] = $metaline; | |
465 | + } | |
466 | + } | |
467 | + $this->metalines = $metalines; | |
468 | + } | |
469 | + | |
470 | + function include_metalines() | |
471 | + { | |
472 | + if ($this->options['include'][1]) { | |
473 | + return; | |
474 | + } | |
475 | + $metalines = array(); | |
476 | + foreach ($this->metalines as $metaline) { | |
477 | + if ($metaline['page'] == $this->options['page'][1]) { | |
478 | + $metalines[] = $metaline; | |
479 | + } | |
480 | + } | |
481 | + $this->metalines = $metalines; | |
482 | + } | |
488 | 483 | |
489 | - function init_metalines($page) | |
490 | - { | |
491 | - $this->metalines = array(); | |
492 | - $this->visited = array(); | |
493 | - if ($this->read_cache($page) !== false) { return; } | |
494 | - $this->metalines = $this->r_metalines($page); | |
495 | - $this->write_cache($page); | |
496 | - } | |
484 | + function fromhere_metalines() | |
485 | + { | |
486 | + if (! $this->options['fromhere'][1]) { | |
487 | + return; | |
488 | + } | |
489 | + $metalines = array(); | |
490 | + foreach ($this->metalines as $metaline) { | |
491 | + if ($metaline['fromhere']) { | |
492 | + $metalines[] = $metaline; | |
493 | + } | |
494 | + } | |
495 | + $this->metalines = $metalines; | |
496 | + } | |
497 | 497 | |
498 | - function get_cache_filename($page) | |
499 | - { | |
500 | - return CACHE_DIR . encode($page) . ".$this->plugin"; | |
501 | - } | |
498 | + function init_metalines($page) | |
499 | + { | |
500 | + $this->metalines = array(); | |
501 | + $this->visited = array(); | |
502 | + if ($this->read_cache($page) !== false) { return; } | |
503 | + $this->metalines = $this->r_metalines($page); | |
504 | + $this->write_cache($page); | |
505 | + } | |
502 | 506 | |
503 | - function get_cache_filenames() | |
504 | - { | |
505 | - return get_existfiles(CACHE_DIR, ".$this->plugin"); | |
506 | - } | |
507 | + function get_cache_filename($page) | |
508 | + { | |
509 | + return CACHE_DIR . encode($page) . ".$this->plugin"; | |
510 | + } | |
507 | 511 | |
508 | - /** | |
509 | - * Read cache | |
510 | - * | |
511 | - * @param $apage pagename | |
512 | - * @return mixed contents or FALSE if cache should be renewed | |
513 | - */ | |
514 | - function read_cache($apage) | |
515 | - { | |
516 | - if ($this->options['cache'][1] == 'off' || $this->options['cache'][1] == 'reset') { | |
517 | - return false; | |
518 | - } | |
519 | - if (! is_page($apage)) { | |
520 | - return false; | |
521 | - } | |
522 | - $cache = $this->get_cache_filename($apage); | |
523 | - if (! $this->file_exists($cache)) { | |
524 | - return false; | |
525 | - } | |
526 | - if (! $this->is_readable($cache)) { | |
527 | - $this->error = "Cache file, $cache is not readable. "; | |
528 | - return; | |
529 | - } | |
512 | + function get_cache_filenames() | |
513 | + { | |
514 | + return get_existfiles(CACHE_DIR, ".$this->plugin"); | |
515 | + } | |
530 | 516 | |
531 | - $lines = file($cache); | |
517 | + /** | |
518 | + * Read cache | |
519 | + * | |
520 | + * @param $apage pagename | |
521 | + * @return mixed contents or FALSE if cache should be renewed | |
522 | + */ | |
523 | + function read_cache($apage) | |
524 | + { | |
525 | + if ($this->options['cache'][1] == 'off' || $this->options['cache'][1] == 'reset') { | |
526 | + return false; | |
527 | + } | |
528 | + if (! is_page($apage)) { | |
529 | + return false; | |
530 | + } | |
531 | + $cache = $this->get_cache_filename($apage); | |
532 | + if (! $this->file_exists($cache)) { | |
533 | + return false; | |
534 | + } | |
535 | + if (! $this->is_readable($cache)) { | |
536 | + $this->error = "Cache file, $cache is not readable. "; | |
537 | + return; | |
538 | + } | |
532 | 539 | |
533 | - $pages = csv_explode(',', rtrim(array_shift($lines))); | |
534 | - foreach ($pages as $page) { | |
535 | - list($page, $title) = csv_explode('=', $page); | |
536 | - $visited[$page] = $title; | |
537 | - } | |
540 | + $lines = file($cache); | |
538 | 541 | |
539 | - // renew cache if preview mode | |
540 | - if (isset($vars['preview']) || isset($vars['realview'])) { | |
541 | - return false; | |
542 | - } | |
543 | - // renew cache if page is newer than cache | |
544 | - foreach ($visited as $page => $title) { | |
545 | - if (is_page_newer($page, $cache)) { | |
546 | - return false; | |
547 | - } | |
548 | - } | |
542 | + $pages = csv_explode(',', rtrim(array_shift($lines))); | |
543 | + foreach ($pages as $page) { | |
544 | + list($page, $title) = csv_explode('=', $page); | |
545 | + $visited[$page] = $title; | |
546 | + } | |
549 | 547 | |
550 | - $this->visited = $visited; | |
551 | - $metalines = array(); | |
552 | - foreach ($lines as $line) { | |
553 | - $metas = csv_explode(',', rtrim($line)); | |
554 | - $metaline = array(); | |
555 | - foreach ($metas as $meta) { | |
556 | - list($key, $val) = explode('=', $meta, 2); | |
557 | - $metaline[$key] = $val; | |
558 | - } | |
559 | - $metalines[] = $metaline; | |
560 | - } | |
561 | - $this->metalines = $metalines; | |
562 | - } | |
548 | + // renew cache if preview mode | |
549 | + if (isset($vars['preview']) || isset($vars['realview'])) { | |
550 | + return false; | |
551 | + } | |
552 | + // renew cache if page is newer than cache | |
553 | + foreach ($visited as $page => $title) { | |
554 | + if (is_page_newer($page, $cache)) { | |
555 | + return false; | |
556 | + } | |
557 | + } | |
563 | 558 | |
564 | - function write_cache($apage) | |
565 | - { | |
566 | - if ($this->options['cache'][1] == 'off') { | |
567 | - return; | |
568 | - } | |
569 | - if (! is_page($apage)) { | |
570 | - return; | |
571 | - } | |
572 | - $cache = $this->get_cache_filename($apage); | |
573 | - if ($this->file_exists($cache) && ! $this->is_writable($cache)) { | |
574 | - $this->error = "Cache file, $cache is not writable. "; | |
575 | - return; | |
576 | - } | |
577 | - | |
578 | - $pages = array(); | |
579 | - foreach ($this->visited as $page => $title) { | |
580 | - $pages[] = csv_implode('=', array($page, $title)); | |
581 | - } | |
582 | - $contents = ''; | |
583 | - $contents .= csv_implode(',', $pages) . "\n"; | |
584 | - foreach ($this->metalines as $metaline) { | |
585 | - $metas = array(); | |
586 | - foreach ($metaline as $key => $val) { | |
587 | - $metas[] = "$key=$val"; | |
588 | - } | |
589 | - $contents .= csv_implode(',', $metas) . "\n"; | |
590 | - } | |
591 | - // file_put_contents($cache, $contents); // PHP5 | |
592 | - if (! $fp = fopen($cache, "w")) { | |
593 | - $this->error = "Can not open $cache. "; | |
594 | - return; | |
595 | - } | |
596 | - if (! fwrite($fp, $contents)) { | |
597 | - $this->error = "Can not write to $cache. "; | |
598 | - return; | |
599 | - } | |
600 | - fclose($fp); | |
601 | - } | |
559 | + $this->visited = $visited; | |
560 | + $metalines = array(); | |
561 | + foreach ($lines as $line) { | |
562 | + $metas = csv_explode(',', rtrim($line)); | |
563 | + $metaline = array(); | |
564 | + foreach ($metas as $meta) { | |
565 | + list($key, $val) = explode('=', $meta, 2); | |
566 | + $metaline[$key] = $val; | |
567 | + } | |
568 | + $metalines[] = $metaline; | |
569 | + } | |
570 | + $this->metalines = $metalines; | |
571 | + } | |
602 | 572 | |
603 | - function r_metalines($page, $detected = false) | |
604 | - { | |
605 | - if (array_key_exists($page, $this->visited)) { | |
606 | - return array(); | |
607 | - } | |
608 | - if (! is_page($page)) { | |
609 | - return array(); | |
610 | - } | |
611 | - $this->visited[$page] = ''; | |
612 | - $lines = $this->get_source($page); | |
613 | - $multiline = 0; | |
614 | - $metalines = array(); | |
615 | - foreach ($lines as $i => $line) { | |
616 | - // multiline plugin. refer lib/convert_html | |
617 | - if(defined('PKWKEXP_DISABLE_MULTILINE_PLUGIN_HACK') && PKWKEXP_DISABLE_MULTILINE_PLUGIN_HACK === 0) { | |
618 | - $matches = array(); | |
619 | - if ($multiline < 2) { | |
620 | - if(preg_match('/^#([^\(\{]+)(?:\(([^\r]*)\))?(\{*)/', $line, $matches)) { | |
621 | - $multiline = strlen($matches[3]); | |
622 | - } | |
623 | - } else { | |
624 | - if (preg_match('/^\}{' . $multiline . '}$/', $line, $matches)) { | |
625 | - $multiline = 0; | |
626 | - } | |
627 | - continue; | |
628 | - } | |
629 | - } | |
573 | + function write_cache($apage) | |
574 | + { | |
575 | + if ($this->options['cache'][1] == 'off') { | |
576 | + return; | |
577 | + } | |
578 | + if (! is_page($apage)) { | |
579 | + return; | |
580 | + } | |
581 | + $cache = $this->get_cache_filename($apage); | |
582 | + if ($this->file_exists($cache) && ! $this->is_writable($cache)) { | |
583 | + $this->error = "Cache file, $cache is not writable. "; | |
584 | + return; | |
585 | + } | |
586 | + | |
587 | + $pages = array(); | |
588 | + foreach ($this->visited as $page => $title) { | |
589 | + $pages[] = csv_implode('=', array($page, $title)); | |
590 | + } | |
591 | + $contents = ''; | |
592 | + $contents .= csv_implode(',', $pages) . "\n"; | |
593 | + foreach ($this->metalines as $metaline) { | |
594 | + $metas = array(); | |
595 | + foreach ($metaline as $key => $val) { | |
596 | + $metas[] = "$key=$val"; | |
597 | + } | |
598 | + $contents .= csv_implode(',', $metas) . "\n"; | |
599 | + } | |
600 | + // file_put_contents($cache, $contents); // PHP5 | |
601 | + if (! $fp = fopen($cache, "w")) { | |
602 | + $this->error = "Can not open $cache. "; | |
603 | + return; | |
604 | + } | |
605 | + if (! fwrite($fp, $contents)) { | |
606 | + $this->error = "Can not write to $cache. "; | |
607 | + return; | |
608 | + } | |
609 | + fclose($fp); | |
610 | + } | |
630 | 611 | |
631 | - // fromhere | |
632 | - if ($this->options['page'][1] == $page && !$detected) { | |
633 | - if (preg_match('/^#' . $this->plugin . '/', $line, $matches)) { | |
634 | - $detected = true; | |
635 | - continue; | |
636 | - } | |
637 | - } | |
638 | - | |
639 | - if (preg_match($this->conf['def_headline'], $line, $matches)) { | |
640 | - $depth = strlen($matches[1]); | |
641 | - $anchor = '#' . $this->make_heading($line); // *** [id] is removed from $line | |
642 | - $headline = trim($line); | |
643 | - $metalines[] = array(page=>$page, headline=>$headline, anchor=>$anchor, depth=>$depth, linenum=>$i, fromhere=>$detected); | |
644 | - continue; | |
645 | - } | |
612 | + function r_metalines($page, $detected = false) | |
613 | + { | |
614 | + if (array_key_exists($page, $this->visited)) { | |
615 | + return array(); | |
616 | + } | |
617 | + if (! is_page($page)) { | |
618 | + return array(); | |
619 | + } | |
620 | + $this->visited[$page] = ''; | |
621 | + $lines = $this->get_source($page); | |
622 | + $multiline = 0; | |
623 | + $metalines = array(); | |
624 | + foreach ($lines as $i => $line) { | |
625 | + // multiline plugin. refer lib/convert_html | |
626 | + if(defined('PKWKEXP_DISABLE_MULTILINE_PLUGIN_HACK') && PKWKEXP_DISABLE_MULTILINE_PLUGIN_HACK === 0) { | |
627 | + $matches = array(); | |
628 | + if ($multiline < 2) { | |
629 | + if(preg_match('/^#([^\(\{]+)(?:\(([^\r]*)\))?(\{*)/', $line, $matches)) { | |
630 | + $multiline = strlen($matches[3]); | |
631 | + } | |
632 | + } else { | |
633 | + if (preg_match('/^\}{' . $multiline . '}$/', $line, $matches)) { | |
634 | + $multiline = 0; | |
635 | + } | |
636 | + continue; | |
637 | + } | |
638 | + } | |
646 | 639 | |
647 | - if (preg_match($this->conf['def_include'], $line, $matches)) { | |
648 | - $args = csv_explode(',', $matches[1]); | |
649 | - $inclpage = array_shift($args); | |
650 | - $options = array(); | |
651 | - foreach ($args as $arg) { | |
652 | - list($key, $val) = array_pad(explode('=', $arg, 2), 2, true); | |
653 | - $options[$key] = $val; | |
654 | - } | |
655 | - $inclpage = get_fullname($inclpage, $page); | |
656 | - if (! $this->is_page($inclpage)) { | |
657 | - continue; | |
658 | - } | |
659 | - // $anchor = PluginIncludex::get_page_anchor($inclpage) | |
660 | - $anchor = 'z' . md5($inclpage); | |
661 | - $anchor = '#' . htmlspecialchars($anchor); | |
662 | - if (exist_plugin('includex') & is_callable(array('PluginIncludex', 'get_titlestr'))) { | |
663 | - $titlestr = PluginIncludex::get_titlestr($inclpage, $options['titlestr']); | |
664 | - } else { | |
665 | - $titlestr = $inclpage; | |
666 | - } | |
667 | - $metalines[] = array(page=>$inclpage, headline=>$titlestr, anchor=>$anchor, depth=>0, linenum=>$i, fromhere=>$detected); | |
668 | - $metalines = array_merge($metalines, $this->r_metalines($inclpage, $detected)); | |
669 | - continue; | |
670 | - } | |
640 | + // fromhere | |
641 | + if ($this->options['page'][1] == $page && !$detected) { | |
642 | + if (preg_match('/^#' . $this->plugin . '/', $line, $matches)) { | |
643 | + $detected = true; | |
644 | + continue; | |
645 | + } | |
646 | + } | |
647 | + | |
648 | + if (preg_match($this->conf['def_headline'], $line, $matches)) { | |
649 | + $depth = strlen($matches[1]); | |
650 | + $anchor = '#' . $this->make_heading($line); // *** [id] is removed from $line | |
651 | + $headline = trim($line); | |
652 | + $metalines[] = array('page'=>$page, 'headline'=>$headline, 'anchor'=>$anchor, 'depth'=>$depth, 'linenum'=>$i, 'fromhere'=>$detected); | |
653 | + continue; | |
654 | + } | |
671 | 655 | |
672 | - if (preg_match($this->conf['def_title'], $line, $matches)) { | |
673 | - $title = $matches[1]; | |
674 | - $this->visited[$page] = $title; | |
675 | - continue; | |
676 | - } | |
677 | - } | |
678 | - return $metalines; | |
679 | - } | |
656 | + if (preg_match($this->conf['def_include'], $line, $matches)) { | |
657 | + $args = csv_explode(',', $matches[1]); | |
658 | + $inclpage = array_shift($args); | |
659 | + $options = array(); | |
660 | + foreach ($args as $arg) { | |
661 | + list($key, $val) = array_pad(explode('=', $arg, 2), 2, true); | |
662 | + $options[$key] = $val; | |
663 | + } | |
664 | + $inclpage = get_fullname($inclpage, $page); | |
665 | + if (! $this->is_page($inclpage)) { | |
666 | + continue; | |
667 | + } | |
668 | + // $anchor = PluginIncludex::get_page_anchor($inclpage) | |
669 | + $anchor = 'z' . md5($inclpage); | |
670 | + $anchor = '#' . htmlsc($anchor); | |
671 | + if (exist_plugin('includex') & is_callable(array('PluginIncludex', 'get_titlestr'))) { | |
672 | + $titlestr = PluginIncludex::get_titlestr($inclpage, $options['titlestr']); | |
673 | + } else { | |
674 | + $titlestr = $inclpage; | |
675 | + } | |
676 | + $metalines[] = array('page'=>$inclpage, 'headline'=>$titlestr, 'anchor'=>$anchor, 'depth'=>0, 'linenum'=>$i, 'fromhere'=>$detected); | |
677 | + $metalines = array_merge($metalines, $this->r_metalines($inclpage, $detected)); | |
678 | + continue; | |
679 | + } | |
680 | 680 | |
681 | - // copy from lib/html.php | |
682 | - function make_heading(& $str, $strip = TRUE) | |
683 | - { | |
684 | - global $NotePattern; | |
681 | + if (preg_match($this->conf['def_title'], $line, $matches)) { | |
682 | + $title = $matches[1]; | |
683 | + $this->visited[$page] = $title; | |
684 | + continue; | |
685 | + } | |
686 | + } | |
687 | + return $metalines; | |
688 | + } | |
685 | 689 | |
686 | - // Cut fixed-heading anchors | |
687 | - $id = ''; | |
688 | - $matches = array(); | |
689 | - if (preg_match('/^(\*{0,3})(.*?)\[#([A-Za-z][\w-]+)\](.*?)$/m', $str, $matches)) { | |
690 | - $str = $matches[2] . $matches[4]; | |
691 | - $id = & $matches[3]; | |
692 | - } else { | |
693 | - $str = preg_replace('/^\*{0,3}/', '', $str); | |
694 | - } | |
695 | - | |
696 | - // Cut footnotes and tags | |
697 | - if ($strip === TRUE) { | |
698 | - // $str = strip_htmltag(make_link(preg_replace($NotePattern, '', $str))); // sonots | |
699 | - $str = preg_replace($NotePattern, '', $str); // sonots | |
700 | - } | |
701 | - | |
702 | - return $id; | |
703 | - } | |
690 | + // copy from lib/html.php | |
691 | + function make_heading(& $str, $strip = TRUE) | |
692 | + { | |
693 | + global $NotePattern; | |
704 | 694 | |
705 | - function check_page($page) | |
706 | - { | |
707 | - global $vars, $defaultpage; | |
708 | - if ($page == "") { | |
709 | - $page = isset($vars['page']) ? $vars['page'] : $defaultpage; | |
710 | - } else { | |
711 | - $page = get_fullname($page, $vars['page']); | |
712 | - $this->options['fromhere'][1] = false; | |
713 | - } | |
714 | - if (! $this->is_page($page)) { | |
715 | - $this->error = "No such a page, " . $page; | |
716 | - return; | |
717 | - } | |
718 | - if (! $this->check_readable($page, FALSE, FALSE)) { | |
719 | - $this->error = "Page, " . $page . ", is not readable."; | |
720 | - } | |
721 | - return $page; | |
722 | - } | |
723 | - | |
724 | - // PukiWiki API | |
725 | - function get_source($page) | |
726 | - { | |
727 | - return get_source($page); | |
728 | - } | |
729 | - | |
730 | - function is_page($page) | |
731 | - { | |
732 | - return is_page($page); | |
733 | - } | |
695 | + // Cut fixed-heading anchors | |
696 | + $id = ''; | |
697 | + $matches = array(); | |
698 | + if (preg_match('/^(\*{0,3})(.*?)\[#([A-Za-z][\w-]+)\](.*?)$/m', $str, $matches)) { | |
699 | + $str = $matches[2] . $matches[4]; | |
700 | + $id = & $matches[3]; | |
701 | + } else { | |
702 | + $str = preg_replace('/^\*{0,3}/', '', $str); | |
703 | + } | |
704 | + | |
705 | + // Cut footnotes and tags | |
706 | + if ($strip === TRUE) { | |
707 | + // $str = strip_htmltag(make_link(preg_replace($NotePattern, '', $str))); // sonots | |
708 | + $str = preg_replace($NotePattern, '', $str); // sonots | |
709 | + } | |
710 | + | |
711 | + return $id; | |
712 | + } | |
734 | 713 | |
735 | - function check_readable($page, $flag, $flag) | |
736 | - { | |
737 | - return check_readable($page, $flag, $flag); | |
738 | - } | |
714 | + function check_page($page) | |
715 | + { | |
716 | + global $vars, $defaultpage; | |
717 | + if ($page == "") { | |
718 | + $page = isset($vars['page']) ? $vars['page'] : $defaultpage; | |
719 | + } else { | |
720 | + $page = get_fullname($page, $vars['page']); | |
721 | + $this->options['fromhere'][1] = false; | |
722 | + } | |
723 | + if (! $this->is_page($page)) { | |
724 | + $this->error = "No such a page, " . $page; | |
725 | + return; | |
726 | + } | |
727 | + if (! $this->check_readable($page, FALSE, FALSE)) { | |
728 | + $this->error = "Page, " . $page . ", is not readable."; | |
729 | + } | |
730 | + return $page; | |
731 | + } | |
732 | + | |
733 | + // PukiWiki API | |
734 | + function get_source($page) | |
735 | + { | |
736 | + return get_source($page); | |
737 | + } | |
738 | + | |
739 | + function is_page($page) | |
740 | + { | |
741 | + return is_page($page); | |
742 | + } | |
739 | 743 | |
740 | - // PHP API | |
741 | - function file_exists($file) | |
742 | - { | |
743 | - return file_exists($file); | |
744 | - } | |
744 | + function check_readable($page, $flag, $flag2) | |
745 | + { | |
746 | + return check_readable($page, $flag, $flag2); | |
747 | + } | |
745 | 748 | |
746 | - function is_readable($file) | |
747 | - { | |
748 | - return is_readable($file); | |
749 | - } | |
749 | + // PHP API | |
750 | + function file_exists($file) | |
751 | + { | |
752 | + return file_exists($file); | |
753 | + } | |
750 | 754 | |
751 | - function is_writable($file) | |
752 | - { | |
753 | - return is_writable($file); | |
754 | - } | |
755 | + function is_readable($file) | |
756 | + { | |
757 | + return is_readable($file); | |
758 | + } | |
759 | + | |
760 | + function is_writable($file) | |
761 | + { | |
762 | + return is_writable($file); | |
763 | + } | |
755 | 764 | } |
756 | 765 | |
757 | 766 | /////////////////////////////////////// |
758 | 767 | class PluginContentsxOptionParser |
759 | 768 | { |
760 | - var $error = ""; | |
769 | + var $error = ""; | |
761 | 770 | |
762 | - function parse_options($args, $options) | |
763 | - { | |
764 | - if (! is_associative_array($args)) { | |
765 | - $args = $this->associative_args($args, $options); | |
766 | - if ($this->error != "") { return; } | |
767 | - } | |
771 | + function parse_options($args, $options) | |
772 | + { | |
773 | + if (! is_associative_array($args)) { | |
774 | + $args = $this->associative_args($args, $options); | |
775 | + if ($this->error != "") { return; } | |
776 | + } | |
768 | 777 | |
769 | - foreach ($args as $key => $val) { | |
770 | - if ( !isset($options[$key]) ) { continue; } // for action ($vars) | |
771 | - $type = $options[$key][0]; | |
778 | + foreach ($args as $key => $val) { | |
779 | + if ( !isset($options[$key]) ) { continue; } // for action ($vars) | |
780 | + $type = $options[$key][0]; | |
772 | 781 | |
773 | - switch ($type) { | |
774 | - case 'bool': | |
775 | - if($val == "" || $val == "on" || $val == "true") { | |
776 | - $options[$key][1] = true; | |
777 | - } elseif ($val == "off" || $val == "false" ) { | |
778 | - $options[$key][1] = false; | |
779 | - } else { | |
780 | - $this->error = htmlspecialchars("$key=$val") . " is invalid. "; | |
781 | - $this->error .= "The option, $key, accepts only a boolean value."; | |
782 | - $this->error .= "#$this->plugin($key) or #$this->plugin($key=on) or #$this->plugin($key=true) for true. "; | |
783 | - $this->error .= "#$this->plugin($key=off) or #$this->plugin($key=false) for false. "; | |
784 | - return; | |
785 | - } | |
786 | - break; | |
787 | - case 'string': | |
788 | - $options[$key][1] = $val; | |
789 | - break; | |
790 | - case 'sanitize': | |
791 | - $options[$key][1] = htmlspecialchars($val); | |
792 | - break; | |
793 | - case 'number': | |
794 | - // Do not parse yet, parse after getting min and max. Here, just format checking | |
795 | - if ($val === '') { | |
796 | - $options[$key][1] = ''; | |
797 | - break; | |
798 | - } | |
799 | - if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
800 | - $val = substr($val, 1, strlen($val) - 2); | |
801 | - } | |
802 | - foreach (explode(",", $val) as $range) { | |
803 | - if (preg_match('/^-?\d+$/', $range)) { | |
804 | - } elseif (preg_match('/^-?\d*\:-?\d*$/', $range)) { | |
805 | - } elseif (preg_match('/^-?\d+\+-?\d+$/', $range)) { | |
806 | - } else { | |
807 | - $this->error = htmlspecialchars("$key=$val") . " is invalid. "; | |
808 | - $this->error .= "The option, " . $key . ", accepts number values such as 1, 1:3, 1+3, 1,2,4. "; | |
809 | - $this->error .= "Specify options as \"$key=1,2,4\" or $key=(1,2,3) when you want to use \",\". "; | |
810 | - $this->error .= "In more details, a style like (1:3,5:7,9:) is also possible. 9: means from 9 to the last. "; | |
811 | - $this->error .= "Furtermore, - means backward. -1:-3 means 1,2,3 from the tail. "; | |
812 | - return; | |
813 | - } | |
814 | - } | |
815 | - $options[$key][1] = $val; | |
816 | - break; | |
817 | - case 'enum': | |
818 | - if($val == "") { | |
819 | - $options[$key][1] = $options[$key][2][0]; | |
820 | - } elseif (in_array($val, $options[$key][2])) { | |
821 | - $options[$key][1] = $val; | |
822 | - } else { | |
823 | - $this->error = htmlspecialchars("$key=$val") . " is invalid. "; | |
824 | - $this->error .= "The option, " . $key . ", accepts values from one of (" . join(",", $options[$key][2]) . "). "; | |
825 | - $this->error .= "By the way, #$this->plugin($key) equals to #$this->plugin($key=" . $options[$key][2][0] . "). "; | |
826 | - return; | |
827 | - } | |
828 | - break; | |
829 | - case 'array': | |
830 | - if ($val == '') { | |
831 | - $options[$key][1] = array(); | |
832 | - break; | |
833 | - } | |
834 | - if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
835 | - $val = substr($val, 1, strlen($val) - 2); | |
836 | - } | |
837 | - $val = explode(',', $val); | |
838 | - //$val = $this->support_paren($val); | |
839 | - $options[$key][1] = $val; | |
840 | - break; | |
841 | - case 'enumarray': | |
842 | - if ($val == '') { | |
843 | - $options[$key][1] = $options[$key][2]; | |
844 | - break; | |
845 | - } | |
846 | - if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
847 | - $val = substr($val, 1, strlen($val) - 2); | |
848 | - } | |
849 | - $val = explode(',', $val); | |
850 | - //$val = $this->support_paren($val); | |
851 | - $options[$key][1] = $val; | |
852 | - foreach ($options[$key][1] as $each) { | |
853 | - if (! in_array($each, $options[$key][2])) { | |
854 | - $this->error = "$key=" . htmlspecialchars(join(",", $options[$key][1])) . " is invalid. "; | |
855 | - $this->error .= "The option, " . $key . ", accepts sets of values from (" . join(",", $options[$key][2]) . "). "; | |
856 | - $this->error .= "By the way, #$this->plugin($key) equals to #$this->plugin($key=(" . join(',',$options[$key][2]) . ")). "; | |
857 | - return; | |
858 | - } | |
859 | - } | |
860 | - break; | |
861 | - default: | |
862 | - } | |
863 | - } | |
782 | + switch ($type) { | |
783 | + case 'bool': | |
784 | + if($val == "" || $val == "on" || $val == "true") { | |
785 | + $options[$key][1] = true; | |
786 | + } elseif ($val == "off" || $val == "false" ) { | |
787 | + $options[$key][1] = false; | |
788 | + } else { | |
789 | + $this->error = htmlsc("$key=$val") . " is invalid. "; | |
790 | + $this->error .= "The option, $key, accepts only a boolean value."; | |
791 | + $this->error .= "#$this->plugin($key) or #$this->plugin($key=on) or #$this->plugin($key=true) for true. "; | |
792 | + $this->error .= "#$this->plugin($key=off) or #$this->plugin($key=false) for false. "; | |
793 | + return; | |
794 | + } | |
795 | + break; | |
796 | + case 'string': | |
797 | + $options[$key][1] = $val; | |
798 | + break; | |
799 | + case 'sanitize': | |
800 | + $options[$key][1] = htmlsc($val); | |
801 | + break; | |
802 | + case 'number': | |
803 | + // Do not parse yet, parse after getting min and max. Here, just format checking | |
804 | + if ($val === '') { | |
805 | + $options[$key][1] = ''; | |
806 | + break; | |
807 | + } | |
808 | + if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
809 | + $val = substr($val, 1, strlen($val) - 2); | |
810 | + } | |
811 | + foreach (explode(",", $val) as $range) { | |
812 | + if (preg_match('/^-?\d+$/', $range)) { | |
813 | + } elseif (preg_match('/^-?\d*\:-?\d*$/', $range)) { | |
814 | + } elseif (preg_match('/^-?\d+\+-?\d+$/', $range)) { | |
815 | + } else { | |
816 | + $this->error = htmlsc("$key=$val") . " is invalid. "; | |
817 | + $this->error .= "The option, " . $key . ", accepts number values such as 1, 1:3, 1+3, 1,2,4. "; | |
818 | + $this->error .= "Specify options as \"$key=1,2,4\" or $key=(1,2,3) when you want to use \",\". "; | |
819 | + $this->error .= "In more details, a style like (1:3,5:7,9:) is also possible. 9: means from 9 to the last. "; | |
820 | + $this->error .= "Furtermore, - means backward. -1:-3 means 1,2,3 from the tail. "; | |
821 | + return; | |
822 | + } | |
823 | + } | |
824 | + $options[$key][1] = $val; | |
825 | + break; | |
826 | + case 'enum': | |
827 | + if($val == "") { | |
828 | + $options[$key][1] = $options[$key][2][0]; | |
829 | + } elseif (in_array($val, $options[$key][2])) { | |
830 | + $options[$key][1] = $val; | |
831 | + } else { | |
832 | + $this->error = htmlsc("$key=$val") . " is invalid. "; | |
833 | + $this->error .= "The option, " . $key . ", accepts values from one of (" . join(",", $options[$key][2]) . "). "; | |
834 | + $this->error .= "By the way, #$this->plugin($key) equals to #$this->plugin($key=" . $options[$key][2][0] . "). "; | |
835 | + return; | |
836 | + } | |
837 | + break; | |
838 | + case 'array': | |
839 | + if ($val == '') { | |
840 | + $options[$key][1] = array(); | |
841 | + break; | |
842 | + } | |
843 | + if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
844 | + $val = substr($val, 1, strlen($val) - 2); | |
845 | + } | |
846 | + $val = explode(',', $val); | |
847 | + //$val = $this->support_paren($val); | |
848 | + $options[$key][1] = $val; | |
849 | + break; | |
850 | + case 'enumarray': | |
851 | + if ($val == '') { | |
852 | + $options[$key][1] = $options[$key][2]; | |
853 | + break; | |
854 | + } | |
855 | + if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
856 | + $val = substr($val, 1, strlen($val) - 2); | |
857 | + } | |
858 | + $val = explode(',', $val); | |
859 | + //$val = $this->support_paren($val); | |
860 | + $options[$key][1] = $val; | |
861 | + foreach ($options[$key][1] as $each) { | |
862 | + if (! in_array($each, $options[$key][2])) { | |
863 | + $this->error = "$key=" . htmlsc(join(",", $options[$key][1])) . " is invalid. "; | |
864 | + $this->error .= "The option, " . $key . ", accepts sets of values from (" . join(",", $options[$key][2]) . "). "; | |
865 | + $this->error .= "By the way, #$this->plugin($key) equals to #$this->plugin($key=(" . join(',',$options[$key][2]) . ")). "; | |
866 | + return; | |
867 | + } | |
868 | + } | |
869 | + break; | |
870 | + default: | |
871 | + } | |
872 | + } | |
864 | 873 | |
865 | - return $options; | |
866 | - } | |
867 | - | |
868 | - /** | |
869 | - * Handle associative type option arguments as | |
870 | - * ["prefix=Hoge/", "contents=(hoge", "hoge", "hoge)"] => ["prefix"=>"hoge/", "contents"=>"(hoge,hoge,hoge)"] | |
871 | - * This has special supports for parentheses type arguments (number, array, enumarray) | |
872 | - * Check option in along with. | |
873 | - * @access public | |
874 | - * @param Array $args Original option arguments | |
875 | - * @return Array $result Converted associative option arguments | |
876 | - */ | |
877 | - function associative_args($args, $options) | |
878 | - { | |
879 | - $result = array(); | |
880 | - while (($arg = current($args)) !== false) { | |
881 | - list($key, $val) = array_pad(explode("=", $arg, 2), 2, ''); | |
882 | - if (! isset($options[$key])) { | |
883 | - $this->error = 'No such a option, ' . htmlspecialchars($key); | |
884 | - return; | |
885 | - } | |
886 | - // paren support | |
887 | - if ($val[0] === '(' && ($options[$key][0] == 'number' || | |
888 | - $options[$key][0] == 'array' || $options[$key][0] == 'enumarray')) { | |
889 | - while(true) { | |
890 | - if ($val[strlen($val)-1] === ')' && substr_count($val, '(') == substr_count($val, ')')) { | |
891 | - break; | |
892 | - } | |
893 | - $arg = next($args); | |
894 | - if ($arg === false) { | |
895 | - $this->error = "The # of open and close parentheses of one of your arguments did not match. "; | |
896 | - return; | |
897 | - } | |
898 | - $val .= ',' . $arg; | |
899 | - } | |
900 | - } | |
901 | - $result[$key] = $val; | |
902 | - next($args); | |
903 | - } | |
904 | - return $result; | |
905 | - } | |
874 | + return $options; | |
875 | + } | |
876 | + | |
877 | + /** | |
878 | + * Handle associative type option arguments as | |
879 | + * ["prefix=Hoge/", "contents=(hoge", "hoge", "hoge)"] => ["prefix"=>"hoge/", "contents"=>"(hoge,hoge,hoge)"] | |
880 | + * This has special supports for parentheses type arguments (number, array, enumarray) | |
881 | + * Check option in along with. | |
882 | + * @access public | |
883 | + * @param Array $args Original option arguments | |
884 | + * @return Array $result Converted associative option arguments | |
885 | + */ | |
886 | + function associative_args($args, $options) | |
887 | + { | |
888 | + $result = array(); | |
889 | + while (($arg = current($args)) !== false) { | |
890 | + list($key, $val) = array_pad(explode("=", $arg, 2), 2, ''); | |
891 | + if (! isset($options[$key])) { | |
892 | + $this->error = 'No such a option, ' . htmlsc($key); | |
893 | + return; | |
894 | + } | |
895 | + // paren support | |
896 | + if ($val[0] === '(' && ($options[$key][0] == 'number' || | |
897 | + $options[$key][0] == 'array' || $options[$key][0] == 'enumarray')) { | |
898 | + while(true) { | |
899 | + if ($val[strlen($val)-1] === ')' && substr_count($val, '(') == substr_count($val, ')')) { | |
900 | + break; | |
901 | + } | |
902 | + $arg = next($args); | |
903 | + if ($arg === false) { | |
904 | + $this->error = "The # of open and close parentheses of one of your arguments did not match. "; | |
905 | + return; | |
906 | + } | |
907 | + $val .= ',' . $arg; | |
908 | + } | |
909 | + } | |
910 | + $result[$key] = $val; | |
911 | + next($args); | |
912 | + } | |
913 | + return $result; | |
914 | + } | |
906 | 915 | |
907 | - function parse_numoption($optionval, $min, $max) | |
908 | - { | |
909 | - if ($optionval === '') { | |
910 | - return ''; | |
911 | - } | |
912 | - $result = array(); | |
913 | - foreach (explode(",", $optionval) as $range) { | |
914 | - if (preg_match('/^-?\d+$/', $range)) { | |
915 | - $left = $right = $range; | |
916 | - } elseif (preg_match('/^-?\d*\:-?\d*$/', $range)) { | |
917 | - list($left, $right) = explode(":", $range, 2); | |
918 | - if ($left == "" && $right == "") { | |
919 | - $left = $min; | |
920 | - $right = $max; | |
921 | - } elseif($left == "") { | |
922 | - $left = $min; | |
923 | - } elseif ($right == "") { | |
924 | - $right = $max; | |
925 | - } | |
926 | - } elseif (preg_match('/^-?\d+\+-?\d+$/', $range)) { | |
927 | - list($left, $right) = explode("+", $range, 2); | |
928 | - $right += $left; | |
929 | - } | |
930 | - if ($left < 0) { | |
931 | - $left += $max + 1; | |
932 | - } | |
933 | - if ($right < 0) { | |
934 | - $right += $max + 1; | |
935 | - } | |
936 | - $result = array_merge($result, range($left, $right)); | |
937 | - // range allows like range(5, 3) also | |
938 | - } | |
939 | - // filter | |
940 | - foreach (array_keys($result) as $i) { | |
941 | - if ($result[$i] < $min || $result[$i] > $max) { | |
942 | - unset($result[$i]); | |
943 | - } | |
944 | - } | |
945 | - sort($result); | |
946 | - $result = array_unique($result); | |
916 | + function parse_numoption($optionval, $min, $max) | |
917 | + { | |
918 | + if ($optionval === '') { | |
919 | + return ''; | |
920 | + } | |
921 | + $result = array(); | |
922 | + foreach (explode(",", $optionval) as $range) { | |
923 | + if (preg_match('/^-?\d+$/', $range)) { | |
924 | + $left = $right = $range; | |
925 | + } elseif (preg_match('/^-?\d*\:-?\d*$/', $range)) { | |
926 | + list($left, $right) = explode(":", $range, 2); | |
927 | + if ($left == "" && $right == "") { | |
928 | + $left = $min; | |
929 | + $right = $max; | |
930 | + } elseif($left == "") { | |
931 | + $left = $min; | |
932 | + } elseif ($right == "") { | |
933 | + $right = $max; | |
934 | + } | |
935 | + } elseif (preg_match('/^-?\d+\+-?\d+$/', $range)) { | |
936 | + list($left, $right) = explode("+", $range, 2); | |
937 | + $right += $left; | |
938 | + } | |
939 | + if ($left < 0) { | |
940 | + $left += $max + 1; | |
941 | + } | |
942 | + if ($right < 0) { | |
943 | + $right += $max + 1; | |
944 | + } | |
945 | + $result = array_merge($result, range($left, $right)); | |
946 | + // range allows like range(5, 3) also | |
947 | + } | |
948 | + // filter | |
949 | + foreach (array_keys($result) as $i) { | |
950 | + if ($result[$i] < $min || $result[$i] > $max) { | |
951 | + unset($result[$i]); | |
952 | + } | |
953 | + } | |
954 | + sort($result); | |
955 | + $result = array_unique($result); | |
947 | 956 | |
948 | - return $result; | |
949 | - } | |
957 | + return $result; | |
958 | + } | |
950 | 959 | |
951 | - function option_debug_print($options) { | |
952 | - foreach ($options as $key => $val) { | |
953 | - $type = $val[0]; | |
954 | - $val = $val[1]; | |
955 | - if(is_array($val)) { | |
956 | - $val=join(',', $val); | |
957 | - } | |
958 | - $body .= "$key=>($type, $val),"; | |
959 | - } | |
960 | - return $body; | |
961 | - } | |
960 | + function option_debug_print($options) { | |
961 | + foreach ($options as $key => $val) { | |
962 | + $type = $val[0]; | |
963 | + $val = $val[1]; | |
964 | + if(is_array($val)) { | |
965 | + $val=join(',', $val); | |
966 | + } | |
967 | + $body .= "$key=>($type, $val),"; | |
968 | + } | |
969 | + return $body; | |
970 | + } | |
962 | 971 | |
963 | - // php extension | |
964 | - function is_associative_array($array) | |
965 | - { | |
966 | - if (!is_array($array) || empty($array)) | |
967 | - return false; | |
968 | - $keys = array_keys($array); | |
969 | - return array_keys($keys) !== $keys; | |
970 | - // or | |
971 | - //return is_array($array) && !is_numeric(implode(array_keys($array))); | |
972 | - } | |
972 | + // php extension | |
973 | + function is_associative_array($array) | |
974 | + { | |
975 | + if (!is_array($array) || empty($array)) | |
976 | + return false; | |
977 | + $keys = array_keys($array); | |
978 | + return array_keys($keys) !== $keys; | |
979 | + // or | |
980 | + //return is_array($array) && !is_numeric(implode(array_keys($array))); | |
981 | + } | |
973 | 982 | } |
974 | 983 | |
975 | 984 | //////////////// PukiWiki API Extension |
976 | 985 | if (! function_exists('is_admin')) { |
977 | - /** | |
978 | - * PukiWiki admin login with session | |
979 | - * | |
980 | - * @param string $pass | |
981 | - * @param boolean $use_session Use Session log | |
982 | - * @param boolean $use_basicauth Use BasicAuth log | |
983 | - * @return boolean | |
984 | - */ | |
985 | - function is_admin($pass = null, $use_session = false, $use_basicauth = false) | |
986 | - { | |
987 | - $is_admin = FALSE; | |
988 | - if ($use_basicauth) { | |
989 | - if (is_callable(array('auth', 'check_role'))) { // Plus! | |
990 | - $is_admin = ! auth::check_role('role_adm_contents'); | |
991 | - } | |
992 | - } | |
993 | - if (! $is_admin && isset($pass)) { | |
994 | - $is_admin = function_exists('pkwk_login') ? pkwk_login($pass) : | |
995 | - md5($pass) === $GLOBALS['adminpass']; // 1.4.3 | |
996 | - } | |
997 | - if ($use_session) { | |
998 | - session_start(); | |
999 | - if ($is_admin) $_SESSION['is_admin'] = TRUE; | |
1000 | - return isset($_SESSION['is_admin']) && $_SESSION['is_admin']; | |
1001 | - } else { | |
1002 | - return $is_admin; | |
1003 | - } | |
1004 | - } | |
986 | + /** | |
987 | + * PukiWiki admin login with session | |
988 | + * | |
989 | + * @param string $pass | |
990 | + * @param boolean $use_session Use Session log | |
991 | + * @param boolean $use_basicauth Use BasicAuth log | |
992 | + * @return boolean | |
993 | + */ | |
994 | + function is_admin($pass = null, $use_session = false, $use_basicauth = false) | |
995 | + { | |
996 | + $is_admin = FALSE; | |
997 | + if ($use_basicauth) { | |
998 | + if (is_callable(array('auth', 'check_role'))) { // Plus! | |
999 | + $is_admin = ! auth::check_role('role_adm_contents'); | |
1000 | + } | |
1001 | + } | |
1002 | + if (! $is_admin && isset($pass)) { | |
1003 | + $is_admin = function_exists('pkwk_login') ? pkwk_login($pass) : | |
1004 | + md5($pass) === $GLOBALS['adminpass']; // 1.4.3 | |
1005 | + } | |
1006 | + if ($use_session) { | |
1007 | + session_start(); | |
1008 | + if ($is_admin) $_SESSION['is_admin'] = TRUE; | |
1009 | + return isset($_SESSION['is_admin']) && $_SESSION['is_admin']; | |
1010 | + } else { | |
1011 | + return $is_admin; | |
1012 | + } | |
1013 | + } | |
1005 | 1014 | } |
1006 | 1015 | |
1007 | 1016 | if (! function_exists('is_page_newer')) { |
1008 | - /** | |
1009 | - * Check if the page timestamp is newer than the file timestamp | |
1010 | - * | |
1011 | - * PukiWiki API Extension | |
1012 | - * | |
1013 | - * @param string $page pagename | |
1014 | - * @param string $file filename | |
1015 | - * @param bool $ignore_notimestamp Ignore notimestamp edit and see the real time editted | |
1016 | - * @return boolean | |
1017 | - */ | |
1018 | - function is_page_newer($page, $file, $ignore_notimestamp = TRUE) | |
1019 | - { | |
1020 | - $filestamp = file_exists($file) ? filemtime($file) : 0; | |
1021 | - if ($ignore_notimestamp) { // See the diff file. PukiWiki Trick. | |
1022 | - $pagestamp = is_page($page) ? filemtime(DIFF_DIR . encode($page) . '.txt') : 0; | |
1023 | - } else { | |
1024 | - $pagestamp = is_page($page) ? filemtime(get_filename($page)) : 0; | |
1025 | - } | |
1026 | - return $pagestamp > $filestamp; | |
1027 | - } | |
1017 | + /** | |
1018 | + * Check if the page timestamp is newer than the file timestamp | |
1019 | + * | |
1020 | + * PukiWiki API Extension | |
1021 | + * | |
1022 | + * @param string $page pagename | |
1023 | + * @param string $file filename | |
1024 | + * @param bool $ignore_notimestamp Ignore notimestamp edit and see the real time editted | |
1025 | + * @return boolean | |
1026 | + */ | |
1027 | + function is_page_newer($page, $file, $ignore_notimestamp = TRUE) | |
1028 | + { | |
1029 | + $filestamp = file_exists($file) ? filemtime($file) : 0; | |
1030 | + if ($ignore_notimestamp) { // See the diff file. PukiWiki Trick. | |
1031 | + $pagestamp = is_page($page) ? filemtime(DIFF_DIR . encode($page) . '.txt') : 0; | |
1032 | + } else { | |
1033 | + $pagestamp = is_page($page) ? filemtime(get_filename($page)) : 0; | |
1034 | + } | |
1035 | + return $pagestamp > $filestamp; | |
1036 | + } | |
1028 | 1037 | } |
1029 | 1038 | |
1030 | 1039 | if (! function_exists('exec_page')) { |
1031 | - /** | |
1032 | - * Execute (convert_html) this page | |
1033 | - * | |
1034 | - * PukiWiki API Extension | |
1035 | - * | |
1036 | - * @param string $page | |
1037 | - * @param string $regexp execute only matched lines (preg_grep) | |
1038 | - * @return boolean executed | |
1039 | - */ | |
1040 | - function exec_page($page, $regexp = null) | |
1041 | - { | |
1042 | - global $vars, $get, $post; | |
1043 | - $lines = get_source($page); | |
1044 | - if (isset($regexp)) { | |
1045 | - $lines = preg_grep($regexp, $lines); | |
1046 | - } | |
1047 | - if (empty($lines)) return FALSE; | |
1048 | - $tmp_page = $vars['page']; | |
1049 | - $tmp_cmd = $vars['cmd']; | |
1050 | - $vars['cmd'] = $get['cmd'] = $post['cmd'] = 'read'; | |
1051 | - $vars['page'] = $get['page'] = $post['page'] = $page; | |
1052 | - convert_html($lines); | |
1053 | - $vars['page'] = $get['page'] = $post['page'] = $tmp_page; | |
1054 | - $vars['cmd'] = $get['cmd'] = $post['cmd'] = $tmp_cmd; | |
1055 | - return TRUE; | |
1056 | - } | |
1040 | + /** | |
1041 | + * Execute (convert_html) this page | |
1042 | + * | |
1043 | + * PukiWiki API Extension | |
1044 | + * | |
1045 | + * @param string $page | |
1046 | + * @param string $regexp execute only matched lines (preg_grep) | |
1047 | + * @return boolean executed | |
1048 | + */ | |
1049 | + function exec_page($page, $regexp = null) | |
1050 | + { | |
1051 | + global $vars, $get, $post; | |
1052 | + $lines = get_source($page); | |
1053 | + if (isset($regexp)) { | |
1054 | + $lines = preg_grep($regexp, $lines); | |
1055 | + } | |
1056 | + if (empty($lines)) return FALSE; | |
1057 | + $tmp_page = $vars['page']; | |
1058 | + $tmp_cmd = $vars['cmd']; | |
1059 | + $vars['cmd'] = $get['cmd'] = $post['cmd'] = 'read'; | |
1060 | + $vars['page'] = $get['page'] = $post['page'] = $page; | |
1061 | + convert_html($lines); | |
1062 | + $vars['page'] = $get['page'] = $post['page'] = $tmp_page; | |
1063 | + $vars['cmd'] = $get['cmd'] = $post['cmd'] = $tmp_cmd; | |
1064 | + return TRUE; | |
1065 | + } | |
1057 | 1066 | } |
1058 | 1067 | |
1059 | 1068 | if (! function_exists('exec_existpages')) { |
1060 | - /** | |
1061 | - * Execute (convert_html) all pages | |
1062 | - * | |
1063 | - * PukiWiki API Extension | |
1064 | - * | |
1065 | - * @param string $regexp execute only matched lines (preg_grep) | |
1066 | - * @return array executed pages | |
1067 | - */ | |
1068 | - function exec_existpages($regexp = null) | |
1069 | - { | |
1070 | - global $vars, $get, $post; | |
1071 | - $pages = get_existpages(); | |
1072 | - $exec_pages = array(); | |
1073 | - $tmp_page = $vars['page']; | |
1074 | - $tmp_cmd = $vars['cmd']; | |
1075 | - $vars['cmd'] = $get['cmd'] = $post['cmd'] = 'read'; | |
1076 | - foreach ($pages as $page) { | |
1077 | - $vars['page'] = $get['page'] = $post['page'] = $page; | |
1078 | - $lines = get_source($page); | |
1079 | - if (isset($regexp)) { | |
1080 | - $lines = preg_grep($regexp, $lines); | |
1081 | - } | |
1082 | - if (empty($lines)) continue; | |
1083 | - convert_html($lines); | |
1084 | - $exec_pages[] = $page; | |
1085 | - } | |
1086 | - $vars['page'] = $get['page'] = $post['page'] = $tmp_page; | |
1087 | - $vars['cmd'] = $get['cmd'] = $post['cmd'] = $tmp_cmd; | |
1088 | - return $exec_pages; | |
1089 | - } | |
1069 | + /** | |
1070 | + * Execute (convert_html) all pages | |
1071 | + * | |
1072 | + * PukiWiki API Extension | |
1073 | + * | |
1074 | + * @param string $regexp execute only matched lines (preg_grep) | |
1075 | + * @return array executed pages | |
1076 | + */ | |
1077 | + function exec_existpages($regexp = null) | |
1078 | + { | |
1079 | + global $vars, $get, $post; | |
1080 | + $pages = get_existpages(); | |
1081 | + $exec_pages = array(); | |
1082 | + $tmp_page = $vars['page']; | |
1083 | + $tmp_cmd = $vars['cmd']; | |
1084 | + $vars['cmd'] = $get['cmd'] = $post['cmd'] = 'read'; | |
1085 | + foreach ($pages as $page) { | |
1086 | + $vars['page'] = $get['page'] = $post['page'] = $page; | |
1087 | + $lines = get_source($page); | |
1088 | + if (isset($regexp)) { | |
1089 | + $lines = preg_grep($regexp, $lines); | |
1090 | + } | |
1091 | + if (empty($lines)) continue; | |
1092 | + convert_html($lines); | |
1093 | + $exec_pages[] = $page; | |
1094 | + } | |
1095 | + $vars['page'] = $get['page'] = $post['page'] = $tmp_page; | |
1096 | + $vars['cmd'] = $get['cmd'] = $post['cmd'] = $tmp_cmd; | |
1097 | + return $exec_pages; | |
1098 | + } | |
1090 | 1099 | } |
1091 | 1100 | |
1092 | 1101 | ////////////// PHP API Extension |
1093 | 1102 | if (! function_exists('get_existfiles')) { |
1094 | - /** | |
1095 | - * Get list of files in a directory | |
1096 | - * | |
1097 | - * PHP Extension | |
1098 | - * | |
1099 | - * @access public | |
1100 | - * @param string $dir Directory Name | |
1101 | - * @param string $ext File Extension | |
1102 | - * @param bool $recursive Traverse Recursively | |
1103 | - * @return array array of filenames | |
1104 | - * @uses is_dir() | |
1105 | - * @uses opendir() | |
1106 | - * @uses readdir() | |
1107 | - */ | |
1108 | - function &get_existfiles($dir, $ext = '', $recursive = FALSE) | |
1109 | - { | |
1110 | - if (($dp = @opendir($dir)) == FALSE) | |
1111 | - return FALSE; | |
1112 | - $pattern = '/' . preg_quote($ext, '/') . '$/'; | |
1113 | - $dir = ($dir[strlen($dir)-1] == '/') ? $dir : $dir . '/'; | |
1114 | - $dir = ($dir == '.' . '/') ? '' : $dir; | |
1115 | - $files = array(); | |
1116 | - while (($file = readdir($dp)) !== false ) { | |
1117 | - if($file != '.' && $file != '..' && is_dir($dir . $file) && $recursive) { | |
1118 | - $files = array_merge($files, get_existfiles($dir . $file, $ext, $recursive)); | |
1119 | - } else { | |
1120 | - $matches = array(); | |
1121 | - if (preg_match($pattern, $file, $matches)) { | |
1122 | - $files[] = $dir . $file; | |
1123 | - } | |
1124 | - } | |
1125 | - } | |
1126 | - closedir($dp); | |
1127 | - return $files; | |
1128 | - } | |
1103 | + /** | |
1104 | + * Get list of files in a directory | |
1105 | + * | |
1106 | + * PHP Extension | |
1107 | + * | |
1108 | + * @access public | |
1109 | + * @param string $dir Directory Name | |
1110 | + * @param string $ext File Extension | |
1111 | + * @param bool $recursive Traverse Recursively | |
1112 | + * @return array array of filenames | |
1113 | + * @uses is_dir() | |
1114 | + * @uses opendir() | |
1115 | + * @uses readdir() | |
1116 | + */ | |
1117 | + function &get_existfiles($dir, $ext = '', $recursive = FALSE) | |
1118 | + { | |
1119 | + if (($dp = @opendir($dir)) == FALSE) | |
1120 | + return FALSE; | |
1121 | + $pattern = '/' . preg_quote($ext, '/') . '$/'; | |
1122 | + $dir = ($dir[strlen($dir)-1] == '/') ? $dir : $dir . '/'; | |
1123 | + $dir = ($dir == '.' . '/') ? '' : $dir; | |
1124 | + $files = array(); | |
1125 | + while (($file = readdir($dp)) !== false ) { | |
1126 | + if($file != '.' && $file != '..' && is_dir($dir . $file) && $recursive) { | |
1127 | + $files = array_merge($files, get_existfiles($dir . $file, $ext, $recursive)); | |
1128 | + } else { | |
1129 | + $matches = array(); | |
1130 | + if (preg_match($pattern, $file, $matches)) { | |
1131 | + $files[] = $dir . $file; | |
1132 | + } | |
1133 | + } | |
1134 | + } | |
1135 | + closedir($dp); | |
1136 | + return $files; | |
1137 | + } | |
1129 | 1138 | } |
1130 | 1139 | |
1131 | 1140 | if (! function_exists('is_associative_array')) { |
1132 | - /** | |
1133 | - * Check if an array is an associative array | |
1134 | - * | |
1135 | - * PHP Extension | |
1136 | - * | |
1137 | - * @param array $array | |
1138 | - * @return boolean | |
1139 | - */ | |
1140 | - function is_associative_array($array) | |
1141 | - { | |
1142 | - if (!is_array($array) || empty($array)) | |
1143 | - return false; | |
1144 | - $keys = array_keys($array); | |
1145 | - return array_keys($keys) !== $keys; | |
1146 | - // or | |
1147 | - //return is_array($array) && !is_numeric(implode(array_keys($array))); | |
1148 | - } | |
1141 | + /** | |
1142 | + * Check if an array is an associative array | |
1143 | + * | |
1144 | + * PHP Extension | |
1145 | + * | |
1146 | + * @param array $array | |
1147 | + * @return boolean | |
1148 | + */ | |
1149 | + function is_associative_array($array) | |
1150 | + { | |
1151 | + if (!is_array($array) || empty($array)) | |
1152 | + return false; | |
1153 | + $keys = array_keys($array); | |
1154 | + return array_keys($keys) !== $keys; | |
1155 | + // or | |
1156 | + //return is_array($array) && !is_numeric(implode(array_keys($array))); | |
1157 | + } | |
1149 | 1158 | } |
1150 | 1159 | |
1151 | 1160 | if (! function_exists('_')) { |
1152 | - function &_($str) | |
1153 | - { | |
1154 | - return $str; | |
1155 | - } | |
1161 | + function &_($str) | |
1162 | + { | |
1163 | + return $str; | |
1164 | + } | |
1156 | 1165 | } |
1157 | 1166 | |
1158 | 1167 | /////////////////////////////////// |
1159 | 1168 | function plugin_contentsx_common_init() |
1160 | 1169 | { |
1161 | - global $plugin_contentsx; | |
1162 | - if (class_exists('PluginContentsxUnitTest')) { | |
1163 | - $plugin_contentsx = new PluginContentsxUnitTest(); | |
1164 | - } elseif (class_exists('PluginContentsxUser')) { | |
1165 | - $plugin_contentsx = new PluginContentsxUser(); | |
1166 | - } else { | |
1167 | - $plugin_contentsx = new PluginContentsx(); | |
1168 | - } | |
1170 | + global $plugin_contentsx; | |
1171 | + if (class_exists('PluginContentsxUnitTest')) { | |
1172 | + $plugin_contentsx = new PluginContentsxUnitTest(); | |
1173 | + } elseif (class_exists('PluginContentsxUser')) { | |
1174 | + $plugin_contentsx = new PluginContentsxUser(); | |
1175 | + } else { | |
1176 | + $plugin_contentsx = new PluginContentsx(); | |
1177 | + } | |
1169 | 1178 | } |
1170 | 1179 | |
1171 | 1180 | function plugin_contentsx_convert() |
1172 | 1181 | { |
1173 | - global $plugin_contentsx; plugin_contentsx_common_init(); | |
1174 | - $args = func_get_args(); | |
1175 | - return call_user_func_array(array(&$plugin_contentsx, 'convert'), $args); | |
1182 | + global $plugin_contentsx; plugin_contentsx_common_init(); | |
1183 | + $args = func_get_args(); | |
1184 | + return call_user_func_array(array(&$plugin_contentsx, 'convert'), $args); | |
1176 | 1185 | } |
1177 | 1186 | function plugin_contentsx_action() |
1178 | 1187 | { |
1179 | - global $plugin_contentsx; plugin_contentsx_common_init(); | |
1180 | - return call_user_func(array(&$plugin_contentsx, 'action')); | |
1188 | + global $plugin_contentsx; plugin_contentsx_common_init(); | |
1189 | + return call_user_func(array(&$plugin_contentsx, 'action')); | |
1181 | 1190 | } |
1182 | 1191 | |
1183 | 1192 | ?> |
@@ -8,674 +8,680 @@ | ||
8 | 8 | * @version $Id: includex.inc.php,v 1.5 2007-06-05 07:23:17Z sonots $ |
9 | 9 | * @package plugin |
10 | 10 | */ |
11 | + // v1.51 PHP8.0対応 2021-12-15 byはいふん | |
11 | 12 | |
12 | 13 | class PluginIncludex |
13 | 14 | { |
14 | - function PluginIncludex() | |
15 | - { | |
16 | - // Modify here for default values (type, default, choices) | |
17 | - static $default_options = array( | |
18 | - 'num' => array('number', ''), | |
19 | - 'except' => array('string', ''), | |
20 | - 'filter' => array('string', ''), | |
21 | - 'title' => array('enum', 'on', array('on', 'off', 'nolink', 'basename')), // obsolete | |
22 | - 'titlestr' => array('enum', 'title', array('name', 'off', 'basename', 'title', 'relname')), | |
23 | - 'titlelink' => array('bool', true), | |
24 | - 'section' => array('array', array()), | |
25 | - 'permalink' => array('string', false), | |
26 | - 'head' => array('bool', true), | |
27 | - ); | |
28 | - static $default_section_options = array( | |
29 | - 'num' => array('number', ''), | |
30 | - 'depth' => array('number', ''), | |
31 | - 'except' => array('string', ''), | |
32 | - 'filter' => array('string', ''), | |
33 | - 'cache' => array('enum', 'on', array('on', 'off', 'reset')), | |
34 | - 'inclsub' => array('bool', false), // not yet | |
35 | - ); | |
36 | - $this->default_options = &$default_options; | |
37 | - $this->default_section_options = &$default_section_options; | |
38 | - | |
39 | - // init | |
40 | - static $visited = array(); | |
41 | - $this->visited = &$visited; | |
42 | - $this->options = $this->default_options; | |
43 | - $this->section_options = $this->default_section_options; | |
44 | - } | |
45 | - | |
46 | - // static | |
47 | - var $default_options; | |
48 | - var $default_section_options; | |
49 | - var $visited; | |
50 | - // var | |
51 | - var $error = ""; | |
52 | - var $plugin = "includex"; | |
53 | - var $options; | |
54 | - var $section_options; | |
55 | - var $inclpage; | |
56 | - var $lines; | |
57 | - var $headlines; | |
58 | - var $narrowed_headlines; | |
59 | - | |
60 | - function convert() | |
61 | - { | |
62 | - $args = func_get_args(); | |
63 | - $body = $this->body($args); | |
64 | - if ($this->error != "" ) { return "<p>#$this->plugin(): $this->error</p>"; } | |
65 | - return $body; | |
66 | - } | |
67 | - | |
68 | - function body($args) | |
69 | - { | |
70 | - global $vars, $get, $post; | |
71 | - | |
72 | - $this->visited[$vars['page']] = TRUE; | |
73 | - $this->inclpage = array_shift($args); | |
74 | - $this->check_page(); | |
75 | - if ($this->error != "") { return; } | |
76 | - | |
77 | - $parser = new PluginIncludexOptionParser(); | |
78 | - $this->options = $parser->parse_options($args, $this->options); | |
79 | - if ($parser->error != "") { $this->error = $parser->error; return; } | |
80 | - | |
81 | - $this->check_options(); | |
82 | - if ($this->error != "") { return; } | |
83 | - | |
84 | - $this->init_lines(); | |
85 | - if ($this->error !== "") { return; } | |
86 | - | |
87 | - $this->narrow_lines(); | |
88 | - if ($this->error !== "") { return; } | |
89 | - | |
90 | - $body = $this->frontend(); | |
91 | - if ($this->error !== "") { return; } | |
92 | - | |
93 | - $this->visited[$this->inclpage] = TRUE; | |
94 | - return $body; | |
95 | - } | |
96 | - | |
97 | - function check_options() | |
98 | - { | |
99 | - // support lower version | |
100 | - if ($this->options['title'][1] != 'on') { | |
101 | - if ($this->options['title'][1] == 'nolink') { | |
102 | - $this->options['titlelink'][1] = false; | |
103 | - $this->options['titlestr'][1] = 'name'; | |
104 | - } else { | |
105 | - $this->options['titlestr'][1] = $this->options['title'][1]; | |
106 | - } | |
107 | - } | |
108 | - if ($this->options['permalink'][1] === '') { | |
109 | - $this->options['permalink'][1] = _('Permalink'); | |
110 | - } | |
111 | - } | |
112 | - | |
113 | - function check_page() | |
114 | - { | |
115 | - global $vars; | |
116 | - | |
117 | - if (empty($this->inclpage)) { | |
118 | - $this->error = "No page is specified."; | |
119 | - return; | |
120 | - } | |
121 | - $current = $vars['page']; | |
122 | - $this->inclpage = get_fullname($this->inclpage, $current); | |
123 | - | |
124 | - if (! $this->is_page($this->inclpage)) { | |
125 | - $this->error = "$this->inclpage does not eixst."; | |
126 | - return; | |
127 | - } | |
128 | - if (! $this->check_readable($this->inclpage, false, false)) { | |
129 | - $this->error = "$this->inclpage is not readable."; | |
130 | - return; | |
131 | - } | |
132 | - if (isset($this->visited[$this->inclpage])) { | |
133 | - $this->error = "$this->inclpage is already included."; | |
134 | - return; | |
135 | - } | |
136 | - } | |
137 | - | |
138 | - function frontend() | |
139 | - { | |
140 | - global $vars, $get, $post; | |
141 | - | |
142 | - $titlestr = PluginIncludex::get_titlestr($this->inclpage, $this->options['titlestr'][1]); | |
143 | - $title = PluginIncludex::get_title($this->inclpage, $titlestr, $this->options['title'][1]); | |
144 | - if ($this->error != "") { return; } | |
145 | - | |
146 | - // because included page would use these variables. | |
147 | - $tmp = $vars['page']; | |
148 | - $get['page'] = $post['page'] = $vars['page'] = $this->inclpage; | |
149 | - if (function_exists('convert_filter')) { | |
150 | - $this->lines = convert_filter($this->lines); // plus | |
151 | - } | |
152 | - $body = convert_html($this->lines); | |
153 | - $get['page'] = $post['page'] = $vars['page'] = $tmp; | |
154 | - if ($this->error != "") { return; } | |
155 | - | |
156 | - $footer = ''; | |
157 | - if ($this->options['permalink'][1] !== false) { | |
158 | - $linkstr = $this->make_inline($this->options['permalink'][1]); | |
159 | - $footer = '<p class="permalink">' . | |
160 | - make_pagelink($this->inclpage, $linkstr) . '</p>'; | |
161 | - } | |
162 | - | |
163 | - return $title . "\n" . $body . $footer; | |
164 | - } | |
165 | - | |
166 | - // static | |
167 | - function get_titlestr($inclpage, $option = null, $current = null) | |
168 | - { | |
169 | - switch ($option) { | |
170 | - case 'off': | |
171 | - $titlestr = ''; | |
172 | - break; | |
173 | - case 'name': | |
174 | - $titlestr = htmlspecialchars($inclpage); | |
175 | - break; | |
176 | - case 'basename': | |
177 | - $titlestr = htmlspecialchars(basename($inclpage)); | |
178 | - break; | |
179 | - case 'relname': | |
180 | - if (! isset($current)) $current = $GLOBALS['vars']['page']; | |
181 | - if (($i = strpos($inclpage, $current . '/')) === 0) { | |
182 | - $titlestr = htmlspecialchars(substr($inclpage, strlen($current)+1)); | |
183 | - } else { | |
184 | - $titlestr = htmlspecialchars($inclpage); | |
185 | - } | |
186 | - break; | |
187 | - case 'on': | |
188 | - case 'title': | |
189 | - default: | |
190 | - if (exist_plugin('contentsx')) { | |
191 | - $contentsx = new PluginContentsx(); | |
192 | - if (method_exists($contentsx, 'get_title')) { | |
193 | - $titlestr = $contentsx->get_title($inclpage); | |
194 | - $titlestr = strip_htmltag(make_link($titlestr)); | |
195 | - } | |
196 | - } | |
197 | - if ($titlestr == '') $titlestr = htmlspecialchars($inclpage); | |
198 | - break; | |
199 | - } | |
200 | - return $titlestr; | |
201 | - } | |
202 | - | |
203 | - // static | |
204 | - function get_title($inclpage, $titlestr, $option = true) | |
205 | - { | |
206 | - global $fixed_heading_edited; | |
207 | - $anchorlink = ' ' . PluginIncludex::get_page_anchorlink($inclpage); | |
208 | - $editlink = $fixed_heading_edited ? ' ' . PluginIncludex::get_page_editlink($inclpage) : ''; | |
209 | - | |
210 | - if ($titlestr == '') { | |
211 | - //return $ret = '<div class="' .$this->plugin . '">' . $anchorlink . '</div>'; | |
212 | - return ''; | |
213 | - } | |
214 | - switch ($option) { | |
215 | - case false: | |
216 | - $ret = '<h1 class="includex">' . $titlestr . $editlink . $anchorlink . '</h1>'; | |
217 | - break; | |
218 | - case true: | |
219 | - default: | |
220 | - $link = make_pagelink($inclpage, $titlestr); | |
221 | - $ret = '<h1 class="includex">' . $link . $editlink . $anchorlink . '</h1>'; | |
222 | - break; | |
223 | - } | |
224 | - return $ret; | |
225 | - } | |
226 | - | |
227 | - function narrow_lines() | |
228 | - { | |
229 | - $parser = new PluginIncludexOptionParser(); | |
230 | - | |
231 | - if (! empty($this->options['section'][1]) && exist_plugin('contentsx')) { | |
232 | - $this->section_lines(); | |
233 | - } | |
234 | - | |
235 | - $this->filter_lines(); | |
236 | - $this->except_lines(); | |
237 | - | |
238 | - $num = sizeof($this->lines); | |
239 | - $this->options['num'][1] = $parser->parse_numoption($this->options['num'][1], 1, $num); | |
240 | - if ($parser->error !== "") { $this->error = $parser->error; return; } | |
241 | - $this->num_filter_lines(); | |
242 | - | |
243 | - $this->cut_head_lines(); | |
244 | - } | |
245 | - | |
246 | - function cut_head_lines() | |
247 | - { | |
248 | - // cut the headline on the first line | |
249 | - if ($this->options['head'][1] === FALSE) { | |
250 | - $def_headline = '/^(\*{1,3})/'; | |
251 | - if (preg_match($def_headline, $this->lines[0])) { | |
252 | - unset($this->lines[0]); | |
253 | - } | |
254 | - } | |
255 | - } | |
256 | - | |
257 | - | |
258 | - function section_lines() | |
259 | - { | |
260 | - if (empty($this->options['section'][1])) { | |
261 | - return; | |
262 | - } | |
263 | - $parser = new PluginIncludexOptionParser(); | |
264 | - $this->section_options = $parser->parse_options($this->options['section'][1], $this->section_options); | |
265 | - if ($parser->error != "") { $this->error = $parser->error; return; } | |
266 | - | |
267 | - // what a public class! hehehe | |
268 | - $contentsx = new PluginContentsx(); | |
269 | - $contentsx->options['include'][1] = false; | |
270 | - $contentsx->options['fromhere'][1] = false; | |
271 | - $contentsx->options['page'][1] = $contentsx->check_page($this->inclpage); | |
272 | - $this->headlines = $contentsx->get_metalines($this->inclpage); | |
273 | - if ($contentsx->error != "") { $this->error = $contentsx->error; return; } | |
274 | - foreach ($this->section_options as $key => $val) { | |
275 | - $contentsx->options[$key] = $val; | |
276 | - } | |
277 | - | |
278 | - $contentsx->narrow_metalines(); | |
279 | - if ($contentsx->error != "") { $this->error = $contentsx->error; return; } | |
280 | - $this->narrowed_headlines = $contentsx->metalines; | |
281 | - | |
282 | - $size = sizeof($this->headlines); | |
283 | - $this->section_options['num'][1] = $parser->parse_numoption($this->section_options['num'][1], 0, $size); | |
284 | - $lines = array(); | |
285 | - if (in_array(0, $this->section_options['num'][1])) { | |
286 | - $linenum = $this->headlines[0]['linenum']; | |
287 | - $lines = array_merge($lines, array_splice($this->lines, 0, $linenum)); | |
288 | - } | |
289 | - // FutureWork: Do no rely on contentsx's cache as much as possible. | |
290 | - $i = 0; $size = sizeof($this->headlines); | |
291 | - foreach ($this->narrowed_headlines as $narrowed_headline) { | |
292 | - $linenum = $narrowed_headline['linenum']; | |
293 | - for (; $i < $size; $i++ ) { | |
294 | - $current = $i; | |
295 | - if ($linenum != $this->headlines[$current]['linenum']) { | |
296 | - continue; | |
297 | - } | |
298 | - $next = $i + 1; | |
299 | - if ($next < $size) { | |
300 | - $len = $this->headlines[$next]['linenum'] - $linenum; | |
301 | - $lines = array_merge($lines, array_slice($this->lines, $linenum, $len)); | |
302 | - } else { | |
303 | - $lines = array_merge($lines, array_slice($this->lines, $linenum)); | |
304 | - } | |
305 | - break; | |
306 | - } | |
307 | - } | |
308 | - $this->lines = $lines; | |
309 | - } | |
310 | - | |
311 | - function num_filter_lines() | |
312 | - { | |
313 | - if ($this->options['num'][1] === '') { | |
314 | - return; | |
315 | - } | |
316 | - $lines = array(); | |
317 | - foreach ($this->options['num'][1] as $num) { | |
318 | - $lines[] = $this->lines[$num - 1]; | |
319 | - } | |
320 | - $this->lines = $lines; | |
321 | - } | |
322 | - | |
323 | - function filter_lines() | |
324 | - { | |
325 | - if ($this->options['filter'][1] === "") { | |
326 | - return; | |
327 | - } | |
328 | - $lines = array(); | |
329 | - foreach ($this->lines as $line) { | |
330 | - if (ereg($this->options['filter'][1], $line)) { | |
331 | - $lines[] = $line; | |
332 | - } | |
333 | - } | |
334 | - $this->lines = $lines; | |
335 | - } | |
336 | - | |
337 | - function except_lines() | |
338 | - { | |
339 | - if ($this->options['except'][1] === "") { | |
340 | - return; | |
341 | - } | |
342 | - $lines = array(); | |
343 | - foreach ($this->lines as $line) { | |
344 | - if (! ereg($this->options['except'][1], $line)) { | |
345 | - $lines[] = $line; | |
346 | - } | |
347 | - } | |
348 | - $this->lines = $lines; | |
349 | - } | |
350 | - | |
351 | - function init_lines() | |
352 | - { | |
353 | - $this->lines = $this->get_source($this->inclpage); | |
354 | - } | |
355 | - | |
356 | - // static | |
357 | - function get_page_anchor($page) { | |
358 | - // anchor must be '^[A-Za-z][A-Za-z0-9_-]*' | |
359 | - return 'z' . md5($page); | |
360 | - } | |
361 | - | |
362 | - // PukiWiki API Extension | |
363 | - | |
364 | - // convert inline plugins | |
365 | - // PukiWiki API InlineConverter does htmlspecialchars, too. | |
366 | - // refer plugin/make_link.php#make_link | |
367 | - // static | |
368 | - function make_inline($string, $page = '') | |
369 | - { | |
370 | - global $vars; | |
371 | - static $converter; | |
372 | - | |
373 | - if (! isset($converter)) $converter = new InlineConverter(array('plugin')); | |
374 | - | |
375 | - $clone = $converter->get_clone($converter); | |
376 | - return $clone->convert($string, ($page != '') ? $page : $vars['page']); | |
377 | - } | |
378 | - | |
379 | - // refer plugin/aname.inc.php | |
380 | - // static | |
381 | - function get_page_anchorlink($page) { | |
382 | - global $_symbol_anchor; | |
383 | - global $pkwk_dtd; | |
384 | - | |
385 | - $id = $this->get_page_anchor($page); | |
386 | - $id = htmlspecialchars($id); | |
387 | - | |
388 | - // aname allows only fiexed_anchors such as x83dvkd8 | |
389 | - //if (exist_plugin_inline('aname')) { | |
390 | - //$link = do_plugin_inline('aname', "$anchor,super,$_symbol_anchor"); | |
391 | - //} | |
392 | - | |
393 | - if (isset($pkwk_dtd) && $pkwk_dtd < PKWK_DTD_XHTML_1_1) { | |
394 | - $attr_id = ' id="' . $id . '" name="' . $id . '"'; | |
395 | - } else { | |
396 | - $attr_id = ' id="' . $id . '"'; | |
397 | - } | |
398 | - $attr_href = ' href="#' . $id . '"'; | |
399 | - $attr_title = ' title="' . $id . '"'; | |
400 | - $attr_class = ' class="anchor_super"'; | |
401 | - $link = '<a' . $attr_class . $attr_id . $attr_href . $attr_title . '>' . $_symbol_anchor . '</a>'; | |
402 | - return $link; | |
403 | - } | |
404 | - | |
405 | - // static | |
406 | - function get_page_editlink($page) { | |
407 | - $r_page = rawurlencode($page); | |
408 | - $link = '<a class="anchor_super" href="' . get_script_uri() . '?cmd=edit&page=' . $r_page . '">'; | |
409 | - $link .= '<img class="paraedit" src="' . IMAGE_DIR . 'edit.png" alt="Edit" title="Edit" />'; | |
410 | - $link .= '</a>'; | |
411 | - return $link; | |
412 | - } | |
413 | - | |
414 | - function get_source($page) | |
415 | - { | |
416 | - return get_source($page); | |
417 | - } | |
418 | - | |
419 | - function is_page($page) | |
420 | - { | |
421 | - return is_page($page); | |
422 | - } | |
423 | - | |
424 | - function check_readable($page, $flag, $flag) | |
425 | - { | |
426 | - return check_readable($page, $flag, $flag); | |
427 | - } | |
15 | + function __construct() | |
16 | + { | |
17 | + // Modify here for default values (type, default, choices) | |
18 | + static $default_options = array( | |
19 | + 'num' => array('number', ''), | |
20 | + 'except' => array('string', ''), | |
21 | + 'filter' => array('string', ''), | |
22 | + 'title' => array('enum', 'on', array('on', 'off', 'nolink', 'basename')), // obsolete | |
23 | + 'titlestr' => array('enum', 'title', array('name', 'off', 'basename', 'title', 'relname')), | |
24 | + 'titlelink' => array('bool', true), | |
25 | + 'section' => array('array', array()), | |
26 | + 'permalink' => array('string', false), | |
27 | + 'head' => array('bool', true), | |
28 | + ); | |
29 | + static $default_section_options = array( | |
30 | + 'num' => array('number', ''), | |
31 | + 'depth' => array('number', ''), | |
32 | + 'except' => array('string', ''), | |
33 | + 'filter' => array('string', ''), | |
34 | + 'cache' => array('enum', 'on', array('on', 'off', 'reset')), | |
35 | + 'inclsub' => array('bool', false), // not yet | |
36 | + ); | |
37 | + $this->default_options = &$default_options; | |
38 | + $this->default_section_options = &$default_section_options; | |
39 | + | |
40 | + // init | |
41 | + static $visited = array(); | |
42 | + $this->visited = &$visited; | |
43 | + $this->options = $this->default_options; | |
44 | + $this->section_options = $this->default_section_options; | |
45 | + } | |
46 | + | |
47 | + function PluginIncludex() { | |
48 | + $this->__construct(); | |
49 | + } | |
50 | + | |
51 | + // static | |
52 | + var $default_options; | |
53 | + var $default_section_options; | |
54 | + var $visited; | |
55 | + // var | |
56 | + var $error = ""; | |
57 | + var $plugin = "includex"; | |
58 | + var $options; | |
59 | + var $section_options; | |
60 | + var $inclpage; | |
61 | + var $lines; | |
62 | + var $headlines; | |
63 | + var $narrowed_headlines; | |
64 | + | |
65 | + function convert() | |
66 | + { | |
67 | + $args = func_get_args(); | |
68 | + $body = $this->body($args); | |
69 | + if ($this->error != "" ) { return "<p>#$this->plugin(): $this->error</p>"; } | |
70 | + return $body; | |
71 | + } | |
72 | + | |
73 | + function body($args) | |
74 | + { | |
75 | + global $vars, $get, $post; | |
76 | + | |
77 | + $this->visited[$vars['page']] = TRUE; | |
78 | + $this->inclpage = array_shift($args); | |
79 | + $this->check_page(); | |
80 | + if ($this->error != "") { return; } | |
81 | + | |
82 | + $parser = new PluginIncludexOptionParser(); | |
83 | + $this->options = $parser->parse_options($args, $this->options); | |
84 | + if ($parser->error != "") { $this->error = $parser->error; return; } | |
85 | + | |
86 | + $this->check_options(); | |
87 | + if ($this->error != "") { return; } | |
88 | + | |
89 | + $this->init_lines(); | |
90 | + if ($this->error !== "") { return; } | |
91 | + | |
92 | + $this->narrow_lines(); | |
93 | + if ($this->error !== "") { return; } | |
94 | + | |
95 | + $body = $this->frontend(); | |
96 | + if ($this->error !== "") { return; } | |
97 | + | |
98 | + $this->visited[$this->inclpage] = TRUE; | |
99 | + return $body; | |
100 | + } | |
101 | + | |
102 | + function check_options() | |
103 | + { | |
104 | + // support lower version | |
105 | + if ($this->options['title'][1] != 'on') { | |
106 | + if ($this->options['title'][1] == 'nolink') { | |
107 | + $this->options['titlelink'][1] = false; | |
108 | + $this->options['titlestr'][1] = 'name'; | |
109 | + } else { | |
110 | + $this->options['titlestr'][1] = $this->options['title'][1]; | |
111 | + } | |
112 | + } | |
113 | + if ($this->options['permalink'][1] === '') { | |
114 | + $this->options['permalink'][1] = _('Permalink'); | |
115 | + } | |
116 | + } | |
117 | + | |
118 | + function check_page() | |
119 | + { | |
120 | + global $vars; | |
121 | + | |
122 | + if (empty($this->inclpage)) { | |
123 | + $this->error = "No page is specified."; | |
124 | + return; | |
125 | + } | |
126 | + $current = $vars['page']; | |
127 | + $this->inclpage = get_fullname($this->inclpage, $current); | |
128 | + | |
129 | + if (! $this->is_page($this->inclpage)) { | |
130 | + $this->error = "$this->inclpage does not eixst."; | |
131 | + return; | |
132 | + } | |
133 | + if (! $this->check_readable($this->inclpage, false, false)) { | |
134 | + $this->error = "$this->inclpage is not readable."; | |
135 | + return; | |
136 | + } | |
137 | + if (isset($this->visited[$this->inclpage])) { | |
138 | + $this->error = "$this->inclpage is already included."; | |
139 | + return; | |
140 | + } | |
141 | + } | |
142 | + | |
143 | + function frontend() | |
144 | + { | |
145 | + global $vars, $get, $post; | |
146 | + | |
147 | + $titlestr = PluginIncludex::get_titlestr($this->inclpage, $this->options['titlestr'][1]); | |
148 | + $title = PluginIncludex::get_title($this->inclpage, $titlestr, $this->options['title'][1]); | |
149 | + if ($this->error != "") { return; } | |
150 | + | |
151 | + // because included page would use these variables. | |
152 | + $tmp = $vars['page']; | |
153 | + $get['page'] = $post['page'] = $vars['page'] = $this->inclpage; | |
154 | + if (function_exists('convert_filter')) { | |
155 | + $this->lines = convert_filter($this->lines); // plus | |
156 | + } | |
157 | + $body = convert_html($this->lines); | |
158 | + $get['page'] = $post['page'] = $vars['page'] = $tmp; | |
159 | + if ($this->error != "") { return; } | |
160 | + | |
161 | + $footer = ''; | |
162 | + if ($this->options['permalink'][1] !== false) { | |
163 | + $linkstr = $this->make_inline($this->options['permalink'][1]); | |
164 | + $footer = '<p class="permalink">' . | |
165 | + make_pagelink($this->inclpage, $linkstr) . '</p>'; | |
166 | + } | |
167 | + | |
168 | + return $title . "\n" . $body . $footer; | |
169 | + } | |
170 | + | |
171 | + // static | |
172 | + function get_titlestr($inclpage, $option = null, $current = null) | |
173 | + { | |
174 | + switch ($option) { | |
175 | + case 'off': | |
176 | + $titlestr = ''; | |
177 | + break; | |
178 | + case 'name': | |
179 | + $titlestr = htmlsc($inclpage); | |
180 | + break; | |
181 | + case 'basename': | |
182 | + $titlestr = htmlsc(basename($inclpage)); | |
183 | + break; | |
184 | + case 'relname': | |
185 | + if (! isset($current)) $current = $GLOBALS['vars']['page']; | |
186 | + if (($i = strpos($inclpage, $current . '/')) === 0) { | |
187 | + $titlestr = htmlsc(substr($inclpage, strlen($current)+1)); | |
188 | + } else { | |
189 | + $titlestr = htmlsc($inclpage); | |
190 | + } | |
191 | + break; | |
192 | + case 'on': | |
193 | + case 'title': | |
194 | + default: | |
195 | + if (exist_plugin('contentsx')) { | |
196 | + $contentsx = new PluginContentsx(); | |
197 | + if (method_exists($contentsx, 'get_title')) { | |
198 | + $titlestr = $contentsx->get_title($inclpage); | |
199 | + $titlestr = strip_htmltag(make_link($titlestr)); | |
200 | + } | |
201 | + } | |
202 | + if ($titlestr == '') $titlestr = htmlsc($inclpage); | |
203 | + break; | |
204 | + } | |
205 | + return $titlestr; | |
206 | + } | |
207 | + | |
208 | + // static | |
209 | + function get_title($inclpage, $titlestr, $option = true) | |
210 | + { | |
211 | + global $fixed_heading_edited; | |
212 | + $anchorlink = ' ' . PluginIncludex::get_page_anchorlink($inclpage); | |
213 | + $editlink = $fixed_heading_edited ? ' ' . PluginIncludex::get_page_editlink($inclpage) : ''; | |
214 | + | |
215 | + if ($titlestr == '') { | |
216 | + //return $ret = '<div class="' .$this->plugin . '">' . $anchorlink . '</div>'; | |
217 | + return ''; | |
218 | + } | |
219 | + switch ($option) { | |
220 | + case false: | |
221 | + $ret = '<h1 class="includex">' . $titlestr . $editlink . $anchorlink . '</h1>'; | |
222 | + break; | |
223 | + case true: | |
224 | + default: | |
225 | + $link = make_pagelink($inclpage, $titlestr); | |
226 | + $ret = '<h1 class="includex">' . $link . $editlink . $anchorlink . '</h1>'; | |
227 | + break; | |
228 | + } | |
229 | + return $ret; | |
230 | + } | |
231 | + | |
232 | + function narrow_lines() | |
233 | + { | |
234 | + $parser = new PluginIncludexOptionParser(); | |
235 | + | |
236 | + if (! empty($this->options['section'][1]) && exist_plugin('contentsx')) { | |
237 | + $this->section_lines(); | |
238 | + } | |
239 | + | |
240 | + $this->filter_lines(); | |
241 | + $this->except_lines(); | |
242 | + | |
243 | + $num = sizeof($this->lines); | |
244 | + $this->options['num'][1] = $parser->parse_numoption($this->options['num'][1], 1, $num); | |
245 | + if ($parser->error !== "") { $this->error = $parser->error; return; } | |
246 | + $this->num_filter_lines(); | |
247 | + | |
248 | + $this->cut_head_lines(); | |
249 | + } | |
250 | + | |
251 | + function cut_head_lines() | |
252 | + { | |
253 | + // cut the headline on the first line | |
254 | + if ($this->options['head'][1] === FALSE) { | |
255 | + $def_headline = '/^(\*{1,3})/'; | |
256 | + if (preg_match($def_headline, $this->lines[0])) { | |
257 | + unset($this->lines[0]); | |
258 | + } | |
259 | + } | |
260 | + } | |
261 | + | |
262 | + | |
263 | + function section_lines() | |
264 | + { | |
265 | + if (empty($this->options['section'][1])) { | |
266 | + return; | |
267 | + } | |
268 | + $parser = new PluginIncludexOptionParser(); | |
269 | + $this->section_options = $parser->parse_options($this->options['section'][1], $this->section_options); | |
270 | + if ($parser->error != "") { $this->error = $parser->error; return; } | |
271 | + | |
272 | + // what a public class! hehehe | |
273 | + $contentsx = new PluginContentsx(); | |
274 | + $contentsx->options['include'][1] = false; | |
275 | + $contentsx->options['fromhere'][1] = false; | |
276 | + $contentsx->options['page'][1] = $contentsx->check_page($this->inclpage); | |
277 | + $this->headlines = $contentsx->get_metalines($this->inclpage); | |
278 | + if ($contentsx->error != "") { $this->error = $contentsx->error; return; } | |
279 | + foreach ($this->section_options as $key => $val) { | |
280 | + $contentsx->options[$key] = $val; | |
281 | + } | |
282 | + | |
283 | + $contentsx->narrow_metalines(); | |
284 | + if ($contentsx->error != "") { $this->error = $contentsx->error; return; } | |
285 | + $this->narrowed_headlines = $contentsx->metalines; | |
286 | + | |
287 | + $size = sizeof($this->headlines); | |
288 | + $this->section_options['num'][1] = $parser->parse_numoption($this->section_options['num'][1], 0, $size); | |
289 | + $lines = array(); | |
290 | + if (in_array(0, $this->section_options['num'][1])) { | |
291 | + $linenum = $this->headlines[0]['linenum']; | |
292 | + $lines = array_merge($lines, array_splice($this->lines, 0, $linenum)); | |
293 | + } | |
294 | + // FutureWork: Do no rely on contentsx's cache as much as possible. | |
295 | + $i = 0; $size = sizeof($this->headlines); | |
296 | + foreach ($this->narrowed_headlines as $narrowed_headline) { | |
297 | + $linenum = $narrowed_headline['linenum']; | |
298 | + for (; $i < $size; $i++ ) { | |
299 | + $current = $i; | |
300 | + if ($linenum != $this->headlines[$current]['linenum']) { | |
301 | + continue; | |
302 | + } | |
303 | + $next = $i + 1; | |
304 | + if ($next < $size) { | |
305 | + $len = $this->headlines[$next]['linenum'] - $linenum; | |
306 | + $lines = array_merge($lines, array_slice($this->lines, $linenum, $len)); | |
307 | + } else { | |
308 | + $lines = array_merge($lines, array_slice($this->lines, $linenum)); | |
309 | + } | |
310 | + break; | |
311 | + } | |
312 | + } | |
313 | + $this->lines = $lines; | |
314 | + } | |
315 | + | |
316 | + function num_filter_lines() | |
317 | + { | |
318 | + if ($this->options['num'][1] === '') { | |
319 | + return; | |
320 | + } | |
321 | + $lines = array(); | |
322 | + foreach ($this->options['num'][1] as $num) { | |
323 | + $lines[] = $this->lines[$num - 1]; | |
324 | + } | |
325 | + $this->lines = $lines; | |
326 | + } | |
327 | + | |
328 | + function filter_lines() | |
329 | + { | |
330 | + if ($this->options['filter'][1] === "") { | |
331 | + return; | |
332 | + } | |
333 | + $lines = array(); | |
334 | + foreach ($this->lines as $line) { | |
335 | + if (ereg($this->options['filter'][1], $line)) { | |
336 | + $lines[] = $line; | |
337 | + } | |
338 | + } | |
339 | + $this->lines = $lines; | |
340 | + } | |
341 | + | |
342 | + function except_lines() | |
343 | + { | |
344 | + if ($this->options['except'][1] === "") { | |
345 | + return; | |
346 | + } | |
347 | + $lines = array(); | |
348 | + foreach ($this->lines as $line) { | |
349 | + if (! ereg($this->options['except'][1], $line)) { | |
350 | + $lines[] = $line; | |
351 | + } | |
352 | + } | |
353 | + $this->lines = $lines; | |
354 | + } | |
355 | + | |
356 | + function init_lines() | |
357 | + { | |
358 | + $this->lines = $this->get_source($this->inclpage); | |
359 | + } | |
360 | + | |
361 | + // static | |
362 | + function get_page_anchor($page) { | |
363 | + // anchor must be '^[A-Za-z][A-Za-z0-9_-]*' | |
364 | + return 'z' . md5($page); | |
365 | + } | |
366 | + | |
367 | + // PukiWiki API Extension | |
368 | + | |
369 | + // convert inline plugins | |
370 | + // PukiWiki API InlineConverter does htmlsc, too. | |
371 | + // refer plugin/make_link.php#make_link | |
372 | + // static | |
373 | + function make_inline($string, $page = '') | |
374 | + { | |
375 | + global $vars; | |
376 | + static $converter; | |
377 | + | |
378 | + if (! isset($converter)) $converter = new InlineConverter(array('plugin')); | |
379 | + | |
380 | + $clone = $converter->get_clone($converter); | |
381 | + return $clone->convert($string, ($page != '') ? $page : $vars['page']); | |
382 | + } | |
383 | + | |
384 | + // refer plugin/aname.inc.php | |
385 | + // static | |
386 | + function get_page_anchorlink($page) { | |
387 | + global $_symbol_anchor; | |
388 | + global $pkwk_dtd; | |
389 | + | |
390 | + $id = $this->get_page_anchor($page); | |
391 | + $id = htmlsc($id); | |
392 | + | |
393 | + // aname allows only fiexed_anchors such as x83dvkd8 | |
394 | + //if (exist_plugin_inline('aname')) { | |
395 | + //$link = do_plugin_inline('aname', "$anchor,super,$_symbol_anchor"); | |
396 | + //} | |
397 | + | |
398 | + if (isset($pkwk_dtd) && $pkwk_dtd < PKWK_DTD_XHTML_1_1) { | |
399 | + $attr_id = ' id="' . $id . '" name="' . $id . '"'; | |
400 | + } else { | |
401 | + $attr_id = ' id="' . $id . '"'; | |
402 | + } | |
403 | + $attr_href = ' href="#' . $id . '"'; | |
404 | + $attr_title = ' title="' . $id . '"'; | |
405 | + $attr_class = ' class="anchor_super"'; | |
406 | + $link = '<a' . $attr_class . $attr_id . $attr_href . $attr_title . '>' . $_symbol_anchor . '</a>'; | |
407 | + return $link; | |
408 | + } | |
409 | + | |
410 | + // static | |
411 | + function get_page_editlink($page) { | |
412 | + $r_page = rawurlencode($page); | |
413 | + $link = '<a class="anchor_super" href="' . get_script_uri() . '?cmd=edit&page=' . $r_page . '">'; | |
414 | + $link .= '<img class="paraedit" src="' . IMAGE_DIR . 'edit.png" alt="Edit" title="Edit" />'; | |
415 | + $link .= '</a>'; | |
416 | + return $link; | |
417 | + } | |
418 | + | |
419 | + function get_source($page) | |
420 | + { | |
421 | + return get_source($page); | |
422 | + } | |
423 | + | |
424 | + function is_page($page) | |
425 | + { | |
426 | + return is_page($page); | |
427 | + } | |
428 | + | |
429 | + function check_readable($page, $flag, $flag2) | |
430 | + { | |
431 | + return check_readable($page, $flag, $flag2); | |
432 | + } | |
428 | 433 | |
429 | 434 | } |
430 | 435 | |
431 | 436 | /////////////////////////////////////// |
432 | 437 | class PluginIncludexOptionParser |
433 | 438 | { |
434 | - var $error = ""; | |
435 | - | |
436 | - function parse_options($args, $options) | |
437 | - { | |
438 | - if (! $this->is_associative_array($args)) { | |
439 | - $args = $this->associative_args($args, $options); | |
440 | - if ($this->error != "") { return; } | |
441 | - } | |
442 | - | |
443 | - foreach ($args as $key => $val) { | |
444 | - if ( !isset($options[$key]) ) { continue; } // for action ($vars) | |
445 | - $type = $options[$key][0]; | |
446 | - | |
447 | - switch ($type) { | |
448 | - case 'bool': | |
449 | - if($val == "" || $val == "on" || $val == "true") { | |
450 | - $options[$key][1] = true; | |
451 | - } elseif ($val == "off" || $val == "false" ) { | |
452 | - $options[$key][1] = false; | |
453 | - } else { | |
454 | - $this->error = htmlspecialchars("$key=$val") . " is invalid. "; | |
455 | - $this->error .= "The option, $key, accepts only a boolean value."; | |
456 | - $this->error .= "#$this->plugin($key) or #$this->plugin($key=on) or #$this->plugin($key=true) for true. "; | |
457 | - $this->error .= "#$this->plugin($key=off) or #$this->plugin($key=false) for false. "; | |
458 | - return; | |
459 | - } | |
460 | - break; | |
461 | - case 'string': | |
462 | - $options[$key][1] = $val; | |
463 | - break; | |
464 | - case 'sanitize': | |
465 | - $options[$key][1] = htmlspecialchars($val); | |
466 | - break; | |
467 | - case 'number': | |
468 | - // Do not parse yet, parse after getting min and max. Here, just format checking | |
469 | - if ($val === '') { | |
470 | - $options[$key][1] = ''; | |
471 | - break; | |
472 | - } | |
473 | - if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
474 | - $val = substr($val, 1, strlen($val) - 2); | |
475 | - } | |
476 | - foreach (explode(",", $val) as $range) { | |
477 | - if (preg_match('/^-?\d+$/', $range)) { | |
478 | - } elseif (preg_match('/^-?\d*\:-?\d*$/', $range)) { | |
479 | - } elseif (preg_match('/^-?\d+\+-?\d+$/', $range)) { | |
480 | - } else { | |
481 | - $this->error = htmlspecialchars("$key=$val") . " is invalid. "; | |
482 | - $this->error .= "The option, " . $key . ", accepts number values such as 1, 1:3, 1+3, 1,2,4. "; | |
483 | - $this->error .= "Specify options as \"$key=1,2,4\" or $key=(1,2,3) when you want to use \",\". "; | |
484 | - $this->error .= "In more details, a style like (1:3,5:7,9:) is also possible. 9: means from 9 to the last. "; | |
485 | - $this->error .= "Furtermore, - means backward. -1:-3 means 1,2,3 from the tail. "; | |
486 | - return; | |
487 | - } | |
488 | - } | |
489 | - $options[$key][1] = $val; | |
490 | - break; | |
491 | - case 'enum': | |
492 | - if($val == "") { | |
493 | - $options[$key][1] = $options[$key][2][0]; | |
494 | - } elseif (in_array($val, $options[$key][2])) { | |
495 | - $options[$key][1] = $val; | |
496 | - } else { | |
497 | - $this->error = htmlspecialchars("$key=$val") . " is invalid. "; | |
498 | - $this->error .= "The option, " . $key . ", accepts values from one of (" . join(",", $options[$key][2]) . "). "; | |
499 | - $this->error .= "By the way, #$this->plugin($key) equals to #$this->plugin($key=" . $options[$key][2][0] . "). "; | |
500 | - return; | |
501 | - } | |
502 | - break; | |
503 | - case 'array': | |
504 | - if ($val == '') { | |
505 | - $options[$key][1] = array(); | |
506 | - break; | |
507 | - } | |
508 | - if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
509 | - $val = substr($val, 1, strlen($val) - 2); | |
510 | - } | |
511 | - $val = explode(',', $val); | |
512 | - //$val = $this->support_paren($val); | |
513 | - $options[$key][1] = $val; | |
514 | - break; | |
515 | - case 'enumarray': | |
516 | - if ($val == '') { | |
517 | - $options[$key][1] = $options[$key][2]; | |
518 | - break; | |
519 | - } | |
520 | - if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
521 | - $val = substr($val, 1, strlen($val) - 2); | |
522 | - } | |
523 | - $val = explode(',', $val); | |
524 | - //$val = $this->support_paren($val); | |
525 | - $options[$key][1] = $val; | |
526 | - foreach ($options[$key][1] as $each) { | |
527 | - if (! in_array($each, $options[$key][2])) { | |
528 | - $this->error = "$key=" . htmlspecialchars(join(",", $options[$key][1])) . " is invalid. "; | |
529 | - $this->error .= "The option, " . $key . ", accepts sets of values from (" . join(",", $options[$key][2]) . "). "; | |
530 | - $this->error .= "By the way, #$this->plugin($key) equals to #$this->plugin($key=(" . join(',',$options[$key][2]) . ")). "; | |
531 | - return; | |
532 | - } | |
533 | - } | |
534 | - break; | |
535 | - default: | |
536 | - } | |
537 | - } | |
538 | - | |
539 | - return $options; | |
540 | - } | |
541 | - | |
542 | - /** | |
543 | - * Handle associative type option arguments as | |
544 | - * ["prefix=Hoge/", "contents=(hoge", "hoge", "hoge)"] => ["prefix"=>"hoge/", "contents"=>"(hoge,hoge,hoge)"] | |
545 | - * This has special supports for parentheses type arguments (number, array, enumarray) | |
546 | - * Check option in along with. | |
547 | - * @access public | |
548 | - * @param Array $args Original option arguments | |
549 | - * @return Array $result Converted associative option arguments | |
550 | - */ | |
551 | - function associative_args($args, $options) | |
552 | - { | |
553 | - $result = array(); | |
554 | - while (($arg = current($args)) !== false) { | |
555 | - list($key, $val) = array_pad(explode("=", $arg, 2), 2, ''); | |
556 | - if (! isset($options[$key])) { | |
557 | - $this->error = 'No such a option, ' . htmlspecialchars($key); | |
558 | - return; | |
559 | - } | |
560 | - // paren support | |
561 | - if ($val[0] === '(' && ($options[$key][0] == 'number' || | |
562 | - $options[$key][0] == 'array' || $options[$key][0] == 'enumarray')) { | |
563 | - while(true) { | |
564 | - if ($val[strlen($val)-1] === ')' && substr_count($val, '(') == substr_count($val, ')')) { | |
565 | - break; | |
566 | - } | |
567 | - $arg = next($args); | |
568 | - if ($arg === false) { | |
569 | - $this->error = "The # of open and close parentheses of one of your arguments did not match. "; | |
570 | - return; | |
571 | - } | |
572 | - $val .= ',' . $arg; | |
573 | - } | |
574 | - } | |
575 | - $result[$key] = $val; | |
576 | - next($args); | |
577 | - } | |
578 | - return $result; | |
579 | - } | |
580 | - | |
581 | - function parse_numoption($optionval, $min, $max) | |
582 | - { | |
583 | - if ($optionval === '') { | |
584 | - return ''; | |
585 | - } | |
586 | - $result = array(); | |
587 | - foreach (explode(",", $optionval) as $range) { | |
588 | - if (preg_match('/^-?\d+$/', $range)) { | |
589 | - $left = $right = $range; | |
590 | - } elseif (preg_match('/^-?\d*\:-?\d*$/', $range)) { | |
591 | - list($left, $right) = explode(":", $range, 2); | |
592 | - if ($left == "" && $right == "") { | |
593 | - $left = $min; | |
594 | - $right = $max; | |
595 | - } elseif($left == "") { | |
596 | - $left = $min; | |
597 | - } elseif ($right == "") { | |
598 | - $right = $max; | |
599 | - } | |
600 | - } elseif (preg_match('/^-?\d+\+-?\d+$/', $range)) { | |
601 | - list($left, $right) = explode("+", $range, 2); | |
602 | - $right += $left; | |
603 | - } | |
604 | - if ($left < 0) { | |
605 | - $left += $max + 1; | |
606 | - } | |
607 | - if ($right < 0) { | |
608 | - $right += $max + 1; | |
609 | - } | |
610 | - $result = array_merge($result, range($left, $right)); | |
611 | - // range allows like range(5, 3) also | |
612 | - } | |
613 | - // filter | |
614 | - foreach (array_keys($result) as $i) { | |
615 | - if ($result[$i] < $min || $result[$i] > $max) { | |
616 | - unset($result[$i]); | |
617 | - } | |
618 | - } | |
619 | - sort($result); | |
620 | - $result = array_unique($result); | |
621 | - | |
622 | - return $result; | |
623 | - } | |
624 | - | |
625 | - function option_debug_print($options) { | |
626 | - foreach ($options as $key => $val) { | |
627 | - $type = $val[0]; | |
628 | - $val = $val[1]; | |
629 | - if(is_array($val)) { | |
630 | - $val=join(',', $val); | |
631 | - } | |
632 | - $body .= "$key=>($type, $val),"; | |
633 | - } | |
634 | - return $body; | |
635 | - } | |
636 | - | |
637 | - // php extension | |
638 | - function is_associative_array($array) | |
639 | - { | |
640 | - if (!is_array($array) || empty($array)) | |
641 | - return false; | |
642 | - $keys = array_keys($array); | |
643 | - return array_keys($keys) !== $keys; | |
644 | - // or | |
645 | - //return is_array($array) && !is_numeric(implode(array_keys($array))); | |
646 | - } | |
439 | + var $error = ""; | |
440 | + | |
441 | + function parse_options($args, $options) | |
442 | + { | |
443 | + if (! $this->is_associative_array($args)) { | |
444 | + $args = $this->associative_args($args, $options); | |
445 | + if ($this->error != "") { return; } | |
446 | + } | |
447 | + | |
448 | + foreach ($args as $key => $val) { | |
449 | + if ( !isset($options[$key]) ) { continue; } // for action ($vars) | |
450 | + $type = $options[$key][0]; | |
451 | + | |
452 | + switch ($type) { | |
453 | + case 'bool': | |
454 | + if($val == "" || $val == "on" || $val == "true") { | |
455 | + $options[$key][1] = true; | |
456 | + } elseif ($val == "off" || $val == "false" ) { | |
457 | + $options[$key][1] = false; | |
458 | + } else { | |
459 | + $this->error = htmlsc("$key=$val") . " is invalid. "; | |
460 | + $this->error .= "The option, $key, accepts only a boolean value."; | |
461 | + $this->error .= "#$this->plugin($key) or #$this->plugin($key=on) or #$this->plugin($key=true) for true. "; | |
462 | + $this->error .= "#$this->plugin($key=off) or #$this->plugin($key=false) for false. "; | |
463 | + return; | |
464 | + } | |
465 | + break; | |
466 | + case 'string': | |
467 | + $options[$key][1] = $val; | |
468 | + break; | |
469 | + case 'sanitize': | |
470 | + $options[$key][1] = htmlsc($val); | |
471 | + break; | |
472 | + case 'number': | |
473 | + // Do not parse yet, parse after getting min and max. Here, just format checking | |
474 | + if ($val === '') { | |
475 | + $options[$key][1] = ''; | |
476 | + break; | |
477 | + } | |
478 | + if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
479 | + $val = substr($val, 1, strlen($val) - 2); | |
480 | + } | |
481 | + foreach (explode(",", $val) as $range) { | |
482 | + if (preg_match('/^-?\d+$/', $range)) { | |
483 | + } elseif (preg_match('/^-?\d*\:-?\d*$/', $range)) { | |
484 | + } elseif (preg_match('/^-?\d+\+-?\d+$/', $range)) { | |
485 | + } else { | |
486 | + $this->error = htmlsc("$key=$val") . " is invalid. "; | |
487 | + $this->error .= "The option, " . $key . ", accepts number values such as 1, 1:3, 1+3, 1,2,4. "; | |
488 | + $this->error .= "Specify options as \"$key=1,2,4\" or $key=(1,2,3) when you want to use \",\". "; | |
489 | + $this->error .= "In more details, a style like (1:3,5:7,9:) is also possible. 9: means from 9 to the last. "; | |
490 | + $this->error .= "Furtermore, - means backward. -1:-3 means 1,2,3 from the tail. "; | |
491 | + return; | |
492 | + } | |
493 | + } | |
494 | + $options[$key][1] = $val; | |
495 | + break; | |
496 | + case 'enum': | |
497 | + if($val == "") { | |
498 | + $options[$key][1] = $options[$key][2][0]; | |
499 | + } elseif (in_array($val, $options[$key][2])) { | |
500 | + $options[$key][1] = $val; | |
501 | + } else { | |
502 | + $this->error = htmlsc("$key=$val") . " is invalid. "; | |
503 | + $this->error .= "The option, " . $key . ", accepts values from one of (" . join(",", $options[$key][2]) . "). "; | |
504 | + $this->error .= "By the way, #$this->plugin($key) equals to #$this->plugin($key=" . $options[$key][2][0] . "). "; | |
505 | + return; | |
506 | + } | |
507 | + break; | |
508 | + case 'array': | |
509 | + if ($val == '') { | |
510 | + $options[$key][1] = array(); | |
511 | + break; | |
512 | + } | |
513 | + if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
514 | + $val = substr($val, 1, strlen($val) - 2); | |
515 | + } | |
516 | + $val = explode(',', $val); | |
517 | + //$val = $this->support_paren($val); | |
518 | + $options[$key][1] = $val; | |
519 | + break; | |
520 | + case 'enumarray': | |
521 | + if ($val == '') { | |
522 | + $options[$key][1] = $options[$key][2]; | |
523 | + break; | |
524 | + } | |
525 | + if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
526 | + $val = substr($val, 1, strlen($val) - 2); | |
527 | + } | |
528 | + $val = explode(',', $val); | |
529 | + //$val = $this->support_paren($val); | |
530 | + $options[$key][1] = $val; | |
531 | + foreach ($options[$key][1] as $each) { | |
532 | + if (! in_array($each, $options[$key][2])) { | |
533 | + $this->error = "$key=" . htmlsc(join(",", $options[$key][1])) . " is invalid. "; | |
534 | + $this->error .= "The option, " . $key . ", accepts sets of values from (" . join(",", $options[$key][2]) . "). "; | |
535 | + $this->error .= "By the way, #$this->plugin($key) equals to #$this->plugin($key=(" . join(',',$options[$key][2]) . ")). "; | |
536 | + return; | |
537 | + } | |
538 | + } | |
539 | + break; | |
540 | + default: | |
541 | + } | |
542 | + } | |
543 | + | |
544 | + return $options; | |
545 | + } | |
546 | + | |
547 | + /** | |
548 | + * Handle associative type option arguments as | |
549 | + * ["prefix=Hoge/", "contents=(hoge", "hoge", "hoge)"] => ["prefix"=>"hoge/", "contents"=>"(hoge,hoge,hoge)"] | |
550 | + * This has special supports for parentheses type arguments (number, array, enumarray) | |
551 | + * Check option in along with. | |
552 | + * @access public | |
553 | + * @param Array $args Original option arguments | |
554 | + * @return Array $result Converted associative option arguments | |
555 | + */ | |
556 | + function associative_args($args, $options) | |
557 | + { | |
558 | + $result = array(); | |
559 | + while (($arg = current($args)) !== false) { | |
560 | + list($key, $val) = array_pad(explode("=", $arg, 2), 2, ''); | |
561 | + if (! isset($options[$key])) { | |
562 | + $this->error = 'No such a option, ' . htmlsc($key); | |
563 | + return; | |
564 | + } | |
565 | + // paren support | |
566 | + if ($val[0] === '(' && ($options[$key][0] == 'number' || | |
567 | + $options[$key][0] == 'array' || $options[$key][0] == 'enumarray')) { | |
568 | + while(true) { | |
569 | + if ($val[strlen($val)-1] === ')' && substr_count($val, '(') == substr_count($val, ')')) { | |
570 | + break; | |
571 | + } | |
572 | + $arg = next($args); | |
573 | + if ($arg === false) { | |
574 | + $this->error = "The # of open and close parentheses of one of your arguments did not match. "; | |
575 | + return; | |
576 | + } | |
577 | + $val .= ',' . $arg; | |
578 | + } | |
579 | + } | |
580 | + $result[$key] = $val; | |
581 | + next($args); | |
582 | + } | |
583 | + return $result; | |
584 | + } | |
585 | + | |
586 | + function parse_numoption($optionval, $min, $max) | |
587 | + { | |
588 | + if ($optionval === '') { | |
589 | + return ''; | |
590 | + } | |
591 | + $result = array(); | |
592 | + foreach (explode(",", $optionval) as $range) { | |
593 | + if (preg_match('/^-?\d+$/', $range)) { | |
594 | + $left = $right = $range; | |
595 | + } elseif (preg_match('/^-?\d*\:-?\d*$/', $range)) { | |
596 | + list($left, $right) = explode(":", $range, 2); | |
597 | + if ($left == "" && $right == "") { | |
598 | + $left = $min; | |
599 | + $right = $max; | |
600 | + } elseif($left == "") { | |
601 | + $left = $min; | |
602 | + } elseif ($right == "") { | |
603 | + $right = $max; | |
604 | + } | |
605 | + } elseif (preg_match('/^-?\d+\+-?\d+$/', $range)) { | |
606 | + list($left, $right) = explode("+", $range, 2); | |
607 | + $right += $left; | |
608 | + } | |
609 | + if ($left < 0) { | |
610 | + $left += $max + 1; | |
611 | + } | |
612 | + if ($right < 0) { | |
613 | + $right += $max + 1; | |
614 | + } | |
615 | + $result = array_merge($result, range($left, $right)); | |
616 | + // range allows like range(5, 3) also | |
617 | + } | |
618 | + // filter | |
619 | + foreach (array_keys($result) as $i) { | |
620 | + if ($result[$i] < $min || $result[$i] > $max) { | |
621 | + unset($result[$i]); | |
622 | + } | |
623 | + } | |
624 | + sort($result); | |
625 | + $result = array_unique($result); | |
626 | + | |
627 | + return $result; | |
628 | + } | |
629 | + | |
630 | + function option_debug_print($options) { | |
631 | + foreach ($options as $key => $val) { | |
632 | + $type = $val[0]; | |
633 | + $val = $val[1]; | |
634 | + if(is_array($val)) { | |
635 | + $val=join(',', $val); | |
636 | + } | |
637 | + $body .= "$key=>($type, $val),"; | |
638 | + } | |
639 | + return $body; | |
640 | + } | |
641 | + | |
642 | + // php extension | |
643 | + function is_associative_array($array) | |
644 | + { | |
645 | + if (!is_array($array) || empty($array)) | |
646 | + return false; | |
647 | + $keys = array_keys($array); | |
648 | + return array_keys($keys) !== $keys; | |
649 | + // or | |
650 | + //return is_array($array) && !is_numeric(implode(array_keys($array))); | |
651 | + } | |
647 | 652 | } |
648 | 653 | |
649 | 654 | // php extension |
650 | 655 | if (! function_exists('_')) { |
651 | - function &_($str) | |
652 | - { | |
653 | - return $str; | |
654 | - } | |
656 | + function &_($str) | |
657 | + { | |
658 | + return $str; | |
659 | + } | |
655 | 660 | } |
656 | 661 | |
657 | 662 | //////////////////////////////////////////// |
658 | 663 | function plugin_includex_common_init() |
659 | 664 | { |
660 | - global $plugin_includex; | |
661 | - if (class_exists('PluginIncludexUnitTest')) { | |
662 | - $plugin_includex = new PluginIncludexUnitTest(); | |
663 | - } elseif (class_exists('PluginIncludexUser')) { | |
664 | - $plugin_includex = new PluginIncludexUser(); | |
665 | - } else { | |
666 | - $plugin_includex = new PluginIncludex(); | |
667 | - } | |
665 | + global $plugin_includex; | |
666 | + if (class_exists('PluginIncludexUnitTest')) { | |
667 | + $plugin_includex = new PluginIncludexUnitTest(); | |
668 | + } elseif (class_exists('PluginIncludexUser')) { | |
669 | + $plugin_includex = new PluginIncludexUser(); | |
670 | + } else { | |
671 | + $plugin_includex = new PluginIncludex(); | |
672 | + } | |
668 | 673 | } |
669 | 674 | |
670 | 675 | function plugin_includex_convert() |
671 | 676 | { |
672 | - global $plugin_includex; plugin_includex_common_init(); | |
673 | - $args = func_get_args(); | |
674 | - return call_user_func_array(array(&$plugin_includex, 'convert'), $args); | |
677 | + global $plugin_includex; | |
678 | + plugin_includex_common_init(); | |
679 | + $args = func_get_args(); | |
680 | + return call_user_func_array(array(&$plugin_includex, 'convert'), $args); | |
675 | 681 | } |
676 | 682 | |
677 | 683 | if (! defined('INIT_DIR')) // if not Plus! |
678 | - if (file_exists(DATA_HOME . 'init/includex.ini.php')) | |
679 | - include_once(DATA_HOME . 'init/includex.ini.php'); | |
684 | + if (file_exists(DATA_HOME . 'init/includex.ini.php')) | |
685 | + include_once(DATA_HOME . 'init/includex.ini.php'); | |
680 | 686 | |
681 | 687 | ?> |
@@ -8,1272 +8,1278 @@ | ||
8 | 8 | * @version $Id: lsx.inc.php,v 1.17 2007-06-16 11:14:46 sonots $ |
9 | 9 | * @package plugin |
10 | 10 | */ |
11 | + // v1.18 PHP8.0対応 2021-12-15 byはいふん | |
11 | 12 | |
12 | 13 | class PluginLsx |
13 | 14 | { |
14 | - function PluginLsx() | |
15 | - { | |
16 | - // Configure external plugins | |
17 | - static $conf = array( | |
18 | - 'plugin_contents' => 'contentsx', | |
19 | - 'plugin_include' => 'includex', | |
20 | - 'plugin_new' => 'new', | |
21 | - 'plugin_tag' => 'tag', | |
22 | - ); | |
23 | - // Modify here for default option values | |
24 | - static $default_options = array( | |
25 | - 'hierarchy' => array('bool', true), | |
26 | - 'non_list' => array('bool', true), | |
27 | - 'reverse' => array('bool', false), | |
28 | - 'basename' => array('bool', false), // obsolete | |
29 | - 'sort' => array('enum', 'name', array('name', 'reading', 'date')), | |
30 | - 'tree' => array('enum', false, array(false, 'leaf', 'dir')), | |
31 | - 'depth' => array('number', ''), | |
32 | - 'num' => array('number', ''), | |
33 | - 'next' => array('bool', false), | |
34 | - 'except' => array('string', ''), | |
35 | - 'filter' => array('string', ''), | |
36 | - 'prefix' => array('string', ''), | |
37 | - 'contents' => array('array', ''), | |
38 | - 'include' => array('array', ''), | |
39 | - 'info' => array('enumarray', array(), array('date', 'new')), | |
40 | - 'date' => array('bool', false), // will be obsolete | |
41 | - 'new' => array('bool', false), | |
42 | - 'tag' => array('string', ''), | |
43 | - 'linkstr' => array('enum', 'relative', array('relative', 'absolute', 'basename', 'title', 'headline')), | |
44 | - 'link' => array('enum', 'page', array('page', 'anchor', 'off')), | |
45 | - 'newpage' => array('enum', false, array('on', 'except')), | |
46 | - 'popular' => array('enum', false, array('total', 'today', 'yesterday', 'recent')), // alpha | |
47 | - ); | |
48 | - $this->conf = &$conf; | |
49 | - $this->default_options = &$default_options; | |
50 | - | |
51 | - // init | |
52 | - $this->options = $this->default_options; | |
53 | - if (function_exists('mb_ereg')) { // extension_loaded('mbstring') | |
54 | - mb_regex_encoding(SOURCE_ENCODING); | |
55 | - $this->ereg = 'mb_ereg'; | |
56 | - } else { | |
57 | - $this->ereg = 'ereg'; | |
58 | - } | |
59 | - } | |
60 | - | |
61 | - // static | |
62 | - var $conf; | |
63 | - var $default_options; | |
64 | - // var | |
65 | - var $options; | |
66 | - var $error = ""; | |
67 | - var $plugin = "lsx"; | |
68 | - var $metapages; | |
69 | - | |
70 | - function convert() | |
71 | - { | |
72 | - $args = func_get_args(); | |
73 | - $body = $this->body($args); | |
74 | - if ($this->error != "") { | |
75 | - $body = "<p>$this->plugin(): $this->error</p>"; | |
76 | - } | |
77 | - return $body; | |
78 | - } | |
79 | - | |
80 | - function action() | |
81 | - { | |
82 | - global $vars; | |
83 | - | |
84 | - $args = $vars; | |
85 | - $body = $this->body($args); | |
86 | - if ($this->error != "") { | |
87 | - $body = "<p>$this->plugin(): $this->error</p>"; | |
88 | - } | |
89 | - if (! isset($body)) $body = '<p>no result.</p>'; | |
90 | - | |
91 | - if ($this->options['tag'][1] != '') { | |
92 | - $msg = htmlspecialchars($this->options['tag'][1]); | |
93 | - } elseif ($this->options['prefix'][1] != '') { | |
94 | - $msg = htmlspecialchars($this->options['prefix'][1]); | |
95 | - } else { | |
96 | - $msg = $this->plugin; | |
97 | - } | |
98 | - return array('msg'=>$msg, 'body'=>$body); | |
99 | - } | |
100 | - | |
101 | - function body($args) | |
102 | - { | |
103 | - $parser = new PluginLsxOptionParser(); | |
104 | - $this->options = $parser->parse_options($args, $this->options); | |
105 | - if ($parser->error != "") { $this->error = $parser->error; return; } | |
106 | - | |
107 | - $this->validate_options(); | |
108 | - if ($this->error !== "") { return $this->error; } | |
109 | - | |
110 | - $this->init_metapages(); | |
111 | - if ($this->error !== "") { return $this->error; } | |
112 | - $this->prefix_filter_metapages(); | |
113 | - if ($this->error !== "") { return $this->error; } | |
114 | - $this->nonlist_filter_metapages(); | |
115 | - if ($this->error !== "") { return $this->error; } | |
116 | - $this->relative_metapages(); // before filter, except | |
117 | - if ($this->error !== "") { return $this->error; } | |
118 | - $this->filter_filter_metapages(); | |
119 | - if ($this->error !== "") { return $this->error; } | |
120 | - $this->except_filter_metapages(); | |
121 | - if ($this->error !== "") { return $this->error; } | |
122 | - | |
123 | - $this->newpage_filter_metapages(); | |
124 | - if ($this->error !== "") { return $this->error; } | |
125 | - | |
126 | - $parser = new PluginLsxOptionParser(); | |
127 | - $this->maxdepth = $this->depth_metapages(); | |
128 | - $this->options['depth'][1] = $parser->parse_numoption($this->options['depth'][1], 1, $this->maxdepth); | |
129 | - if ($parser->error != "") { $this->error = $parser->error; return; } | |
130 | - $this->depth_filter_metapages(); | |
131 | - if ($this->error !== "") { return $this->error; } | |
132 | - | |
133 | - $this->tree_filter_metapages(); | |
134 | - if ($this->error !== "") { return $this->error; } | |
135 | - $this->popular_metapages(); // before sort | |
136 | - if ($this->error !== "") { return $this->error; } | |
137 | - $this->timestamp_metapages(); // before sort | |
138 | - if ($this->error !== "") { return $this->error; } | |
139 | - $this->sort_metapages(); // before num_filter | |
140 | - if ($this->error !== "") { return $this->error; } | |
141 | - | |
142 | - $this->maxnum = sizeof($this->metapages); // after all filters | |
143 | - $this->options['num'][1] = $parser->parse_numoption($this->options['num'][1], 1, $this->maxnum); | |
144 | - if ($parser->error != "") { $this->error = $parser->error; return; } | |
145 | - $this->num_filter_metapages(); | |
146 | - if ($this->error !== "") { return $this->error; } | |
147 | - | |
148 | - $this->hierarchy_metapages(); | |
149 | - if ($this->error !== "") { return $this->error; } | |
150 | - | |
151 | - $this->info_metapages(); | |
152 | - if ($this->error !== "") { return $this->error; } | |
153 | - $this->linkstr_metapages(); | |
154 | - if ($this->error !== "") { return $this->error; } | |
155 | - $this->link_metapages(); | |
156 | - if ($this->error !== "") { return $this->error; } | |
157 | - | |
158 | - $body = $this->list_pages(); | |
159 | - $body .= $this->next_pages(); | |
160 | - | |
161 | - return $body; | |
162 | - } | |
163 | - | |
164 | - function validate_options() | |
165 | - { | |
166 | - global $vars; | |
167 | - if ($this->options['tag'][1] != '') { | |
168 | - if(! exist_plugin($this->conf['plugin_tag'])) { | |
169 | - $this->error .= "The option, tag, requires #{$this->conf['plugin_tag']} plugin, but it does not exist. "; | |
170 | - return; | |
171 | - } | |
172 | - $this->options['hierarchy'][1] = false; | |
173 | - // best is to turn off the default only so that 'hierarchy' can be configured by option. | |
174 | - } else { | |
175 | - if ($this->options['prefix'][1] == '') { | |
176 | - $this->options['prefix'][1] = $vars['page'] != '' ? $vars['page'] . '/' : ''; | |
177 | - } | |
178 | - } | |
179 | - if ($this->options['prefix'][1] == '/') { | |
180 | - $this->options['prefix'][1] = ''; | |
181 | - } elseif ($this->options['prefix'][1] != '') { | |
182 | - $this->options['prefix'][1] = $this->get_fullname($this->options['prefix'][1], $vars['page']); | |
183 | - } | |
184 | - $this->options['prefix'][4] = $this->options['prefix'][1]; | |
185 | - | |
186 | - if ($this->options['sort'][1] == 'date') { | |
187 | - $this->options['hierarchy'][1] = false; | |
188 | - } | |
189 | - | |
190 | - // alpha func | |
191 | - if ($this->options['popular'][1] != false) { | |
192 | - $this->options['sort'][1] = 'popular'; | |
193 | - $this->options['hierarchy'][1] = false; | |
194 | - // Future Work: info_popular. hmmm | |
195 | - } | |
196 | - // Another Idea | |
197 | - // sort=popular>today,popular>total,popular>yesterday,popular>recent | |
198 | - // if (strpos($this->options['sort'][1], 'popular>') !== false) { | |
199 | - // list($this->optiions['sort'][1], $this->options['popular'][1]) = explode('>', $this->options['sort'][1]); | |
200 | - // $this->options['hierarchy'][1] = false; | |
201 | - // } | |
202 | - | |
203 | - if ($this->options['contents'][1] != '') { | |
204 | - if(! exist_plugin_convert($this->conf['plugin_contents'])) { | |
205 | - $this->error .= "The option, contents, requires {$this->conf['plugin_contents']} plugin, but it does not exist. "; | |
206 | - return; | |
207 | - } | |
208 | - } | |
209 | - | |
210 | - if ($this->options['include'][1] != '') { | |
211 | - if(! exist_plugin_convert($this->conf['plugin_include'])) { | |
212 | - $this->error .= "The option, include, requires {$this->conf['plugin_include']} plugin, but it does not exist. "; | |
213 | - return; | |
214 | - } | |
215 | - $this->options['hierarchy'][1] = false; // hierarchy + include => XHTML invalid | |
216 | - $this->options['date'][1] = false; // include does not use definitely | |
217 | - $this->options['new'][1] = false; // include does not use definitely | |
218 | - $this->options['contents'][1] = ''; // include does not use definitely | |
219 | - } | |
220 | - | |
221 | - if ($this->options['linkstr'][1] === 'title' || $this->options['linkstr'][1] === 'headline') { | |
222 | - if(! exist_plugin_convert($this->conf['plugin_contents'])) { | |
223 | - $this->error .= "The option, linkstr, requires {$this->conf['plugin_contents']} plugin, but it does not exist. "; | |
224 | - return; | |
225 | - } | |
226 | - } | |
227 | - | |
228 | - // to support lower versions | |
229 | - // basename -> linkstr | |
230 | - if ($this->options['basename'][1] === true) { | |
231 | - $this->options['linkstr'][1] = 'basename'; | |
232 | - } | |
233 | - | |
234 | - // new,date -> info | |
235 | - foreach ($this->options['info'][2] as $key) { | |
236 | - if ($this->options[$key][1]) { | |
237 | - array_push($this->options['info'][1], $key); | |
238 | - } | |
239 | - } | |
240 | - $this->options['info'][1] = array_unique($this->options['info'][1]); | |
241 | - // to save time (to avoid in_array everytime) | |
242 | - foreach ($this->options['info'][1] as $key) { | |
243 | - $this->options[$key][1] = true; | |
244 | - } | |
245 | - if ($this->options['new'][1] && ! exist_plugin_inline($this->conf['plugin_new'])) { | |
246 | - $this->error .= "The option, new, requires {$this->conf['plugin_new']} plugin, but it does not exist. "; | |
247 | - return; | |
248 | - } | |
249 | - } | |
250 | - | |
251 | - function next_pages() | |
252 | - { | |
253 | - if (! $this->options['next'][1] || $this->options['num'][1] == '') return; | |
254 | - | |
255 | - $options = $this->options; | |
256 | - unset($options['num']); | |
257 | - $href = get_script_uri() . '?' . 'cmd=lsx'; | |
258 | - foreach ($options as $key => $val) { | |
259 | - if (isset($val[4])) { | |
260 | - $href .= '&' . htmlspecialchars($key) . '=' . htmlspecialchars(rawurlencode($val[4])); | |
261 | - } | |
262 | - } | |
263 | - $count = count($this->options['num'][1]); | |
264 | - $min = reset($this->options['num'][1]); | |
265 | - $max = end($this->options['num'][1]); | |
266 | - $maxnum = $this->maxnum; | |
267 | - $prevmin = max($min - $count, 0); | |
268 | - $prevmax = min($min - 1, $maxnum); | |
269 | - $prevlink = ''; | |
270 | - if ($prevmax > 0) { | |
271 | - $prevhref = $href . '&num=' . $prevmin . ':' . $prevmax; | |
272 | - $prevlink = '<span class="prev" style="float:left;"><a href="' . $prevhref . '">' . _('Prev ') . $count . '</a></span>'; | |
273 | - } | |
274 | - $nextmin = max($max + 1, 0); | |
275 | - $nextmax = min($max + $count, $maxnum); | |
276 | - $nextlink = ''; | |
277 | - if ($nextmin < $maxnum) { | |
278 | - $nexthref = $href . '&num=' . $nextmin . ':' . $nextmax; | |
279 | - $nextlink = '<span class="next" style="float:right;"><a href="' . $nexthref . '">' . _('Next ') . $count . '</a></span>'; | |
280 | - } | |
281 | - $ret = ''; | |
282 | - $ret .= '<div class="lsx">' . $prevlink . $nextlink . '</div><div style="clear:both;"></div>'; | |
283 | - return $ret; | |
284 | - } | |
285 | - | |
286 | - function list_pages() | |
287 | - { | |
288 | - global $script; | |
289 | - | |
290 | - if (sizeof($this->metapages) == 0) { | |
291 | - return; | |
292 | - } | |
293 | - | |
294 | - /* HTML validate (without <ul><li style="list-type:none"><ul><li>, we have to do as | |
295 | - <ul><li style="padding-left:16*2px;margin-left:16*2px"> as pukiwiki standard. I did not like it) | |
296 | - | |
297 | - <ul> <ul><li>1 | |
298 | - <li>1</li> </li><li>1 | |
299 | - <li>1 <ul><li>2 | |
300 | - <ul> </li></ul></li><li>1 | |
301 | - <li>2</li> </li><li>1 | |
302 | - </ul> => <ul><li style="list-type:none"><ul><li>3 | |
303 | - </li> </li></ul></li></ul></li></ul> | |
304 | - <li>1</li> | |
305 | - <li>1</li> | |
306 | - <ul><li style="list-type:none"><ul> | |
307 | - <li>3</li> | |
308 | - </ul></li></ul> | |
309 | - </li> | |
310 | - </ul> | |
311 | - */ | |
312 | - $ul = $pdepth = 0; | |
313 | - foreach ($this->metapages as $i => $metapage) { | |
314 | - $page = $metapage['page']; | |
315 | - $exist = $metapage['exist']; | |
316 | - $depth = $metapage['listdepth']; | |
317 | - $info = $metapage['info']; | |
318 | - $link = $metapage['link']; | |
319 | - if ($exist && $this->options['include'][1] != '') { | |
320 | - $option = '"' . $page . '"'; | |
321 | - if (! empty($this->options['include'][1])) { | |
322 | - $option .= ',' . csv_implode(',', $this->options['include'][1]); | |
323 | - } | |
324 | - $html .= do_plugin_convert($this->conf['plugin_include'], $option); | |
325 | - continue; | |
326 | - } | |
327 | - if ($depth > $pdepth) { | |
328 | - $diff = $depth - $pdepth; | |
329 | - $html .= str_repeat('<ul><li style="list-style:none">', $diff - 1); | |
330 | - if ($depth == 1) { // or $first flag | |
331 | - $html .= '<ul class="' . $this->plugin . '"><li>'; | |
332 | - } else { | |
333 | - $html .= '<ul><li>'; | |
334 | - } | |
335 | - $ul += $diff; | |
336 | - } elseif ($depth == $pdepth) { | |
337 | - $html .= '</li><li>'; | |
338 | - } elseif ($depth < $pdepth) { | |
339 | - $diff = $pdepth - $depth; | |
340 | - $html .= str_repeat('</li></ul>', $diff); | |
341 | - $html .= '</li><li>'; | |
342 | - $ul -= $diff; | |
343 | - } | |
344 | - $pdepth = $depth; | |
345 | - | |
346 | - $html .= $link; | |
347 | - if (isset($info) && $info != '') { | |
348 | - $html .= '<span class="lsx_info">' . $info . '</span>' . "\n"; | |
349 | - } | |
350 | - | |
351 | - if ($exist && $this->options['contents'][1] != '') { | |
352 | - $args = $this->options['contents'][1]; | |
353 | - $pagearg = 'page=' . $page ; | |
354 | - array_unshift($args, $pagearg); | |
355 | - $contentsx = new PluginContentsx(); | |
356 | - $html .= call_user_func(array($contentsx, 'body'), $args); | |
357 | - } | |
358 | - } | |
359 | - $html .= str_repeat('</li></ul>', $ul); | |
360 | - return $html; | |
361 | - } | |
362 | - | |
363 | - function link_metapages() | |
364 | - { | |
365 | - switch ($this->options['link'][1]) { | |
366 | - case 'page': | |
367 | - foreach ($this->metapages as $i => $metapage) { | |
368 | - if ($metapage['exist']) { | |
369 | - $this->metapages[$i]['link'] = | |
370 | - $this->make_pagelink($metapage['page'], $metapage['linkstr']); | |
371 | - } else { | |
372 | - $this->metapages[$i]['link'] = $metapage['linkstr']; | |
373 | - } | |
374 | - } | |
375 | - break; | |
376 | - case 'anchor': | |
377 | - foreach ($this->metapages as $i => $metapage) { | |
378 | - // PluginIncludex::get_page_anchor($metapage['page']) | |
379 | - $anchor = 'z' . md5($metapage['page']); | |
380 | - $anchor = '#' . htmlspecialchars($anchor); | |
381 | - if ($metapage['exist']) { | |
382 | - $this->metapages[$i]['link'] = | |
383 | - $this->make_pagelink('', $metapage['linkstr'], $anchor); | |
384 | - } else { | |
385 | - $this->metapages[$i]['link'] = $metapage['linkstr']; | |
386 | - } | |
387 | - } | |
388 | - break; | |
389 | - case 'off': | |
390 | - foreach ($this->metapages as $i => $metapage) { | |
391 | - $this->metapages[$i]['link'] = $metapage['linkstr']; | |
392 | - } | |
393 | - break; | |
394 | - } | |
395 | - } | |
396 | - | |
397 | - function linkstr_metapages() | |
398 | - { | |
399 | - switch ($this->options['linkstr'][1]) { | |
400 | - case 'absolute': | |
401 | - foreach ($this->metapages as $i => $metapage) { | |
402 | - $this->metapages[$i]['linkstr'] = | |
403 | - htmlspecialchars($metapage['page']); | |
404 | - } | |
405 | - break; | |
406 | - case 'basename': | |
407 | - foreach ($this->metapages as $i => $metapage) { | |
408 | - $this->metapages[$i]['linkstr'] = | |
409 | - htmlspecialchars($this->my_basename($metapage['page'])); | |
410 | - } | |
411 | - break; | |
412 | - case 'title': | |
413 | - $contentsx = new PluginContentsx(); | |
414 | - foreach ($this->metapages as $i => $metapage) { | |
415 | - $title = $contentsx->get_title($metapage['page']); | |
416 | - $title = strip_htmltag(make_link($title)); | |
417 | - $this->metapages[$i]['linkstr'] = $title; | |
418 | - } | |
419 | - break; | |
420 | - case 'headline': | |
421 | - $contentsx = new PluginContentsx(); | |
422 | - foreach ($this->metapages as $i => $metapage) { | |
423 | - $metalines = $contentsx->get_metalines($metapage['page']); | |
424 | - $title = $metalines[0]['headline']; | |
425 | - $title = strip_htmltag(make_link($title)); | |
426 | - $this->metapages[$i]['linkstr'] = $title; | |
427 | - } | |
428 | - break; | |
429 | - } | |
430 | - // default: relative | |
431 | - if ($this->options['hierarchy'][1] === true) { | |
432 | - foreach ($this->metapages as $i => $metapage) { | |
433 | - if (! isset($metapage['linkstr']) || $metapage['linkstr'] === '') { | |
434 | - $this->metapages[$i]['linkstr'] = | |
435 | - htmlspecialchars($this->my_basename($metapage['page'])); | |
436 | - } | |
437 | - } | |
438 | - } else { | |
439 | - foreach ($this->metapages as $i => $metapage) { | |
440 | - if (! isset($metapage['linkstr']) || $metapage['linkstr'] === '') { | |
441 | - $this->metapages[$i]['linkstr'] = | |
442 | - htmlspecialchars($metapage['relative']); | |
443 | - } | |
444 | - } | |
445 | - } | |
446 | - } | |
447 | - | |
448 | - function popular_metapages() | |
449 | - { | |
450 | - if ($this->options['popular'][1] === false) { | |
451 | - return; | |
452 | - } | |
453 | - | |
454 | - if (function_exists('set_timezone')) { // plus | |
455 | - list($zone, $zonetime) = set_timezone(DEFAULT_LANG); | |
456 | - $localtime = UTIME + $zonetime; | |
457 | - $today = gmdate('Y/m/d', $localtime); | |
458 | - $yesterday = gmdate('Y/m/d',gmmktime(0,0,0, gmdate('m',$localtime), gmdate('d',$localtime)-1, gmdate('Y',$localtime))); | |
459 | - } else { | |
460 | - $localtime = ZONETIME + UTIME; | |
461 | - $today = get_date('Y/m/d'); // == get_date('Y/m/d', UTIME) == date('Y/m/d, ZONETIME + UTIME); | |
462 | - $yesterday = get_date('Y/m/d', mktime(0,0,0, date('m',$localtime), date('d',$localtime)-1, date('Y',$localtime))); | |
463 | - } | |
464 | - | |
465 | - foreach ($this->metapages as $i => $metapage) { | |
466 | - $page = $metapage['page']; | |
467 | - $lines = file(COUNTER_DIR . encode($page) . '.count'); | |
468 | - $lines = array_map('rtrim', $lines); | |
469 | - list($total_count, $date, $today_count, $yesterday_count, $ip) = $lines; | |
470 | - | |
471 | - $popular = 0; | |
472 | - switch ($this->options['popular'][1]) { | |
473 | - case 'total': | |
474 | - $popular = $total_count; | |
475 | - break; | |
476 | - case 'today': | |
477 | - if ($date == $today) { | |
478 | - $popular = $today_count; | |
479 | - } | |
480 | - break; | |
481 | - case 'yesterday': | |
482 | - if ($date == $today) { | |
483 | - $popular = $yesterday_count; | |
484 | - } elseif ($date == $yesterday) { | |
485 | - $popular = $today_count; | |
486 | - } | |
487 | - break; | |
488 | - case 'recent': | |
489 | - if ($date == $today) { | |
490 | - $popular = $today_count + $yesterday_count; | |
491 | - } elseif ($date == $yesterday) { | |
492 | - $popular = $today_count; | |
493 | - } | |
494 | - break; | |
495 | - } | |
496 | - if ($popular > 0) { | |
497 | - $this->metapages[$i]['popular'] = $popular; | |
498 | - } else { | |
499 | - unset($this->metapages[$i]); // like popular plugin | |
500 | - } | |
501 | - } | |
502 | - } | |
503 | - | |
504 | - function timestamp_metapages() | |
505 | - { | |
506 | - if (! $this->options['date'][1] && ! $this->options['new'][1] && | |
507 | - $this->options['sort'][1] !== 'date') { | |
508 | - return; | |
509 | - } | |
510 | - foreach ($this->metapages as $i => $metapage) { | |
511 | - $page = $metapage['page']; | |
512 | - $timestamp = $this->get_filetime($page); | |
513 | - $this->metapages[$i]['timestamp'] = $timestamp; | |
514 | - } | |
515 | - } | |
516 | - | |
517 | - function date_metapages() | |
518 | - { | |
519 | - if (! $this->options['date'][1] && ! $this->options['new'][1]) { | |
520 | - return; | |
521 | - } | |
522 | - foreach ($this->metapages as $i => $metapage) { | |
523 | - $timestamp = $metapage['timestamp']; | |
524 | - $date = format_date($timestamp); | |
525 | - $this->metapages[$i]['date'] = $date; | |
526 | - } | |
527 | - } | |
528 | - | |
529 | - function info_date_metapages() | |
530 | - { | |
531 | - if (! $this->options['date'][1]) { | |
532 | - return; | |
533 | - } | |
534 | - foreach ($this->metapages as $i => $metapage) { | |
535 | - $this->metapages[$i]['info_date'] = | |
536 | - '<span class="comment_date">' . $metapage['date'] . '</span>'; | |
537 | - } | |
538 | - } | |
539 | - | |
540 | - function info_new_metapages() | |
541 | - { | |
542 | - if (! $this->options['new'][1]) { | |
543 | - return; | |
544 | - } | |
545 | - foreach ($this->metapages as $i => $metapage) { | |
546 | - $date = $this->metapages[$i]['date']; | |
547 | - // burdonsome, but to use configuration of new plugin | |
548 | - $new = do_plugin_inline($this->conf['plugin_new'], 'nodate', $date); | |
549 | - $this->metapages[$i]['info_new'] = $new; | |
550 | - } | |
551 | - } | |
552 | - | |
553 | - function info_metapages() | |
554 | - { | |
555 | - if (empty($this->options['info'][1])) { | |
556 | - return; | |
557 | - } | |
558 | - | |
559 | - $this->date_metapages(); | |
560 | - $this->info_date_metapages(); | |
561 | - $this->info_new_metapages(); | |
562 | - | |
563 | - //foreach ($this->options['info'][2] as $key) { | |
564 | - // call_user_func(array($this, $key . '_metapages')); | |
565 | - //} | |
566 | - foreach ($this->metapages as $i => $metapage) { | |
567 | - $info = ''; | |
568 | - foreach ($this->options['info'][1] as $key) { | |
569 | - $info .= ' ' . $metapage['info_' . $key]; | |
570 | - } | |
571 | - $this->metapages[$i]['info'] = $info; | |
572 | - } | |
573 | - } | |
574 | - | |
575 | - function tree_filter_metapages() | |
576 | - { | |
577 | - if ($this->options['tree'][1] === false) { | |
578 | - return; | |
579 | - } | |
580 | - $allpages = get_existpages(); | |
581 | - $this->sort_pages($allpages); | |
582 | - $current = current($allpages); | |
583 | - while ($next = next($allpages)) { | |
584 | - if (strpos($next, $current . '/') === FALSE) { | |
585 | - $leafs[$current] = TRUE; | |
586 | - } else { | |
587 | - $leafs[$current] = FALSE; | |
588 | - } | |
589 | - $current = $next; | |
590 | - } | |
591 | - $leafs[$current] = TRUE; | |
592 | - | |
593 | - switch ($this->options['tree'][1]) { | |
594 | - case 'dir': | |
595 | - foreach ($this->metapages as $i => $metapage) { | |
596 | - $page = $metapage['page']; | |
597 | - if ($leafs[$page]) { | |
598 | - unset($this->metapages[$i]); | |
599 | - } | |
600 | - } | |
601 | - break; | |
602 | - case 'leaf': | |
603 | - foreach ($this->metapages as $i => $metapage) { | |
604 | - $page = $metapage['page']; | |
605 | - if (! $leafs[$page]) { | |
606 | - unset($this->metapages[$i]); | |
607 | - } | |
608 | - } | |
609 | - break; | |
610 | - } | |
611 | - } | |
612 | - | |
613 | - function hierarchy_metapages() | |
614 | - { | |
615 | - if ($this->options['hierarchy'][1] === false) { | |
616 | - return; | |
617 | - } | |
618 | - $pdepth = substr_count($this->options['prefix'][1], '/') - 1; | |
619 | - $pdir = $this->my_dirname($this->options['prefix'][1]); | |
620 | - $pdirlen = ($pdir == '') ? 0 : strlen($pdir) + 1; // Add '/' | |
621 | - $num = count($this->metapages); | |
622 | - foreach ($this->metapages as $i => $metapage) { | |
623 | - $page = $metapage['page']; | |
624 | - $depth = $metapage['depth']; // depth_metapages() | |
625 | - if ($this->options['hierarchy'][1] === true) { | |
626 | - $this->metapages[$i]['listdepth'] = $depth; | |
627 | - } | |
628 | - while ($depth > 1) { | |
629 | - $page = $this->my_dirname($page); | |
630 | - if ($page == '') break; | |
631 | - $depth = substr_count($page, '/') - $pdepth; | |
632 | - | |
633 | - // if parent dir does not exist, complement | |
634 | - if (($j = $this->array_search_by($page, $this->metapages, 'page')) === false) { | |
635 | - if ($this->options['hierarchy'][1] === true) { | |
636 | - $relative = substr($page, $pdirlen); | |
637 | - $listdepth = $depth; | |
638 | - $this->metapages[] = array('reading'=>$page,'page'=>$page, 'relative'=>$relative, 'exist'=>false, 'depth'=>$depth, 'listdepth'=>$listdepth, 'timestamp'=>1, 'date'=>'', 'leaf'=>false); | |
639 | - // PHP: new item is ignored on this loop | |
640 | - } | |
641 | - } | |
642 | - } | |
643 | - } | |
644 | - if (count($this->metapages) != $num) { | |
645 | - $this->sort_metapages(); | |
646 | - } | |
647 | - } | |
648 | - | |
649 | - function sort_metapages($sort = 'natcasesort', $sortflag = SORT_REGULAR) | |
650 | - { | |
651 | - switch ($this->options['sort'][1]) { | |
652 | - case 'name': | |
653 | - $this->sort_by($this->metapages, 'page', 'sort', SORT_STRING); | |
654 | - break; | |
655 | - case 'date': | |
656 | - $this->sort_by($this->metapages, 'timestamp', 'rsort', SORT_NUMERIC); | |
657 | - break; | |
658 | - case 'reading': | |
659 | - $this->sort_by($this->metapages, 'reading', 'sort', SORT_STRING); | |
660 | - break; | |
661 | - case 'popular': | |
662 | - $this->sort_by($this->metapages, 'popular', 'rsort', SORT_NUMERIC); | |
663 | - break; | |
664 | - default: | |
665 | - $this->sort_by($this->metapages, $this->options['sort'][1], $sort, $sortflag); | |
666 | - break; | |
667 | - } | |
668 | - | |
669 | - if ($this->options['reverse'][1]) { | |
670 | - $this->metapages = array_reverse($this->metapages); | |
671 | - } | |
672 | - } | |
673 | - | |
674 | - function depth_metapages() | |
675 | - { | |
676 | - if ($this->options['depth'][1] === '' && $this->options['hierarchy'][1] === false && | |
677 | - $this->options['tree'][1] === false ) { | |
678 | - return; | |
679 | - } | |
680 | - $pdepth = substr_count($this->options['prefix'][1], '/') - 1; | |
681 | - | |
682 | - foreach ($this->metapages as $i => $metapage) { | |
683 | - $page = $metapage['page']; | |
684 | - $depth = substr_count($page, '/'); | |
685 | - $this->metapages[$i]['depth'] = $depth - $pdepth; | |
686 | - } | |
687 | - | |
688 | - return $this->max_by($this->metapages, 'depth'); | |
689 | - } | |
690 | - | |
691 | - function relative_metapages() | |
692 | - { | |
693 | - $pdir = $this->my_dirname($this->options['prefix'][1]); | |
694 | - if ($pdir == '') { | |
695 | - foreach ($this->metapages as $i => $metapage) { | |
696 | - $this->metapages[$i]['relative'] = $metapage['page']; | |
697 | - } | |
698 | - } else { | |
699 | - $pdirlen = strlen($pdir) + 1; // Add strlen('/') | |
700 | - foreach ($this->metapages as $i => $metapage) { | |
701 | - $this->metapages[$i]['relative'] = substr($metapage['page'], $pdirlen); | |
702 | - } | |
703 | - } | |
704 | - } | |
705 | - | |
706 | - function init_metapages() | |
707 | - { | |
708 | - if ($this->options['sort'][1] === 'reading') { | |
709 | - // Beta Function | |
710 | - if ($this->options['tag'][1] == '') { | |
711 | - $readings = $this->get_readings(); | |
712 | - } else { | |
713 | - $plugin_tag = new PluginTag(); | |
714 | - $pages = $plugin_tag->get_taggedpages($this->options['tag'][1]); | |
715 | - if ($pages === FALSE) { | |
716 | - $this->error = 'The tag token, ' . htmlspecialchars($this->options['tag'][1]) . ', is invalid. '; | |
717 | - $this->error .= 'Perhaps, the tag does not exist. '; | |
718 | - } | |
719 | - $readings = $this->get_readings(); // why can not set pages... | |
720 | - foreach ($pages as $page) | |
721 | - $tagged_readings[$page] = ''; | |
722 | - // array_intersect_key >= PHP 5.1.0 RC1 | |
723 | - // $readings = array_intersect_key($readings, $tagged_readings); | |
724 | - foreach ($readings as $page => $reading) { | |
725 | - if (! isset($tagged_readings[$page])) unset($readings[$page]); | |
726 | - } | |
727 | - } | |
728 | - $metapages = array(); | |
729 | - foreach ($readings as $page => $reading) { | |
730 | - unset($readings[$page]); | |
731 | - $metapages[] = array('reading'=>$reading,'page'=>$page, 'exist'=>true, 'depth'=>1, 'listdepth'=>1, 'timestamp'=>1, 'date'=>''); | |
732 | - } | |
733 | - $this->metapages = $metapages; | |
734 | - } else { | |
735 | - if ($this->options['tag'][1] == '') { | |
736 | - $pages = get_existpages(); | |
737 | - } else { | |
738 | - $plugin_tag = new PluginTag(); | |
739 | - $pages = $plugin_tag->get_taggedpages($this->options['tag'][1]); | |
740 | - if ($pages === FALSE) { | |
741 | - $this->error = 'The tag token, ' . htmlspecialchars($this->options['tag'][1]) . ', is invalid. '; | |
742 | - $this->error .= 'Perhaps, the tag does not exist. '; | |
743 | - } | |
744 | - } | |
745 | - $metapages = array(); | |
746 | - foreach ($pages as $i => $page) { | |
747 | - unset($pages[$i]); | |
748 | - $metapages[] = array('page'=>$page, 'exist'=>true, 'depth'=>1, 'listdepth'=>1, 'timestamp'=>1, 'date'=>''); | |
749 | - } | |
750 | - $this->metapages = $metapages; | |
751 | - } | |
752 | - } | |
753 | - | |
754 | - function depth_filter_metapages() | |
755 | - { | |
756 | - if ($this->options['depth'][1] === '') { | |
757 | - return; | |
758 | - } | |
759 | - $metapages = array(); | |
760 | - foreach ($this->metapages as $i => $metapage) { | |
761 | - unset($this->metapages[$i]); | |
762 | - if (in_array($metapage['depth'], $this->options['depth'][1])) { | |
763 | - $metapages[] = $metapage; | |
764 | - } | |
765 | - } | |
766 | - $this->metapages = $metapages; | |
767 | - } | |
768 | - | |
769 | - // sort before this ($this->sort_by) | |
770 | - function num_filter_metapages() | |
771 | - { | |
772 | - if ($this->options['num'][1] === '') { | |
773 | - return; | |
774 | - } | |
775 | - $metapages = array(); | |
776 | - // $num < count($this->metapages) is assured. | |
777 | - foreach ($this->options['num'][1] as $num) { | |
778 | - $metapages[] = $this->metapages[$num - 1]; | |
779 | - } | |
780 | - $this->metapages = $metapages; | |
781 | - } | |
782 | - | |
783 | - function newpage_filter_metapages() | |
784 | - { | |
785 | - if ($this->options['newpage'][1] === false) { | |
786 | - return; | |
787 | - } | |
788 | - if ($this->options['newpage'][1] == 'on') { | |
789 | - $new = true; | |
790 | - } elseif ($this->options['newpage'][1] == 'except') { | |
791 | - $new = false; | |
792 | - } | |
793 | - $metapages = array(); | |
794 | - foreach ($this->metapages as $i => $metapage) { | |
795 | - unset($this->metapages[$i]); | |
796 | - if ($new == $this->is_newpage($metapage['page'])) { | |
797 | - $metapages[] = $metapage; | |
798 | - } | |
799 | - } | |
800 | - $this->metapages = $metapages; | |
801 | - } | |
802 | - | |
803 | - function prefix_filter_metapages() | |
804 | - { | |
805 | - if ($this->options['prefix'][1] === "") { | |
806 | - return; | |
807 | - } | |
808 | - $metapages = array(); | |
809 | - foreach ($this->metapages as $i => $metapage) { | |
810 | - unset($this->metapages[$i]); | |
811 | - if (strpos($metapage['page'], $this->options['prefix'][1]) !== 0) { | |
812 | - continue; | |
813 | - } | |
814 | - $metapages[] = $metapage; | |
815 | - } | |
816 | - $this->metapages = $metapages; | |
817 | - } | |
818 | - | |
819 | - function nonlist_filter_metapages() | |
820 | - { | |
821 | - if ($this->options['non_list'][1] === false) { | |
822 | - return; | |
823 | - } | |
824 | - global $non_list; | |
825 | - $metapages = array(); | |
826 | - foreach ($this->metapages as $i => $metapage) { | |
827 | - unset($this->metapages[$i]); | |
828 | - if (preg_match("/$non_list/", $metapage['page'])) { | |
829 | - continue; | |
830 | - } | |
831 | - $metapages[] = $metapage; | |
832 | - } | |
833 | - $this->metapages = $metapages; | |
834 | - } | |
835 | - | |
836 | - function except_filter_metapages() | |
837 | - { | |
838 | - if ($this->options['except'][1] === "") { | |
839 | - return; | |
840 | - } | |
841 | - $metapages = array(); | |
842 | - foreach ($this->metapages as $i => $metapage) { | |
843 | - unset($this->metapages[$i]); | |
844 | - if (call_user_func($this->ereg, $this->options['except'][1], $metapage['relative'])) { | |
845 | - continue; | |
846 | - } | |
847 | - $metapages[] = $metapage; | |
848 | - } | |
849 | - $this->metapages = $metapages; | |
850 | - } | |
851 | - | |
852 | - function filter_filter_metapages() | |
853 | - { | |
854 | - if ($this->options['filter'][1] === "") { | |
855 | - return; | |
856 | - } | |
857 | - $metapages = array(); | |
858 | - foreach ($this->metapages as $i => $metapage) { | |
859 | - unset($this->metapages[$i]); | |
860 | - if (! call_user_func($this->ereg, $this->options['filter'][1], $metapage['relative'])) { | |
861 | - continue; | |
862 | - } | |
863 | - $metapages[] = $metapage; | |
864 | - } | |
865 | - $this->metapages = $metapages; | |
866 | - } | |
867 | - | |
868 | - // PukiWiki API Extension | |
869 | - | |
870 | - function sort_pages(&$pages) | |
871 | - { | |
872 | - $pages = str_replace('/', "\0", $pages); | |
873 | - sort($pages, SORT_STRING); | |
874 | - $pages = str_replace("\0", '/', $pages); | |
875 | - } | |
876 | - | |
877 | - // No PREG_SPLIT_NO_EMPTY version | |
878 | - // copy from lib/make_link.php#get_fullname | |
879 | - function get_fullname($name, $refer) | |
880 | - { | |
881 | - global $defaultpage; | |
882 | - | |
883 | - // 'Here' | |
884 | - if ($name == '' || $name == './') return $refer; | |
885 | - | |
886 | - // Absolute path | |
887 | - if ($name{0} == '/') { | |
888 | - $name = substr($name, 1); | |
889 | - return ($name == '') ? $defaultpage : $name; | |
890 | - } | |
891 | - | |
892 | - // Relative path from 'Here' | |
893 | - if (substr($name, 0, 2) == './') { | |
894 | - $arrn = preg_split('#/#', $name, -1); //, PREG_SPLIT_NO_EMPTY); | |
895 | - $arrn[0] = $refer; | |
896 | - return join('/', $arrn); | |
897 | - } | |
898 | - | |
899 | - // Relative path from dirname() | |
900 | - if (substr($name, 0, 3) == '../') { | |
901 | - $arrn = preg_split('#/#', $name, -1); //, PREG_SPLIT_NO_EMPTY); | |
902 | - $arrp = preg_split('#/#', $refer, -1, PREG_SPLIT_NO_EMPTY); | |
903 | - | |
904 | - while (! empty($arrn) && $arrn[0] == '..') { | |
905 | - array_shift($arrn); | |
906 | - array_pop($arrp); | |
907 | - } | |
908 | - $name = ! empty($arrp) ? join('/', array_merge($arrp, $arrn)) : | |
909 | - (! empty($arrn) ? $defaultpage . '/' . join('/', $arrn) : $defaultpage); | |
910 | - } | |
911 | - | |
912 | - return $name; | |
913 | - } | |
914 | - | |
915 | - function is_newpage($page) | |
916 | - { | |
917 | - // pukiwiki trick | |
918 | - return ! _backup_file_exists($page); | |
919 | - } | |
920 | - | |
921 | - function make_pagelink($page, $alias = '', $anchor = '', $refer = '', $isautolink = FALSE) | |
922 | - { | |
923 | - // no passage | |
924 | - global $show_passage; | |
925 | - $tmp = $show_passage; $show_passage = 0; | |
926 | - $link = make_pagelink($page, $alias, $anchor, $refer, $isautolink); | |
927 | - $show_passage = $tmp; | |
928 | - return $link; | |
929 | - } | |
930 | - | |
931 | - function get_readings() | |
932 | - { | |
933 | - return get_readings(); | |
934 | - } | |
935 | - | |
936 | - function get_filetime($page) | |
937 | - { | |
938 | - return get_filetime($page); | |
939 | - } | |
940 | - | |
941 | - // PHP Extension | |
942 | - | |
943 | - // dirname(Page/) => '.' , dirname(Page/a) => Page, dirname(Page) => '.' | |
944 | - // But, want Page/ => Page, Page/a => Page, Page => '' | |
945 | - function my_dirname($page) | |
946 | - { | |
947 | - if (($pos = strrpos($page, '/')) !== false) { | |
948 | - return substr($page, 0, $pos); | |
949 | - } else { | |
950 | - return ''; | |
951 | - } | |
952 | - } | |
953 | - | |
954 | - // basename(Page/) => Page , basename(Page/a) => a, basename(Page) => Page | |
955 | - // But, want Page/ => '', Page/a => a, Page => Page | |
956 | - function my_basename($page) | |
957 | - { | |
958 | - if (($pos = strrpos($page, '/')) !== false) { | |
959 | - return substr($page, $pos + 1); | |
960 | - } else { | |
961 | - return $page; | |
962 | - } | |
963 | - } | |
964 | - | |
965 | - function array_search_by($value, $array, $fieldname = null) | |
966 | - { | |
967 | - foreach ($array as $i => $val) { | |
968 | - if ($value == $val[$fieldname]) { | |
969 | - return $i; | |
970 | - } | |
971 | - } | |
972 | - return false; | |
973 | - } | |
974 | - | |
975 | - function in_array_by($value, $array, $fieldname = null) | |
976 | - { | |
977 | - //foreach ($array as $i => $befree) { | |
978 | - // $field_array[$i] = $array[$i][$fieldname]; | |
979 | - //} | |
980 | - //return in_array($value, $field_array); | |
981 | - | |
982 | - foreach ($array as $i => $val) { | |
983 | - if ($value == $val[$fieldname]) { | |
984 | - return true; | |
985 | - } | |
986 | - } | |
987 | - return false; | |
988 | - } | |
989 | - | |
990 | - # sort arrays by a specific field without maintaining key association | |
991 | - function sort_by(&$array, $fieldname = null, $sort, $sortflag = SORT_REGULAR) | |
992 | - { | |
993 | - $field_array = $inarray = array(); | |
994 | - # store the keyvalues in a seperate array | |
995 | - foreach ($array as $i => $befree) { | |
996 | - $field_array[$i] = $array[$i][$fieldname]; | |
997 | - } | |
998 | - $field_array = str_replace('/', "\0", $field_array); // must not be here. Refactor me. | |
999 | - switch ($sort) { | |
1000 | - case 'sort': | |
1001 | - # sort an array and maintain index association... | |
1002 | - asort($field_array, $sortflag); | |
1003 | - break; | |
1004 | - case 'rsort': | |
1005 | - # sort an array in reverse order and maintain index association | |
1006 | - arsort($field_array, $sortflag); | |
1007 | - break; | |
1008 | - case 'natsort': | |
1009 | - natsort($field_array); | |
1010 | - case 'natcasesort': | |
1011 | - # sort an array using a case insensitive "natural order" algorithm | |
1012 | - natcasesort($field_array); | |
1013 | - break; | |
1014 | - } | |
1015 | - # rebuild the array | |
1016 | - $outarray = array(); | |
1017 | - foreach ( $field_array as $i=> $befree) { | |
1018 | - $outarray[] = $array[$i]; | |
1019 | - unset($array[$i]); | |
1020 | - } | |
1021 | - $array = $outarray; | |
1022 | - } | |
1023 | - | |
1024 | - function max_by($array, $fieldname = null) | |
1025 | - { | |
1026 | - $field_array = $inarray = array(); | |
1027 | - # store the keyvalues in a seperate array | |
1028 | - foreach ($array as $i => $befree) { | |
1029 | - $field_array[$i] = $array[$i][$fieldname]; | |
1030 | - } | |
1031 | - return max($field_array); | |
1032 | - } | |
15 | + function __construct() | |
16 | + { | |
17 | + // Configure external plugins | |
18 | + static $conf = array( | |
19 | + 'plugin_contents' => 'contentsx', | |
20 | + 'plugin_include' => 'includex', | |
21 | + 'plugin_new' => 'new', | |
22 | + 'plugin_tag' => 'tag', | |
23 | + ); | |
24 | + // Modify here for default option values | |
25 | + static $default_options = array( | |
26 | + 'hierarchy' => array('bool', true), | |
27 | + 'non_list' => array('bool', true), | |
28 | + 'reverse' => array('bool', false), | |
29 | + 'basename' => array('bool', false), // obsolete | |
30 | + 'sort' => array('enum', 'name', array('name', 'reading', 'date')), | |
31 | + 'tree' => array('enum', false, array(false, 'leaf', 'dir')), | |
32 | + 'depth' => array('number', ''), | |
33 | + 'num' => array('number', ''), | |
34 | + 'next' => array('bool', false), | |
35 | + 'except' => array('string', ''), | |
36 | + 'filter' => array('string', ''), | |
37 | + 'prefix' => array('string', ''), | |
38 | + 'contents' => array('array', ''), | |
39 | + 'include' => array('array', ''), | |
40 | + 'info' => array('enumarray', array(), array('date', 'new')), | |
41 | + 'date' => array('bool', false), // will be obsolete | |
42 | + 'new' => array('bool', false), | |
43 | + 'tag' => array('string', ''), | |
44 | + 'linkstr' => array('enum', 'relative', array('relative', 'absolute', 'basename', 'title', 'headline')), | |
45 | + 'link' => array('enum', 'page', array('page', 'anchor', 'off')), | |
46 | + 'newpage' => array('enum', false, array('on', 'except')), | |
47 | + 'popular' => array('enum', false, array('total', 'today', 'yesterday', 'recent')), // alpha | |
48 | + ); | |
49 | + $this->conf = &$conf; | |
50 | + $this->default_options = &$default_options; | |
51 | + | |
52 | + // init | |
53 | + $this->options = $this->default_options; | |
54 | + if (function_exists('mb_ereg')) { // extension_loaded('mbstring') | |
55 | + mb_regex_encoding(SOURCE_ENCODING); | |
56 | + $this->ereg = 'mb_ereg'; | |
57 | + } else { | |
58 | + $this->ereg = 'ereg'; | |
59 | + } | |
60 | + } | |
61 | + | |
62 | + function PluginLsx() { | |
63 | + $this->__construct(); | |
64 | + } | |
65 | + | |
66 | + // static | |
67 | + var $conf; | |
68 | + var $default_options; | |
69 | + // var | |
70 | + var $options; | |
71 | + var $error = ""; | |
72 | + var $plugin = "lsx"; | |
73 | + var $metapages; | |
74 | + | |
75 | + function convert() | |
76 | + { | |
77 | + $args = func_get_args(); | |
78 | + $body = $this->body($args); | |
79 | + if ($this->error != "") { | |
80 | + $body = "<p>$this->plugin(): $this->error</p>"; | |
81 | + } | |
82 | + return $body; | |
83 | + } | |
84 | + | |
85 | + function action() | |
86 | + { | |
87 | + global $vars; | |
88 | + | |
89 | + $args = $vars; | |
90 | + $body = $this->body($args); | |
91 | + if ($this->error != "") { | |
92 | + $body = "<p>$this->plugin(): $this->error</p>"; | |
93 | + } | |
94 | + if (! isset($body)) $body = '<p>no result.</p>'; | |
95 | + | |
96 | + if ($this->options['tag'][1] != '') { | |
97 | + $msg = htmlsc($this->options['tag'][1]); | |
98 | + } elseif ($this->options['prefix'][1] != '') { | |
99 | + $msg = htmlsc($this->options['prefix'][1]); | |
100 | + } else { | |
101 | + $msg = $this->plugin; | |
102 | + } | |
103 | + return array('msg'=>$msg, 'body'=>$body); | |
104 | + } | |
105 | + | |
106 | + function body($args) | |
107 | + { | |
108 | + $parser = new PluginLsxOptionParser(); | |
109 | + $this->options = $parser->parse_options($args, $this->options); | |
110 | + if ($parser->error != "") { $this->error = $parser->error; return; } | |
111 | + | |
112 | + $this->validate_options(); | |
113 | + if ($this->error !== "") { return $this->error; } | |
114 | + | |
115 | + $this->init_metapages(); | |
116 | + if ($this->error !== "") { return $this->error; } | |
117 | + $this->prefix_filter_metapages(); | |
118 | + if ($this->error !== "") { return $this->error; } | |
119 | + $this->nonlist_filter_metapages(); | |
120 | + if ($this->error !== "") { return $this->error; } | |
121 | + $this->relative_metapages(); // before filter, except | |
122 | + if ($this->error !== "") { return $this->error; } | |
123 | + $this->filter_filter_metapages(); | |
124 | + if ($this->error !== "") { return $this->error; } | |
125 | + $this->except_filter_metapages(); | |
126 | + if ($this->error !== "") { return $this->error; } | |
127 | + | |
128 | + $this->newpage_filter_metapages(); | |
129 | + if ($this->error !== "") { return $this->error; } | |
130 | + | |
131 | + $parser = new PluginLsxOptionParser(); | |
132 | + $this->maxdepth = $this->depth_metapages(); | |
133 | + $this->options['depth'][1] = $parser->parse_numoption($this->options['depth'][1], 1, $this->maxdepth); | |
134 | + if ($parser->error != "") { $this->error = $parser->error; return; } | |
135 | + $this->depth_filter_metapages(); | |
136 | + if ($this->error !== "") { return $this->error; } | |
137 | + | |
138 | + $this->tree_filter_metapages(); | |
139 | + if ($this->error !== "") { return $this->error; } | |
140 | + $this->popular_metapages(); // before sort | |
141 | + if ($this->error !== "") { return $this->error; } | |
142 | + $this->timestamp_metapages(); // before sort | |
143 | + if ($this->error !== "") { return $this->error; } | |
144 | + $this->sort_metapages(); // before num_filter | |
145 | + if ($this->error !== "") { return $this->error; } | |
146 | + | |
147 | + $this->maxnum = sizeof($this->metapages); // after all filters | |
148 | + $this->options['num'][1] = $parser->parse_numoption($this->options['num'][1], 1, $this->maxnum); | |
149 | + if ($parser->error != "") { $this->error = $parser->error; return; } | |
150 | + $this->num_filter_metapages(); | |
151 | + if ($this->error !== "") { return $this->error; } | |
152 | + | |
153 | + $this->hierarchy_metapages(); | |
154 | + if ($this->error !== "") { return $this->error; } | |
155 | + | |
156 | + $this->info_metapages(); | |
157 | + if ($this->error !== "") { return $this->error; } | |
158 | + $this->linkstr_metapages(); | |
159 | + if ($this->error !== "") { return $this->error; } | |
160 | + $this->link_metapages(); | |
161 | + if ($this->error !== "") { return $this->error; } | |
162 | + | |
163 | + $body = $this->list_pages(); | |
164 | + $body .= $this->next_pages(); | |
165 | + | |
166 | + return $body; | |
167 | + } | |
168 | + | |
169 | + function validate_options() | |
170 | + { | |
171 | + global $vars; | |
172 | + if ($this->options['tag'][1] != '') { | |
173 | + if(! exist_plugin($this->conf['plugin_tag'])) { | |
174 | + $this->error .= "The option, tag, requires #{$this->conf['plugin_tag']} plugin, but it does not exist. "; | |
175 | + return; | |
176 | + } | |
177 | + $this->options['hierarchy'][1] = false; | |
178 | + // best is to turn off the default only so that 'hierarchy' can be configured by option. | |
179 | + } else { | |
180 | + if ($this->options['prefix'][1] == '') { | |
181 | + $this->options['prefix'][1] = $vars['page'] != '' ? $vars['page'] . '/' : ''; | |
182 | + } | |
183 | + } | |
184 | + if ($this->options['prefix'][1] == '/') { | |
185 | + $this->options['prefix'][1] = ''; | |
186 | + } elseif ($this->options['prefix'][1] != '') { | |
187 | + $this->options['prefix'][1] = $this->get_fullname($this->options['prefix'][1], $vars['page']); | |
188 | + } | |
189 | + $this->options['prefix'][4] = $this->options['prefix'][1]; | |
190 | + | |
191 | + if ($this->options['sort'][1] == 'date') { | |
192 | + $this->options['hierarchy'][1] = false; | |
193 | + } | |
194 | + | |
195 | + // alpha func | |
196 | + if ($this->options['popular'][1] != false) { | |
197 | + $this->options['sort'][1] = 'popular'; | |
198 | + $this->options['hierarchy'][1] = false; | |
199 | + // Future Work: info_popular. hmmm | |
200 | + } | |
201 | + // Another Idea | |
202 | + // sort=popular>today,popular>total,popular>yesterday,popular>recent | |
203 | + // if (strpos($this->options['sort'][1], 'popular>') !== false) { | |
204 | + // list($this->optiions['sort'][1], $this->options['popular'][1]) = explode('>', $this->options['sort'][1]); | |
205 | + // $this->options['hierarchy'][1] = false; | |
206 | + // } | |
207 | + | |
208 | + if ($this->options['contents'][1] != '') { | |
209 | + if(! exist_plugin_convert($this->conf['plugin_contents'])) { | |
210 | + $this->error .= "The option, contents, requires {$this->conf['plugin_contents']} plugin, but it does not exist. "; | |
211 | + return; | |
212 | + } | |
213 | + } | |
214 | + | |
215 | + if ($this->options['include'][1] != '') { | |
216 | + if(! exist_plugin_convert($this->conf['plugin_include'])) { | |
217 | + $this->error .= "The option, include, requires {$this->conf['plugin_include']} plugin, but it does not exist. "; | |
218 | + return; | |
219 | + } | |
220 | + $this->options['hierarchy'][1] = false; // hierarchy + include => XHTML invalid | |
221 | + $this->options['date'][1] = false; // include does not use definitely | |
222 | + $this->options['new'][1] = false; // include does not use definitely | |
223 | + $this->options['contents'][1] = ''; // include does not use definitely | |
224 | + } | |
225 | + | |
226 | + if ($this->options['linkstr'][1] === 'title' || $this->options['linkstr'][1] === 'headline') { | |
227 | + if(! exist_plugin_convert($this->conf['plugin_contents'])) { | |
228 | + $this->error .= "The option, linkstr, requires {$this->conf['plugin_contents']} plugin, but it does not exist. "; | |
229 | + return; | |
230 | + } | |
231 | + } | |
232 | + | |
233 | + // to support lower versions | |
234 | + // basename -> linkstr | |
235 | + if ($this->options['basename'][1] === true) { | |
236 | + $this->options['linkstr'][1] = 'basename'; | |
237 | + } | |
238 | + | |
239 | + // new,date -> info | |
240 | + foreach ($this->options['info'][2] as $key) { | |
241 | + if ($this->options[$key][1]) { | |
242 | + array_push($this->options['info'][1], $key); | |
243 | + } | |
244 | + } | |
245 | + $this->options['info'][1] = array_unique($this->options['info'][1]); | |
246 | + // to save time (to avoid in_array everytime) | |
247 | + foreach ($this->options['info'][1] as $key) { | |
248 | + $this->options[$key][1] = true; | |
249 | + } | |
250 | + if ($this->options['new'][1] && ! exist_plugin_inline($this->conf['plugin_new'])) { | |
251 | + $this->error .= "The option, new, requires {$this->conf['plugin_new']} plugin, but it does not exist. "; | |
252 | + return; | |
253 | + } | |
254 | + } | |
255 | + | |
256 | + function next_pages() | |
257 | + { | |
258 | + if (! $this->options['next'][1] || $this->options['num'][1] == '') return; | |
259 | + | |
260 | + $options = $this->options; | |
261 | + unset($options['num']); | |
262 | + $href = get_script_uri() . '?' . 'cmd=lsx'; | |
263 | + foreach ($options as $key => $val) { | |
264 | + if (isset($val[4])) { | |
265 | + $href .= '&' . htmlsc($key) . '=' . htmlsc(rawurlencode($val[4])); | |
266 | + } | |
267 | + } | |
268 | + $count = count($this->options['num'][1]); | |
269 | + $min = reset($this->options['num'][1]); | |
270 | + $max = end($this->options['num'][1]); | |
271 | + $maxnum = $this->maxnum; | |
272 | + $prevmin = max($min - $count, 0); | |
273 | + $prevmax = min($min - 1, $maxnum); | |
274 | + $prevlink = ''; | |
275 | + if ($prevmax > 0) { | |
276 | + $prevhref = $href . '&num=' . $prevmin . ':' . $prevmax; | |
277 | + $prevlink = '<span class="prev" style="float:left;"><a href="' . $prevhref . '">' . _('Prev ') . $count . '</a></span>'; | |
278 | + } | |
279 | + $nextmin = max($max + 1, 0); | |
280 | + $nextmax = min($max + $count, $maxnum); | |
281 | + $nextlink = ''; | |
282 | + if ($nextmin < $maxnum) { | |
283 | + $nexthref = $href . '&num=' . $nextmin . ':' . $nextmax; | |
284 | + $nextlink = '<span class="next" style="float:right;"><a href="' . $nexthref . '">' . _('Next ') . $count . '</a></span>'; | |
285 | + } | |
286 | + $ret = ''; | |
287 | + $ret .= '<div class="lsx">' . $prevlink . $nextlink . '</div><div style="clear:both;"></div>'; | |
288 | + return $ret; | |
289 | + } | |
290 | + | |
291 | + function list_pages() | |
292 | + { | |
293 | + global $script; | |
294 | + | |
295 | + if (sizeof($this->metapages) == 0) { | |
296 | + return; | |
297 | + } | |
298 | + | |
299 | + /* HTML validate (without <ul><li style="list-type:none"><ul><li>, we have to do as | |
300 | + <ul><li style="padding-left:16*2px;margin-left:16*2px"> as pukiwiki standard. I did not like it) | |
301 | + | |
302 | + <ul> <ul><li>1 | |
303 | + <li>1</li> </li><li>1 | |
304 | + <li>1 <ul><li>2 | |
305 | + <ul> </li></ul></li><li>1 | |
306 | + <li>2</li> </li><li>1 | |
307 | + </ul> => <ul><li style="list-type:none"><ul><li>3 | |
308 | + </li> </li></ul></li></ul></li></ul> | |
309 | + <li>1</li> | |
310 | + <li>1</li> | |
311 | + <ul><li style="list-type:none"><ul> | |
312 | + <li>3</li> | |
313 | + </ul></li></ul> | |
314 | + </li> | |
315 | + </ul> | |
316 | + */ | |
317 | + $html = ""; | |
318 | + $ul = $pdepth = 0; | |
319 | + foreach ($this->metapages as $i => $metapage) { | |
320 | + $page = $metapage['page']; | |
321 | + $exist = $metapage['exist']; | |
322 | + $depth = $metapage['listdepth']; | |
323 | + $info = $metapage['info']; | |
324 | + $link = $metapage['link']; | |
325 | + if ($exist && $this->options['include'][1] != '') { | |
326 | + $option = '"' . $page . '"'; | |
327 | + if (! empty($this->options['include'][1])) { | |
328 | + $option .= ',' . csv_implode(',', $this->options['include'][1]); | |
329 | + } | |
330 | + $html .= do_plugin_convert($this->conf['plugin_include'], $option); | |
331 | + continue; | |
332 | + } | |
333 | + if ($depth > $pdepth) { | |
334 | + $diff = $depth - $pdepth; | |
335 | + $html .= str_repeat('<ul><li style="list-style:none">', $diff - 1); | |
336 | + if ($depth == 1) { // or $first flag | |
337 | + $html .= '<ul class="' . $this->plugin . '"><li>'; | |
338 | + } else { | |
339 | + $html .= '<ul><li>'; | |
340 | + } | |
341 | + $ul += $diff; | |
342 | + } elseif ($depth == $pdepth) { | |
343 | + $html .= '</li><li>'; | |
344 | + } elseif ($depth < $pdepth) { | |
345 | + $diff = $pdepth - $depth; | |
346 | + $html .= str_repeat('</li></ul>', $diff); | |
347 | + $html .= '</li><li>'; | |
348 | + $ul -= $diff; | |
349 | + } | |
350 | + $pdepth = $depth; | |
351 | + | |
352 | + $html .= $link; | |
353 | + if (isset($info) && $info != '') { | |
354 | + $html .= '<span class="lsx_info">' . $info . '</span>' . "\n"; | |
355 | + } | |
356 | + | |
357 | + if ($exist && $this->options['contents'][1] != '') { | |
358 | + $args = $this->options['contents'][1]; | |
359 | + $pagearg = 'page=' . $page ; | |
360 | + array_unshift($args, $pagearg); | |
361 | + $contentsx = new PluginContentsx(); | |
362 | + $html .= call_user_func(array($contentsx, 'body'), $args); | |
363 | + } | |
364 | + } | |
365 | + $html .= str_repeat('</li></ul>', $ul); | |
366 | + return $html; | |
367 | + } | |
368 | + | |
369 | + function link_metapages() | |
370 | + { | |
371 | + switch ($this->options['link'][1]) { | |
372 | + case 'page': | |
373 | + foreach ($this->metapages as $i => $metapage) { | |
374 | + if ($metapage['exist']) { | |
375 | + $this->metapages[$i]['link'] = | |
376 | + $this->make_pagelink($metapage['page'], $metapage['linkstr']); | |
377 | + } else { | |
378 | + $this->metapages[$i]['link'] = $metapage['linkstr']; | |
379 | + } | |
380 | + } | |
381 | + break; | |
382 | + case 'anchor': | |
383 | + foreach ($this->metapages as $i => $metapage) { | |
384 | + // PluginIncludex::get_page_anchor($metapage['page']) | |
385 | + $anchor = 'z' . md5($metapage['page']); | |
386 | + $anchor = '#' . htmlsc($anchor); | |
387 | + if ($metapage['exist']) { | |
388 | + $this->metapages[$i]['link'] = | |
389 | + $this->make_pagelink('', $metapage['linkstr'], $anchor); | |
390 | + } else { | |
391 | + $this->metapages[$i]['link'] = $metapage['linkstr']; | |
392 | + } | |
393 | + } | |
394 | + break; | |
395 | + case 'off': | |
396 | + foreach ($this->metapages as $i => $metapage) { | |
397 | + $this->metapages[$i]['link'] = $metapage['linkstr']; | |
398 | + } | |
399 | + break; | |
400 | + } | |
401 | + } | |
402 | + | |
403 | + function linkstr_metapages() | |
404 | + { | |
405 | + switch ($this->options['linkstr'][1]) { | |
406 | + case 'absolute': | |
407 | + foreach ($this->metapages as $i => $metapage) { | |
408 | + $this->metapages[$i]['linkstr'] = | |
409 | + htmlsc($metapage['page']); | |
410 | + } | |
411 | + break; | |
412 | + case 'basename': | |
413 | + foreach ($this->metapages as $i => $metapage) { | |
414 | + $this->metapages[$i]['linkstr'] = | |
415 | + htmlsc($this->my_basename($metapage['page'])); | |
416 | + } | |
417 | + break; | |
418 | + case 'title': | |
419 | + $contentsx = new PluginContentsx(); | |
420 | + foreach ($this->metapages as $i => $metapage) { | |
421 | + $title = $contentsx->get_title($metapage['page']); | |
422 | + $title = strip_htmltag(make_link($title)); | |
423 | + $this->metapages[$i]['linkstr'] = $title; | |
424 | + } | |
425 | + break; | |
426 | + case 'headline': | |
427 | + $contentsx = new PluginContentsx(); | |
428 | + foreach ($this->metapages as $i => $metapage) { | |
429 | + $metalines = $contentsx->get_metalines($metapage['page']); | |
430 | + $title = $metalines[0]['headline']; | |
431 | + $title = strip_htmltag(make_link($title)); | |
432 | + $this->metapages[$i]['linkstr'] = $title; | |
433 | + } | |
434 | + break; | |
435 | + } | |
436 | + // default: relative | |
437 | + if ($this->options['hierarchy'][1] === true) { | |
438 | + foreach ($this->metapages as $i => $metapage) { | |
439 | + if (! isset($metapage['linkstr']) || $metapage['linkstr'] === '') { | |
440 | + $this->metapages[$i]['linkstr'] = | |
441 | + htmlsc($this->my_basename($metapage['page'])); | |
442 | + } | |
443 | + } | |
444 | + } else { | |
445 | + foreach ($this->metapages as $i => $metapage) { | |
446 | + if (! isset($metapage['linkstr']) || $metapage['linkstr'] === '') { | |
447 | + $this->metapages[$i]['linkstr'] = | |
448 | + htmlsc($metapage['relative']); | |
449 | + } | |
450 | + } | |
451 | + } | |
452 | + } | |
453 | + | |
454 | + function popular_metapages() | |
455 | + { | |
456 | + if ($this->options['popular'][1] === false) { | |
457 | + return; | |
458 | + } | |
459 | + | |
460 | + if (function_exists('set_timezone')) { // plus | |
461 | + list($zone, $zonetime) = set_timezone(DEFAULT_LANG); | |
462 | + $localtime = UTIME + $zonetime; | |
463 | + $today = gmdate('Y/m/d', $localtime); | |
464 | + $yesterday = gmdate('Y/m/d',gmmktime(0,0,0, gmdate('m',$localtime), gmdate('d',$localtime)-1, gmdate('Y',$localtime))); | |
465 | + } else { | |
466 | + $localtime = ZONETIME + UTIME; | |
467 | + $today = get_date('Y/m/d'); // == get_date('Y/m/d', UTIME) == date('Y/m/d, ZONETIME + UTIME); | |
468 | + $yesterday = get_date('Y/m/d', mktime(0,0,0, date('m',$localtime), date('d',$localtime)-1, date('Y',$localtime))); | |
469 | + } | |
470 | + | |
471 | + foreach ($this->metapages as $i => $metapage) { | |
472 | + $page = $metapage['page']; | |
473 | + $lines = file(COUNTER_DIR . encode($page) . '.count'); | |
474 | + $lines = array_map('rtrim', $lines); | |
475 | + list($total_count, $date, $today_count, $yesterday_count, $ip) = $lines; | |
476 | + | |
477 | + $popular = 0; | |
478 | + switch ($this->options['popular'][1]) { | |
479 | + case 'total': | |
480 | + $popular = $total_count; | |
481 | + break; | |
482 | + case 'today': | |
483 | + if ($date == $today) { | |
484 | + $popular = $today_count; | |
485 | + } | |
486 | + break; | |
487 | + case 'yesterday': | |
488 | + if ($date == $today) { | |
489 | + $popular = $yesterday_count; | |
490 | + } elseif ($date == $yesterday) { | |
491 | + $popular = $today_count; | |
492 | + } | |
493 | + break; | |
494 | + case 'recent': | |
495 | + if ($date == $today) { | |
496 | + $popular = $today_count + $yesterday_count; | |
497 | + } elseif ($date == $yesterday) { | |
498 | + $popular = $today_count; | |
499 | + } | |
500 | + break; | |
501 | + } | |
502 | + if ($popular > 0) { | |
503 | + $this->metapages[$i]['popular'] = $popular; | |
504 | + } else { | |
505 | + unset($this->metapages[$i]); // like popular plugin | |
506 | + } | |
507 | + } | |
508 | + } | |
509 | + | |
510 | + function timestamp_metapages() | |
511 | + { | |
512 | + if (! $this->options['date'][1] && ! $this->options['new'][1] && | |
513 | + $this->options['sort'][1] !== 'date') { | |
514 | + return; | |
515 | + } | |
516 | + foreach ($this->metapages as $i => $metapage) { | |
517 | + $page = $metapage['page']; | |
518 | + $timestamp = $this->get_filetime($page); | |
519 | + $this->metapages[$i]['timestamp'] = $timestamp; | |
520 | + } | |
521 | + } | |
522 | + | |
523 | + function date_metapages() | |
524 | + { | |
525 | + if (! $this->options['date'][1] && ! $this->options['new'][1]) { | |
526 | + return; | |
527 | + } | |
528 | + foreach ($this->metapages as $i => $metapage) { | |
529 | + $timestamp = $metapage['timestamp']; | |
530 | + $date = format_date($timestamp); | |
531 | + $this->metapages[$i]['date'] = $date; | |
532 | + } | |
533 | + } | |
534 | + | |
535 | + function info_date_metapages() | |
536 | + { | |
537 | + if (! $this->options['date'][1]) { | |
538 | + return; | |
539 | + } | |
540 | + foreach ($this->metapages as $i => $metapage) { | |
541 | + $this->metapages[$i]['info_date'] = | |
542 | + '<span class="comment_date">' . $metapage['date'] . '</span>'; | |
543 | + } | |
544 | + } | |
545 | + | |
546 | + function info_new_metapages() | |
547 | + { | |
548 | + if (! $this->options['new'][1]) { | |
549 | + return; | |
550 | + } | |
551 | + foreach ($this->metapages as $i => $metapage) { | |
552 | + $date = $this->metapages[$i]['date']; | |
553 | + // burdonsome, but to use configuration of new plugin | |
554 | + $new = do_plugin_inline($this->conf['plugin_new'], 'nodate', $date); | |
555 | + $this->metapages[$i]['info_new'] = $new; | |
556 | + } | |
557 | + } | |
558 | + | |
559 | + function info_metapages() | |
560 | + { | |
561 | + if (empty($this->options['info'][1])) { | |
562 | + return; | |
563 | + } | |
564 | + | |
565 | + $this->date_metapages(); | |
566 | + $this->info_date_metapages(); | |
567 | + $this->info_new_metapages(); | |
568 | + | |
569 | + //foreach ($this->options['info'][2] as $key) { | |
570 | + // call_user_func(array($this, $key . '_metapages')); | |
571 | + //} | |
572 | + foreach ($this->metapages as $i => $metapage) { | |
573 | + $info = ''; | |
574 | + foreach ($this->options['info'][1] as $key) { | |
575 | + $info .= ' ' . $metapage['info_' . $key]; | |
576 | + } | |
577 | + $this->metapages[$i]['info'] = $info; | |
578 | + } | |
579 | + } | |
580 | + | |
581 | + function tree_filter_metapages() | |
582 | + { | |
583 | + if ($this->options['tree'][1] === false) { | |
584 | + return; | |
585 | + } | |
586 | + $allpages = get_existpages(); | |
587 | + $this->sort_pages($allpages); | |
588 | + $current = current($allpages); | |
589 | + while ($next = next($allpages)) { | |
590 | + if (strpos($next, $current . '/') === FALSE) { | |
591 | + $leafs[$current] = TRUE; | |
592 | + } else { | |
593 | + $leafs[$current] = FALSE; | |
594 | + } | |
595 | + $current = $next; | |
596 | + } | |
597 | + $leafs[$current] = TRUE; | |
598 | + | |
599 | + switch ($this->options['tree'][1]) { | |
600 | + case 'dir': | |
601 | + foreach ($this->metapages as $i => $metapage) { | |
602 | + $page = $metapage['page']; | |
603 | + if ($leafs[$page]) { | |
604 | + unset($this->metapages[$i]); | |
605 | + } | |
606 | + } | |
607 | + break; | |
608 | + case 'leaf': | |
609 | + foreach ($this->metapages as $i => $metapage) { | |
610 | + $page = $metapage['page']; | |
611 | + if (! $leafs[$page]) { | |
612 | + unset($this->metapages[$i]); | |
613 | + } | |
614 | + } | |
615 | + break; | |
616 | + } | |
617 | + } | |
618 | + | |
619 | + function hierarchy_metapages() | |
620 | + { | |
621 | + if ($this->options['hierarchy'][1] === false) { | |
622 | + return; | |
623 | + } | |
624 | + $pdepth = substr_count($this->options['prefix'][1], '/') - 1; | |
625 | + $pdir = $this->my_dirname($this->options['prefix'][1]); | |
626 | + $pdirlen = ($pdir == '') ? 0 : strlen($pdir) + 1; // Add '/' | |
627 | + $num = count($this->metapages); | |
628 | + foreach ($this->metapages as $i => $metapage) { | |
629 | + $page = $metapage['page']; | |
630 | + $depth = $metapage['depth']; // depth_metapages() | |
631 | + if ($this->options['hierarchy'][1] === true) { | |
632 | + $this->metapages[$i]['listdepth'] = $depth; | |
633 | + } | |
634 | + while ($depth > 1) { | |
635 | + $page = $this->my_dirname($page); | |
636 | + if ($page == '') break; | |
637 | + $depth = substr_count($page, '/') - $pdepth; | |
638 | + | |
639 | + // if parent dir does not exist, complement | |
640 | + if (($j = $this->array_search_by($page, $this->metapages, 'page')) === false) { | |
641 | + if ($this->options['hierarchy'][1] === true) { | |
642 | + $relative = substr($page, $pdirlen); | |
643 | + $listdepth = $depth; | |
644 | + $this->metapages[] = array('reading'=>$page,'page'=>$page, 'relative'=>$relative, 'exist'=>false, 'depth'=>$depth, 'listdepth'=>$listdepth, 'timestamp'=>1, 'date'=>'', 'leaf'=>false); | |
645 | + // PHP: new item is ignored on this loop | |
646 | + } | |
647 | + } | |
648 | + } | |
649 | + } | |
650 | + if (count($this->metapages) != $num) { | |
651 | + $this->sort_metapages(); | |
652 | + } | |
653 | + } | |
654 | + | |
655 | + function sort_metapages($sort = 'natcasesort', $sortflag = SORT_REGULAR) | |
656 | + { | |
657 | + switch ($this->options['sort'][1]) { | |
658 | + case 'name': | |
659 | + $this->sort_by($this->metapages, 'page', 'sort', SORT_STRING); | |
660 | + break; | |
661 | + case 'date': | |
662 | + $this->sort_by($this->metapages, 'timestamp', 'rsort', SORT_NUMERIC); | |
663 | + break; | |
664 | + case 'reading': | |
665 | + $this->sort_by($this->metapages, 'reading', 'sort', SORT_STRING); | |
666 | + break; | |
667 | + case 'popular': | |
668 | + $this->sort_by($this->metapages, 'popular', 'rsort', SORT_NUMERIC); | |
669 | + break; | |
670 | + default: | |
671 | + $this->sort_by($this->metapages, $this->options['sort'][1], $sort, $sortflag); | |
672 | + break; | |
673 | + } | |
674 | + | |
675 | + if ($this->options['reverse'][1]) { | |
676 | + $this->metapages = array_reverse($this->metapages); | |
677 | + } | |
678 | + } | |
679 | + | |
680 | + function depth_metapages() | |
681 | + { | |
682 | + if ($this->options['depth'][1] === '' && $this->options['hierarchy'][1] === false && | |
683 | + $this->options['tree'][1] === false ) { | |
684 | + return; | |
685 | + } | |
686 | + $pdepth = substr_count($this->options['prefix'][1], '/') - 1; | |
687 | + | |
688 | + foreach ($this->metapages as $i => $metapage) { | |
689 | + $page = $metapage['page']; | |
690 | + $depth = substr_count($page, '/'); | |
691 | + $this->metapages[$i]['depth'] = $depth - $pdepth; | |
692 | + } | |
693 | + | |
694 | + return $this->max_by($this->metapages, 'depth'); | |
695 | + } | |
696 | + | |
697 | + function relative_metapages() | |
698 | + { | |
699 | + $pdir = $this->my_dirname($this->options['prefix'][1]); | |
700 | + if ($pdir == '') { | |
701 | + foreach ($this->metapages as $i => $metapage) { | |
702 | + $this->metapages[$i]['relative'] = $metapage['page']; | |
703 | + } | |
704 | + } else { | |
705 | + $pdirlen = strlen($pdir) + 1; // Add strlen('/') | |
706 | + foreach ($this->metapages as $i => $metapage) { | |
707 | + $this->metapages[$i]['relative'] = substr($metapage['page'], $pdirlen); | |
708 | + } | |
709 | + } | |
710 | + } | |
711 | + | |
712 | + function init_metapages() | |
713 | + { | |
714 | + if ($this->options['sort'][1] === 'reading') { | |
715 | + // Beta Function | |
716 | + if ($this->options['tag'][1] == '') { | |
717 | + $readings = $this->get_readings(); | |
718 | + } else { | |
719 | + $plugin_tag = new PluginTag(); | |
720 | + $pages = $plugin_tag->get_taggedpages($this->options['tag'][1]); | |
721 | + if ($pages === FALSE) { | |
722 | + $this->error = 'The tag token, ' . htmlsc($this->options['tag'][1]) . ', is invalid. '; | |
723 | + $this->error .= 'Perhaps, the tag does not exist. '; | |
724 | + } | |
725 | + $readings = $this->get_readings(); // why can not set pages... | |
726 | + foreach ($pages as $page) | |
727 | + $tagged_readings[$page] = ''; | |
728 | + // array_intersect_key >= PHP 5.1.0 RC1 | |
729 | + // $readings = array_intersect_key($readings, $tagged_readings); | |
730 | + foreach ($readings as $page => $reading) { | |
731 | + if (! isset($tagged_readings[$page])) unset($readings[$page]); | |
732 | + } | |
733 | + } | |
734 | + $metapages = array(); | |
735 | + foreach ($readings as $page => $reading) { | |
736 | + unset($readings[$page]); | |
737 | + $metapages[] = array('reading'=>$reading,'page'=>$page, 'exist'=>true, 'depth'=>1, 'listdepth'=>1, 'timestamp'=>1, 'date'=>''); | |
738 | + } | |
739 | + $this->metapages = $metapages; | |
740 | + } else { | |
741 | + if ($this->options['tag'][1] == '') { | |
742 | + $pages = get_existpages(); | |
743 | + } else { | |
744 | + $plugin_tag = new PluginTag(); | |
745 | + $pages = $plugin_tag->get_taggedpages($this->options['tag'][1]); | |
746 | + if ($pages === FALSE) { | |
747 | + $this->error = 'The tag token, ' . htmlsc($this->options['tag'][1]) . ', is invalid. '; | |
748 | + $this->error .= 'Perhaps, the tag does not exist. '; | |
749 | + } | |
750 | + } | |
751 | + $metapages = array(); | |
752 | + foreach ($pages as $i => $page) { | |
753 | + unset($pages[$i]); | |
754 | + $metapages[] = array('page'=>$page, 'exist'=>true, 'depth'=>1, 'listdepth'=>1, 'timestamp'=>1, 'date'=>''); | |
755 | + } | |
756 | + $this->metapages = $metapages; | |
757 | + } | |
758 | + } | |
759 | + | |
760 | + function depth_filter_metapages() | |
761 | + { | |
762 | + if ($this->options['depth'][1] === '') { | |
763 | + return; | |
764 | + } | |
765 | + $metapages = array(); | |
766 | + foreach ($this->metapages as $i => $metapage) { | |
767 | + unset($this->metapages[$i]); | |
768 | + if (in_array($metapage['depth'], $this->options['depth'][1])) { | |
769 | + $metapages[] = $metapage; | |
770 | + } | |
771 | + } | |
772 | + $this->metapages = $metapages; | |
773 | + } | |
774 | + | |
775 | + // sort before this ($this->sort_by) | |
776 | + function num_filter_metapages() | |
777 | + { | |
778 | + if ($this->options['num'][1] === '') { | |
779 | + return; | |
780 | + } | |
781 | + $metapages = array(); | |
782 | + // $num < count($this->metapages) is assured. | |
783 | + foreach ($this->options['num'][1] as $num) { | |
784 | + $metapages[] = $this->metapages[$num - 1]; | |
785 | + } | |
786 | + $this->metapages = $metapages; | |
787 | + } | |
788 | + | |
789 | + function newpage_filter_metapages() | |
790 | + { | |
791 | + if ($this->options['newpage'][1] === false) { | |
792 | + return; | |
793 | + } | |
794 | + if ($this->options['newpage'][1] == 'on') { | |
795 | + $new = true; | |
796 | + } elseif ($this->options['newpage'][1] == 'except') { | |
797 | + $new = false; | |
798 | + } | |
799 | + $metapages = array(); | |
800 | + foreach ($this->metapages as $i => $metapage) { | |
801 | + unset($this->metapages[$i]); | |
802 | + if ($new == $this->is_newpage($metapage['page'])) { | |
803 | + $metapages[] = $metapage; | |
804 | + } | |
805 | + } | |
806 | + $this->metapages = $metapages; | |
807 | + } | |
808 | + | |
809 | + function prefix_filter_metapages() | |
810 | + { | |
811 | + if ($this->options['prefix'][1] === "") { | |
812 | + return; | |
813 | + } | |
814 | + $metapages = array(); | |
815 | + foreach ($this->metapages as $i => $metapage) { | |
816 | + unset($this->metapages[$i]); | |
817 | + if (strpos($metapage['page'], $this->options['prefix'][1]) !== 0) { | |
818 | + continue; | |
819 | + } | |
820 | + $metapages[] = $metapage; | |
821 | + } | |
822 | + $this->metapages = $metapages; | |
823 | + } | |
824 | + | |
825 | + function nonlist_filter_metapages() | |
826 | + { | |
827 | + if ($this->options['non_list'][1] === false) { | |
828 | + return; | |
829 | + } | |
830 | + global $non_list; | |
831 | + $metapages = array(); | |
832 | + foreach ($this->metapages as $i => $metapage) { | |
833 | + unset($this->metapages[$i]); | |
834 | + if (preg_match("/$non_list/", $metapage['page'])) { | |
835 | + continue; | |
836 | + } | |
837 | + $metapages[] = $metapage; | |
838 | + } | |
839 | + $this->metapages = $metapages; | |
840 | + } | |
841 | + | |
842 | + function except_filter_metapages() | |
843 | + { | |
844 | + if ($this->options['except'][1] === "") { | |
845 | + return; | |
846 | + } | |
847 | + $metapages = array(); | |
848 | + foreach ($this->metapages as $i => $metapage) { | |
849 | + unset($this->metapages[$i]); | |
850 | + if (call_user_func($this->ereg, $this->options['except'][1], $metapage['relative'])) { | |
851 | + continue; | |
852 | + } | |
853 | + $metapages[] = $metapage; | |
854 | + } | |
855 | + $this->metapages = $metapages; | |
856 | + } | |
857 | + | |
858 | + function filter_filter_metapages() | |
859 | + { | |
860 | + if ($this->options['filter'][1] === "") { | |
861 | + return; | |
862 | + } | |
863 | + $metapages = array(); | |
864 | + foreach ($this->metapages as $i => $metapage) { | |
865 | + unset($this->metapages[$i]); | |
866 | + if (! call_user_func($this->ereg, $this->options['filter'][1], $metapage['relative'])) { | |
867 | + continue; | |
868 | + } | |
869 | + $metapages[] = $metapage; | |
870 | + } | |
871 | + $this->metapages = $metapages; | |
872 | + } | |
873 | + | |
874 | + // PukiWiki API Extension | |
875 | + | |
876 | + function sort_pages(&$pages) | |
877 | + { | |
878 | + $pages = str_replace('/', "\0", $pages); | |
879 | + sort($pages, SORT_STRING); | |
880 | + $pages = str_replace("\0", '/', $pages); | |
881 | + } | |
882 | + | |
883 | + // No PREG_SPLIT_NO_EMPTY version | |
884 | + // copy from lib/make_link.php#get_fullname | |
885 | + function get_fullname($name, $refer) | |
886 | + { | |
887 | + global $defaultpage; | |
888 | + | |
889 | + // 'Here' | |
890 | + if ($name == '' || $name == './') return $refer; | |
891 | + | |
892 | + // Absolute path | |
893 | + if ($name[0] == '/') { | |
894 | + $name = substr($name, 1); | |
895 | + return ($name == '') ? $defaultpage : $name; | |
896 | + } | |
897 | + | |
898 | + // Relative path from 'Here' | |
899 | + if (substr($name, 0, 2) == './') { | |
900 | + $arrn = preg_split('#/#', $name, -1); //, PREG_SPLIT_NO_EMPTY); | |
901 | + $arrn[0] = $refer; | |
902 | + return join('/', $arrn); | |
903 | + } | |
904 | + | |
905 | + // Relative path from dirname() | |
906 | + if (substr($name, 0, 3) == '../') { | |
907 | + $arrn = preg_split('#/#', $name, -1); //, PREG_SPLIT_NO_EMPTY); | |
908 | + $arrp = preg_split('#/#', $refer, -1, PREG_SPLIT_NO_EMPTY); | |
909 | + | |
910 | + while (! empty($arrn) && $arrn[0] == '..') { | |
911 | + array_shift($arrn); | |
912 | + array_pop($arrp); | |
913 | + } | |
914 | + $name = ! empty($arrp) ? join('/', array_merge($arrp, $arrn)) : | |
915 | + (! empty($arrn) ? $defaultpage . '/' . join('/', $arrn) : $defaultpage); | |
916 | + } | |
917 | + | |
918 | + return $name; | |
919 | + } | |
920 | + | |
921 | + function is_newpage($page) | |
922 | + { | |
923 | + // pukiwiki trick | |
924 | + return ! _backup_file_exists($page); | |
925 | + } | |
926 | + | |
927 | + function make_pagelink($page, $alias = '', $anchor = '', $refer = '', $isautolink = FALSE) | |
928 | + { | |
929 | + // no passage | |
930 | + global $show_passage; | |
931 | + $tmp = $show_passage; $show_passage = 0; | |
932 | + $link = make_pagelink($page, $alias, $anchor, $refer, $isautolink); | |
933 | + $show_passage = $tmp; | |
934 | + return $link; | |
935 | + } | |
936 | + | |
937 | + function get_readings() | |
938 | + { | |
939 | + return get_readings(); | |
940 | + } | |
941 | + | |
942 | + function get_filetime($page) | |
943 | + { | |
944 | + return get_filetime($page); | |
945 | + } | |
946 | + | |
947 | + // PHP Extension | |
948 | + | |
949 | + // dirname(Page/) => '.' , dirname(Page/a) => Page, dirname(Page) => '.' | |
950 | + // But, want Page/ => Page, Page/a => Page, Page => '' | |
951 | + function my_dirname($page) | |
952 | + { | |
953 | + if (($pos = strrpos($page, '/')) !== false) { | |
954 | + return substr($page, 0, $pos); | |
955 | + } else { | |
956 | + return ''; | |
957 | + } | |
958 | + } | |
959 | + | |
960 | + // basename(Page/) => Page , basename(Page/a) => a, basename(Page) => Page | |
961 | + // But, want Page/ => '', Page/a => a, Page => Page | |
962 | + function my_basename($page) | |
963 | + { | |
964 | + if (($pos = strrpos($page, '/')) !== false) { | |
965 | + return substr($page, $pos + 1); | |
966 | + } else { | |
967 | + return $page; | |
968 | + } | |
969 | + } | |
970 | + | |
971 | + function array_search_by($value, $array, $fieldname = null) | |
972 | + { | |
973 | + foreach ($array as $i => $val) { | |
974 | + if ($value == $val[$fieldname]) { | |
975 | + return $i; | |
976 | + } | |
977 | + } | |
978 | + return false; | |
979 | + } | |
980 | + | |
981 | + function in_array_by($value, $array, $fieldname = null) | |
982 | + { | |
983 | + //foreach ($array as $i => $befree) { | |
984 | + // $field_array[$i] = $array[$i][$fieldname]; | |
985 | + //} | |
986 | + //return in_array($value, $field_array); | |
987 | + | |
988 | + foreach ($array as $i => $val) { | |
989 | + if ($value == $val[$fieldname]) { | |
990 | + return true; | |
991 | + } | |
992 | + } | |
993 | + return false; | |
994 | + } | |
995 | + | |
996 | + # sort arrays by a specific field without maintaining key association | |
997 | + function sort_by(&$array, $fieldname, $sort, $sortflag) | |
998 | + { | |
999 | + $field_array = $inarray = array(); | |
1000 | + # store the keyvalues in a seperate array | |
1001 | + foreach ($array as $i => $befree) { | |
1002 | + $field_array[$i] = $array[$i][$fieldname]; | |
1003 | + } | |
1004 | + $field_array = str_replace('/', "\0", $field_array); // must not be here. Refactor me. | |
1005 | + switch ($sort) { | |
1006 | + case 'sort': | |
1007 | + # sort an array and maintain index association... | |
1008 | + asort($field_array, $sortflag); | |
1009 | + break; | |
1010 | + case 'rsort': | |
1011 | + # sort an array in reverse order and maintain index association | |
1012 | + arsort($field_array, $sortflag); | |
1013 | + break; | |
1014 | + case 'natsort': | |
1015 | + natsort($field_array); | |
1016 | + case 'natcasesort': | |
1017 | + # sort an array using a case insensitive "natural order" algorithm | |
1018 | + natcasesort($field_array); | |
1019 | + break; | |
1020 | + } | |
1021 | + # rebuild the array | |
1022 | + $outarray = array(); | |
1023 | + foreach ( $field_array as $i=> $befree) { | |
1024 | + $outarray[] = $array[$i]; | |
1025 | + unset($array[$i]); | |
1026 | + } | |
1027 | + $array = $outarray; | |
1028 | + } | |
1029 | + | |
1030 | + function max_by($array, $fieldname = null) | |
1031 | + { | |
1032 | + $field_array = $inarray = array(); | |
1033 | + # store the keyvalues in a seperate array | |
1034 | + foreach ($array as $i => $befree) { | |
1035 | + $field_array[$i] = $array[$i][$fieldname]; | |
1036 | + } | |
1037 | + return empty($field_array) ? 0 : max($field_array); | |
1038 | + } | |
1033 | 1039 | } |
1034 | 1040 | /////////////////////////////////////// |
1035 | 1041 | class PluginLsxOptionParser |
1036 | 1042 | { |
1037 | - var $error = ""; | |
1038 | - | |
1039 | - function parse_options($args, $options) | |
1040 | - { | |
1041 | - if (! $this->is_associative_array($args)) { | |
1042 | - $args = $this->associative_args($args, $options); | |
1043 | - if ($this->error != "") { return; } | |
1044 | - } | |
1045 | - | |
1046 | - foreach ($args as $key => $val) { | |
1047 | - if ( !isset($options[$key]) ) { continue; } // for action ($vars) | |
1048 | - $type = $options[$key][0]; | |
1049 | - $options[$key][4] = $val; | |
1050 | - | |
1051 | - switch ($type) { | |
1052 | - case 'bool': | |
1053 | - if($val == "" || $val == "on" || $val == "true") { | |
1054 | - $options[$key][1] = true; | |
1055 | - } elseif ($val == "off" || $val == "false" ) { | |
1056 | - $options[$key][1] = false; | |
1057 | - } else { | |
1058 | - $this->error = htmlspecialchars("$key=$val") . " is invalid. "; | |
1059 | - $this->error .= "The option, $key, accepts only a boolean value."; | |
1060 | - $this->error .= "#$this->plugin($key) or #$this->plugin($key=on) or #$this->plugin($key=true) for true. "; | |
1061 | - $this->error .= "#$this->plugin($key=off) or #$this->plugin($key=false) for false. "; | |
1062 | - return; | |
1063 | - } | |
1064 | - break; | |
1065 | - case 'string': | |
1066 | - $options[$key][1] = $val; | |
1067 | - break; | |
1068 | - case 'sanitize': | |
1069 | - $options[$key][1] = htmlspecialchars($val); | |
1070 | - break; | |
1071 | - case 'number': | |
1072 | - // Do not parse yet, parse after getting min and max. Here, just format checking | |
1073 | - if ($val === '') { | |
1074 | - $options[$key][1] = ''; | |
1075 | - break; | |
1076 | - } | |
1077 | - if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
1078 | - $val = substr($val, 1, strlen($val) - 2); | |
1079 | - } | |
1080 | - foreach (explode(",", $val) as $range) { | |
1081 | - if (preg_match('/^-?\d+$/', $range)) { | |
1082 | - } elseif (preg_match('/^-?\d*\:-?\d*$/', $range)) { | |
1083 | - } elseif (preg_match('/^-?\d+\+-?\d+$/', $range)) { | |
1084 | - } else { | |
1085 | - $this->error = htmlspecialchars("$key=$val") . " is invalid. "; | |
1086 | - $this->error .= "The option, " . $key . ", accepts number values such as 1, 1:3, 1+3, 1,2,4. "; | |
1087 | - $this->error .= "Specify options as \"$key=1,2,4\" or $key=(1,2,3) when you want to use \",\". "; | |
1088 | - $this->error .= "In more details, a style like (1:3,5:7,9:) is also possible. 9: means from 9 to the last. "; | |
1089 | - $this->error .= "Furtermore, - means backward. -1:-3 means 1,2,3 from the tail. "; | |
1090 | - return; | |
1091 | - } | |
1092 | - } | |
1093 | - $options[$key][1] = $val; | |
1094 | - break; | |
1095 | - case 'enum': | |
1096 | - if($val == "") { | |
1097 | - $options[$key][1] = $options[$key][2][0]; | |
1098 | - } elseif (in_array($val, $options[$key][2])) { | |
1099 | - $options[$key][1] = $val; | |
1100 | - } else { | |
1101 | - $this->error = htmlspecialchars("$key=$val") . " is invalid. "; | |
1102 | - $this->error .= "The option, " . $key . ", accepts values from one of (" . join(",", $options[$key][2]) . "). "; | |
1103 | - $this->error .= "By the way, #$this->plugin($key) equals to #$this->plugin($key=" . $options[$key][2][0] . "). "; | |
1104 | - return; | |
1105 | - } | |
1106 | - break; | |
1107 | - case 'array': | |
1108 | - if ($val == '') { | |
1109 | - $options[$key][1] = array(); | |
1110 | - break; | |
1111 | - } | |
1112 | - if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
1113 | - $val = substr($val, 1, strlen($val) - 2); | |
1114 | - } | |
1115 | - $val = explode(',', $val); | |
1116 | - //$val = $this->support_paren($val); | |
1117 | - $options[$key][1] = $val; | |
1118 | - break; | |
1119 | - case 'enumarray': | |
1120 | - if ($val == '') { | |
1121 | - $options[$key][1] = $options[$key][2]; | |
1122 | - break; | |
1123 | - } | |
1124 | - if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
1125 | - $val = substr($val, 1, strlen($val) - 2); | |
1126 | - } | |
1127 | - $val = explode(',', $val); | |
1128 | - //$val = $this->support_paren($val); | |
1129 | - $options[$key][1] = $val; | |
1130 | - foreach ($options[$key][1] as $each) { | |
1131 | - if (! in_array($each, $options[$key][2])) { | |
1132 | - $this->error = "$key=" . htmlspecialchars(join(",", $options[$key][1])) . " is invalid. "; | |
1133 | - $this->error .= "The option, " . $key . ", accepts sets of values from (" . join(",", $options[$key][2]) . "). "; | |
1134 | - $this->error .= "By the way, #$this->plugin($key) equals to #$this->plugin($key=(" . join(',',$options[$key][2]) . ")). "; | |
1135 | - return; | |
1136 | - } | |
1137 | - } | |
1138 | - break; | |
1139 | - default: | |
1140 | - } | |
1141 | - } | |
1142 | - | |
1143 | - return $options; | |
1144 | - } | |
1145 | - | |
1146 | - /** | |
1147 | - * Handle associative type option arguments as | |
1148 | - * ["prefix=Hoge/", "contents=(hoge", "hoge", "hoge)"] => ["prefix"=>"hoge/", "contents"=>"(hoge,hoge,hoge)"] | |
1149 | - * This has special supports for parentheses type arguments (number, array, enumarray) | |
1150 | - * Check option in along with. | |
1151 | - * @access public | |
1152 | - * @param Array $args Original option arguments | |
1153 | - * @return Array $result Converted associative option arguments | |
1154 | - */ | |
1155 | - function associative_args($args, $options) | |
1156 | - { | |
1157 | - $result = array(); | |
1158 | - while (($arg = current($args)) !== false) { | |
1159 | - list($key, $val) = array_pad(explode("=", $arg, 2), 2, ''); | |
1160 | - if (! isset($options[$key])) { | |
1161 | - $this->error = 'No such a option, ' . htmlspecialchars($key); | |
1162 | - return; | |
1163 | - } | |
1164 | - // paren support | |
1165 | - if ($val[0] === '(' && ($options[$key][0] == 'number' || | |
1166 | - $options[$key][0] == 'array' || $options[$key][0] == 'enumarray')) { | |
1167 | - while(true) { | |
1168 | - if ($val[strlen($val)-1] === ')' && substr_count($val, '(') == substr_count($val, ')')) { | |
1169 | - break; | |
1170 | - } | |
1171 | - $arg = next($args); | |
1172 | - if ($arg === false) { | |
1173 | - $this->error = "The # of open and close parentheses of one of your arguments did not match. "; | |
1174 | - return; | |
1175 | - } | |
1176 | - $val .= ',' . $arg; | |
1177 | - } | |
1178 | - } | |
1179 | - $result[$key] = $val; | |
1180 | - next($args); | |
1181 | - } | |
1182 | - return $result; | |
1183 | - } | |
1184 | - | |
1185 | - function parse_numoption($optionval, $min, $max) | |
1186 | - { | |
1187 | - if ($optionval === '') { | |
1188 | - return ''; | |
1189 | - } | |
1190 | - $result = array(); | |
1191 | - foreach (explode(",", $optionval) as $range) { | |
1192 | - if (preg_match('/^-?\d+$/', $range)) { | |
1193 | - $left = $right = $range; | |
1194 | - } elseif (preg_match('/^-?\d*\:-?\d*$/', $range)) { | |
1195 | - list($left, $right) = explode(":", $range, 2); | |
1196 | - if ($left == "" && $right == "") { | |
1197 | - $left = $min; | |
1198 | - $right = $max; | |
1199 | - } elseif($left == "") { | |
1200 | - $left = $min; | |
1201 | - } elseif ($right == "") { | |
1202 | - $right = $max; | |
1203 | - } | |
1204 | - } elseif (preg_match('/^-?\d+\+-?\d+$/', $range)) { | |
1205 | - list($left, $right) = explode("+", $range, 2); | |
1206 | - $right += $left; | |
1207 | - } | |
1208 | - if ($left < 0) { | |
1209 | - $left += $max + 1; | |
1210 | - } | |
1211 | - if ($right < 0) { | |
1212 | - $right += $max + 1; | |
1213 | - } | |
1214 | - $result = array_merge($result, range($left, $right)); | |
1215 | - // range allows like range(5, 3) also | |
1216 | - } | |
1217 | - // filter | |
1218 | - foreach (array_keys($result) as $i) { | |
1219 | - if ($result[$i] < $min || $result[$i] > $max) { | |
1220 | - unset($result[$i]); | |
1221 | - } | |
1222 | - } | |
1223 | - sort($result); | |
1224 | - $result = array_unique($result); | |
1225 | - | |
1226 | - return $result; | |
1227 | - } | |
1228 | - | |
1229 | - function option_debug_print($options) { | |
1230 | - foreach ($options as $key => $val) { | |
1231 | - $type = $val[0]; | |
1232 | - $val = $val[1]; | |
1233 | - if(is_array($val)) { | |
1234 | - $val=join(',', $val); | |
1235 | - } | |
1236 | - $body .= "$key=>($type, $val),"; | |
1237 | - } | |
1238 | - return $body; | |
1239 | - } | |
1240 | - | |
1241 | - // php extension | |
1242 | - function is_associative_array($array) | |
1243 | - { | |
1244 | - if (!is_array($array) || empty($array)) | |
1245 | - return false; | |
1246 | - $keys = array_keys($array); | |
1247 | - return array_keys($keys) !== $keys; | |
1248 | - // or | |
1249 | - //return is_array($array) && !is_numeric(implode(array_keys($array))); | |
1250 | - } | |
1043 | + var $error = ""; | |
1044 | + | |
1045 | + function parse_options($args, $options) | |
1046 | + { | |
1047 | + if (! $this->is_associative_array($args)) { | |
1048 | + $args = $this->associative_args($args, $options); | |
1049 | + if ($this->error != "") { return; } | |
1050 | + } | |
1051 | + | |
1052 | + foreach ($args as $key => $val) { | |
1053 | + if ( !isset($options[$key]) ) { continue; } // for action ($vars) | |
1054 | + $type = $options[$key][0]; | |
1055 | + $options[$key][4] = $val; | |
1056 | + | |
1057 | + switch ($type) { | |
1058 | + case 'bool': | |
1059 | + if($val == "" || $val == "on" || $val == "true") { | |
1060 | + $options[$key][1] = true; | |
1061 | + } elseif ($val == "off" || $val == "false" ) { | |
1062 | + $options[$key][1] = false; | |
1063 | + } else { | |
1064 | + $this->error = htmlsc("$key=$val") . " is invalid. "; | |
1065 | + $this->error .= "The option, $key, accepts only a boolean value."; | |
1066 | + $this->error .= "#$this->plugin($key) or #$this->plugin($key=on) or #$this->plugin($key=true) for true. "; | |
1067 | + $this->error .= "#$this->plugin($key=off) or #$this->plugin($key=false) for false. "; | |
1068 | + return; | |
1069 | + } | |
1070 | + break; | |
1071 | + case 'string': | |
1072 | + $options[$key][1] = $val; | |
1073 | + break; | |
1074 | + case 'sanitize': | |
1075 | + $options[$key][1] = htmlsc($val); | |
1076 | + break; | |
1077 | + case 'number': | |
1078 | + // Do not parse yet, parse after getting min and max. Here, just format checking | |
1079 | + if ($val === '') { | |
1080 | + $options[$key][1] = ''; | |
1081 | + break; | |
1082 | + } | |
1083 | + if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
1084 | + $val = substr($val, 1, strlen($val) - 2); | |
1085 | + } | |
1086 | + foreach (explode(",", $val) as $range) { | |
1087 | + if (preg_match('/^-?\d+$/', $range)) { | |
1088 | + } elseif (preg_match('/^-?\d*\:-?\d*$/', $range)) { | |
1089 | + } elseif (preg_match('/^-?\d+\+-?\d+$/', $range)) { | |
1090 | + } else { | |
1091 | + $this->error = htmlsc("$key=$val") . " is invalid. "; | |
1092 | + $this->error .= "The option, " . $key . ", accepts number values such as 1, 1:3, 1+3, 1,2,4. "; | |
1093 | + $this->error .= "Specify options as \"$key=1,2,4\" or $key=(1,2,3) when you want to use \",\". "; | |
1094 | + $this->error .= "In more details, a style like (1:3,5:7,9:) is also possible. 9: means from 9 to the last. "; | |
1095 | + $this->error .= "Furtermore, - means backward. -1:-3 means 1,2,3 from the tail. "; | |
1096 | + return; | |
1097 | + } | |
1098 | + } | |
1099 | + $options[$key][1] = $val; | |
1100 | + break; | |
1101 | + case 'enum': | |
1102 | + if($val == "") { | |
1103 | + $options[$key][1] = $options[$key][2][0]; | |
1104 | + } elseif (in_array($val, $options[$key][2])) { | |
1105 | + $options[$key][1] = $val; | |
1106 | + } else { | |
1107 | + $this->error = htmlsc("$key=$val") . " is invalid. "; | |
1108 | + $this->error .= "The option, " . $key . ", accepts values from one of (" . join(",", $options[$key][2]) . "). "; | |
1109 | + $this->error .= "By the way, #$this->plugin($key) equals to #$this->plugin($key=" . $options[$key][2][0] . "). "; | |
1110 | + return; | |
1111 | + } | |
1112 | + break; | |
1113 | + case 'array': | |
1114 | + if ($val == '') { | |
1115 | + $options[$key][1] = array(); | |
1116 | + break; | |
1117 | + } | |
1118 | + if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
1119 | + $val = substr($val, 1, strlen($val) - 2); | |
1120 | + } | |
1121 | + $val = explode(',', $val); | |
1122 | + //$val = $this->support_paren($val); | |
1123 | + $options[$key][1] = $val; | |
1124 | + break; | |
1125 | + case 'enumarray': | |
1126 | + if ($val == '') { | |
1127 | + $options[$key][1] = $options[$key][2]; | |
1128 | + break; | |
1129 | + } | |
1130 | + if ($val[0] === '(' && $val[strlen($val) - 1] == ')') { | |
1131 | + $val = substr($val, 1, strlen($val) - 2); | |
1132 | + } | |
1133 | + $val = explode(',', $val); | |
1134 | + //$val = $this->support_paren($val); | |
1135 | + $options[$key][1] = $val; | |
1136 | + foreach ($options[$key][1] as $each) { | |
1137 | + if (! in_array($each, $options[$key][2])) { | |
1138 | + $this->error = "$key=" . htmlsc(join(",", $options[$key][1])) . " is invalid. "; | |
1139 | + $this->error .= "The option, " . $key . ", accepts sets of values from (" . join(",", $options[$key][2]) . "). "; | |
1140 | + $this->error .= "By the way, #$this->plugin($key) equals to #$this->plugin($key=(" . join(',',$options[$key][2]) . ")). "; | |
1141 | + return; | |
1142 | + } | |
1143 | + } | |
1144 | + break; | |
1145 | + default: | |
1146 | + } | |
1147 | + } | |
1148 | + | |
1149 | + return $options; | |
1150 | + } | |
1151 | + | |
1152 | + /** | |
1153 | + * Handle associative type option arguments as | |
1154 | + * ["prefix=Hoge/", "contents=(hoge", "hoge", "hoge)"] => ["prefix"=>"hoge/", "contents"=>"(hoge,hoge,hoge)"] | |
1155 | + * This has special supports for parentheses type arguments (number, array, enumarray) | |
1156 | + * Check option in along with. | |
1157 | + * @access public | |
1158 | + * @param Array $args Original option arguments | |
1159 | + * @return Array $result Converted associative option arguments | |
1160 | + */ | |
1161 | + function associative_args($args, $options) | |
1162 | + { | |
1163 | + $result = array(); | |
1164 | + while (($arg = current($args)) !== false) { | |
1165 | + list($key, $val) = array_pad(explode("=", $arg, 2), 2, ''); | |
1166 | + if (! isset($options[$key])) { | |
1167 | + $this->error = 'No such a option, ' . htmlsc($key); | |
1168 | + return; | |
1169 | + } | |
1170 | + // paren support | |
1171 | + if ($val[0] === '(' && ($options[$key][0] == 'number' || | |
1172 | + $options[$key][0] == 'array' || $options[$key][0] == 'enumarray')) { | |
1173 | + while(true) { | |
1174 | + if ($val[strlen($val)-1] === ')' && substr_count($val, '(') == substr_count($val, ')')) { | |
1175 | + break; | |
1176 | + } | |
1177 | + $arg = next($args); | |
1178 | + if ($arg === false) { | |
1179 | + $this->error = "The # of open and close parentheses of one of your arguments did not match. "; | |
1180 | + return; | |
1181 | + } | |
1182 | + $val .= ',' . $arg; | |
1183 | + } | |
1184 | + } | |
1185 | + $result[$key] = $val; | |
1186 | + next($args); | |
1187 | + } | |
1188 | + return $result; | |
1189 | + } | |
1190 | + | |
1191 | + function parse_numoption($optionval, $min, $max) | |
1192 | + { | |
1193 | + if ($optionval === '') { | |
1194 | + return ''; | |
1195 | + } | |
1196 | + $result = array(); | |
1197 | + foreach (explode(",", $optionval) as $range) { | |
1198 | + if (preg_match('/^-?\d+$/', $range)) { | |
1199 | + $left = $right = $range; | |
1200 | + } elseif (preg_match('/^-?\d*\:-?\d*$/', $range)) { | |
1201 | + list($left, $right) = explode(":", $range, 2); | |
1202 | + if ($left == "" && $right == "") { | |
1203 | + $left = $min; | |
1204 | + $right = $max; | |
1205 | + } elseif($left == "") { | |
1206 | + $left = $min; | |
1207 | + } elseif ($right == "") { | |
1208 | + $right = $max; | |
1209 | + } | |
1210 | + } elseif (preg_match('/^-?\d+\+-?\d+$/', $range)) { | |
1211 | + list($left, $right) = explode("+", $range, 2); | |
1212 | + $right += $left; | |
1213 | + } | |
1214 | + if ($left < 0) { | |
1215 | + $left += $max + 1; | |
1216 | + } | |
1217 | + if ($right < 0) { | |
1218 | + $right += $max + 1; | |
1219 | + } | |
1220 | + $result = array_merge($result, range($left, $right)); | |
1221 | + // range allows like range(5, 3) also | |
1222 | + } | |
1223 | + // filter | |
1224 | + foreach (array_keys($result) as $i) { | |
1225 | + if ($result[$i] < $min || $result[$i] > $max) { | |
1226 | + unset($result[$i]); | |
1227 | + } | |
1228 | + } | |
1229 | + sort($result); | |
1230 | + $result = array_unique($result); | |
1231 | + | |
1232 | + return $result; | |
1233 | + } | |
1234 | + | |
1235 | + function option_debug_print($options) { | |
1236 | + foreach ($options as $key => $val) { | |
1237 | + $type = $val[0]; | |
1238 | + $val = $val[1]; | |
1239 | + if(is_array($val)) { | |
1240 | + $val=join(',', $val); | |
1241 | + } | |
1242 | + $body .= "$key=>($type, $val),"; | |
1243 | + } | |
1244 | + return $body; | |
1245 | + } | |
1246 | + | |
1247 | + // php extension | |
1248 | + function is_associative_array($array) | |
1249 | + { | |
1250 | + if (!is_array($array) || empty($array)) | |
1251 | + return false; | |
1252 | + $keys = array_keys($array); | |
1253 | + return array_keys($keys) !== $keys; | |
1254 | + // or | |
1255 | + //return is_array($array) && !is_numeric(implode(array_keys($array))); | |
1256 | + } | |
1251 | 1257 | } |
1252 | 1258 | |
1253 | 1259 | ////////////////////////////////// |
1254 | 1260 | function plugin_lsx_common_init() |
1255 | 1261 | { |
1256 | - global $plugin_lsx; | |
1257 | - if (class_exists('PluginLsxUnitTest')) { | |
1258 | - $plugin_lsx = new PluginLsxUnitTest(); | |
1259 | - } elseif (class_exists('PluginLsxUser')) { | |
1260 | - $plugin_lsx = new PluginLsxUser(); | |
1261 | - } else { | |
1262 | - $plugin_lsx = new PluginLsx(); | |
1263 | - } | |
1262 | + global $plugin_lsx; | |
1263 | + if (class_exists('PluginLsxUnitTest')) { | |
1264 | + $plugin_lsx = new PluginLsxUnitTest(); | |
1265 | + } elseif (class_exists('PluginLsxUser')) { | |
1266 | + $plugin_lsx = new PluginLsxUser(); | |
1267 | + } else { | |
1268 | + $plugin_lsx = new PluginLsx(); | |
1269 | + } | |
1264 | 1270 | } |
1265 | 1271 | |
1266 | 1272 | function plugin_lsx_convert() |
1267 | 1273 | { |
1268 | - global $plugin_lsx; plugin_lsx_common_init(); | |
1269 | - $args = func_get_args(); | |
1270 | - return call_user_func_array(array(&$plugin_lsx, 'convert'), $args); | |
1274 | + global $plugin_lsx; plugin_lsx_common_init(); | |
1275 | + $args = func_get_args(); | |
1276 | + return call_user_func_array(array(&$plugin_lsx, 'convert'), $args); | |
1271 | 1277 | } |
1272 | 1278 | |
1273 | 1279 | function plugin_lsx_action() |
1274 | 1280 | { |
1275 | - global $plugin_lsx; plugin_lsx_common_init(); | |
1276 | - return call_user_func(array(&$plugin_lsx, 'action')); | |
1281 | + global $plugin_lsx; plugin_lsx_common_init(); | |
1282 | + return call_user_func(array(&$plugin_lsx, 'action')); | |
1277 | 1283 | } |
1278 | 1284 | |
1279 | 1285 | ?> |