OSDN Git Service

変数初期化
[pukiwiki/pukiwiki.git] / plugin / tracker.inc.php
1 <?php
2 /////////////////////////////////////////////////
3 // PukiWiki - Yet another WikiWikiWeb clone.
4 //
5 // $Id: tracker.inc.php,v 1.16 2003/11/02 14:03:30 arino Exp $
6 //
7
8 // tracker_list¤Çɽ¼¨¤·¤Ê¤¤¥Ú¡¼¥¸Ì¾(Àµµ¬É½¸½¤Ç)
9 // 'SubMenu'¥Ú¡¼¥¸ ¤ª¤è¤Ó '/'¤ò´Þ¤à¥Ú¡¼¥¸¤ò½ü³°¤¹¤ë
10 define('TRACKER_LIST_EXCLUDE_PATTERN','#^SubMenu$|/#');
11 // À©¸Â¤·¤Ê¤¤¾ì¹ç¤Ï¤³¤Á¤é
12 //define('TRACKER_LIST_EXCLUDE_PATTERN','#(?!)#');
13
14 // ¹àÌܤμè¤ê½Ð¤·¤Ë¼ºÇÔ¤·¤¿¥Ú¡¼¥¸¤ò°ìÍ÷¤Ëɽ¼¨¤¹¤ë
15 define('TRACKER_LIST_SHOW_ERROR_PAGE',TRUE);
16
17 function plugin_tracker_convert()
18 {
19         global $script,$vars;
20         
21         $base = $refer = $vars['page'];
22         
23         $config_name = 'default';
24         $form = 'form';
25         $options = array();
26         if (func_num_args())
27         {
28                 $args = func_get_args();
29                 switch (count($args))
30                 {
31                         case 3:
32                                 $options = array_splice($args,2);
33                         case 2:
34                                 $_base = get_fullname($args[1],$base);
35                                 if (is_pagename($_base))
36                                 {
37                                         $base = $_base;
38                                 }
39                         case 1:
40                                 $config_name = $args[0];
41                                 list($config_name,$_form) = array_pad(explode('/',$config_name,2),2,$form);
42                 }
43         }
44         
45         $config = new Config('plugin/tracker/'.$config_name);
46         
47         if (!$config->read())
48         {
49                 return "<p>config file '".htmlspecialchars($config_name)."' not found.</p>";
50         }
51         
52         $config->config_name = $config_name;
53         
54         $fields = plugin_tracker_get_fields($base,$refer,$config);
55         
56         $form = is_page($config->page.'/'.$_form) ? $_form : $form;
57         $retval = convert_html(plugin_tracker_get_source($config->page.'/'.$form));
58         $hiddens = '';
59         
60         foreach (array_keys($fields) as $name)
61         {
62                 $replace = $fields[$name]->get_tag();
63                 if (is_a($fields[$name],'Tracker_field_hidden'))
64                 {
65                         $hiddens .= $replace;
66                         $replace = '';
67                 }
68                 $retval = str_replace("[$name]",$replace,$retval);
69         }
70         return <<<EOD
71 <form enctype="multipart/form-data" action="$script" method="post">
72 <div>
73 $retval
74 $hiddens
75 </div>
76 </form>
77 EOD;
78 }
79 function plugin_tracker_action()
80 {
81         global $script,$post,$vars,$now;
82         
83         $config_name = array_key_exists('_config',$post) ? $post['_config'] : '';
84         
85         $config = new Config('plugin/tracker/'.$config_name);
86         if (!$config->read())
87         {
88                 return "<p>config file '".htmlspecialchars($config_name)."' not found.</p>";
89         }
90         $config->config_name = $config_name;
91         $source = $config->page.'/page';
92         
93         $refer = array_key_exists('_refer',$post) ? $post['_refer'] : $post['_base'];
94         
95         if (!is_pagename($refer))
96         {
97                 return array(
98                         'msg'=>'cannot write',
99                         'body'=>'page name ('.htmlspecialchars($refer).') is not valid.'
100                 );
101         }
102         if (!is_page($source))
103         {
104                 return array(
105                         'msg'=>'cannot write',
106                         'body'=>'page template ('.htmlspecialchars($source).') is not exist.'
107                 );
108         }
109         // ¥Ú¡¼¥¸Ì¾¤ò·èÄê
110         $base = $post['_base'];
111         $num = 0;
112         $name = (array_key_exists('_name',$post)) ? $post['_name'] : '';
113         if (array_key_exists('_page',$post))
114         {
115                 $page = $real = $post['_page'];
116         }
117         else
118         {
119                 $real = is_pagename($name) ? $name : ++$num;
120                 $page = get_fullname('./'.$real,$base);
121         }
122         if (!is_pagename($page))
123         {
124                 $page = $base;
125         }
126         
127         while (is_page($page))
128         {
129                 $real = ++$num;
130                 $page = "$base/$real";
131         }
132         // ¥Ú¡¼¥¸¥Ç¡¼¥¿¤òÀ¸À®
133         $postdata = plugin_tracker_get_source($source);
134         
135         // µ¬Äê¤Î¥Ç¡¼¥¿
136         $_post = array_merge($post,$_FILES);
137         $_post['_date'] = $now;
138         $_post['_page'] = $page;
139         $_post['_name'] = $name;
140         $_post['_real'] = $real;
141         // $_post['_refer'] = $_post['refer'];
142         
143         $fields = plugin_tracker_get_fields($page,$refer,$config);
144         
145         foreach (array_keys($fields) as $key)
146         {
147                 if (!array_key_exists($key,$_post))
148                 {
149                         continue;
150                 }
151                 $value = $fields[$key]->format_value($_post[$key]);
152                 foreach (array_keys($postdata) as $num)
153                 {
154                         if (trim($postdata[$num]) == '')
155                         {
156                                 continue;
157                         }
158                         $postdata[$num] = str_replace(
159                                 "[$key]",
160                                 ($postdata[$num]{0} == '|' or $postdata[$num]{0} == ':') ?
161                                         str_replace('|','&#x7c;',$value) : $value,
162                                 $postdata[$num]
163                         );
164                 }
165         }
166         
167         // ½ñ¤­¹þ¤ß
168         page_write($page,join('',$postdata));
169         
170         $r_page = rawurlencode($page);
171         
172         header("Location: $script?$r_page");
173         exit;
174 }
175 /*
176 function plugin_tracker_inline()
177 {
178         global $vars;
179         
180         $args = func_get_args();
181         if (count($args) < 3)
182         {
183                 return FALSE;
184         }
185         $body = array_pop($args);
186         list($config_name,$field) = $args;
187         
188         $config = new Config('plugin/tracker/'.$config_name);
189         
190         if (!$config->read())
191         {
192                 return "config file '".htmlspecialchars($config_name)."' not found.";
193         }
194         
195         $config->config_name = $config_name;
196         
197         $fields = plugin_tracker_get_fields($vars['page'],$vars['page'],$config);
198         $fields[$field]->default_value = $body;
199         return $fields[$field]->get_tag();
200 }
201 */
202 // ¥Õ¥£¡¼¥ë¥É¥ª¥Ö¥¸¥§¥¯¥È¤ò¹½ÃÛ¤¹¤ë
203 function plugin_tracker_get_fields($base,$refer,&$config)
204 {
205         global $now,$_tracker_messages;
206         
207         $fields = array();
208         // Í½Ìó¸ì
209         foreach (array(
210                 '_date'=>'text',    // Åê¹ÆÆü»þ
211                 '_update'=>'date',  // ºÇ½ª¹¹¿·
212                 '_past'=>'past',    // ·Ð²á(passage)
213                 '_page'=>'page',    // ¥Ú¡¼¥¸Ì¾
214                 '_name'=>'text',    // »ØÄꤵ¤ì¤¿¥Ú¡¼¥¸Ì¾
215                 '_real'=>'real',    // ¼ÂºÝ¤Î¥Ú¡¼¥¸Ì¾
216                 '_refer'=>'page',   // »²¾È¸µ(¥Õ¥©¡¼¥à¤Î¤¢¤ë¥Ú¡¼¥¸)
217                 '_base'=>'page',    // ´ð½à¥Ú¡¼¥¸
218                 '_submit'=>'submit' // Äɲåܥ¿¥ó
219                 ) as $field=>$class)
220         {
221                 $class = 'Tracker_field_'.$class;
222                 $fields[$field] = &new $class(array($field,$_tracker_messages["btn$field"],'','20',''),$base,$refer,$config);
223         }
224         
225         foreach ($config->get('fields') as $field)
226         {
227                 // 0=>¹àÌÜ̾ 1=>¸«½Ð¤· 2=>·Á¼° 3=>¥ª¥×¥·¥ç¥ó 4=>¥Ç¥Õ¥©¥ë¥ÈÃÍ
228                 $class = 'Tracker_field_'.$field[2];
229                 if (!class_exists($class))
230                 { // ¥Ç¥Õ¥©¥ë¥È
231                         $class = 'Tracker_field_text';
232                         $field[2] = 'text';
233                         $field[3] = '20';
234                 }
235                 $fields[$field[0]] = &new $class($field,$base,$refer,$config);
236         }
237         return $fields;
238 }
239 // ¥Õ¥£¡¼¥ë¥É¥¯¥é¥¹
240 class Tracker_field
241 {
242         var $name;
243         var $title;
244         var $values;
245         var $default_value;
246         var $page;
247         var $refer;
248         var $config;
249         var $data;
250         var $sort_type = SORT_REGULAR;
251         
252         function Tracker_field($field,$page,$refer,&$config)
253         {
254                 global $post;
255                 
256                 $this->name = $field[0];
257                 $this->title = $field[1];
258                 $this->values = explode(',',$field[3]);
259                 $this->default_value = $field[4];
260                 $this->page = $page;
261                 $this->refer = $refer;
262                 $this->config = &$config;
263                 $this->data = array_key_exists($this->name,$post) ? $post[$this->name] : '';
264         }
265         function get_tag()
266         {
267         }
268         function get_style($str)
269         {
270                 return '%s';
271         }
272         function format_value($value)
273         {
274                 return $value;
275         }
276         function format_cell($str)
277         {
278                 return $str;
279         }
280         function get_value($value)
281         {
282                 return $value;
283         }
284 }
285 class Tracker_field_text extends Tracker_field
286 {
287         var $sort_type = SORT_STRING;
288         
289         function get_tag()
290         {
291                 $s_name = htmlspecialchars($this->name);
292                 $s_size = htmlspecialchars($this->values[0]);
293                 $s_value = htmlspecialchars($this->default_value);
294                 return "<input type=\"text\" name=\"$s_name\" size=\"$s_size\" value=\"$s_value\" />";
295         }
296 }
297 class Tracker_field_page extends Tracker_field_text
298 {
299         var $sort_type = SORT_STRING;
300         
301         function format_value($value)
302         {
303                 global $WikiName;
304                 
305                 $value = strip_bracket($value);
306                 if (is_pagename($value))
307                 {
308                         $value = "[[$value]]";
309                 }
310                 return parent::format_value($value);
311         }
312 }
313 class Tracker_field_real extends Tracker_field_text
314 {
315         var $sort_type = SORT_REGULAR;
316 }
317 class Tracker_field_title extends Tracker_field_text
318 {
319         var $sort_type = SORT_STRING;
320         
321         function format_cell($str)
322         {
323                 make_heading($str);
324                 return $str;
325         }
326 }
327 class Tracker_field_textarea extends Tracker_field
328 {
329         var $sort_type = SORT_STRING;
330         
331         function get_tag()
332         {
333                 $s_name = htmlspecialchars($this->name);
334                 $s_cols = htmlspecialchars($this->values[0]);
335                 $s_rows = htmlspecialchars($this->values[1]);
336                 $s_value = htmlspecialchars($this->default_value);
337                 return "<textarea name=\"$s_name\" cols=\"$s_cols\" rows=\"$s_rows\">$s_value</textarea>";
338         }
339         function format_cell($str)
340         {
341                 $str = preg_replace('/[\r\n]+/','',$str);
342                 if (!empty($this->values[2]) and strlen($str) > ($this->values[2] + 3))
343                 {
344                         $str = mb_substr($str,0,$this->values[2]).'...';
345                 }
346                 return $str;
347         }
348 }
349 class Tracker_field_format extends Tracker_field
350 {
351         var $sort_type = SORT_STRING;
352         
353         var $styles = array();
354         var $formats = array();
355         
356         function Tracker_field_format($field,$page,$refer,&$config)
357         {
358                 parent::Tracker_field($field,$page,$refer,$config);
359                 
360                 foreach ($this->config->get($this->name) as $option)
361                 {
362                         list($key,$style,$format) = array_pad(array_map(create_function('$a','return trim($a);'),$option),3,'');
363                         if ($style != '')
364                         {
365                                 $this->styles[$key] = $style;
366                         }
367                         if ($format != '')
368                         {
369                                 $this->formats[$key] = $format;
370                         } 
371                 }
372         }
373         function get_tag()
374         {
375                 $s_name = htmlspecialchars($this->name);
376                 $s_size = htmlspecialchars($this->values[0]);
377                 return "<input type=\"text\" name=\"$s_name\" size=\"$s_size\" />";
378         }
379         function get_key($str)
380         {
381                 return ($str == '') ? 'IS NULL' : 'IS NOT NULL';
382         }
383         function format_value($str)
384         {
385                 if (is_array($str))
386                 {
387                         return join(', ',array_map(array($this,'format_value'),$str));
388                 }
389                 $key = $this->get_key($str);
390                 return array_key_exists($key,$this->formats) ? str_replace('%s',$str,$this->formats[$key]) : $str;
391         }
392         function get_style($str)
393         {
394                 $key = $this->get_key($str);
395                 return array_key_exists($key,$this->styles) ? $this->styles[$key] : '%s';
396         }
397 }
398 class Tracker_field_file extends Tracker_field_format
399 {
400         var $sort_type = SORT_STRING;
401         
402         function get_tag()
403         {
404                 $s_name = htmlspecialchars($this->name);
405                 $s_size = htmlspecialchars($this->values[0]);
406                 return "<input type=\"file\" name=\"$s_name\" size=\"$s_size\" />";
407         }
408         function format_value($str)
409         {
410                 if (array_key_exists($this->name,$_FILES))
411                 {
412                         require_once(PLUGIN_DIR.'attach.inc.php');
413                         $result = attach_upload($_FILES[$this->name],$this->page);
414                         if ($result['result']) // ¥¢¥Ã¥×¥í¡¼¥ÉÀ®¸ù
415                         {
416                                 return parent::format_value($this->page.'/'.$_FILES[$this->name]['name']);
417                         }
418                 }
419                 // ¥Õ¥¡¥¤¥ë¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤«¡¢¥¢¥Ã¥×¥í¡¼¥É¤Ë¼ºÇÔ
420                 return parent::format_value('');
421         }
422 }
423 class Tracker_field_radio extends Tracker_field_format
424 {
425         var $sort_type = SORT_NUMERIC;
426         
427         function get_tag()
428         {
429                 $s_name = htmlspecialchars($this->name);
430                 $retval = '';
431                 foreach ($this->config->get($this->name) as $option)
432                 {
433                         $s_option = htmlspecialchars($option[0]);
434                         $checked = trim($option[0]) == trim($this->default_value) ? ' checked="checked"' : '';
435                         $retval .= "<input type=\"radio\" name=\"$s_name\" value=\"$s_option\"$checked />$s_option\n";
436                 }
437                 
438                 return $retval;
439         }
440         function get_key($str)
441         {
442                 return $str;
443         }
444         function get_value($value)
445         {
446                 static $options = array();
447                 if (!array_key_exists($this->name,$options))
448                 {
449                         $options[$this->name] = array_flip(array_map(create_function('$arr','return $arr[0];'),$this->config->get($this->name)));
450                 }
451                 return array_key_exists($value,$options[$this->name]) ? $options[$this->name][$value] : $value;
452         }
453 }
454 class Tracker_field_select extends Tracker_field_radio
455 {
456         var $sort_type = SORT_NUMERIC;
457         
458         function get_tag($empty=FALSE)
459         {
460                 $s_name = htmlspecialchars($this->name);
461                 $s_size = (array_key_exists(0,$this->values) and is_numeric($this->values[0])) ?
462                         ' size="'.htmlspecialchars($this->values[0]).'"' : '';
463                 $s_multiple = (array_key_exists(1,$this->values) and strtolower($this->values[1]) == 'multiple') ?
464                         ' multiple="multiple"' : '';
465                 $retval = "<select name=\"{$s_name}[]\"$s_size$s_multiple>\n";
466                 if ($empty)
467                 {
468                         $retval .= " <option value=\"\"></option>\n";
469                 }
470                 $defaults = array_flip(preg_split('/\s*,\s*/',$this->default_value,-1,PREG_SPLIT_NO_EMPTY));
471                 foreach ($this->config->get($this->name) as $option)
472                 {
473                         $s_option = htmlspecialchars($option[0]);
474                         $selected = array_key_exists(trim($option[0]),$defaults) ? ' selected="selected"' : '';
475                         $retval .= " <option value=\"$s_option\"$selected>$s_option</option>\n";
476                 }
477                 $retval .= "</select>";
478                 
479                 return $retval;
480         }
481 }
482 class Tracker_field_checkbox extends Tracker_field_radio
483 {
484         var $sort_type = SORT_NUMERIC;
485         
486         function get_tag($empty=FALSE)
487         {
488                 $s_name = htmlspecialchars($this->name);
489                 $defaults = array_flip(preg_split('/\s*,\s*/',$this->default_value,-1,PREG_SPLIT_NO_EMPTY));
490                 $retval = '';
491                 foreach ($this->config->get($this->name) as $option)
492                 {
493                         $s_option = htmlspecialchars($option[0]);
494                         $checked = array_key_exists(trim($option[0]),$defaults) ?
495                                 ' checked="checked"' : '';
496                         $retval .= "<input type=\"checkbox\" name=\"{$s_name}[]\" value=\"$s_option\"$checked />$s_option\n";
497                 }
498                 
499                 return $retval;
500         }
501 }
502 class Tracker_field_hidden extends Tracker_field_radio
503 {
504         var $sort_type = SORT_NUMERIC;
505         
506         function get_tag($empty=FALSE)
507         {
508                 $s_name = htmlspecialchars($this->name);
509                 $s_default = htmlspecialchars($this->default_value);
510                 $retval = "<input type=\"hidden\" name=\"$s_name\" value=\"$s_default\" />\n";
511                 
512                 return $retval;
513         }
514 }
515 class Tracker_field_submit extends Tracker_field
516 {
517         function get_tag()
518         {
519                 $s_title = htmlspecialchars($this->title);
520                 $s_page = htmlspecialchars($this->page);
521                 $s_refer = htmlspecialchars($this->refer);
522                 $s_config = htmlspecialchars($this->config->config_name);
523                 
524                 return <<<EOD
525 <input type="submit" value="$s_title" />
526 <input type="hidden" name="plugin" value="tracker" />
527 <input type="hidden" name="_refer" value="$s_refer" />
528 <input type="hidden" name="_base" value="$s_page" />
529 <input type="hidden" name="_config" value="$s_config" />
530 EOD;
531         }
532 }
533 class Tracker_field_date extends Tracker_field
534 {
535         var $sort_type = SORT_NUMERIC;
536         
537         function format_cell($timestamp)
538         {
539                 return format_date($timestamp);
540         }
541 }
542 class Tracker_field_past extends Tracker_field
543 {
544         var $sort_type = SORT_NUMERIC;
545         
546         function format_cell($timestamp)
547         {
548                 return get_passage($timestamp,FALSE);
549         }
550         function get_value($value)
551         {
552                 return UTIME - $value;
553         }
554 }
555 ///////////////////////////////////////////////////////////////////////////
556 // °ìÍ÷ɽ¼¨
557 function plugin_tracker_list_convert()
558 {
559         global $vars;
560         
561         $config = 'default';
562         $page = $refer = $vars['page'];
563         $field = '_page';
564         $order = '';
565         $list = 'list'; 
566         $limit = NULL;
567         if (func_num_args())
568         {
569                 $args = func_get_args();
570                 switch (count($args))
571                 {
572                         case 4:
573                                 $limit = is_numeric($args[3]) ? $args[3] : $limit;
574                         case 3:
575                                 $order = $args[2];
576                         case 2:
577                                 $page = is_pagename($args[1]) ? $args[1] : $page;
578                         case 1:
579                                 $config = ($args[0] != '') ? $args[0] : $config;
580                                 list($config,$list) = array_pad(explode('/',$config,2),2,$list);
581                 }
582         }
583         return plugin_tracker_getlist($page,$refer,$config,$list,$order,$limit);
584 }
585 function plugin_tracker_list_action()
586 {
587         global $script,$vars,$_tracker_messages;
588         
589         $page = $refer = $vars['refer'];
590         $s_page = make_pagelink($page);
591         $config = $vars['config'];
592         $list = array_key_exists('list',$vars) ? $vars['list'] : 'list';
593         $order = array_key_exists('order',$vars) ? $vars['order'] : '_real:SORT_DESC';
594                 
595         return array(
596                 'msg' => $_tracker_messages['msg_list'],
597                 'body'=> str_replace('$1',$s_page,$_tracker_messages['msg_back']).
598                         plugin_tracker_getlist($page,$refer,$config,$list,$order)
599         );
600 }
601 function plugin_tracker_getlist($page,$refer,$config_name,$list,$order='',$limit=NULL)
602 {
603         $config = new Config('plugin/tracker/'.$config_name);
604         
605         if (!$config->read())
606         {
607                 return "<p>config file '".htmlspecialchars($config_name)."' is not exist.";
608         }
609         $config->config_name = $config_name;
610         $list = &new Tracker_list($page,$refer,$config,$list);
611         $list->sort($order);
612         return $list->toString($limit);
613 }
614
615 // °ìÍ÷¥¯¥é¥¹
616 class Tracker_list
617 {
618         var $page;
619         var $config;
620         var $list;
621         var $fields;
622         var $pattern;
623         var $pattern_fields;
624         var $rows;
625         var $order;
626         
627         function Tracker_list($page,$refer,&$config,$list)
628         {
629                 $this->page = $page;
630                 $this->config = &$config;
631                 $this->list = is_page($config->page.'/'.$list) ? $list : 'list';
632                 $this->fields = plugin_tracker_get_fields($page,$refer,$config);
633                 
634                 $pattern = join('',plugin_tracker_get_source($config->page.'/page'));
635                 // ¥Ö¥í¥Ã¥¯¥×¥é¥°¥¤¥ó¤ò¥Õ¥£¡¼¥ë¥É¤ËÃÖ´¹
636                 // #comment¤Ê¤É¤ÇÁ°¸å¤Ëʸ»úÎó¤ÎÁý¸º¤¬¤¢¤Ã¤¿¾ì¹ç¤Ë¡¢[_block_xxx]¤ËµÛ¤¤¹þ¤Þ¤»¤ë¤è¤¦¤Ë¤¹¤ë
637                 $pattern = preg_replace('/^\#([^\(\s]+)(?:\((.*)\))?\s*$/m','[_block_$1]',$pattern);
638                 
639                 // ¥Ñ¥¿¡¼¥ó¤òÀ¸À®
640                 $this->pattern = '';
641                 $this->pattern_fields = array();
642                 $pattern = preg_split('/\\\\\[(\w+)\\\\\]/',preg_quote($pattern,'/'),-1,PREG_SPLIT_DELIM_CAPTURE);
643                 while (count($pattern))
644                 {
645                         $this->pattern .= preg_replace('/\s+/','\\s*','(?>\\s*'.trim(array_shift($pattern)).'\\s*)');
646                         if (count($pattern))
647                         {
648                                 $field = array_shift($pattern);
649                                 $this->pattern_fields[] = $field;
650                                 $this->pattern .= '(.*)';
651                         }
652                 }
653                 // ¥Ú¡¼¥¸¤ÎÎóµó¤È¼è¤ê¹þ¤ß
654                 $this->rows = array();
655                 $pattern = "$page/";
656                 $pattern_len = strlen($pattern);
657                 foreach (get_existpages() as $_page)
658                 {
659                         if (strpos($_page,$pattern) === 0)
660                         {
661                                 $name = substr($_page,$pattern_len);
662                                 if (preg_match(TRACKER_LIST_EXCLUDE_PATTERN,$name))
663                                 {
664                                         continue;
665                                 }
666                                 $this->add($_page,$name);
667                         }
668                 }
669         }
670         function add($page,$name)
671         {
672                 static $moved = array();
673                 
674                 // Ìµ¸Â¥ë¡¼¥×ËÉ»ß
675                 if (array_key_exists($name,$this->rows))
676                 {
677                         return;
678                 }
679                 
680                 $source = plugin_tracker_get_source($page);
681                 if (preg_match('/move\sto\s(.+)/',$source[0],$matches))
682                 {
683                         $page = strip_bracket(trim($matches[1]));
684                         if (array_key_exists($page,$moved) or !is_page($page))
685                         {
686                                 return;
687                         }
688                         $moved[$page] = TRUE;
689                         return $this->add($page,$name);
690                 }
691                 $source = join('',preg_replace('/^(\*{1,3}.*)\[#[A-Za-z][\w-]+\](.*)$/','$1$2',$source));
692                 
693                 // ¥Ç¥Õ¥©¥ë¥ÈÃÍ
694                 $this->rows[$name] = array(
695                         '_page'  => "[[$page]]",
696                         '_refer' => $this->page,
697                         '_real'  => $name,
698                         '_update'=> get_filetime($page),
699                         '_past'  => get_filetime($page)
700                 );
701                 if ($this->rows[$name]['_match'] = preg_match("/{$this->pattern}/s",$source,$matches))
702                 {
703                         array_shift($matches);
704                         foreach ($this->pattern_fields as $key=>$field)
705                         {
706                                 $this->rows[$name][$field] = trim($matches[$key]);
707                         }
708                 }
709         }
710         function sort($order)
711         {
712                 if ($order == '')
713                 {
714                         return;
715                 }
716                 $names = array_flip(array_keys($this->fields));
717                 $this->order = array();
718                 foreach (explode(';',$order) as $item)
719                 {
720                         list($key,$dir) = array_pad(explode(':',$item),1,'ASC');
721                         if (!array_key_exists($key,$names))
722                         {
723                                 continue;
724                         }
725                         switch (strtoupper($dir))
726                         {
727                                 case 'SORT_ASC':
728                                 case 'ASC':
729                                 case SORT_ASC:
730                                         $dir = SORT_ASC;
731                                         break;
732                                 case 'SORT_DESC':
733                                 case 'DESC':
734                                 case SORT_DESC:
735                                         $dir = SORT_DESC;
736                                         break;
737                                 default:
738                                         continue;
739                         }
740                         $this->order[$key] = $dir;
741                 }
742                 $keys = array();
743                 $eval_arg = 'return array_multisort(';
744                 foreach ($this->order as $field=>$order)
745                 {
746                         if (!array_key_exists($field,$names))
747                         {
748                                 continue;
749                         }
750                         $eval_arg .= '$keys['."'$field'],".
751                                 $this->fields[$field]->sort_type.','.
752                                 $order.',';
753                         foreach ($this->rows as $row)
754                         {
755                                 $keys[$field][] = $this->fields[$field]->get_value($row[$field]);
756                         }
757                 }
758                 $eval_arg .= '$this->rows);';
759                 eval($eval_arg);
760         }
761         function replace_item($arr)
762         {
763                 $params = explode(',',$arr[1]);
764                 $name = array_shift($params);
765                 if ($name == '')
766                 {
767                         $str = '';
768                 }
769                 else if (array_key_exists($name,$this->items))
770                 {
771                         $str = $this->items[$name];
772                         if (array_key_exists($name,$this->fields))
773                         {
774                                 $str = $this->fields[$name]->format_cell($str);
775                         }
776                 }
777                 else
778                 {
779                         return $this->pipe ? str_replace('|','&#x7c;',$arr[0]) : $arr[0];
780                 }
781                 $style = count($params) ? $params[0] : $name;
782                 if (array_key_exists($style,$this->items)
783                         and array_key_exists($style,$this->fields))
784                 {
785                         $str = sprintf($this->fields[$style]->get_style($this->items[$style]),$str);
786                 }
787                 return $this->pipe ? str_replace('|','&#x7c;',$str) : $str;
788         }
789         function replace_title($arr)
790         {
791                 global $script;
792                 
793                 $field = $sort = $arr[1];
794                 if ($sort == '_name' or $sort == '_page')
795                 {
796                         $sort = '_real';
797                 }
798                 if (!array_key_exists($field,$this->fields))
799                 {
800                         return $arr[0];
801                 }
802                 $dir = SORT_ASC;
803                 $arrow = '';
804                 $order = $this->order;
805                 
806                 if (array_key_exists($sort,$order))
807                 {
808                         $b_end = ($sort == array_shift(array_keys($order)));
809                         $b_order = ($order[$sort] == SORT_ASC);
810                         $dir = ($b_end xor $b_order) ? SORT_ASC : SORT_DESC;
811                         $arrow = $b_end ? ($b_order ? '&uarr;' : '&darr;') : '';
812                         unset($order[$sort]);
813                 }
814                 $title = $this->fields[$field]->title;
815                 $r_page = rawurlencode($this->page);
816                 $r_config = rawurlencode($this->config->config_name);
817                 $r_list = rawurlencode($this->list);
818                 $_order = array("$sort:$dir");
819                 foreach ($order as $key=>$value)
820                 {
821                         $_order[] = "$key:$value";
822                 }
823                 $r_order = rawurlencode(join(';',$_order));
824                 
825                 return "[[$title$arrow>$script?plugin=tracker_list&refer=$r_page&config=$r_config&list=$r_list&order=$r_order]]";
826         }
827         function toString($limit=NULL)
828         {
829                 global $_tracker_messages;
830                 
831                 $source = '';
832                 $body = array();
833                 
834                 if ($limit !== NULL and count($this->rows) > $limit)
835                 {
836                         $source = str_replace(
837                                 array('$1','$2'),
838                                 array(count($this->rows),$limit),
839                                 $_tracker_messages['msg_limit'])."\n";
840                         $this->rows = array_splice($this->rows,0,$limit);
841                 }
842                 if (count($this->rows) == 0)
843                 {
844                         return '';
845                 }
846                 foreach (plugin_tracker_get_source($this->config->page.'/'.$this->list) as $line)
847                 {
848                         if (preg_match('/^\|(.+)\|[hHfFcC]$/',$line))
849                         {
850                                 $source .= preg_replace_callback('/\[([^\[\]]+)\]/',array(&$this,'replace_title'),$line);
851                         }
852                         else
853                         {
854                                 $body[] = $line;
855                         }
856                 }
857                 foreach ($this->rows as $key=>$row)
858                 {
859                         if (!TRACKER_LIST_SHOW_ERROR_PAGE and !$row['_match'])
860                         {
861                                 continue;
862                         } 
863                         $this->items = $row;
864                         foreach ($body as $line)
865                         {
866                                 if (trim($line) == '')
867                                 {
868                                         $source .= $line;
869                                         continue;
870                                 }
871                                 $this->pipe = ($line{0} == '|' or $line{0} == ':');
872                                 $source .= preg_replace_callback('/\[([^\[\]]+)\]/',array(&$this,'replace_item'),$line);
873                         }
874                 }
875                 return convert_html($source);
876         }
877 }
878 function plugin_tracker_get_source($page)
879 {
880         $source = get_source($page);
881         // ¸«½Ð¤·¤Î¸ÇÍ­IDÉô¤òºï½ü
882         $source = preg_replace('/^(\*{1,3}.*)\[#[A-Za-z][\w-]+\](.*)$/m','$1$2',$source);
883         // #freeze¤òºï½ü
884         return preg_replace('/^#freeze\s*$/m','',$source);
885 }
886 ?>