/** * make_backup * バックアップを作成する * * @access public * @param String $page ページ名 * @param Boolean $delete TRUE:バックアップを削除する * * @return Void */ function make_backup($page, $delete = FALSE) { global $cycle, $maxage; global $do_backup, $del_backup; // if (PKWK_READONLY || ! $do_backup) return; if (auth::check_role('readonly') || !$do_backup) { return; } if ($del_backup && $delete) { _backup_delete($page); return; } if (!is_page($page)) { return; } $lastmod = _backup_get_filetime($page); if ($lastmod == 0 || UTIME - $lastmod > 60 * 60 * $cycle) { $backups = get_backup($page); $count = count($backups) + 1; // 直後に1件追加するので、(最大件数 - 1)を超える要素を捨てる if ($count > $maxage) { array_splice($backups, 0, $count - $maxage); } $strout = ''; foreach ($backups as $age => $data) { // BugTrack/685 by UPK //$strout .= PKWK_SPLITTER . ' ' . $data['time'] . "\n"; // Splitter format $strout .= PKWK_SPLITTER . ' ' . $data['time'] . ' ' . $data['real'] . "\n"; // Splitter format $strout .= join('', $data['data']); unset($backups[$age]); } $strout = preg_replace("/([^\n])\n*\$/", "\$1\n", $strout); // Escape 'lines equal to PKWK_SPLITTER', by inserting a space $body = preg_replace('/^(' . preg_quote(PKWK_SPLITTER) . "\\s\\d+(\\s(\\d+)|))\$/", '$1 ', get_source($page)); // BugTrack/685 by UPK // $body = PKWK_SPLITTER . ' ' . get_filetime($page) . "\n" . join('', $body); $body = PKWK_SPLITTER . ' ' . get_filetime($page) . ' ' . UTIME . "\n" . join('', $body); $body = preg_replace("/\n*\$/", "\n", $body); $fp = _backup_fopen($page, 'wb') or die_message('Cannot open ' . htmlspecialchars(_backup_get_filename($page)) . '<br />Maybe permission is not writable or filename is too long'); _backup_fputs($fp, $strout); _backup_fputs($fp, $body); _backup_fclose($fp); } }
function plugin_revert_action() { global $vars, $post, $_revert_messages, $_msg_preview; $pass = isset($post['pass']) ? $post['pass'] : FALSE; $page = isset($vars['page']) ? $vars['page'] : ''; $age = isset($vars['age']) ? $vars['age'] : ''; if ($page === '') { return; } if (PLUGIN_REVERT_USE_ADMIN_ONLY && $pass === FALSE) { return array('msg' => 'revert plugin', 'body' => plugin_revert_auth($page, $age)); } if (PLUGIN_REVERT_USE_ADMIN_ONLY && !pkwk_login($pass)) { return array('msg' => 'revert plugin', 'body' => $_revert_messages['invalidpass']); } if ($age) { // get_backup($page, $age)の形式だと最後の世代だけ取得できず全世代取得になる $backups = get_backup($page); if (empty($backups[$age]['data'])) { return array('msg' => 'revert plugin', 'body' => 'Backup file not found.'); } $revertdata = $backups[$age]['data']; unset($backups); } else { $filename = DIFF_DIR . encode($page) . '.txt'; if (!file_exists($filename)) { return array('msg' => 'revert plugin', 'body' => 'Diff file not found.'); } $revertdata = array(); foreach (file($filename) as $line) { if ($line[0] !== '+') { $revertdata[] = substr($line, 1); } } } $vars['preview'] = $post['preview'] = 1; $vars['msg'] = $post['msg'] = join('', $revertdata); $vars['digest'] = $post['digest'] = is_page($page) ? md5(join('', get_source($page))) : FALSE; $_msg_preview = $_revert_messages['caution'] . "<br />\n" . $_msg_preview; return do_plugin_action('edit'); }
/** * Get page created time * * PukiWiki API Extension * * @access public * @static * @param string $page pagename * @return int timestamp * @see get_filetime($page) * @version $Id: v 1.0 2008-06-05 11:14:46 sonots $ */ function get_filecreatetime($page) { if (_backup_file_exists($page)) { // PukiWiki Trick // This is not a created time exactly, but the closest time $backup = get_backup($page, 1); // 1st age return $backup['time']; } else { return get_filetime($page); } }
function plugin_backup_get_list($page) { global $layout_pages; //レイアウト部品の場合、スタイルを変更する $is_layout = FALSE; if (isset($layout_pages) && isset($layout_pages[$page])) { $is_layout = TRUE; } $qm = get_qm(); $script = get_script_uri(); $r_page = rawurlencode($page); $s_page = htmlspecialchars($page); //バックアップ一覧へのリンクは、 //レイアウト部品の場合、編集リンクを表示する $backuplist_link = $is_layout ? '<a href="' . h($script) . '?cmd=edit&page=' . $r_page . '">' . h($layout_pages[$page]) . 'を編集する</a>' : '<a href="' . h($script) . '?cmd=backup">' . $qm->m['plg_backup']['backuplist'] . '</a>'; $retval = array(); $retval[0] = ' <ul> <li> ' . $backuplist_link . ' <ul> '; $retval[1] = "\n"; $retval[2] = <<<EOD </ul> </li> </ul> EOD; $backups = _backup_file_exists($page) ? get_backup($page) : array(); if (empty($backups)) { $pagelink = $is_layout ? h($layout_pages[$page]) : make_pagelink($page); $msg = str_replace('$1', $pagelink, $qm->m['plg_backup']['nobackup']); $retval[1] .= ' <li>' . $msg . '</li>' . "\n"; return join('', $retval); } if (!PKWK_READONLY) { $retval[1] .= ' <li><a href="' . $script . '?cmd=backup&action=delete&page=' . $r_page . '">'; $retval[1] .= str_replace('$1', $is_layout ? h($layout_pages[$page]) : $s_page, $qm->m['plg_backup']['title_backup_delete']); $retval[1] .= '</a></li>' . "\n"; } $href = $script . '?cmd=backup&page=' . $r_page . '&age='; $_anchor_from = $_anchor_to = ''; foreach ($backups as $age => $data) { if (!PLUGIN_BACKUP_DISABLE_BACKUP_RENDERING) { $_anchor_from = '<a href="' . $href . $age . '">'; $_anchor_to = '</a>'; } $date = format_date($data['time'], TRUE); $retval[1] .= <<<EOD <li>{$_anchor_from}{$age} {$date}{$_anchor_to} [ <a href="{$href}{$age}&action=diff">{$qm->m['plg_backup']['diff']}</a> | <a href="{$href}{$age}&action=nowdiff">{$qm->m['plg_backup']['nowdiff']}</a> | <a href="{$href}{$age}&action=source">{$qm->m['plg_backup']['source']}</a> ] </li> EOD; } return join('', $retval); }
function plugin_backup_convert() { global $vars, $script; // global $_msg_backuplist, $_msg_diff, $_msg_nowdiff, $_msg_source, $_msg_nobackup; // global $_title_backup_delete; $page = isset($vars['page']) ? $vars['page'] : ''; check_readable($page, false); $_msg_backuplist = _('List of Backups'); $_msg_diff = _('diff'); $_msg_nowdiff = _('diff current'); $_msg_source = _('source'); $_msg_nobackup = _('There are no backup(s) of $1.'); $_title_backup_delete = _('Deleting backup of $1'); // Get arguments $with_label = TRUE; $args = func_get_args(); while (isset($args[0])) { switch (array_shift($args)) { case 'default': $diff_mode = 0; break; case 'nowdiff': $diff_mode = 1; break; case 'visualdiff': $diff_mode = 2; break; case 'label': $with_label = TRUE; break; case 'nolabel': $with_label = FALSE; break; } } $r_page = rawurlencode($page); $s_page = htmlspecialchars($page); $retval = array(); $date = get_date("m/d", get_filetime($page)); if ($with_label) { $retval[0] = <<<EOD <form class="center_form" action=""><div><label>Versions: <select onchange="javascript:location.href=this[this.selectedIndex].value"> EOD; $retval[1] = "\n"; $retval[2] = <<<EOD </select></label></div> </form> EOD; } else { $retval[0] = <<<EOD <form class="center_form" action=""><div> <select onchange="javascript:location.href=this[this.selectedIndex].value"> EOD; $retval[1] = "\n"; $retval[2] = <<<EOD </select> </div></form> EOD; } $backups = _backup_file_exists($page) ? get_backup($page) : array(); if (count($backups) == 0) { $retval[1] .= '<option value="' . get_page_uri($page) . '" selected="selected">' . _('->') . " {$date}(No.1)</option>\n"; return join('', $retval); } $maxcnt = count($backups) + 1; $retval[1] .= '<option value="' . get_page_uri($page) . '" selected="selected">' . _('->') . " {$date}(No.{$maxcnt})</option>\n"; $backups = array_reverse($backups, True); foreach ($backups as $age => $data) { $time = isset($data['real']) ? $data['real'] : $data['time']; $date = get_date('m/d', $time); $href = $script . '?cmd=backup&page=' . $r_page . '&age=' . $age; $retval[1] .= '<option value="' . $href; switch ($diff_mode) { case 2: $retval[1] .= '&action=visualdiff'; break; case 1: $retval[1] .= '&action=nowdiff'; break; } $retval[1] .= '">' . $date . ' (No.' . $age . ')</option>' . "\n"; } return join('', $retval); }
function plugin_backup_get_list($page) { global $_msg_backuplist, $_msg_diff, $_msg_nowdiff, $_msg_source, $_msg_nobackup; global $_title_backup_delete; $script = get_script_uri(); $r_page = rawurlencode($page); $s_page = htmlsc($page); $retval = array(); $retval[0] = <<<EOD <ul> <li><a href="{$script}?cmd=backup">{$_msg_backuplist}</a> <ul> EOD; $retval[1] = "\n"; $retval[2] = <<<EOD </ul> </li> </ul> EOD; $backups = _backup_file_exists($page) ? get_backup($page) : array(); if (empty($backups)) { $msg = str_replace('$1', make_pagelink($page), $_msg_nobackup); $retval[1] .= ' <li>' . $msg . '</li>' . "\n"; return join('', $retval); } if (!PKWK_READONLY) { $retval[1] .= ' <li><a href="' . $script . '?cmd=backup&action=delete&page=' . $r_page . '">'; $retval[1] .= str_replace('$1', $s_page, $_title_backup_delete); $retval[1] .= '</a></li>' . "\n"; } $href = $script . '?cmd=backup&page=' . $r_page . '&age='; $_anchor_from = $_anchor_to = ''; foreach ($backups as $age => $data) { if (!PLUGIN_BACKUP_DISABLE_BACKUP_RENDERING) { $_anchor_from = '<a href="' . $href . $age . '">'; $_anchor_to = '</a>'; } $date = format_date($data['time'], true); $retval[1] .= <<<EOD <li>{$_anchor_from}{$age} {$date}{$_anchor_to} [ <a href="{$href}{$age}&action=diff">{$_msg_diff}</a> | <a href="{$href}{$age}&action=nowdiff">{$_msg_nowdiff}</a> | <a href="{$href}{$age}&action=source">{$_msg_source}</a> ] </li> EOD; } return join('', $retval); }
function get_backup_max_age($page) { static $backup_page; if (!isset($backup_page)) { $backup_page = get_backup($page); } if (count($backup_page) == 0) { return -1; } // 存在しない ksort($backup_page); return current(array_keys($backup_page, $backup_page[count($backup_page) - 1])); }
/** * 更新日時のバックアップデータの世代を確定する * @static */ function get_backup_age($page, $update_time) { static $backup_page; if (!isset($backup_page)) { $backup_page = get_backup($page); } if (count($backup_page) == 0) { return -1; } // 存在しない // 初回バックアップ作成は、文書生成日時となる $create_date = $backup_page[1]['time']; if ($update_time == $create_date) { return 1; } $match = -1; foreach ($backup_page as $age => $val) { if ($val['real'] == $update_time) { $match = $age; } } $match++; // ヒットした次が書き込んだ内容(バックアップなため) if ($age < $match) { return 0; } // カレント(diffを読む) if ($match > 0) { return $match; } return -1; // 存在しない(一致したものが存在しない) }