<?php
// PukiWiki - Yet another WikiWikiWeb clone
-// $Id: tracker.inc.php,v 1.28 2005/01/23 08:29:20 henoheno Exp $
+// $Id: tracker.inc.php,v 1.124 2011/01/25 15:01:01 henoheno Exp $
+// Copyright (C) 2003-2005, 2007 PukiWiki Developers Team
+// License: GPL v2 or (at your option) any later version
//
// Issue tracker plugin (See Also bugtrack plugin)
-// tracker_list¤Çɽ¼¨¤·¤Ê¤¤¥Ú¡¼¥¸Ì¾(Àµµ¬É½¸½¤Ç)
-// 'SubMenu'¥Ú¡¼¥¸ ¤ª¤è¤Ó '/'¤ò´Þ¤à¥Ú¡¼¥¸¤ò½ü³°¤¹¤ë
+// tracker_listで表示しないページ名(正規表現で)
+// 'SubMenu'ページ および '/'を含むページを除外する
define('TRACKER_LIST_EXCLUDE_PATTERN','#^SubMenu$|/#');
-// À©¸Â¤·¤Ê¤¤¾ì¹ç¤Ï¤³¤Á¤é
+// 制限しない場合はこちら
//define('TRACKER_LIST_EXCLUDE_PATTERN','#(?!)#');
-// ¹àÌܤμè¤ê½Ð¤·¤Ë¼ºÇÔ¤·¤¿¥Ú¡¼¥¸¤ò°ìÍ÷¤Ëɽ¼¨¤¹¤ë
+// 項目の取り出しに失敗したページを一覧に表示する
define('TRACKER_LIST_SHOW_ERROR_PAGE',TRUE);
function plugin_tracker_convert()
if (!$config->read())
{
- return "<p>config file '".htmlspecialchars($config_name)."' not found.</p>";
+ return "<p>config file '".htmlsc($config_name)."' not found.</p>";
}
$config->config_name = $config_name;
$config = new Config('plugin/tracker/'.$config_name);
if (!$config->read())
{
- return "<p>config file '".htmlspecialchars($config_name)."' not found.</p>";
+ return "<p>config file '".htmlsc($config_name)."' not found.</p>";
}
$config->config_name = $config_name;
$source = $config->page.'/page';
{
return array(
'msg'=>'cannot write',
- 'body'=>'page name ('.htmlspecialchars($refer).') is not valid.'
+ 'body'=>'page name ('.htmlsc($refer).') is not valid.'
);
}
if (!is_page($source))
{
return array(
'msg'=>'cannot write',
- 'body'=>'page template ('.htmlspecialchars($source).') is not exist.'
+ 'body'=>'page template ('.htmlsc($source).') is not exist.'
);
}
- // ¥Ú¡¼¥¸Ì¾¤ò·èÄê
+ // ページ名を決定
$base = $post['_base'];
$num = 0;
$name = (array_key_exists('_name',$post)) ? $post['_name'] : '';
$real = ++$num;
$page = "$base/$real";
}
- // ¥Ú¡¼¥¸¥Ç¡¼¥¿¤òÀ¸À®
+ // ページデータを生成
$postdata = plugin_tracker_get_source($source);
- // µ¬Äê¤Î¥Ç¡¼¥¿
+ // è¦\8få®\9aã\81®ã\83\87ã\83¼ã\82¿
$_post = array_merge($post,$_FILES);
$_post['_date'] = $now;
$_post['_page'] = $page;
if (!$config->read())
{
- return "config file '".htmlspecialchars($config_name)."' not found.";
+ return "config file '".htmlsc($config_name)."' not found.";
}
$config->config_name = $config_name;
return $fields[$field]->get_tag();
}
*/
-// ¥Õ¥£¡¼¥ë¥É¥ª¥Ö¥¸¥§¥¯¥È¤ò¹½ÃÛ¤¹¤ë
+// フィールドオブジェクトを構築する
function plugin_tracker_get_fields($base,$refer,&$config)
{
global $now,$_tracker_messages;
$fields = array();
- // ͽÌó¸ì
+ // 予約語
foreach (array(
- '_date'=>'text', // Åê¹ÆÆü»þ
- '_update'=>'date', // ºÇ½ª¹¹¿·
- '_past'=>'past', // ·Ð²á(passage)
- '_page'=>'page', // ¥Ú¡¼¥¸Ì¾
- '_name'=>'text', // »ØÄꤵ¤ì¤¿¥Ú¡¼¥¸Ì¾
- '_real'=>'real', // ¼ÂºÝ¤Î¥Ú¡¼¥¸Ì¾
- '_refer'=>'page', // »²¾È¸µ(¥Õ¥©¡¼¥à¤Î¤¢¤ë¥Ú¡¼¥¸)
- '_base'=>'page', // ´ð½à¥Ú¡¼¥¸
- '_submit'=>'submit' // Äɲåܥ¿¥ó
+ '_date'=>'text', // 投稿日時
+ '_update'=>'date', // 最終更新
+ '_past'=>'past', // 経過(passage)
+ '_page'=>'page', // ページ名
+ '_name'=>'text', // 指定されたページ名
+ '_real'=>'real', // 実際のページ名
+ '_refer'=>'page', // å\8f\82ç\85§å\85\83(ã\83\95ã\82©ã\83¼ã\83 ã\81®ã\81\82ã\82\8bã\83\9aã\83¼ã\82¸)
+ '_base'=>'page', // å\9fºæº\96ã\83\9aã\83¼ã\82¸
+ '_submit'=>'submit' // 追加ボタン
) as $field=>$class)
{
$class = 'Tracker_field_'.$class;
foreach ($config->get('fields') as $field)
{
- // 0=>¹àÌÜ̾ 1=>¸«½Ð¤· 2=>·Á¼° 3=>¥ª¥×¥·¥ç¥ó 4=>¥Ç¥Õ¥©¥ë¥ÈÃÍ
+ // 0=>項目名 1=>見出し 2=>形式 3=>オプション 4=>デフォルト値
$class = 'Tracker_field_'.$field[2];
if (!class_exists($class))
- { // ¥Ç¥Õ¥©¥ë¥È
+ { // デフォルト
$class = 'Tracker_field_text';
$field[2] = 'text';
$field[3] = '20';
}
return $fields;
}
-// ¥Õ¥£¡¼¥ë¥É¥¯¥é¥¹
+// ã\83\95ã\82£ã\83¼ã\83«ã\83\89ã\82¯ã\83©ã\82¹
class Tracker_field
{
var $name;
var $config;
var $data;
var $sort_type = SORT_REGULAR;
+ var $id = 0;
function Tracker_field($field,$page,$refer,&$config)
{
global $post;
+ static $id = 0;
+ $this->id = ++$id;
$this->name = $field[0];
$this->title = $field[1];
$this->values = explode(',',$field[3]);
function get_tag()
{
- $s_name = htmlspecialchars($this->name);
- $s_size = htmlspecialchars($this->values[0]);
- $s_value = htmlspecialchars($this->default_value);
+ $s_name = htmlsc($this->name);
+ $s_size = htmlsc($this->values[0]);
+ $s_value = htmlsc($this->default_value);
return "<input type=\"text\" name=\"$s_name\" size=\"$s_size\" value=\"$s_value\" />";
}
}
function get_tag()
{
- $s_name = htmlspecialchars($this->name);
- $s_cols = htmlspecialchars($this->values[0]);
- $s_rows = htmlspecialchars($this->values[1]);
- $s_value = htmlspecialchars($this->default_value);
+ $s_name = htmlsc($this->name);
+ $s_cols = htmlsc($this->values[0]);
+ $s_rows = htmlsc($this->values[1]);
+ $s_value = htmlsc($this->default_value);
return "<textarea name=\"$s_name\" cols=\"$s_cols\" rows=\"$s_rows\">$s_value</textarea>";
}
function format_cell($str)
}
function get_tag()
{
- $s_name = htmlspecialchars($this->name);
- $s_size = htmlspecialchars($this->values[0]);
+ $s_name = htmlsc($this->name);
+ $s_size = htmlsc($this->values[0]);
return "<input type=\"text\" name=\"$s_name\" size=\"$s_size\" />";
}
function get_key($str)
function get_tag()
{
- $s_name = htmlspecialchars($this->name);
- $s_size = htmlspecialchars($this->values[0]);
+ $s_name = htmlsc($this->name);
+ $s_size = htmlsc($this->values[0]);
return "<input type=\"file\" name=\"$s_name\" size=\"$s_size\" />";
}
function format_value($str)
{
require_once(PLUGIN_DIR.'attach.inc.php');
$result = attach_upload($_FILES[$this->name],$this->page);
- if ($result['result']) // ¥¢¥Ã¥×¥í¡¼¥ÉÀ®¸ù
+ if ($result['result']) // アップロード成功
{
return parent::format_value($this->page.'/'.$_FILES[$this->name]['name']);
}
}
- // ¥Õ¥¡¥¤¥ë¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤«¡¢¥¢¥Ã¥×¥í¡¼¥É¤Ë¼ºÇÔ
+ // ファイルが指定されていないか、アップロードに失敗
return parent::format_value('');
}
}
function get_tag()
{
- $s_name = htmlspecialchars($this->name);
+ $s_name = htmlsc($this->name);
$retval = '';
+ $id = 0;
foreach ($this->config->get($this->name) as $option)
{
- $s_option = htmlspecialchars($option[0]);
+ $s_option = htmlsc($option[0]);
$checked = trim($option[0]) == trim($this->default_value) ? ' checked="checked"' : '';
- $retval .= "<input type=\"radio\" name=\"$s_name\" value=\"$s_option\"$checked />$s_option\n";
+ ++$id;
+ $s_id = '_p_tracker_' . $s_name . '_' . $this->id . '_' . $id;
+ $retval .= '<input type="radio" name="' . $s_name . '" id="' . $s_id .
+ '" value="' . $s_option . '"' . $checked . ' />' .
+ '<label for="' . $s_id . '">' . $s_option . '</label>' . "\n";
}
return $retval;
function get_tag($empty=FALSE)
{
- $s_name = htmlspecialchars($this->name);
+ $s_name = htmlsc($this->name);
$s_size = (array_key_exists(0,$this->values) and is_numeric($this->values[0])) ?
- ' size="'.htmlspecialchars($this->values[0]).'"' : '';
+ ' size="'.htmlsc($this->values[0]).'"' : '';
$s_multiple = (array_key_exists(1,$this->values) and strtolower($this->values[1]) == 'multiple') ?
' multiple="multiple"' : '';
$retval = "<select name=\"{$s_name}[]\"$s_size$s_multiple>\n";
$defaults = array_flip(preg_split('/\s*,\s*/',$this->default_value,-1,PREG_SPLIT_NO_EMPTY));
foreach ($this->config->get($this->name) as $option)
{
- $s_option = htmlspecialchars($option[0]);
+ $s_option = htmlsc($option[0]);
$selected = array_key_exists(trim($option[0]),$defaults) ? ' selected="selected"' : '';
$retval .= " <option value=\"$s_option\"$selected>$s_option</option>\n";
}
function get_tag($empty=FALSE)
{
- $s_name = htmlspecialchars($this->name);
+ $s_name = htmlsc($this->name);
$defaults = array_flip(preg_split('/\s*,\s*/',$this->default_value,-1,PREG_SPLIT_NO_EMPTY));
$retval = '';
+ $id = 0;
foreach ($this->config->get($this->name) as $option)
{
- $s_option = htmlspecialchars($option[0]);
+ $s_option = htmlsc($option[0]);
$checked = array_key_exists(trim($option[0]),$defaults) ?
' checked="checked"' : '';
- $retval .= "<input type=\"checkbox\" name=\"{$s_name}[]\" value=\"$s_option\"$checked />$s_option\n";
+ ++$id;
+ $s_id = '_p_tracker_' . $s_name . '_' . $this->id . '_' . $id;
+ $retval .= '<input type="checkbox" name="' . $s_name .
+ '[]" id="' . $s_id . '" value="' . $s_option . '"' . $checked . ' />' .
+ '<label for="' . $s_id . '">' . $s_option . '</label>' . "\n";
}
return $retval;
function get_tag($empty=FALSE)
{
- $s_name = htmlspecialchars($this->name);
- $s_default = htmlspecialchars($this->default_value);
+ $s_name = htmlsc($this->name);
+ $s_default = htmlsc($this->default_value);
$retval = "<input type=\"hidden\" name=\"$s_name\" value=\"$s_default\" />\n";
return $retval;
{
function get_tag()
{
- $s_title = htmlspecialchars($this->title);
- $s_page = htmlspecialchars($this->page);
- $s_refer = htmlspecialchars($this->refer);
- $s_config = htmlspecialchars($this->config->config_name);
+ $s_title = htmlsc($this->title);
+ $s_page = htmlsc($this->page);
+ $s_refer = htmlsc($this->refer);
+ $s_config = htmlsc($this->config->config_name);
return <<<EOD
<input type="submit" value="$s_title" />
}
}
///////////////////////////////////////////////////////////////////////////
-// °ìÍ÷ɽ¼¨
+// 一覧表示
function plugin_tracker_list_convert()
{
global $vars;
if (!$config->read())
{
- return "<p>config file '".htmlspecialchars($config_name)."' is not exist.";
+ return "<p>config file '".htmlsc($config_name)."' is not exist.</p>";
}
$config->config_name = $config_name;
return $list->toString($limit);
}
-// °ìÍ÷¥¯¥é¥¹
+// ä¸\80覧ã\82¯ã\83©ã\82¹
class Tracker_list
{
var $page;
$this->fields = plugin_tracker_get_fields($page,$refer,$config);
$pattern = join('',plugin_tracker_get_source($config->page.'/page'));
- // ¥Ö¥í¥Ã¥¯¥×¥é¥°¥¤¥ó¤ò¥Õ¥£¡¼¥ë¥É¤ËÃÖ´¹
- // #comment¤Ê¤É¤ÇÁ°¸å¤Ëʸ»úÎó¤ÎÁý¸º¤¬¤¢¤Ã¤¿¾ì¹ç¤Ë¡¢[_block_xxx]¤ËµÛ¤¤¹þ¤Þ¤»¤ë¤è¤¦¤Ë¤¹¤ë
+ // ブロックプラグインをフィールドに置換
+ // #commentなどで前後に文字列の増減があった場合に、[_block_xxx]に吸い込ませるようにする
$pattern = preg_replace('/^\#([^\(\s]+)(?:\((.*)\))?\s*$/m','[_block_$1]',$pattern);
- // ¥Ñ¥¿¡¼¥ó¤òÀ¸À®
+ // パターンを生成
$this->pattern = '';
$this->pattern_fields = array();
$pattern = preg_split('/\\\\\[(\w+)\\\\\]/',preg_quote($pattern,'/'),-1,PREG_SPLIT_DELIM_CAPTURE);
$this->pattern .= '(.*)';
}
}
- // ¥Ú¡¼¥¸¤ÎÎóµó¤È¼è¤ê¹þ¤ß
+ // ページの列挙と取り込み
$this->rows = array();
$pattern = "$page/";
$pattern_len = strlen($pattern);
{
static $moved = array();
- // ̵¸Â¥ë¡¼¥×ËÉ»ß
+ // 無限ループ防止
if (array_key_exists($name,$this->rows))
{
return;
}
$source = join('',preg_replace('/^(\*{1,3}.*)\[#[A-Za-z][\w-]+\](.*)$/','$1$2',$source));
- // ¥Ç¥Õ¥©¥ë¥ÈÃÍ
+ // デフォルト値
$this->rows[$name] = array(
'_page' => "[[$page]]",
'_refer' => $this->page,
}
foreach ($this->rows as $row)
{
- $keys[$field][] = $this->fields[$field]->get_value($row[$field]);
+ $keys[$field][] = isset($row[$field])? $this->fields[$field]->get_value($row[$field]) : '';
}
$params[] = $keys[$field];
$params[] = $this->fields[$field]->sort_type;
if (is_array($order) && isset($order[$sort]))
{
- $index = array_flip(array_keys($order));
+ // BugTrack2/106: Only variables can be passed by reference from PHP 5.0.5
+ $order_keys = array_keys($order); // with array_shift();
+
+ $index = array_flip($order_keys);
$pos = 1 + $index[$sort];
- $b_end = ($sort == array_shift(array_keys($order)));
+ $b_end = ($sort == array_shift($order_keys));
$b_order = ($order[$sort] == SORT_ASC);
$dir = ($b_end xor $b_order) ? SORT_ASC : SORT_DESC;
$arrow = '&br;'.($b_order ? '↑' : '↓')."($pos)";
- unset($order[$sort]);
+
+ unset($order[$sort], $order_keys);
}
$title = $this->fields[$field]->title;
$r_page = rawurlencode($this->page);
function plugin_tracker_get_source($page)
{
$source = get_source($page);
- // ¸«½Ð¤·¤Î¸ÇÍIDÉô¤òºï½ü
+ // 見出しの固有ID部を削除
$source = preg_replace('/^(\*{1,3}.*)\[#[A-Za-z][\w-]+\](.*)$/m','$1$2',$source);
- // #freeze¤òºï½ü
+ // #freezeを削除
return preg_replace('/^#freeze\s*$/im', '', $source);
}
?>