4 * PukiWiki - Yet another WikiWikiWeb clone.
10 * @package org.pukiwiki
14 * @version $Id: backup.php,v 1.13 2011/01/25 15:01:01 henoheno Exp $
16 * 2002-2006 PukiWiki Developers Team
17 * 2001-2002 Originally written by yu-ji
18 * License: GPL v2 or (at your option) any later version
26 * @param String $page ページ名
27 * @param Boolean $delete TRUE:バックアップを削除する
32 function make_backup($page, $delete = FALSE)
34 global $cycle, $maxage;
35 global $do_backup, $del_backup;
37 if (PKWK_READONLY || ! $do_backup) return;
39 if ($del_backup && $delete) {
40 _backup_delete($page);
44 if (! is_page($page)) return;
46 $lastmod = _backup_get_filetime($page);
47 if ($lastmod == 0 || UTIME - $lastmod > 60 * 60 * $cycle)
49 $backups = get_backup($page);
50 $count = count($backups) + 1;
52 // 直後に1件追加するので、(最大件数 - 1)を超える要素を捨てる
54 array_splice($backups, 0, $count - $maxage);
57 foreach($backups as $age=>$data) {
58 $strout .= PKWK_SPLITTER . ' ' . $data['time'] . "\n"; // Splitter format
59 $strout .= join('', $data['data']);
60 unset($backups[$age]);
62 $strout = preg_replace("/([^\n])\n*$/", "$1\n", $strout);
64 // Escape 'lines equal to PKWK_SPLITTER', by inserting a space
65 $body = preg_replace('/^(' . preg_quote(PKWK_SPLITTER) . "\s\d+)$/", '$1 ', get_source($page));
66 $body = PKWK_SPLITTER . ' ' . get_filetime($page) . "\n" . join('', $body);
67 $body = preg_replace("/\n*$/", "\n", $body);
69 $fp = _backup_fopen($page, 'wb')
70 or die_message('Cannot open ' . htmlsc(_backup_get_filename($page)) .
71 '<br />Maybe permission is not writable or filename is too long');
72 _backup_fputs($fp, $strout);
73 _backup_fputs($fp, $body);
81 * $age = 0または省略 : 全てのバックアップデータを配列で取得する
82 * $age > 0 : 指定した世代のバックアップデータを取得する
85 * @param String $page ページ名
86 * @param Integer $age バックアップの世代番号 省略時は全て
88 * @return String バックアップ ($age != 0)
89 * Array バックアップの配列 ($age == 0)
91 function get_backup($page, $age = 0)
93 $lines = _backup_file($page);
94 if (! is_array($lines)) return array();
97 $retvars = $match = array();
98 $regex_splitter = '/^' . preg_quote(PKWK_SPLITTER) . '\s(\d+)$/';
99 foreach($lines as $index => $line) {
100 if (preg_match($regex_splitter, $line, $match)) {
101 // A splitter, tells new data of backup will come
103 if ($age > 0 && $_age > $age)
104 return $retvars[$age];
107 $retvars[$_age] = array('time'=>$match[1], 'data'=>array());
109 // The first ... the last line of the data
110 $retvars[$_age]['data'][] = $line;
112 unset($lines[$index]);
119 * _backup_get_filename
123 * @param String $page ページ名
125 * @return String バックアップのファイル名
127 function _backup_get_filename($page)
129 return BACKUP_DIR . encode($page) . BACKUP_EXT;
133 * _backup_file_exists
137 * @param String $page ページ名
139 * @return Boolean TRUE:ある FALSE:ない
141 function _backup_file_exists($page)
143 return file_exists(_backup_get_filename($page));
147 * _backup_get_filetime
151 * @param String $page ページ名
153 * @return Integer ファイルの更新時刻(GMT)
156 function _backup_get_filetime($page)
158 return _backup_file_exists($page) ?
159 filemtime(_backup_get_filename($page)) - LOCALZONE : 0;
167 * @param String $page ページ名
169 * @return Boolean FALSE:失敗
171 function _backup_delete($page)
173 return unlink(_backup_get_filename($page));
176 /////////////////////////////////////////////////
178 if (extension_loaded('zlib')) {
181 define('BACKUP_EXT', '.gz');
188 * @param String $page ページ名
189 * @param String $mode モード
191 * @return Boolean FALSE:失敗
193 function _backup_fopen($page, $mode)
195 return gzopen(_backup_get_filename($page), $mode);
203 * @param Integer $zp ファイルポインタ
204 * @param String $str 文字列
206 * @return Boolean FALSE:失敗 その他:書き込んだバイト数
208 function _backup_fputs($zp, $str)
210 return gzputs($zp, $str);
218 * @param Integer $zp ファイルポインタ
220 * @return Boolean FALSE:失敗
222 function _backup_fclose($zp)
232 * @param String $page ページ名
234 * @return Array ファイルの内容
236 function _backup_file($page)
238 return _backup_file_exists($page) ?
239 gzfile(_backup_get_filename($page)) :
243 /////////////////////////////////////////////////
247 define('BACKUP_EXT', '.txt');
254 * @param String $page ページ名
255 * @param String $mode モード
257 * @return Boolean FALSE:失敗
259 function _backup_fopen($page, $mode)
261 return fopen(_backup_get_filename($page), $mode);
269 * @param Integer $zp ファイルポインタ
270 * @param String $str 文字列
272 * @return Boolean FALSE:失敗 その他:書き込んだバイト数
274 function _backup_fputs($zp, $str)
276 return fputs($zp, $str);
284 * @param Integer $zp ファイルポインタ
286 * @return Boolean FALSE:失敗
288 function _backup_fclose($zp)
298 * @param String $page ページ名
300 * @return Array ファイルの内容
302 function _backup_file($page)
304 return _backup_file_exists($page) ?
305 file(_backup_get_filename($page)) :