OSDN Git Service

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