TRUE, 'adminonly' => TRUE, ); static $default_options = array( 'pcmd' => '', 'pass' => '', 'fromhere' => '', 'filter' => '', 'page' => '', 'plugintype' => 'block', 'oldplugin' => '', 'newplugin' => '', 'oldoption' => '', 'optionnum' => '', 'newoption' => '', 'regexp' => FALSE, 'notimestamp' => TRUE, ); $this->conf = $conf; $this->default_options = $default_options; // init $this->options = $this->default_options; $this->view = new PluginReplacepluginView($this); } function PluginReplaceplugin() { $this->__construct(); } // static var $conf; var $default_options; // var var $error = ''; var $plugin = 'replaceplugin'; var $options = array(); var $view; var $preg_replace; var $str_replace; function action() { if (ini_get('safe_mode') == '0') set_time_limit(0); $this->set_options(); return $this->body(); } function set_options() { global $vars; foreach ($this->options as $key => $val) { $this->options[$key] = isset($vars[$key]) ? $vars[$key] : ''; } } function body() { foreach ($this->options as $key => $val) { ${$key} = $val; } if ($pcmd == '') { $body = $this->view->showform(); } elseif ($oldplugin == '') { $body = $this->view->showform('No Plugin Name.'); } elseif ($newplugin == '' && $oldoption == '' && $optionnum == '') { $body = $this->view->showform('No New Plugin Name and No Target Option.'); } elseif (! $this->view->login()) { // auth::check_role('role_adm_contents') $body = $this->view->showform('The password is wrong.'); } else { if ($pcmd == 'preview') { $body = $this->do_preview(); } elseif ($pcmd == 'replace') { $pages = $this->do_replace_all(); $body = $this->view->result($pages); } } return array('msg'=>$this->plugin, 'body'=>$body); } function do_preview() { foreach ($this->options as $key => $val) { ${$key} = $val; } $diff = ''; $pages = $this->get_pages($filter, $page, $fromhere); foreach ($pages as $apage) { if (($replace = $this->replace($apage)) == '') { continue; } $source = implode("", get_source($apage)); $diff = do_diff($source, $replace); break; } $this->options['fromhere'] = $apage; $body = $this->view->preview($apage, $diff); return $body; } function do_replace_all() { foreach ($this->options as $key => $val) { ${$key} = $val; } global $cycle; $pages = $this->get_pages($filter, $page, $fromhere); $replaced_pages = array(); $found = 0; foreach ($pages as $apage) { if (($replace = $this->replace($apage)) == '') { continue; } $cycle = 0; set_time_limit(30); page_write($apage, $replace, $notimestamp); $replaced_pages[] = $apage; } return $replaced_pages; } ///////////////////////////// function replace($apage) { foreach ($this->options as $key => $val) { ${$key} = $val; } list($targets, $linenums) = $this->retrieve_plugins($apage); $replaces = $this->replace_plugin_names($oldplugin, $newplugin, $targets); $replaces = $this->replace_plugin_options($oldoption, $optionnum, $newoption, $regexp, $replaces); foreach ($targets as $i => $target) { if ($targets[$i] == $replaces[$i]) { unset($targets[$i]); unset($linenums[$i]); unset($replaces[$i]); } } if (empty($targets)) return ''; $lines = get_source($apage); foreach ($linenums as $i => $linenum) { $lines[$linenum] = str_replace($targets[$i], $replaces[$i], $lines[$linenum]); } $replace = implode("", $lines); /* $source = implode("", get_source($apage)); $replace = str_replace($targets, $replaces, $source); if ($source == $replace) return '';*/ return $replace; } function replace_plugin_options($oldoption, $optionnum, $newoption, $regexp, $plugin_strs) { if ($oldoption == '' && $optionnum == '') { return $plugin_strs; } $search = '/^([^(]+)(?:\(([^\r]*)\))(.*)$/'; foreach ($plugin_strs as $i => $line) { $matches = array(); if (preg_match($search, $line, $matches) == 0) { continue; } $head = &$matches[1]; $options = &$matches[2]; $tail = &$matches[3]; $options = csv_explode(',', $options); foreach ($options as $j => $option) { if (strpos($option, ',') !== FALSE) { $options[$j] = '"' . $option . '"'; // csv recover } } if ($oldoption != '') { foreach ($options as $j => $option) { if ($options[$j] == '') continue; if ($regexp) { $options[$j] = preg_replace('/' . str_replace('/', '\/', $oldoption) . '/', $newoption, $options[$j]); } else { $options[$j] = ($oldoption == $option) ? $newoption : $options[$j]; //$options[$j] = str_replace($oldoption, $newoption, $options[$j]); } if ($options[$j] == '') unset($options[$j]); } } else { $num = ($optionnum >= 0) ? $optionnum : count($options) + $optionnum; if ($regexp) { $options[$num] = preg_replace(preg_quote($options[$num], '/'), $newoption, $options[$num]); } else { $options[$num] = $newoption; } if ($options[$num] == '') unset($options[$num]); } // no csv implode. $options = implode(',', $options); $plugin_strs[$i] = "$head($options)$tail"; } return $plugin_strs; } function replace_plugin_names($oldplugin, $newplugin, $plugin_strs) { if ($newplugin == '') { return $plugin_strs; } $search = '/^([#&])' . preg_quote($oldplugin, '/') . '(.*)$/'; $replace = '${1}' . $newplugin . '${2}'; foreach ($plugin_strs as $i => $line) { $plugin_strs[$i] = preg_replace($search, $replace, $plugin_strs[$i]); } return $plugin_strs; } function retrieve_plugins($apage) { $oldplugin = $this->options['oldplugin']; $plugintype = $this->options['plugintype']; if (! $this->is_editable($apage)) { return array(); } $searches = array(); if ($plugintype == 'block') { // #listbox2(hoge,hoge) $searches[] = '/^(#' . preg_quote($oldplugin, '/') . '(?:\(([^\r]*)\))?(\{*))$/'; // |hoge|#listbox2(hoge,hoge)| $searches[] = '/(?:^\|(?:[^|]*\|)*)(#' . preg_quote($oldplugin, '/') . '(?:\(([^\r]*)\))?)(?:\|(?:[^|]*\|)*$)/'; } elseif ($plugintype == 'inline') { // hogehoge&listbox2(hoge,hoge);hoge $searches[] = '/(&' . preg_quote($oldplugin, '/') . '(?:\(([^;\r]*)\))?(\{([^;\r]*)\})?;)/'; } $lines = get_source($apage); $plugin_strs = array(); $linenums = array(); foreach ($lines as $linenum => $line) { foreach ($searches as $search) { $matches = array(); preg_match_all($search, $line, $matches); foreach ($matches[1] as $match) { $linenums[] = $linenum; $plugin_strs[] = $match; } } } return array($plugin_strs, $linenums); } function is_editable($apage) { global $cantedit; if ($this->conf['ignore_freeze']) { $editable = ! in_array($apage, $cantedit); } else { $editable = (! is_freeze($apage) and ! in_array($apage, $cantedit) ); } return $editable; } function get_pages($filter = '', $page = '', $fromhere = '') { if ($page != '') { return array($page); } $pages = get_existpages(); //auth::get_existpages(); if ($filter != '') { foreach($pages as $file => $apage) { if (! preg_match('/' . str_replace('/', '\/', $filter) . '/', $apage)) { unset($pages[$file]); } } } if ($fromhere != '') { foreach ($pages as $i => $apage) { if ($apage != $fromhere) { unset($pages[$i]); } else { break; } } } return $pages; } } ////////////////////////////////// class PluginReplacepluginView { var $plugin = 'replaceplugin'; var $options; var $conf; var $model; function __construct($model) { $this->options = &$model->options; $this->conf = &$model->conf; $this->model = &$model; } function PluginReplacepluginView() { $this->__construct(); } function login() { if ($this->conf['adminonly'] === FALSE) return TRUE; global $vars; $pass = isset($vars['pass']) ? $vars['pass'] : $this->getcookie('pass'); if (pkwk_login($pass)) { $this->setcookie('pass', $pass); return TRUE; } else { return FALSE; } } /** * Get cookie * * @param string $key * @return mixed */ function getcookie($key) { $key = 'plugin_regexp_' . $key; return isset($_COOKIE[$key]) ? unserialize($_COOKIE[$key]) : null; } /** * Set cookie * * @param string $key * @param mixed $val * @return void */ function setcookie($key, $val) { global $script; $parsed = parse_url($script); $path = $this->get_dirname($parsed['path']); $key = 'plugin_regexp_' . $key; setcookie($key, serialize($val), 0, $path); $_COOKIE[$key] = serialize($val); } function result($pages) { $links = array(); foreach ($pages as $apage) { $links[] = make_pagelink($apage); } $msg = implode("
\n", $links); $body = '

The following pages were replaced.

' . $msg . '
'; return $body; } function preview($apage, $diff) { global $script; if ($apage == '' || $diff == '') { return '
No page found or nothing changed.
'; } unset($this->options['pass']); unset($this->options['pcmd']); foreach ($this->options as $key => $val) { $this->setcookie($key, $val); } $msg = '
A preview, ' . make_pagelink($apage) . '
'; //$diff = '
' . htmlspecialchars($diff) . '
'; $msg .= '
' . diff_style_to_css(htmlsc($diff)) . '
'; // Pukiwiki API $form = array(); $form[] = '
'; $form[] = '
'; $form[] = ' Do you want to replace all pages? '; $form[] = ' '; $form[] = ' '; foreach ($this->options as $key => $val) { $form[] = ' '; } $form[] = '
'; $form[] = '
'; $form[] = '
'; $form = implode("\n", $form); return $msg . $form; } function showform($msg = "") { static $text = array(); if (empty($text)) { $text = array( 'label' => array( 'pass' => _('Admin Password'), 'filter' => _('Filter Pages'), 'except' => _('Except Pages'), 'page' => _('A Page'), 'oldplugin' => _('Old Plugin Name'), 'newplugin' => _('New Plugin Name'), 'plugintype' => _('Plugin Type'), 'oldoption' => _('Old Option Name'), 'optionnum' => _('Option Number'), 'newoption' => _('New Option Name'), 'regexp' => _('Regexp'), 'notimestamp' => _('notimestamp'), 'preview' => _('Preview'), ), 'text' => array( 'pass' => '', 'filter' => 'Filter pages to be processed by regular expression.
Ex) "^PukiWiki" => all pages starting with "PukiWiki." No filter(s) => all pages.', 'except' => 'Except pages by regular expression.', 'page' => 'Specify a page to be processed. If this field is specified, "Filter Pages" is ignored.', 'oldplugin' => 'Type the target plugin name', 'newplugin' => 'Type the new plugin name', 'plugintype' => 'Choose the plugin type which is used to replace the plugin name.', 'oldoption' => 'Type the target option name. You may use a regular expression. "Old Option Name" has a priority than "Option Number."', 'optionnum' => 'Choose the target option by number. Negative means from the end. Ex) #ls(a,link) => 0 is "a", 1 is "link"', 'newoption' => 'Type the new option name.', 'regexp' => 'Use regular expression to replace the option name.', 'notimestamp' => 'Do not change timestamps.', 'preview' => '', ), ); if (UI_LANG == "ja") { $text['label'] = array( 'pass' => _('管理者パスワード'), 'filter' => _('フィルターページ'), 'except' => _('除外ページ'), 'page' => _('ページ'), 'oldplugin' => _('古いプラグイン名'), 'newplugin' => _('新しいプラグイン名'), 'plugintype' => _('プラグインタイプ'), 'oldoption' => _('古いオプション名'), 'optionnum' => _('オプション引数'), 'newoption' => _('新しいオプション名'), 'regexp' => _('正規表現'), 'notimestamp' => _('日時更新しない'), 'preview' => _('プレビュー'), ); } } global $script; foreach ($this->options as $key => $val) { ${$key} = $this->getcookie($key); if (is_null(${$key})) ${$key} = $val; } $regexp = ($regexp == 'on') ? ' checked="checked"' : ''; $notimestamp = ($notimestamp == 'on') ? ' checked="checked"' : ''; $form = array(); $form[] = '
'; $form[] = '
'; if ($this->conf['adminonly']) { $form[] = ''; } $form[] = ''; $form[] = ''; $form[] = ''; $form[] = ''; $form[] = ''; $form[] = ''; $form[] = ''; $form[] = ''; $form[] = ''; $form[] = ''; $form[] = ''; $form[] = ''; $form[] = '
' . $text['label']['pass'] . '' . '' . $text['text']['pass'] . '
' . $text['label']['filter'] . '' . '' . $text['text']['filter'] . '
' . $text['label']['except'] . '' . '' . $text['text']['except'] . '
' . $text['label']['page'] . '' . '' . $text['text']['page'] . '
' . $text['label']['plugintype'] . '' . '' . '' . '' . $text['text']['plugintype'] . '
' . $text['label']['oldplugin'] . '' . '' . $text['text']['oldplugin'] . '
' . $text['label']['newplugin'] . '' . '' . $text['text']['newplugin'] . '
' . $text['label']['oldoption'] . '' . '' . $text['text']['oldoption'] . '
' . $text['label']['optionnum'] . '' . '' . '' . '' . '' . '' . '' . '' . '' . '' . '' . '' . $text['text']['optionnum'] . '
' . $text['label']['newoption'] . '' . '' . $text['text']['newoption'] . '
' . '' . '' . $text['text']['regexp'] . '
'; $form[] = '
'; $form[] = ' '; $form[] = ' '; $form[] = ' ' . ' ' . $text['text']['notimestamp'] . ' '; $form[] = ' '; $form[] = '
'; $form[] = '
'; $form = implode("\n", $form); $tips = array(); $tips[] = '

Example

'; $tips[] = '

Target: #ls2(PukiWiki,hoge=Hoge,title)

'; $tips[] = '
'; $tips[] = ''; $tips[] = ''; $tips[] = ''; $tips[] = ''; $tips[] = ''; $tips[] = '
Old Plugin NameNew Plugin NameOld Option NameOption NumberNew Option NameRegexpResult
ls2lsx#lsx(PukiWiki,hoge=Hoge,title)
ls2lsxtitlecontentsoff#lsx(PukiWiki,hoge=Hoge,contents)
ls2^hoge=(.*)$fuga=\1on#ls2(PukiWiki,fuga=Hoge,title)
ls2lsx0prefix=\0on#lsx(prefix=PukiWiki,hoge=Hoge,title)
'; $tips = implode("\n", $tips); if ($msg != '') { $msg = '

' . $msg . '

'; } return $msg . $form . $tips; } /** * Get the dirname of a path * * PHP API Extension * * PHP's dirname works as * * 'Page/' => '.', 'Page/a' => 'Page', 'Page' => '.' * * This function works as * * 'Page/' => 'Page', 'Page/a' => 'Page', 'Page' => '' * * * @access public * @static * @param string $path * @return string dirname * @version $Id: v 1.0 2008-06-05 11:14:46 sonots $ */ function get_dirname($path) { if (($pos = strrpos($path, '/')) !== false) { return substr($path, 0, $pos); } else { return ''; } } } ////////////////////////////////// function plugin_replaceplugin_common_init() { global $plugin_replaceplugin; if (class_exists('PluginReplacepluginUnitTest')) { $plugin_replaceplugin = new PluginReplacepluginUnitTest(); } elseif (class_exists('PluginReplacepluginUser')) { $plugin_replaceplugin = new PluginReplacepluginUser(); } else { $plugin_replaceplugin = new PluginReplaceplugin(); } } function plugin_replaceplugin_action() { global $plugin_replaceplugin; plugin_replaceplugin_common_init(); return call_user_func(array(&$plugin_replaceplugin, 'action')); } ?>