2 // PukiWiki - Yet another WikiWikiWeb clone
4 // Copyright 2002-2018 PukiWiki Development Team
5 // License: GPL v2 or (at your option) any later version
7 // Rename plugin: Rename page-name and related data
9 // Usage: http://path/to/index.php?plugin=rename[&refer=page_name]
11 define('PLUGIN_RENAME_LOGPAGE', ':RenameLog');
13 function plugin_rename_action()
17 if (PKWK_READONLY) die_message('PKWK_READONLY prohibits this');
19 $method = plugin_rename_getvar('method');
20 if ($method == 'regex') {
21 $src = plugin_rename_getvar('src');
22 if ($src == '') return plugin_rename_phase1();
24 $src_pattern = '/' . preg_quote($src, '/') . '/';
25 $arr0 = preg_grep($src_pattern, plugin_rename_get_existpages());
26 if (! is_array($arr0) || empty($arr0))
27 return plugin_rename_phase1('nomatch');
29 $dst = plugin_rename_getvar('dst');
30 $arr1 = preg_replace($src_pattern, $dst, $arr0);
31 foreach ($arr1 as $page)
32 if (! is_pagename($page))
33 return plugin_rename_phase1('notvalid');
35 return plugin_rename_regex($arr0, $arr1);
39 $page = plugin_rename_getvar('page');
40 $refer = plugin_rename_getvar('refer');
43 return plugin_rename_phase1();
45 } else if (! plugin_rename_is_page($refer)) {
46 return plugin_rename_phase1('notpage', $refer);
48 } else if ($refer === $whatsnew) {
49 return plugin_rename_phase1('norename', $refer);
51 } else if ($page == '' || $page === $refer) {
52 return plugin_rename_phase2();
54 } else if (! is_pagename($page)) {
55 return plugin_rename_phase2('notvalid');
58 return plugin_rename_refer();
64 function plugin_rename_getvar($key)
67 return isset($vars[$key]) ? $vars[$key] : '';
71 function plugin_rename_err($err, $page = '')
73 global $_rename_messages;
75 if ($err == '') return '';
77 $body = $_rename_messages['err_' . $err];
78 if (is_array($page)) {
80 foreach ($page as $_page) $tmp .= '<br />' . $_page;
83 if ($page != '') $body = sprintf($body, htmlsc($page));
85 $msg = sprintf($_rename_messages['err'], $body);
90 function plugin_rename_phase1($err = '', $page = '')
92 global $_rename_messages;
94 $script = get_base_uri();
95 $msg = plugin_rename_err($err, $page);
96 $refer = plugin_rename_getvar('refer');
97 $method = plugin_rename_getvar('method');
99 $radio_regex = $radio_page = '';
100 if ($method == 'regex') {
101 $radio_regex = ' checked="checked"';
103 $radio_page = ' checked="checked"';
105 $select_refer = plugin_rename_getselecttag($refer);
107 $s_src = htmlsc(plugin_rename_getvar('src'));
108 $s_dst = htmlsc(plugin_rename_getvar('dst'));
111 $ret['msg'] = $_rename_messages['msg_title'];
112 $ret['body'] = <<<EOD
114 <form action="$script" method="post">
116 <input type="hidden" name="plugin" value="rename" />
117 <input type="radio" name="method" id="_p_rename_page" value="page"$radio_page />
118 <label for="_p_rename_page">{$_rename_messages['msg_page']}:</label>$select_refer<br />
119 <input type="radio" name="method" id="_p_rename_regex" value="regex"$radio_regex />
120 <label for="_p_rename_regex">{$_rename_messages['msg_regex']}:</label><br />
121 <label for="_p_rename_from">From:</label><br />
122 <input type="text" name="src" id="_p_rename_from" size="80" value="$s_src" /><br />
123 <label for="_p_rename_to">To:</label><br />
124 <input type="text" name="dst" id="_p_rename_to" size="80" value="$s_dst" /><br />
125 <input type="submit" value="{$_rename_messages['btn_next']}" /><br />
133 function plugin_rename_phase2($err = '')
135 global $_rename_messages;
137 $script = get_base_uri();
138 $msg = plugin_rename_err($err);
139 $page = plugin_rename_getvar('page');
140 $refer = plugin_rename_getvar('refer');
141 if ($page == '') $page = $refer;
144 $related = plugin_rename_getrelated($refer);
145 if (! empty($related))
146 $msg_related = '<label for="_p_rename_related">' . $_rename_messages['msg_do_related'] . '</label>' .
147 '<input type="checkbox" name="related" id="_p_rename_related" value="1" checked="checked" /><br />';
149 $msg_rename = sprintf($_rename_messages['msg_rename'], make_pagelink($refer));
150 $s_page = htmlsc($page);
151 $s_refer = htmlsc($refer);
154 $ret['msg'] = $_rename_messages['msg_title'];
155 $ret['body'] = <<<EOD
157 <form action="$script" method="post">
159 <input type="hidden" name="plugin" value="rename" />
160 <input type="hidden" name="refer" value="$s_refer" />
162 <label for="_p_rename_newname">{$_rename_messages['msg_newname']}:</label>
163 <input type="text" name="page" id="_p_rename_newname" size="80" value="$s_page" /><br />
165 <input type="submit" value="{$_rename_messages['btn_next']}" /><br />
169 if (! empty($related)) {
170 $ret['body'] .= '<hr /><p>' . $_rename_messages['msg_related'] . '</p><ul>';
171 sort($related, SORT_STRING);
172 foreach ($related as $name)
173 $ret['body'] .= '<li>' . make_pagelink($name) . '</li>';
174 $ret['body'] .= '</ul>';
179 //ページ名と関連するページを列挙し、phase3へ
180 function plugin_rename_refer()
182 $page = plugin_rename_getvar('page');
183 $refer = plugin_rename_getvar('refer');
185 $pages[encode($refer)] = encode($page);
186 if (plugin_rename_getvar('related') != '') {
187 $from = strip_bracket($refer);
188 $to = strip_bracket($page);
189 foreach (plugin_rename_getrelated($refer) as $_page)
190 $pages[encode($_page)] = encode(str_replace($from, $to, $_page));
192 return plugin_rename_phase3($pages);
196 function plugin_rename_regex($arr_from, $arr_to)
199 foreach ($arr_to as $page)
203 if (! empty($exists)) {
204 return plugin_rename_phase1('already', $exists);
207 foreach ($arr_from as $refer)
208 $pages[encode($refer)] = encode(array_shift($arr_to));
209 return plugin_rename_phase3($pages);
213 function plugin_rename_phase3($pages)
215 global $_rename_messages;
217 $script = get_base_uri();
219 $files = plugin_rename_get_files($pages);
222 foreach ($files as $_page=>$arr)
223 foreach ($arr as $old=>$new)
224 if (file_exists($new))
225 $exists[$_page][$old] = $new;
227 $pass = plugin_rename_getvar('pass');
228 if ($pass != '' && pkwk_login($pass)) {
229 return plugin_rename_proceed($pages, $files, $exists);
230 } else if ($pass != '') {
231 $msg = plugin_rename_err('adminpass');
234 $method = plugin_rename_getvar('method');
235 if ($method == 'regex') {
236 $s_src = htmlsc(plugin_rename_getvar('src'));
237 $s_dst = htmlsc(plugin_rename_getvar('dst'));
238 $msg .= $_rename_messages['msg_regex'] . '<br />';
239 $input .= '<input type="hidden" name="method" value="regex" />';
240 $input .= '<input type="hidden" name="src" value="' . $s_src . '" />';
241 $input .= '<input type="hidden" name="dst" value="' . $s_dst . '" />';
243 $s_refer = htmlsc(plugin_rename_getvar('refer'));
244 $s_page = htmlsc(plugin_rename_getvar('page'));
245 $s_related = htmlsc(plugin_rename_getvar('related'));
246 $msg .= $_rename_messages['msg_page'] . '<br />';
247 $input .= '<input type="hidden" name="method" value="page" />';
248 $input .= '<input type="hidden" name="refer" value="' . $s_refer . '" />';
249 $input .= '<input type="hidden" name="page" value="' . $s_page . '" />';
250 $input .= '<input type="hidden" name="related" value="' . $s_related . '" />';
253 if (! empty($exists)) {
254 $msg .= $_rename_messages['err_already_below'] . '<ul>';
255 foreach ($exists as $page=>$arr) {
256 $msg .= '<li>' . make_pagelink(decode($page));
257 $msg .= $_rename_messages['msg_arrow'];
258 $msg .= htmlsc(decode($pages[$page]));
260 $msg .= '<ul>' . "\n";
261 foreach ($arr as $ofile=>$nfile)
262 $msg .= '<li>' . $ofile .
263 $_rename_messages['msg_arrow'] . $nfile . '</li>' . "\n";
266 $msg .= '</li>' . "\n";
268 $msg .= '</ul><hr />' . "\n";
270 $input .= '<input type="radio" name="exist" value="0" checked="checked" />' .
271 $_rename_messages['msg_exist_none'] . '<br />';
272 $input .= '<input type="radio" name="exist" value="1" />' .
273 $_rename_messages['msg_exist_overwrite'] . '<br />';
277 $ret['msg'] = $_rename_messages['msg_title'];
278 $ret['body'] = <<<EOD
280 <form action="$script" method="post">
282 <input type="hidden" name="plugin" value="rename" />
284 <label for="_p_rename_adminpass">{$_rename_messages['msg_adminpass']}</label>
285 <input type="password" name="pass" id="_p_rename_adminpass" value="" />
286 <input type="submit" value="{$_rename_messages['btn_submit']}" />
289 <p>{$_rename_messages['msg_confirm']}</p>
292 ksort($pages, SORT_STRING);
293 $ret['body'] .= '<ul>' . "\n";
294 foreach ($pages as $old=>$new)
295 $ret['body'] .= '<li>' . make_pagelink(decode($old)) .
296 $_rename_messages['msg_arrow'] .
297 htmlsc(decode($new)) . '</li>' . "\n";
298 $ret['body'] .= '</ul>' . "\n";
302 function plugin_rename_get_files($pages)
305 $dirs = array(BACKUP_DIR, DIFF_DIR, DATA_DIR);
306 if (exist_plugin_convert('attach')) $dirs[] = UPLOAD_DIR;
307 if (exist_plugin_convert('counter')) $dirs[] = COUNTER_DIR;
311 foreach ($dirs as $path) {
312 $dir = opendir($path);
313 if (! $dir) continue; // TODO: !== FALSE or die()?
314 while (($file = readdir($dir)) !== FALSE) {
315 if ($file == '.' || $file == '..') continue;
316 foreach ($pages as $from => $to) {
317 // TODO: preg_quote()?
318 $pattern = '/^' . str_replace('/', '\/', $from) . '([._].+)$/';
319 if (preg_match($pattern, $file, $matches)) {
320 $newfile = $to . $matches[1];
321 $files[$from][$path . $file] = $path . $newfile;
329 function plugin_rename_proceed($pages, $files, $exists)
331 global $now, $_rename_messages;
333 if (plugin_rename_getvar('exist') == '')
334 foreach ($exists as $key=>$arr)
338 foreach ($files as $page=>$arr) {
339 foreach ($arr as $old=>$new) {
340 if (isset($exists[$page][$old]) && $exists[$page][$old])
344 // linkデータベースを更新する BugTrack/327 arino
345 $new_page = $pages[$page];
346 links_update(decode($page));
347 links_update(decode($new_page));
350 $pages_decoded = array();
351 foreach ($pages as $old=>$new) {
352 $pages_decoded[decode($old)] = decode($new);
354 if (exist_plugin('counter')) {
355 plugin_counter_page_rename($pages_decoded);
358 $postdata = get_source(PLUGIN_RENAME_LOGPAGE);
359 $postdata[] = '*' . $now . "\n";
360 if (plugin_rename_getvar('method') == 'regex') {
361 $postdata[] = '-' . $_rename_messages['msg_regex'] . "\n";
362 $postdata[] = '--From:[[' . plugin_rename_getvar('src') . ']]' . "\n";
363 $postdata[] = '--To:[[' . plugin_rename_getvar('dst') . ']]' . "\n";
365 $postdata[] = '-' . $_rename_messages['msg_page'] . "\n";
366 $postdata[] = '--From:[[' . plugin_rename_getvar('refer') . ']]' . "\n";
367 $postdata[] = '--To:[[' . plugin_rename_getvar('page') . ']]' . "\n";
370 if (! empty($exists)) {
371 $postdata[] = "\n" . $_rename_messages['msg_result'] . "\n";
372 foreach ($exists as $page=>$arr) {
373 $postdata[] = '-' . decode($page) .
374 $_rename_messages['msg_arrow'] . decode($pages[$page]) . "\n";
375 foreach ($arr as $ofile=>$nfile)
376 $postdata[] = '--' . $ofile .
377 $_rename_messages['msg_arrow'] . $nfile . "\n";
379 $postdata[] = '----' . "\n";
382 foreach ($pages as $old=>$new)
383 $postdata[] = '-' . decode($old) .
384 $_rename_messages['msg_arrow'] . decode($new) . "\n";
389 page_write(PLUGIN_RENAME_LOGPAGE, join('', $postdata));
391 // Refresh RecentChanges / Delete cache/recent.dat
392 delete_recent_changes_cache();
395 $page = plugin_rename_getvar('page');
396 if ($page == '') $page = PLUGIN_RENAME_LOGPAGE;
399 header('Location: ' . get_page_uri($page, PKWK_URI_ROOT));
403 function plugin_rename_getrelated($page)
406 $pages = plugin_rename_get_existpages();
407 $pattern = '/(?:^|\/)' . preg_quote(strip_bracket($page), '/') . '(?:\/|$)/';
408 foreach ($pages as $name) {
409 if ($name === $page) continue;
410 if (preg_match($pattern, $name)) $related[] = $name;
415 function plugin_rename_getselecttag($page)
420 foreach (plugin_rename_get_existpages() as $_page) {
421 if ($_page === $whatsnew) continue;
423 $selected = ($_page === $page) ? ' selected' : '';
424 $s_page = htmlsc($_page);
425 $pages[$_page] = '<option value="' . $s_page . '"' . $selected . '>' .
426 $s_page . '</option>';
428 ksort($pages, SORT_STRING);
429 $list = join("\n" . ' ', $pages);
432 <select name="refer">
433 <option value=""></option>
441 * List exist pages and deleted pages
443 function plugin_rename_get_existpages() {
444 $list1 = array_values(get_existpages());
445 $list2 = array_values(get_existpages(DIFF_DIR, '.txt'));
446 $list3 = array_values(get_existpages(BACKUP_DIR, '.txt'));
447 $list4 = array_values(get_existpages(BACKUP_DIR, '.gz'));
448 $list5 = array_values(get_existpages(COUNTER_DIR, '.count'));
449 $wholelist = array_merge($list1, $list2, $list3, $list4, $list5);
450 $list = array_unique($wholelist);
455 * Return where the page exists or existed
457 function plugin_rename_is_page($page) {
458 $enc = encode($page);
459 if (is_page($page)) {
462 if (file_exists(DIFF_DIR . $enc . '.txt')) {
465 if (file_exists(BACKUP_DIR . $enc . '.txt')) {
468 if (file_exists(BACKUP_DIR . $enc . '.gz')) {
471 if (file_exists(COUNTER_DIR . $enc . '.count')) {
478 * Setup initial pages (:RenameLog)
480 function plugin_rename_setup_initial_pages() {
481 if (!is_page(PLUGIN_RENAME_LOGPAGE)) {
483 $body = "#freeze\n// :RenameLog (rename plugin)\n";
484 page_write(PLUGIN_RENAME_LOGPAGE, $body);