PageRenderTime 120ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/plugin/rename.inc.php

https://github.com/miya5n/pukiwiki
PHP | 434 lines | 347 code | 64 blank | 23 comment | 73 complexity | 9e239ce4522a0d57336b4a783546aac3 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. // PukiWiki - Yet another WikiWikiWeb clone
  3. // $Id: rename.inc.php,v 1.38 2011/01/25 15:01:01 henoheno Exp $
  4. // Copyright (C) 2002-2005, 2007 PukiWiki Developers Team
  5. // License: GPL v2 or (at your option) any later version
  6. //
  7. // Rename plugin: Rename page-name and related data
  8. //
  9. // Usage: http://path/to/index.php?plugin=rename[&refer=page_name]
  10. define('PLUGIN_RENAME_LOGPAGE', ':RenameLog');
  11. function plugin_rename_action()
  12. {
  13. if (PKWK_READONLY) die_message('PKWK_READONLY prohibits this');
  14. $method = plugin_rename_getvar('method');
  15. if ($method == 'regex') {
  16. $src = plugin_rename_getvar('src');
  17. if ($src == '') return plugin_rename_phase1();
  18. $src_pattern = '/' . preg_quote($src, '/') . '/';
  19. $arr0 = preg_grep($src_pattern, get_existpages());
  20. if (! is_array($arr0) || empty($arr0))
  21. return plugin_rename_phase1('nomatch');
  22. $dst = plugin_rename_getvar('dst');
  23. $arr1 = preg_replace($src_pattern, $dst, $arr0);
  24. foreach ($arr1 as $page) {
  25. if (! is_pagename($page)) {
  26. return plugin_rename_phase1('notvalid');
  27. }
  28. }
  29. // Phase one or three
  30. return plugin_rename_regex($arr0, $arr1);
  31. } else {
  32. // $method == 'page'
  33. $page = plugin_rename_getvar('page');
  34. $refer = plugin_rename_getvar('refer');
  35. if ($refer == '') {
  36. return plugin_rename_phase1();
  37. } else if (! is_page($refer)) {
  38. return plugin_rename_phase1('notpage', $refer);
  39. } else if (is_cantedit($refer)) {
  40. return plugin_rename_phase1('norename', $refer);
  41. } else if ($page == '' || $page === $refer) {
  42. return plugin_rename_phase2();
  43. } else if (! is_pagename($page)) {
  44. return plugin_rename_phase2('notvalid');
  45. } else {
  46. // Phase three
  47. return plugin_rename_refer();
  48. }
  49. }
  50. }
  51. function plugin_rename_getvar($key)
  52. {
  53. global $vars;
  54. return isset($vars[$key]) ? $vars[$key] : '';
  55. }
  56. // Generating error messages
  57. function plugin_rename_err($err, $page = '')
  58. {
  59. global $_rename_messages;
  60. if ($err == '') return '';
  61. $body = $_rename_messages['err_' . $err];
  62. if (is_array($page)) {
  63. $tmp = '';
  64. foreach ($page as $_page) $tmp .= '<br />' . $_page;
  65. $page = $tmp;
  66. }
  67. if ($page != '') $body = sprintf($body, htmlsc($page));
  68. $msg = sprintf($_rename_messages['err'], $body);
  69. return $msg;
  70. }
  71. // Phase one: Specifying page name or regex
  72. function plugin_rename_phase1($err = '', $page = '')
  73. {
  74. global $script, $_rename_messages;
  75. $msg = plugin_rename_err($err, $page);
  76. $refer = plugin_rename_getvar('refer');
  77. $method = plugin_rename_getvar('method');
  78. $radio_regex = $radio_page = '';
  79. if ($method == 'regex') {
  80. $radio_regex = ' checked="checked"';
  81. } else {
  82. $radio_page = ' checked="checked"';
  83. }
  84. $select_refer = plugin_rename_getselecttag($refer);
  85. $s_src = htmlsc(plugin_rename_getvar('src'));
  86. $s_dst = htmlsc(plugin_rename_getvar('dst'));
  87. $ret = array();
  88. $ret['msg'] = $_rename_messages['msg_title'];
  89. $ret['body'] = <<<EOD
  90. $msg
  91. <form action="$script" method="post">
  92. <div>
  93. <input type="hidden" name="plugin" value="rename" />
  94. <input type="radio" name="method" id="_p_rename_page" value="page"$radio_page />
  95. <label for="_p_rename_page">{$_rename_messages['msg_page']}:</label>$select_refer<br />
  96. <input type="radio" name="method" id="_p_rename_regex" value="regex"$radio_regex />
  97. <label for="_p_rename_regex">{$_rename_messages['msg_regex']}:</label><br />
  98. <label for="_p_rename_from">From:</label><br />
  99. <input type="text" name="src" id="_p_rename_from" size="80" value="$s_src" /><br />
  100. <label for="_p_rename_to">To:</label><br />
  101. <input type="text" name="dst" id="_p_rename_to" size="80" value="$s_dst" /><br />
  102. <input type="submit" value="{$_rename_messages['btn_next']}" /><br />
  103. </div>
  104. </form>
  105. EOD;
  106. return $ret;
  107. }
  108. // Phase two: Specify new page name
  109. function plugin_rename_phase2($err = '')
  110. {
  111. global $script, $_rename_messages;
  112. $msg = plugin_rename_err($err);
  113. $page = plugin_rename_getvar('page');
  114. $refer = plugin_rename_getvar('refer');
  115. if ($page == '') $page = $refer;
  116. $msg_related = '';
  117. $related = plugin_rename_getrelated($refer);
  118. if (! empty($related))
  119. $msg_related = '<label for="_p_rename_related">' . $_rename_messages['msg_do_related'] . '</label>' .
  120. '<input type="checkbox" name="related" id="_p_rename_related" value="1" checked="checked" /><br />';
  121. $msg_rename = sprintf($_rename_messages['msg_rename'], make_pagelink($refer));
  122. $s_page = htmlsc($page);
  123. $s_refer = htmlsc($refer);
  124. $ret = array();
  125. $ret['msg'] = $_rename_messages['msg_title'];
  126. $ret['body'] = <<<EOD
  127. $msg
  128. <form action="$script" method="post">
  129. <div>
  130. <input type="hidden" name="plugin" value="rename" />
  131. <input type="hidden" name="refer" value="$s_refer" />
  132. $msg_rename<br />
  133. <label for="_p_rename_newname">{$_rename_messages['msg_newname']}:</label>
  134. <input type="text" name="page" id="_p_rename_newname" size="80" value="$s_page" /><br />
  135. $msg_related
  136. <input type="submit" value="{$_rename_messages['btn_next']}" /><br />
  137. </div>
  138. </form>
  139. EOD;
  140. if (! empty($related)) {
  141. $ret['body'] .= '<hr /><p>' . $_rename_messages['msg_related'] . '</p><ul>';
  142. sort($related, SORT_STRING);
  143. foreach ($related as $name)
  144. $ret['body'] .= '<li>' . make_pagelink($name) . '</li>';
  145. $ret['body'] .= '</ul>';
  146. }
  147. return $ret;
  148. }
  149. // Before phase three:Listing specified page and related pages
  150. function plugin_rename_refer()
  151. {
  152. $page = plugin_rename_getvar('page');
  153. $refer = plugin_rename_getvar('refer');
  154. if (is_cantedit($page)) {
  155. return plugin_rename_phase2('notvalid');
  156. }
  157. $pages[encode($refer)] = encode($page);
  158. if (plugin_rename_getvar('related') != '') {
  159. $from = strip_bracket($refer);
  160. $to = strip_bracket($page);
  161. foreach (plugin_rename_getrelated($refer) as $_page) {
  162. $pages[encode($_page)] = encode(str_replace($from, $to, $_page));
  163. }
  164. }
  165. return plugin_rename_phase3($pages);
  166. }
  167. // Before phase one or three: Replace specified page and related pages' name
  168. function plugin_rename_regex($arr_from, $arr_to)
  169. {
  170. $exists = array();
  171. foreach ($arr_to as $page) {
  172. if (is_page($page)) {
  173. $exists[] = $page;
  174. }
  175. }
  176. if (! empty($exists)) return plugin_rename_phase1('already', $exists);
  177. $pages = array();
  178. foreach ($arr_from as $refer) {
  179. $pages[encode($refer)] = encode(array_shift($arr_to));
  180. }
  181. return plugin_rename_phase3($pages);
  182. }
  183. // Phase three: Confirmation
  184. function plugin_rename_phase3($pages)
  185. {
  186. global $script, $_rename_messages;
  187. $msg = $input = '';
  188. $files = plugin_rename_get_files($pages);
  189. $exists = array();
  190. foreach ($files as $_page=>$arr)
  191. foreach ($arr as $old=>$new)
  192. if (file_exists($new))
  193. $exists[$_page][$old] = $new;
  194. $pass = plugin_rename_getvar('pass');
  195. if ($pass != '' && pkwk_login($pass)) {
  196. return plugin_rename_phase4($pages, $files, $exists);
  197. } else if ($pass != '') {
  198. $msg = plugin_rename_err('adminpass');
  199. }
  200. $method = plugin_rename_getvar('method');
  201. if ($method == 'regex') {
  202. $s_src = htmlsc(plugin_rename_getvar('src'));
  203. $s_dst = htmlsc(plugin_rename_getvar('dst'));
  204. $msg .= $_rename_messages['msg_regex'] . '<br />';
  205. $input .= '<input type="hidden" name="method" value="regex" />' . "\n";
  206. $input .= '<input type="hidden" name="src" value="' . $s_src . '" />' . "\n";
  207. $input .= '<input type="hidden" name="dst" value="' . $s_dst . '" />' . "\n";
  208. } else {
  209. $s_refer = htmlsc(plugin_rename_getvar('refer'));
  210. $s_page = htmlsc(plugin_rename_getvar('page'));
  211. $s_related = htmlsc(plugin_rename_getvar('related'));
  212. $msg .= $_rename_messages['msg_page'] . '<br />';
  213. $input .= '<input type="hidden" name="method" value="page" />' . "\n";
  214. $input .= '<input type="hidden" name="refer" value="' . $s_refer . '" />' . "\n";
  215. $input .= '<input type="hidden" name="page" value="' . $s_page . '" />' . "\n";
  216. $input .= '<input type="hidden" name="related" value="' . $s_related . '" />' . "\n";
  217. }
  218. if (! empty($exists)) {
  219. $msg .= $_rename_messages['err_already_below'] . '<ul>';
  220. foreach ($exists as $page=>$arr) {
  221. $msg .= '<li>' . make_pagelink(decode($page));
  222. $msg .= $_rename_messages['msg_arrow'];
  223. $msg .= htmlsc(decode($pages[$page]));
  224. if (! empty($arr)) {
  225. $msg .= '<ul>' . "\n";
  226. foreach ($arr as $ofile=>$nfile)
  227. $msg .= '<li>' . $ofile .
  228. $_rename_messages['msg_arrow'] . $nfile . '</li>' . "\n";
  229. $msg .= '</ul>';
  230. }
  231. $msg .= '</li>' . "\n";
  232. }
  233. $msg .= '</ul><hr />' . "\n";
  234. $input .= '<input type="radio" name="exist" value="0" checked="checked" />' .
  235. $_rename_messages['msg_exist_none'] . '<br />' . "\n";
  236. $input .= '<input type="radio" name="exist" value="1" />' .
  237. $_rename_messages['msg_exist_overwrite'] . '<br />' . "\n";
  238. }
  239. $ret = array();
  240. $ret['msg'] = $_rename_messages['msg_title'];
  241. $ret['body'] = <<<EOD
  242. <p>$msg</p>
  243. <form action="$script" method="post">
  244. <div>
  245. <input type="hidden" name="plugin" value="rename" />
  246. $input
  247. <label for="_p_rename_adminpass">{$_rename_messages['msg_adminpass']}</label>
  248. <input type="password" name="pass" id="_p_rename_adminpass" value="" />
  249. <input type="submit" value="{$_rename_messages['btn_submit']}" />
  250. </div>
  251. </form>
  252. <p>{$_rename_messages['msg_confirm']}</p>
  253. EOD;
  254. ksort($pages, SORT_STRING);
  255. $ret['body'] .= '<ul>' . "\n";
  256. foreach ($pages as $old=>$new)
  257. $ret['body'] .= '<li>' . make_pagelink(decode($old)) .
  258. $_rename_messages['msg_arrow'] .
  259. htmlsc(decode($new)) . '</li>' . "\n";
  260. $ret['body'] .= '</ul>' . "\n";
  261. return $ret;
  262. }
  263. function plugin_rename_get_files($pages)
  264. {
  265. $files = array();
  266. $dirs = array(BACKUP_DIR, DIFF_DIR, DATA_DIR);
  267. if (exist_plugin_convert('attach')) $dirs[] = UPLOAD_DIR;
  268. if (exist_plugin_convert('counter')) $dirs[] = COUNTER_DIR;
  269. // and more ...
  270. $matches = array();
  271. foreach ($dirs as $path) {
  272. $dir = opendir($path);
  273. if (! $dir) continue; // TODO: !== FALSE or die()?
  274. while (($file = readdir($dir)) !== FALSE) {
  275. if ($file == '.' || $file == '..') continue;
  276. foreach ($pages as $from => $to) {
  277. // TODO: preg_quote()?
  278. $pattern = '/^' . str_replace('/', '\/', $from) . '([._].+)$/';
  279. if (preg_match($pattern, $file, $matches)) {
  280. $newfile = $to . $matches[1];
  281. $files[$from][$path . $file] = $path . $newfile;
  282. }
  283. }
  284. }
  285. }
  286. return $files;
  287. }
  288. // Phase four: Rename them, Log them, Redirect
  289. function plugin_rename_phase4($pages, $files, $exists)
  290. {
  291. global $now, $_rename_messages;
  292. if (plugin_rename_getvar('exist') == '')
  293. foreach ($exists as $key=>$arr)
  294. unset($files[$key]);
  295. set_time_limit(0);
  296. foreach ($files as $page=>$arr) {
  297. foreach ($arr as $old=>$new) {
  298. if (isset($exists[$page][$old]) && $exists[$page][$old])
  299. unlink($new);
  300. rename($old, $new);
  301. // Update link database (BugTrack/327) arino
  302. links_update($old);
  303. links_update($new);
  304. }
  305. }
  306. $postdata = get_source(PLUGIN_RENAME_LOGPAGE);
  307. $postdata[] = '*' . $now . "\n";
  308. if (plugin_rename_getvar('method') == 'regex') {
  309. $postdata[] = '-' . $_rename_messages['msg_regex'] . "\n";
  310. $postdata[] = '--From:[[' . plugin_rename_getvar('src') . ']]' . "\n";
  311. $postdata[] = '--To:[[' . plugin_rename_getvar('dst') . ']]' . "\n";
  312. } else {
  313. $postdata[] = '-' . $_rename_messages['msg_page'] . "\n";
  314. $postdata[] = '--From:[[' . plugin_rename_getvar('refer') . ']]' . "\n";
  315. $postdata[] = '--To:[[' . plugin_rename_getvar('page') . ']]' . "\n";
  316. }
  317. if (! empty($exists)) {
  318. $postdata[] = "\n" . $_rename_messages['msg_result'] . "\n";
  319. foreach ($exists as $page=>$arr) {
  320. $postdata[] = '-' . decode($page) .
  321. $_rename_messages['msg_arrow'] . decode($pages[$page]) . "\n";
  322. foreach ($arr as $ofile=>$nfile)
  323. $postdata[] = '--' . $ofile .
  324. $_rename_messages['msg_arrow'] . $nfile . "\n";
  325. }
  326. $postdata[] = '----' . "\n";
  327. }
  328. foreach ($pages as $old=>$new)
  329. $postdata[] = '-' . decode($old) .
  330. $_rename_messages['msg_arrow'] . decode($new) . "\n";
  331. // At this time, collision detection is not implemented
  332. page_write(PLUGIN_RENAME_LOGPAGE, join('', $postdata));
  333. $page = plugin_rename_getvar('page');
  334. if ($page == '') $page = PLUGIN_RENAME_LOGPAGE;
  335. // Redirection
  336. pkwk_headers_sent();
  337. header('Location: ' . get_script_uri() . '?' . rawurlencode($page));
  338. exit;
  339. }
  340. function plugin_rename_getrelated($page)
  341. {
  342. $related = array();
  343. $pages = get_existpages();
  344. $pattern = '/(?:^|\/)' . preg_quote(strip_bracket($page), '/') . '(?:\/|$)/';
  345. foreach ($pages as $name) {
  346. if ($name === $page) continue;
  347. if (preg_match($pattern, $name)) $related[] = $name;
  348. }
  349. return $related;
  350. }
  351. function plugin_rename_getselecttag($page)
  352. {
  353. $pages = array();
  354. foreach (get_existpages() as $_page) {
  355. if (is_cantedit($_page)) continue;
  356. $selected = ($_page === $page) ? ' selected' : '';
  357. $s_page = htmlsc($_page);
  358. $pages[$_page] = '<option value="' . $s_page . '"' . $selected . '>' .
  359. $s_page . '</option>';
  360. }
  361. ksort($pages, SORT_STRING);
  362. $list = join("\n" . ' ', $pages);
  363. return <<<EOD
  364. <select name="refer">
  365. <option value=""></option>
  366. $list
  367. </select>
  368. EOD;
  369. }
  370. ?>