OSDN Git Service

Convert character code of the source code to UTF-8 from EUC-JP
[pukiwiki/pukiwiki.git] / plugin / calendar_viewer.inc.php
1 <?php
2 // PukiWiki - Yet another WikiWikiWeb clone
3 // $Id: calendar_viewer.inc.php,v 1.37 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 // Calendar viewer plugin - List pages that calendar/calnedar2 plugin created
8 // (Based on calendar and recent plugin)
9
10 // Page title's date format
11 //  * See PHP date() manual for detail
12 //  * '$\w' = weeklabel defined in $_msg_week
13 define('PLUGIN_CALENDAR_VIEWER_DATE_FORMAT',
14         //      FALSE         // 'pagename/2004-02-09' -- As is
15         //      'D, d M, Y'   // 'Mon, 09 Feb, 2004'
16         //      'F d, Y'      // 'February 09, 2004'
17         //      '[Y-m-d]'     // '[2004-02-09]'
18                 'Y/n/j ($\w)' // '2004/2/9 (Mon)'
19         );
20
21 // ----
22
23 define('PLUGIN_CALENDAR_VIEWER_USAGE',
24         '#calendar_viewer(pagename,this|yyyy-mm|n|x*y[,mode[,separater]])');
25 /*
26  ** pagename
27  * - A working root of calendar or calendar2 plugin
28  *   pagename/2004-12-30
29  *   pagename/2004-12-31
30  *   ...
31  *
32  ** (yyyy-mm|n|this)
33  * this    - Show 'this month'
34  * yyyy-mm - Show pages at year:yyyy and month:mm
35  * n       - Show first n pages
36  * x*n     - Show first n pages from x-th page (0 = first)
37  *
38  ** [mode]
39  * past   - Show today, and the past below. Recommended for ChangeLogs and diaries (default)
40  * future - Show today, and the future below. Recommended for event planning and scheduling
41  * view   - Show all, from the past to the future
42  *
43  ** [separater]
44  * - Specify separator of yyyy/mm/dd
45  * - Default: '-' (yyyy-mm-dd)
46  *
47  * TODO
48  *  Stop showing links 'next month' and 'previous month' with past/future mode for 'this month'
49  *    #calendar_viewer(pagename,this,past)
50  */
51
52 function plugin_calendar_viewer_convert()
53 {
54         global $vars, $get, $post, $script, $weeklabels;
55         global $_msg_calendar_viewer_right, $_msg_calendar_viewer_left;
56         global $_msg_calendar_viewer_restrict, $_err_calendar_viewer_param2;
57
58         static $viewed = array();
59
60         if (func_num_args() < 2)
61                 return PLUGIN_CALENDAR_VIEWER_USAGE . '<br />' . "\n";
62
63         $func_args = func_get_args();
64
65         // Default values
66         $pagename    = $func_args[0];   // 基準となるページ名
67         $page_YM     = '';      // 一覧表示する年月
68         $limit_base  = 0;       // 先頭から数えて何ページ目から表示するか (先頭)
69         $limit_pitch = 0;       // 何件づつ表示するか
70         $limit_page  = 0;       // サーチするページ数
71         $mode        = 'past';  // 動作モード
72         $date_sep    = '-';     // 日付のセパレータ calendar2なら '-', calendarなら ''
73
74         // Check $func_args[1]
75         $matches = array();
76         if (preg_match('/[0-9]{4}' . $date_sep . '[0-9]{2}/', $func_args[1])) {
77                 // 指定年月の一覧表示
78                 $page_YM     = $func_args[1];
79                 $limit_page  = 31;
80         } else if (preg_match('/this/si', $func_args[1])) {
81                 // 今月の一覧表示
82                 $page_YM     = get_date('Y' . $date_sep . 'm');
83                 $limit_page  = 31;
84         } else if (preg_match('/^[0-9]+$/', $func_args[1])) {
85                 // n日分表示
86                 $limit_pitch = $func_args[1];
87                 $limit_page  = $func_args[1];
88         } else if (preg_match('/(-?[0-9]+)\*([0-9]+)/', $func_args[1], $matches)) {
89                 // 先頭より数えて x ページ目から、y件づつ表示
90                 $limit_base  = $matches[1];
91                 $limit_pitch = $matches[2];
92                 $limit_page  = $matches[1] + $matches[2]; // 読み飛ばす + 表示する
93         } else {
94                 return '#calendar_viewer(): ' . $_err_calendar_viewer_param2 . '<br />' . "\n";
95         }
96
97         // $func_args[2]: Mode setting
98         if (isset($func_args[2]) && preg_match('/^(past|view|future)$/si', $func_args[2]))
99                 $mode = $func_args[2];
100
101         // $func_args[3]: Change default delimiter
102         if (isset($func_args[3])) $date_sep = $func_args[3];
103
104         // Avoid Loop etc.
105         if (isset($viewed[$pagename])) {
106                 $s_page = htmlsc($pagename);
107                 return "#calendar_viewer(): You already view: $s_page<br />";
108         } else {
109                 $viewed[$pagename] = TRUE; // Valid
110         }
111
112         // 一覧表示するページ名とファイル名のパターン ファイル名には年月を含む
113         if ($pagename == '') {
114                 // pagename無しのyyyy-mm-ddに対応するための処理
115                 $pagepattern     = '';
116                 $pagepattern_len = 0;
117                 $filepattern     = encode($page_YM);
118                 $filepattern_len = strlen($filepattern);
119         } else {
120                 $pagepattern     = strip_bracket($pagename) . '/';
121                 $pagepattern_len = strlen($pagepattern);
122                 $filepattern     = encode($pagepattern . $page_YM);
123                 $filepattern_len = strlen($filepattern);
124         }
125
126         // ページリストの取得
127         $pagelist = array();
128         if ($dir = @opendir(DATA_DIR)) {
129                 $_date = get_date('Y' . $date_sep . 'm' . $date_sep . 'd');
130                 $page_date  = '';
131                 while($file = readdir($dir)) {
132                         if ($file == '..' || $file == '.') continue;
133                         if (substr($file, 0, $filepattern_len) != $filepattern) continue;
134
135                         $page      = decode(trim(preg_replace('/\.txt$/', ' ', $file)));
136                         $page_date = substr($page, $pagepattern_len);
137
138                         // Verify the $page_date pattern (Default: yyyy-mm-dd).
139                         // Past-mode hates the future, and
140                         // Future-mode hates the past.
141                         if ((plugin_calendar_viewer_isValidDate($page_date, $date_sep) == FALSE) || 
142                                 ($page_date > $_date && ($mode == 'past')) ||
143                                 ($page_date < $_date && ($mode == 'future')))
144                                         continue;
145
146                         $pagelist[] = $page;
147                 }
148         }
149         closedir($dir);
150
151         if ($mode == 'past') {
152                 rsort($pagelist, SORT_STRING);  // New => Old
153         } else {
154                 sort($pagelist, SORT_STRING);   // Old => New
155         }
156
157         // Include start
158         $tmppage     = $vars['page'];
159         $return_body = '';
160
161         // $limit_page の件数までインクルード
162         $tmp = max($limit_base, 0); // Skip minus
163         while ($tmp < $limit_page) {
164                 if (! isset($pagelist[$tmp])) break;
165
166                 $page = $pagelist[$tmp];
167                 $get['page'] = $post['page'] = $vars['page'] = $page;
168
169                 // 現状で閲覧許可がある場合だけ表示する
170                 if (check_readable($page, FALSE, FALSE)) {
171                         $body = convert_html(get_source($page));
172                 } else {
173                         $body = str_replace('$1', $page, $_msg_calendar_viewer_restrict);
174                 }
175
176                 $r_page = rawurlencode($page);
177
178                 if (PLUGIN_CALENDAR_VIEWER_DATE_FORMAT !== FALSE) {
179                         $time = strtotime(basename($page)); // $date_sep must be assumed '-' or ''!
180                         if ($time == -1) {
181                                 $s_page = htmlsc($page); // Failed. Why?
182                         } else {
183                                 $week   = $weeklabels[date('w', $time)];
184                                 $s_page = htmlsc(str_replace(
185                                                 array('$w' ),
186                                                 array($week),
187                                                 date(PLUGIN_CALENDAR_VIEWER_DATE_FORMAT, $time)
188                                         ));
189                         }
190                 } else {
191                         $s_page = htmlsc($page);
192                 }
193
194                 if (PKWK_READONLY) {
195                         $link   = $script . '?' . $r_page;
196                 } else {
197                         $link   = $script . '?cmd=edit&amp;page=' . $r_page;
198                 }
199                 $link   = '<a href="' . $link . '">' . $s_page . '</a>';
200
201                 $head   = '<h1>' . $link . '</h1>' . "\n";
202                 $return_body .= $head . $body;
203
204                 ++$tmp;
205         }
206
207         // ここで、前後のリンクを表示
208         // ?plugin=calendar_viewer&file=ページ名&date=yyyy-mm
209         $enc_pagename = rawurlencode(substr($pagepattern, 0, $pagepattern_len - 1));
210
211         if ($page_YM != '') {
212                 // 年月表示時
213                 $date_sep_len = strlen($date_sep);
214                 $this_year    = substr($page_YM, 0, 4);
215                 $this_month   = substr($page_YM, 4 + $date_sep_len, 2);
216
217                 // 次月
218                 $next_year  = $this_year;
219                 $next_month = $this_month + 1;
220                 if ($next_month > 12) {
221                         ++$next_year;
222                         $next_month = 1;
223                 }
224                 $next_YM = sprintf('%04d%s%02d', $next_year, $date_sep, $next_month);
225
226                 // 前月
227                 $prev_year  = $this_year;
228                 $prev_month = $this_month - 1;
229                 if ($prev_month < 1) {
230                         --$prev_year;
231                         $prev_month = 12;
232                 }
233                 $prev_YM = sprintf('%04d%s%02d', $prev_year, $date_sep, $prev_month);
234                 if ($mode == 'past') {
235                         $right_YM   = $prev_YM;
236                         $right_text = $prev_YM . '&gt;&gt;'; // >>
237                         $left_YM    = $next_YM;
238                         $left_text  = '&lt;&lt;' . $next_YM; // <<
239                 } else {
240                         $left_YM    = $prev_YM;
241                         $left_text  = '&lt;&lt;' . $prev_YM; // <<
242                         $right_YM   = $next_YM;
243                         $right_text = $next_YM . '&gt;&gt;'; // >>
244                 }
245         } else {
246                 // n件表示時
247                 if ($limit_base <= 0) {
248                         $left_YM = ''; // 表示しない (それより前の項目はない)
249                 } else {
250                         $left_YM   = $limit_base - $limit_pitch . '*' . $limit_pitch;
251                         $left_text = sprintf($_msg_calendar_viewer_left, $limit_pitch);
252
253                 }
254                 if ($limit_base + $limit_pitch >= count($pagelist)) {
255                         $right_YM = ''; // 表示しない (それより後の項目はない)
256                 } else {
257                         $right_YM   = $limit_base + $limit_pitch . '*' . $limit_pitch;
258                         $right_text = sprintf($_msg_calendar_viewer_right, $limit_pitch);
259                 }
260         }
261
262         // ナビゲート用のリンクを末尾に追加
263         if ($left_YM != '' || $right_YM != '') {
264                 $s_date_sep = htmlsc($date_sep);
265                 $left_link = $right_link = '';
266                 $link = $script . '?plugin=calendar_viewer&amp;mode=' . $mode .
267                         '&amp;file=' . $enc_pagename . '&amp;date_sep=' . $s_date_sep . '&amp;';
268                 if ($left_YM != '')
269                         $left_link = '<a href="' . $link .
270                                 'date=' . $left_YM . '">' . $left_text . '</a>';
271                 if ($right_YM != '')
272                         $right_link = '<a href="' . $link .
273                                 'date=' . $right_YM . '">' . $right_text . '</a>';
274                 // past modeは<<新 旧>> 他は<<旧 新>>
275                 $return_body .=
276                         '<div class="calendar_viewer">' .
277                         '<span class="calendar_viewer_left">'  . $left_link  . '</span>' .
278                         '<span class="calendar_viewer_right">' . $right_link . '</span>' .
279                         '</div>';
280         }
281
282         $get['page'] = $post['page'] = $vars['page'] = $tmppage;
283
284         return $return_body;
285 }
286
287 function plugin_calendar_viewer_action()
288 {
289         global $vars, $get, $post, $script;
290
291         $date_sep = '-';
292
293         $return_vars_array = array();
294
295         $page = strip_bracket($vars['page']);
296         $vars['page'] = '*';
297         if (isset($vars['file'])) $vars['page'] = $vars['file'];
298
299         $date_sep = $vars['date_sep'];
300
301         $page_YM = $vars['date'];
302         if ($page_YM == '') $page_YM = get_date('Y' . $date_sep . 'm');
303         $mode = $vars['mode'];
304
305         $args_array = array($vars['page'], $page_YM, $mode, $date_sep);
306         $return_vars_array['body'] = call_user_func_array('plugin_calendar_viewer_convert', $args_array);
307
308         //$return_vars_array['msg'] = 'calendar_viewer ' . $vars['page'] . '/' . $page_YM;
309         $return_vars_array['msg'] = 'calendar_viewer ' . htmlsc($vars['page']);
310         if ($vars['page'] != '') $return_vars_array['msg'] .= '/';
311         if (preg_match('/\*/', $page_YM)) {
312                 // うーん、n件表示の時はなんてページ名にしたらいい?
313         } else {
314                 $return_vars_array['msg'] .= htmlsc($page_YM);
315         }
316
317         $vars['page'] = $page;
318         return $return_vars_array;
319 }
320
321 function plugin_calendar_viewer_isValidDate($aStr, $aSepList = '-/ .')
322 {
323         $matches = array();
324         if ($aSepList == '') {
325                 // yyymmddとしてチェック(手抜き(^^;)
326                 return checkdate(substr($aStr, 4, 2), substr($aStr, 6, 2), substr($aStr, 0, 4));
327         } else if (ereg("^([0-9]{2,4})[$aSepList]([0-9]{1,2})[$aSepList]([0-9]{1,2})$", $aStr, $matches) ) {
328                 return checkdate($matches[2], $matches[3], $matches[1]);
329         } else {
330                 return FALSE;
331         }
332 }
333 ?>