Revisão | 58602f80d335066bea0f1ada03dc429f6d196b99 (tree) |
---|---|
Hora | 2007-09-09 01:30:25 |
Autor | henoheno <henoheno> |
Commiter | henoheno |
Cleanup/Simplify/Todo
* Tracker_field, Tracker_list: Added dispose() to clear some static variables. -- When you create-and-destroy some instances of a class serially without dispose, they will use the same static variable causing side-effects. Note you should not use static variables if you can. When you create multiple instances of a class simultaneously, they will use the same static variables causing terrible side-effects.
* Remove unused arguments
* Less grobal variables
@@ -1,12 +1,13 @@ | ||
1 | 1 | <?php |
2 | 2 | // PukiWiki - Yet another WikiWikiWeb clone |
3 | -// $Id: tracker.inc.php,v 1.44 2007/09/05 15:17:39 henoheno Exp $ | |
3 | +// $Id: tracker.inc.php,v 1.45 2007/09/08 16:30:25 henoheno Exp $ | |
4 | 4 | // Copyright (C) 2003-2005, 2007 PukiWiki Developers Team |
5 | 5 | // License: GPL v2 or (at your option) any later version |
6 | 6 | // |
7 | 7 | // Issue tracker plugin (See Also bugtrack plugin) |
8 | 8 | |
9 | -define('PLUGIN_TRACKER_USAGE', '#tracker([config[/form][,basepage]])'); | |
9 | +define('PLUGIN_TRACKER_USAGE', '#tracker([config[/form][,basepage]])'); | |
10 | +define('PLUGIN_TRACKER_LIST_USAGE', '#tracker_list([config][[,base][,field:sort[;field:sort ...][,limit]]])'); | |
10 | 11 | |
11 | 12 | define('PLUGIN_TRACKER_DEFAULT_CONFIG', 'default'); |
12 | 13 | define('PLUGIN_TRACKER_DEFAULT_FORM', 'form'); |
@@ -58,17 +59,19 @@ function plugin_tracker_convert() | ||
58 | 59 | return '#tracker: Form \'' . make_pagelink($form) . '\' not found<br />'; |
59 | 60 | } |
60 | 61 | |
61 | - $from = $to = $hidden = array(); | |
62 | + $from = $to = $hidden = array(); | |
62 | 63 | $fields = plugin_tracker_get_fields($base, $refer, $config); |
63 | 64 | foreach (array_keys($fields) as $field) { |
64 | 65 | $from[] = '[' . $field . ']'; |
65 | 66 | $_to = $fields[$field]->get_tag(); |
66 | 67 | if (is_a($fields[$field], 'Tracker_field_hidden')) { |
67 | - $hidden[] = $_to; | |
68 | 68 | $to[] = ''; |
69 | + $hidden[] = $_to; | |
69 | 70 | } else { |
70 | 71 | $to[] = $_to; |
71 | 72 | } |
73 | + $fields[$field]->dispose(); | |
74 | + unset($fields[$field]); | |
72 | 75 | } |
73 | 76 | |
74 | 77 | $script = get_script_uri(); |
@@ -141,14 +144,14 @@ function plugin_tracker_action() | ||
141 | 144 | // Creating an empty page, before attaching files |
142 | 145 | pkwk_touch_file(get_filename($page)); |
143 | 146 | |
144 | - // Load $fields | |
145 | - $fields = plugin_tracker_get_fields($page, $refer, $config); | |
146 | 147 | $from = $to = array(); |
148 | + $fields = plugin_tracker_get_fields($page, $refer, $config); | |
147 | 149 | foreach (array_keys($fields) as $field) { |
148 | 150 | $from[] = '[' . $field . ']'; |
149 | 151 | $to[] = isset($_post[$field]) ? $fields[$field]->format_value($_post[$field]) : ''; |
152 | + $fields[$field]->dispose(); | |
153 | + unset($fields[$field]); | |
150 | 154 | } |
151 | - unset($fields); | |
152 | 155 | |
153 | 156 | // Load $template |
154 | 157 | $template = plugin_tracker_get_source($template_page); |
@@ -195,7 +198,7 @@ function plugin_tracker_action() | ||
195 | 198 | // Construct $fields (an array of Tracker_field objects) |
196 | 199 | function plugin_tracker_get_fields($base, $refer, & $config) |
197 | 200 | { |
198 | - global $now, $_tracker_messages; | |
201 | + global $now; | |
199 | 202 | |
200 | 203 | $fields = array(); |
201 | 204 |
@@ -205,7 +208,7 @@ function plugin_tracker_get_fields($base, $refer, & $config) | ||
205 | 208 | // $field[2]: Field type |
206 | 209 | // $field[3]: Option ("size", "cols", "rows", etc) |
207 | 210 | // $field[4]: Default value |
208 | - $class = 'Tracker_field_' . $field[2]; | |
211 | + $class = 'Tracker_field_' . $field[2]; | |
209 | 212 | if (! class_exists($class)) { |
210 | 213 | // Default |
211 | 214 | $field[2] = 'text'; |
@@ -231,7 +234,7 @@ function plugin_tracker_get_fields($base, $refer, & $config) | ||
231 | 234 | ) as $fieldname => $type) |
232 | 235 | { |
233 | 236 | if (isset($fields[$fieldname])) continue; |
234 | - $field = array($fieldname, $_tracker_messages['btn' . $fieldname], '', '20', ''); | |
237 | + $field = array($fieldname, plugin_tracker_message('btn' . $fieldname), '', '20', ''); | |
235 | 238 | $class = 'Tracker_field_' . $type; |
236 | 239 | $fields[$fieldname] = & new $class($field, $base, $refer, $config); |
237 | 240 | } |
@@ -256,7 +259,7 @@ class Tracker_field | ||
256 | 259 | function Tracker_field($field, $page, $refer, & $config) |
257 | 260 | { |
258 | 261 | global $post; |
259 | - static $id = 0; | |
262 | + static $id = 0; // Unique id per instance | |
260 | 263 | |
261 | 264 | $this->id = ++$id; |
262 | 265 | $this->name = $field[0]; |
@@ -269,12 +272,13 @@ class Tracker_field | ||
269 | 272 | $this->data = isset($post[$this->name]) ? $post[$this->name] : ''; |
270 | 273 | } |
271 | 274 | |
275 | + // XHTML part inside a form | |
272 | 276 | function get_tag() |
273 | 277 | { |
274 | 278 | return ''; |
275 | 279 | } |
276 | 280 | |
277 | - function get_style($str) | |
281 | + function get_style() | |
278 | 282 | { |
279 | 283 | return '%s'; |
280 | 284 | } |
@@ -289,9 +293,15 @@ class Tracker_field | ||
289 | 293 | return $str; |
290 | 294 | } |
291 | 295 | |
296 | + // Compare key for Tracker_list->sort() | |
292 | 297 | function get_value($value) |
293 | 298 | { |
294 | - return $value; | |
299 | + return $value; // Default: $value itself | |
300 | + } | |
301 | + | |
302 | + // Release the resources | |
303 | + function dispose() | |
304 | + { | |
295 | 305 | } |
296 | 306 | } |
297 | 307 |
@@ -418,7 +428,7 @@ class Tracker_field_file extends Tracker_field_format | ||
418 | 428 | ' size="' . htmlspecialchars($this->values[0]) . '" />'; |
419 | 429 | } |
420 | 430 | |
421 | - function format_value($str) | |
431 | + function format_value() | |
422 | 432 | { |
423 | 433 | if (isset($_FILES[$this->name])) { |
424 | 434 |
@@ -471,16 +481,29 @@ class Tracker_field_radio extends Tracker_field_format | ||
471 | 481 | function get_value($value) |
472 | 482 | { |
473 | 483 | static $options = array(); |
484 | + | |
485 | + if ($value === NULL) { | |
486 | + $options = array(); | |
487 | + return NULL; | |
488 | + } | |
489 | + | |
474 | 490 | if (! isset($options[$this->name])) { |
475 | - $options[$this->name] = | |
476 | - array_flip( | |
477 | - array_map(create_function('$arr', 'return $arr[0];'), | |
491 | + $options[$this->name] = array_flip( | |
492 | + array_map( | |
493 | + create_function('$arr', 'return $arr[0];'), | |
478 | 494 | $this->config->get($this->name) |
479 | 495 | ) |
480 | 496 | ); |
481 | 497 | } |
498 | + | |
499 | + // Int or $value | |
482 | 500 | return isset($options[$this->name][$value]) ? $options[$this->name][$value] : $value; |
483 | 501 | } |
502 | + | |
503 | + function dispose() | |
504 | + { | |
505 | + $this->get_value(NULL); | |
506 | + } | |
484 | 507 | } |
485 | 508 | |
486 | 509 | class Tracker_field_select extends Tracker_field_radio |
@@ -498,9 +521,7 @@ class Tracker_field_select extends Tracker_field_radio | ||
498 | 521 | ''; |
499 | 522 | |
500 | 523 | $retval = '<select name="' . $s_name . '[]"' . $s_size . $s_multiple . '>' . "\n"; |
501 | - if ($empty){ | |
502 | - $retval .= ' <option value=""></option>' . "\n"; | |
503 | - } | |
524 | + if ($empty) $retval .= ' <option value=""></option>' . "\n"; | |
504 | 525 | $defaults = array_flip(preg_split('/\s*,\s*/', $this->default_value, -1, PREG_SPLIT_NO_EMPTY)); |
505 | 526 | foreach ($this->config->get($this->name) as $option) { |
506 | 527 | $s_option = htmlspecialchars($option[0]); |
@@ -517,7 +538,7 @@ class Tracker_field_checkbox extends Tracker_field_radio | ||
517 | 538 | { |
518 | 539 | var $sort_type = SORT_NUMERIC; |
519 | 540 | |
520 | - function get_tag($empty=FALSE) | |
541 | + function get_tag() | |
521 | 542 | { |
522 | 543 | $retval = ''; |
523 | 544 |
@@ -547,7 +568,7 @@ class Tracker_field_hidden extends Tracker_field_radio | ||
547 | 568 | { |
548 | 569 | var $sort_type = SORT_NUMERIC; |
549 | 570 | |
550 | - function get_tag($empty=FALSE) | |
571 | + function get_tag() | |
551 | 572 | { |
552 | 573 | return '<input type="hidden"' . |
553 | 574 | ' name="' . htmlspecialchars($this->name) . '"' . |
@@ -608,7 +629,6 @@ function plugin_tracker_list_convert() | ||
608 | 629 | |
609 | 630 | $config = PLUGIN_TRACKER_DEFAULT_CONFIG; |
610 | 631 | $page = $refer = isset($vars['page']) ? $vars['page'] : ''; |
611 | - $field = '_page'; | |
612 | 632 | $order = ''; |
613 | 633 | $list = 'list'; |
614 | 634 | $limit = NULL; |
@@ -618,14 +638,15 @@ function plugin_tracker_list_convert() | ||
618 | 638 | $args = func_get_args(); |
619 | 639 | switch (count($args)) { |
620 | 640 | case 4: |
621 | - $limit = is_numeric($args[3]) ? $args[3] : $limit; | |
641 | + if (! is_numeric($args[3])) return PLUGIN_TRACKER_LIST_USAGE . '<br />'; | |
642 | + $limit = intval($args[3]); | |
622 | 643 | case 3: |
623 | 644 | $order = $args[2]; |
624 | 645 | case 2: |
625 | - $args[1] = get_fullname($args[1], $page); | |
626 | - $page = is_pagename($args[1]) ? $args[1] : $page; | |
646 | + $arg = get_fullname($args[1], $page); | |
647 | + if (is_pagename($arg)) $page = $arg; | |
627 | 648 | case 1: |
628 | - $config = ($args[0] != '') ? $args[0] : $config; | |
649 | + if ($args[0] != '') $config = $args[0]; | |
629 | 650 | list($config, $list) = array_pad(explode('/', $config, 2), 2, $list); |
630 | 651 | } |
631 | 652 | } |
@@ -634,7 +655,7 @@ function plugin_tracker_list_convert() | ||
634 | 655 | |
635 | 656 | function plugin_tracker_list_action() |
636 | 657 | { |
637 | - global $script, $vars, $_tracker_messages; | |
658 | + global $vars; | |
638 | 659 | |
639 | 660 | $page = $refer = isset($vars['refer']) ? $vars['refer'] : ''; |
640 | 661 | $config = isset($vars['config']) ? $vars['config'] : ''; |
@@ -643,8 +664,8 @@ function plugin_tracker_list_action() | ||
643 | 664 | |
644 | 665 | $s_page = make_pagelink($page); |
645 | 666 | return array( |
646 | - 'msg' => $_tracker_messages['msg_list'], | |
647 | - 'body'=> str_replace('$1', $s_page, $_tracker_messages['msg_back']) . | |
667 | + 'msg' => plugin_tracker_message('msg_list'), | |
668 | + 'body'=> str_replace('$1', $s_page, plugin_tracker_message('msg_back')) . | |
648 | 669 | plugin_tracker_list_render($page, $refer, $config, $list, $order) |
649 | 670 | ); |
650 | 671 | } |
@@ -662,7 +683,13 @@ function plugin_tracker_list_render($page, $refer, $config_name, $list, $order_c | ||
662 | 683 | |
663 | 684 | $list = & new Tracker_list($page, $refer, $config, $list); |
664 | 685 | $list->sort($order_commands); |
665 | - return $list->toString($limit); | |
686 | + $result = $list->toString($limit); | |
687 | + if ($result == FALSE) { | |
688 | + $result = '#tracker_list: Pages under \'' . htmlspecialchars($page) . '/\' not found' . '<br />'; | |
689 | + } | |
690 | + $list->dispose(); | |
691 | + | |
692 | + return $result; | |
666 | 693 | } |
667 | 694 | |
668 | 695 | // Listing class |
@@ -724,6 +751,11 @@ class Tracker_list | ||
724 | 751 | |
725 | 752 | if (isset($done[$page])) return; |
726 | 753 | |
754 | + if ($page === NULL) { | |
755 | + $done = array(); | |
756 | + return; | |
757 | + } | |
758 | + | |
727 | 759 | $done[$page] = TRUE; |
728 | 760 | |
729 | 761 | $source = plugin_tracker_get_source($page); |
@@ -732,35 +764,38 @@ class Tracker_list | ||
732 | 764 | $matches = array(); |
733 | 765 | if (! empty($source) && preg_match('/move\sto\s(.+)/', $source[0], $matches)) { |
734 | 766 | $to_page = strip_bracket(trim($matches[1])); |
735 | - if (! is_page($to_page)) { | |
736 | - return; // Invalid | |
767 | + if (is_page($to_page)) { | |
768 | + unset($source); // Release | |
769 | + $this->add($to_page, $name); // Recurse(Rescan) | |
770 | + return; | |
737 | 771 | } else { |
738 | - return $this->add($to_page, $name); // Rescan | |
772 | + return; // Invalid | |
739 | 773 | } |
740 | 774 | } |
741 | 775 | |
742 | 776 | // Default |
743 | - $this->rows[$name] = array( | |
777 | + $filetime = get_filetime($page); | |
778 | + $row = array( | |
744 | 779 | '_page' => '[[' . $page . ']]', |
745 | 780 | '_refer' => $this->page, |
746 | 781 | '_real' => $name, |
747 | - '_update' => get_filetime($page), | |
748 | - '_past' => get_filetime($page), | |
782 | + '_update' => $filetime, | |
783 | + '_past' => $filetime, | |
749 | 784 | '_match' => FALSE, |
750 | 785 | ); |
751 | 786 | |
752 | 787 | // Redefine |
753 | 788 | $matches = array(); |
754 | - $this->rows[$name]['_match'] = | |
755 | - preg_match('/' . $this->pattern . '/s', implode('', $source), $matches); | |
789 | + $row['_match'] = preg_match('/' . $this->pattern . '/s', implode('', $source), $matches); | |
756 | 790 | unset($source); |
757 | - | |
758 | - if ($this->rows[$name]['_match']) { | |
791 | + if ($row['_match']) { | |
759 | 792 | array_shift($matches); |
760 | 793 | foreach ($this->pattern_fields as $key => $field) { |
761 | - $this->rows[$name][$field] = trim($matches[$key]); | |
794 | + $row[$field] = trim($matches[$key]); | |
762 | 795 | } |
763 | 796 | } |
797 | + | |
798 | + $this->rows[$name] = $row; | |
764 | 799 | } |
765 | 800 | |
766 | 801 | // Sort $this->rows with $order_commands |
@@ -822,10 +857,10 @@ class Tracker_list | ||
822 | 857 | call_user_func_array('array_multisort', $params); |
823 | 858 | $this->order = $orders; |
824 | 859 | |
825 | - return TRUE; | |
860 | + return TRUE; | |
826 | 861 | } |
827 | 862 | |
828 | - // Used with preg_replace_callback() at toString() | |
863 | + // Used with preg_replace_callback() at toString() | |
829 | 864 | function replace_item($arr) |
830 | 865 | { |
831 | 866 | $params = explode(',', $arr[1]); |
@@ -852,8 +887,6 @@ class Tracker_list | ||
852 | 887 | // Used with preg_replace_callback() at toString() |
853 | 888 | function replace_title($arr) |
854 | 889 | { |
855 | - global $script; | |
856 | - | |
857 | 890 | $field = $sort = $arr[1]; |
858 | 891 | if (! isset($this->fields[$field])) return $arr[0]; |
859 | 892 |
@@ -887,36 +920,48 @@ class Tracker_list | ||
887 | 920 | } |
888 | 921 | $r_order = rawurlencode(join(';', $_order)); |
889 | 922 | |
923 | + $script = get_script_uri(); | |
890 | 924 | return '[[' . $title . $arrow . '>' . |
891 | 925 | $script . '?plugin=tracker_list&refer=' . $r_page . |
892 | 926 | '&config=' . $r_config . |
893 | 927 | '&list=' . $r_list . '&order=' . $r_order . ']]'; |
894 | 928 | } |
895 | 929 | |
896 | - function toString($limit = NULL) | |
930 | + function toString($limit = 10) | |
897 | 931 | { |
898 | - global $_tracker_messages; | |
932 | + if (empty($this->rows)) return FALSE; | |
933 | + | |
934 | + $limit = max(1, intval($limit)); | |
935 | + | |
936 | + $count = $_count = count($this->rows); | |
937 | + if ($limit != 0 && $count > $limit) { | |
938 | + $rows = array_slice($this->rows, 0, $limit); | |
939 | + $_count = count($rows); | |
940 | + } else { | |
941 | + $rows = $this->rows; | |
942 | + } | |
899 | 943 | |
900 | 944 | $source = array(); |
901 | - $count = count($this->rows); | |
902 | - if ($limit !== NULL && $count > $limit) { | |
945 | + | |
946 | + if ($count > $_count) { | |
947 | + // Message | |
903 | 948 | $source[] = str_replace( |
904 | - array('$1', '$2'), | |
905 | - array($count, $limit), | |
906 | - $_tracker_messages['msg_limit']) . "\n"; | |
907 | - $this->rows = array_splice($this->rows, 0, $limit); | |
949 | + array('$1', '$2' ), | |
950 | + array($count, $_count), | |
951 | + plugin_tracker_message('msg_limit') | |
952 | + ) . "\n"; | |
908 | 953 | } |
909 | - if (empty($this->rows)) return ''; | |
910 | 954 | |
911 | 955 | $body = array(); |
912 | 956 | foreach (plugin_tracker_get_source($this->config->page . '/' . $this->list) as $line) { |
913 | - if (preg_match('/^\|(.+)\|[hHfFcC]$/', $line)) { | |
957 | + if (preg_match('/^\|(.+)\|[hfc]$/i', $line)) { | |
958 | + // Table decolations | |
914 | 959 | $source[] = preg_replace_callback('/\[([^\[\]]+)\]/', array(& $this, 'replace_title'), $line); |
915 | 960 | } else { |
916 | 961 | $body[] = $line; |
917 | 962 | } |
918 | 963 | } |
919 | - foreach ($this->rows as $row) { | |
964 | + foreach ($rows as $row) { | |
920 | 965 | if (! PLUGIN_TRACKER_LIST_SHOW_ERROR_PAGE && ! $row['_match']) continue; |
921 | 966 | |
922 | 967 | $this->items = $row; |
@@ -932,6 +977,12 @@ class Tracker_list | ||
932 | 977 | |
933 | 978 | return convert_html(implode('', $source)); |
934 | 979 | } |
980 | + | |
981 | + function dispose() | |
982 | + { | |
983 | + $this->add(NULL, NULL); | |
984 | + return; | |
985 | + } | |
935 | 986 | } |
936 | 987 | |
937 | 988 | function plugin_tracker_get_source($page, $join = FALSE) |
@@ -944,4 +995,11 @@ function plugin_tracker_get_source($page, $join = FALSE) | ||
944 | 995 | // Remove #freeze-es |
945 | 996 | return preg_replace('/^#freeze\s*$/im', '', $source); |
946 | 997 | } |
998 | + | |
999 | +function plugin_tracker_message($key) | |
1000 | +{ | |
1001 | + global $_tracker_messages; | |
1002 | + return isset($_tracker_messages[$key]) ? $_tracker_messages[$key] : 'NOMESSAGE'; | |
1003 | +} | |
1004 | + | |
947 | 1005 | ?> |