TRUE, 'adminonly' => TRUE, ); static $default_options = array( 'pcmd' => '', 'pass' => '', 'filter' => '', 'except' => '', 'page' => '', 'search' => '', 'replace' => '', 'regexp' => TRUE, 'msearch' => '', 'mreplace' => '', 'notimestamp' => TRUE, ); $this->conf = & $conf; $this->default_options = & $default_options; // init $this->options = $this->default_options; $this->view = new PluginRegexpView($this); } function PluginRegexp() { $this->__construct(); } // static var $conf; var $default_values; // var var $error = ''; var $plugin = 'regexp'; var $options = array(); var $view; var $preg_replace; var $str_replace; function action() { set_time_limit(0); global $vars; foreach ($this->options as $key => $val) { $this->options[$key] = isset($vars[$key]) ? $vars[$key] : ''; } foreach ($this->options as $key => $val) { ${$key} = $val; } if ($pcmd == '') { $body = $this->view->showform(); } elseif ($search == '' && $msearch == '') { $body = $this->view->showform('No search.'); } elseif (! $this->view->login()) { // auth::check_role('role_adm_contents') $body = $this->view->showform('The password is wrong.'); } elseif ($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, $except, $page); foreach ($pages as $apage) { $replaced = $this->replace($apage, $search, $replace, $msearch, $mreplace, $regexp); if (is_null($replaced)) continue; $source = implode("", get_source($apage)); $diff = do_diff($source, $replaced); break; } $body = $this->view->preview($apage, $diff, $pages); return $body; } function do_replace_all() { foreach ($this->options as $key => $val) { ${$key} = $val; } $pages = $this->get_pages($filter, $except, $page); $replaced_pages = array(); foreach ($pages as $apage) { $replaced = $this->replace($apage, $search, $replace, $msearch, $mreplace, $regexp); if (is_null($replaced)) continue; $GLOBALS['cycle'] = 0; page_write($apage, $replaced, $notimestamp); $replaced_pages[] = $apage; } return $replaced_pages; } /** * Replace contents of a page * * @param string $page * @param string $search * @param string $replace * @param string $msearch multiline search * @param string $mreplace * @param boolean $regexp * @param string|null replaced contents. null if no replace occurred */ function replace($page, $search, $replace, $msearch, $mreplace, $regexp = TRUE) { if (! $this->is_editable($page)) return null; if ($regexp) { // mb_preg_replace usually does not exist. $replace_func = function_exists('mb_preg_replace') ? 'mb_preg_replace' : 'preg_replace'; if ($msearch != '') $msearch = '/' . str_replace('/', '\/', $msearch) . '/D'; // Memo: refer http://us.php.net/manual/ja/reference.pcre.pattern.modifiers.php for D. if ($search != '') $search = '/' . str_replace('/', '\/', $search) . '/'; } else { // mb_str_replace usually does not exist. $replace_func = function_exists('mb_str_replace') ? 'mb_str_replace' : 'str_replace'; } $lines = get_source($page); $source = implode("", $lines); if ($msearch != '') { $msearch = str_replace("\r", "\n", str_replace("\r\n", "\n", $msearch)); $replace = call_user_func($replace_func, $msearch, $mreplace, $source); } elseif ($search != '') { $replace_lines = array(); foreach ($lines as $line) { $line = rtrim($line, "\n"); $replace_lines[] = call_user_func($replace_func, $search, $replace, $line) . "\n"; } $replace = implode("", $replace_lines); } if ($source == $replace) return null; return $replace; } /** * Get filtered pages (not all existpages) * * @param string $filter regexp filter * @param string $except regexp except filter * @param string $onepage one exact page name */ function get_pages($filter = '', $except = '', $onepage = '') { if (! empty($onepage)) { return (array)$onepage; } if (method_exists('auth', 'get_existpages')) { // plus! $pages = auth::get_existpages(); } else { $pages = get_existpages(); } if (! empty($filter)) { $pregfilter = '/' . str_replace('/', '\/', $filter) . '/'; foreach($pages as $file => $page) { if (! preg_match($pregfilter, $page)) { unset($pages[$file]); } } } if (! empty($except)) { $pregexcept = '/' . str_replace('/', '\/', $except) . '/'; foreach($pages as $file => $page) { if (preg_match($pregexcept, $page)) { unset($pages[$file]); } } } return $pages; } /** * Check if the page is editable or not * * PukiWIki API Extension * * @param string $page * @return boolean */ function is_editable($page) { global $cantedit; if ($this->conf['ignore_freeze']) { $editable = ! in_array($page, $cantedit); } else { $editable = (! is_freeze($page) and ! in_array($page, $cantedit) ); } return $editable; } } ////////////////////////////////// class PluginRegexpView { // static var $msg; // var var $plugin = 'regexp'; var $options; var $conf; var $model; function __construct(&$model) { static $msg = array(); if (empty($msg)) { if (UI_LANG == "ja") { $msg = array( 'label' => array( 'pass' => _('管理者パスワード'), 'filter' => _('フィルターページ'), 'except' => _('除外ページ'), 'page' => _('ページ'), 'search' => _('検索'), 'replace' => _('置換'), 'msearch' => _('複数行検索'), 'mreplace' => _('複数行置換'), 'regexp' => _('正規表現'), 'notimestamp' => _('日時更新しない'), 'preview' => _('プレビュー'), ), 'text' => array( 'pass' => '', 'filter' => 'Filter pages to be processed by regular expression.
Ex) "^PukiWiki" => all pages starting with "PukiWiki."', 'except' => 'Except pages by regular expression.', 'page' => 'Specify a page to be processed. If this field is specified, "Filter Pages" is ignored.', 'search' => 'The string to be replaced. Apply replacing strings to each line separately. ', 'replace' => 'Ex) Search ^#ls\((.*)\)$ => Replace #lsx(\1).
Ex) Search &mimetex\(((?:[^;]|[^)];)*)\); => Replace $ \1 $. (with regexp check)', 'msearch' => 'The multi-line strings to be replaced. Apply replacing strings to whole contents at one time. Use this when you want to include returns or line feeds. If this field is specified, "Search" is ignored. ', 'mreplace' => '', 'regexp' => 'Use regular expression for searching.', 'notimestamp' => 'Do not change timestamps.', 'preview' => '', ), ); } else { $msg = array( 'label' => array( 'pass' => _('Admin Password'), 'filter' => _('Filter Pages'), 'except' => _('Except Pages'), 'page' => _('A Page'), 'search' => _('Search'), 'replace' => _('Replace'), 'msearch' => _('Multiline Search'), 'mreplace' => _('Multiline Replace'), '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."', 'except' => 'Except pages by regular expression.', 'page' => 'Specify a page to be processed. If this field is specified, "Filter Pages" is ignored.', 'search' => 'The string to be replaced. Apply replacing strings to each line separately. ', 'replace' => 'Ex) Search ^#ls\((.*)\)$ => Replace #lsx(\1).
Ex) Search &mimetex\(((?:[^;]|[^)];)*)\); => Replace $ \1 $. (with regexp check)', 'msearch' => 'The multi-line strings to be replaced. Apply replacing strings to whole contents at one time. Use this when you want to include returns or line feeds. If this field is specified, "Search" is ignored. ', 'mreplace' => '', 'regexp' => 'Use regular expression for searching.', 'notimestamp' => 'Do not change timestamps.', 'preview' => '', ), ); } } $this->msg = &$msg; $this->model = &$model; $this->options = &$model->options; $this->conf = &$model->conf; } function PluginRegexpView() { $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 $page) { $links[] = make_pagelink($page); } $msg = implode("
\n", $links); $body = '

The following pages were replaced.

' . $msg . '
'; return $body; } function preview($page, $diff, $pages) { global $script; if ($page == '' || $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, ' . htmlsc($page) . '
'; //$diff = '
' . htmlsc($diff) . '
'; $msg .= '
' . diff_style_to_css(htmlsc($diff)) . '
'; // Pukiwiki API $msg .= '
List of target pages (Result of Filter Pages)
'; $msg .= ''; $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; } /** * Show form * * @param string $msg * @return string html */ function showform($msg = "") { 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[] = '
' . $this->msg['label']['pass'] . '' . '' . $this->msg['text']['pass'] . '
' . $this->msg['label']['filter'] . '' . '' . $this->msg['text']['filter'] . '
' . $this->msg['label']['except'] . '' . '' . $this->msg['text']['except'] . '
' . $this->msg['label']['page'] . '' . '' . $this->msg['text']['page'] . '
' . '' . '' . $this->msg['text']['regexp'] . '
' . $this->msg['label']['search'] . '' . '' . $this->msg['text']['search'] . '
' . $this->msg['label']['replace'] . '' . '' . $this->msg['text']['replace'] . '
' . $this->msg['label']['msearch'] . '' . '' . $this->msg['text']['msearch'] . '
' . $this->msg['label']['mreplace'] . '' . '' . $this->msg['text']['mreplace'] . '
' . '' . '' . $this->msg['text']['notimestamp'] . '
'; $form[] = '
'; $form[] = ' '; $form[] = ' '; $form[] = ' '; $form[] = '
'; $form[] = '
'; $form = implode("\n", $form); if ($msg != '') { $msg = '

' . $msg . '

'; } return $msg . $form; } /** * 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 ''; } } } // php extension if (! function_exists('_')) { function &_($str) { return $str; } } ////////////////////////////////// function plugin_regexp_init() { global $plugin_regexp_name; if (class_exists('PluginRegexpUnitTest')) { $plugin_regexp_name = 'PluginRegexpUnitTest'; } elseif (class_exists('PluginRegexpUser')) { $plugin_regexp_name = 'PluginRegexpUser'; } else { $plugin_regexp_name = 'PluginRegexp'; } } function plugin_regexp_action() { global $plugin_regexp, $plugin_regexp_name; $plugin_regexp = new $plugin_regexp_name(); return call_user_func(array(&$plugin_regexp, 'action')); } if (! defined('INIT_DIR')) // if not Plus! if (file_exists(DATA_HOME . 'init/regexp.ini.php')) include_once(DATA_HOME . 'init/regexp.ini.php'); ?>