<?php
-// $Id: bugtrack.inc.php,v 1.25 2005/04/03 03:33:47 henoheno Exp $
+// PukiWiki - Yet another WikiWikiWeb clone.
+// bugtrack.inc.php
+// Copyright
+// 2002-2016 PukiWiki Development Team
+// 2002 Y.MASUI GPL2 http://masui.net/pukiwiki/ masui@masui.net
//
-// PukiWiki BugTrack plugin
-//
-// Copyright:
-// 2002-2005 PukiWiki Developers Team
-// 2002 Y.MASUI GPL2 http://masui.net/pukiwiki/ masui@masui.net
+// BugTrack plugin
// Numbering format
define('PLUGIN_BUGTRACK_NUMBER_FORMAT', '%d'); // Like 'page/1'
$init = TRUE;
$_plugin_bugtrack = array(
- 'priority_list' => array('¶ÛµÞ', '½ÅÍ×', 'ÉáÄÌ', 'Äã'),
- 'state_list' => array('Äó°Æ', 'Ãå¼ê', 'CVSÂÔ¤Á', '´°Î»', 'ÊÝα', 'µÑ²¼'),
- 'state_sort' => array('Ãå¼ê', 'CVSÂÔ¤Á', 'ÊÝα', '´°Î»', 'Äó°Æ', 'µÑ²¼'),
+ 'priority_list' => array('緊急', '重要', '普通', '低'),
+ 'state_list' => array('提案', '着手', 'CVS待ち', '完了', '保留', '却下'),
+ 'state_sort' => array('着手', 'CVS待ち', '保留', '完了', '提案', '却下'),
'state_bgcolor' => array('#ccccff', '#ffcc99', '#ccddcc', '#ccffcc', '#ffccff', '#cccccc', '#ff3333'),
'header_bgcolor' => '#ffffcc',
- 'base' => '¥Ú¡¼¥¸',
- 'summary' => '¥µ¥Þ¥ê',
- 'nosummary'=> '¤³¤³¤Ë¥µ¥Þ¥ê¤òµÆþ¤·¤Æ²¼¤µ¤¤',
- 'priority' => 'Í¥Àè½ç°Ì',
- 'state' => '¾õÂÖ',
- 'name' => 'Åê¹Æ¼Ô',
- 'noname' => '̵̾¤·¤µ¤ó',
- 'date' => 'Åê¹ÆÆü',
- 'body' => '¥á¥Ã¥»¡¼¥¸',
- 'category' => '¥«¥Æ¥´¥ê¡¼',
- 'pagename' => '¥Ú¡¼¥¸Ì¾',
- 'pagename_comment' => '¶õÍó¤Î¤Þ¤Þ¤À¤È¼«Æ°Åª¤Ë¥Ú¡¼¥¸Ì¾¤¬¿¶¤é¤ì¤Þ¤¹¡£',
- 'version_comment' => '¶õÍó¤Ç¤â¹½¤¤¤Þ¤»¤ó',
- 'version' => '¥Ð¡¼¥¸¥ç¥ó',
- 'submit' => 'ÄɲÃ'
+ 'base' => 'ã\83\9aã\83¼ã\82¸',
+ 'summary' => 'サマリ',
+ 'nosummary'=> 'ここにサマリを記入して下さい',
+ 'priority' => '優先順位',
+ 'state' => '状態',
+ 'name' => '投稿者',
+ 'noname' => '名無しさん',
+ 'date' => '投稿日',
+ 'body' => 'ã\83¡ã\83\83ã\82»ã\83¼ã\82¸',
+ 'category' => 'ã\82«ã\83\86ã\82´ã\83ªã\83¼',
+ 'pagename' => 'ページ名',
+ 'pagename_comment' => '空欄のままだと自動的にページ名が振られます。',
+ 'version_comment' => '空欄でも構いません',
+ 'version' => 'バージョン',
+ 'submit' => '追加'
);
}
$selected = '';
for ($i = 0; $i < $count; ++$i) {
if ($i == ($count - 1)) $selected = ' selected="selected"'; // The last one
- $priority_list = htmlspecialchars($_plugin_bugtrack['priority_list'][$i]);
+ $priority_list = htmlsc($_plugin_bugtrack['priority_list'][$i]);
$select_priority .= ' <option value="' . $priority_list . '"' .
$selected . '>' . $priority_list . '</option>' . "\n";
}
$select_state = "\n";
for ($i = 0; $i < count($_plugin_bugtrack['state_list']); ++$i) {
- $state_list = htmlspecialchars($_plugin_bugtrack['state_list'][$i]);
+ $state_list = htmlsc($_plugin_bugtrack['state_list'][$i]);
$select_state .= ' <option value="' . $state_list . '">' .
$state_list . '</option>' . "\n";
}
} else {
$encoded_category = '<select name="category" id="_p_bugtrack_category_' . $id . '">';
foreach ($category as $_category) {
- $s_category = htmlspecialchars($_category);
+ $s_category = htmlsc($_category);
$encoded_category .= '<option value="' . $s_category . '">' .
$s_category . '</option>' . "\n";
}
}
$script = get_script_uri();
- $s_base = htmlspecialchars($base);
- $s_name = htmlspecialchars($_plugin_bugtrack['name']);
- $s_category = htmlspecialchars($_plugin_bugtrack['category']);
- $s_priority = htmlspecialchars($_plugin_bugtrack['priority']);
- $s_state = htmlspecialchars($_plugin_bugtrack['state']);
- $s_pname = htmlspecialchars($_plugin_bugtrack['pagename']);
- $s_pnamec = htmlspecialchars($_plugin_bugtrack['pagename_comment']);
- $s_version = htmlspecialchars($_plugin_bugtrack['version']);
- $s_versionc = htmlspecialchars($_plugin_bugtrack['version_comment']);
- $s_summary = htmlspecialchars($_plugin_bugtrack['summary']);
- $s_body = htmlspecialchars($_plugin_bugtrack['body']);
- $s_submit = htmlspecialchars($_plugin_bugtrack['submit']);
+ $s_base = htmlsc($base);
+ $s_name = htmlsc($_plugin_bugtrack['name']);
+ $s_category = htmlsc($_plugin_bugtrack['category']);
+ $s_priority = htmlsc($_plugin_bugtrack['priority']);
+ $s_state = htmlsc($_plugin_bugtrack['state']);
+ $s_pname = htmlsc($_plugin_bugtrack['pagename']);
+ $s_pnamec = htmlsc($_plugin_bugtrack['pagename_comment']);
+ $s_version = htmlsc($_plugin_bugtrack['version']);
+ $s_versionc = htmlsc($_plugin_bugtrack['version_comment']);
+ $s_summary = htmlsc($_plugin_bugtrack['summary']);
+ $s_body = htmlsc($_plugin_bugtrack['body']);
+ $s_submit = htmlsc($_plugin_bugtrack['submit']);
$body = <<<EOD
<form action="$script" method="post">
<table border="0">
$post['version'], $post['body']);
pkwk_headers_sent();
- header('Location: ' . get_script_uri() . '?' . rawurlencode($page));
+ header('Location: ' . get_script_uri() . '?' . pagename_urlencode($page));
exit;
}
$postdata = plugin_bugtrack_template($base, $summary, $name, $priority,
$state, $category, $version, $body);
- $id = $jump = 1;
- $page = $base . '/' . sprintf(PLUGIN_BUGTRACK_NUMBER_FORMAT, $id);
- while (is_page($page)) {
- $id = $jump;
- $jump += 50;
- $page = $base . '/' . sprintf(PLUGIN_BUGTRACK_NUMBER_FORMAT, $jump);
+ $page_list = plugin_bugtrack_get_page_list($base, false);
+ usort($page_list, '_plugin_bugtrack_list_paganame_compare');
+ if (count($page_list) == 0) {
+ $id = 1;
+ } else {
+ $latest_page = $page_list[count($page_list) - 1]['name'];
+ $id = intval(substr($latest_page, strlen($base) + 1)) + 1;
}
$page = $base . '/' . sprintf(PLUGIN_BUGTRACK_NUMBER_FORMAT, $id);
- while (is_page($page))
- $page = $base . '/' . sprintf(PLUGIN_BUGTRACK_NUMBER_FORMAT, ++$id);
if ($pagename == '') {
page_write($page, $postdata);
- ${_plugin_bugtrack['priority']}: $priority
- ${_plugin_bugtrack['state' ]}: $state
- ${_plugin_bugtrack['category']}: $category
-- ${_plugin_bugtrack['date' ]}: now?
+- ${_plugin_bugtrack['date' ]}: &now;
- ${_plugin_bugtrack['version' ]}: $version
** ${_plugin_bugtrack['body']}
// ----------------------------------------
// BugTrack-List plugin
-// #bugtrack_list plugin itself
+function _plugin_bugtrack_list_paganame_compare($a, $b)
+{
+ return strnatcmp($a['name'], $b['name']);
+}
+
+
+/**
+ * Get page list for "$page/"
+ */
+function plugin_bugtrack_get_page_list($page, $needs_filetime) {
+ $page_list = array();
+ $pattern = $page . '/';
+ $pattern_len = strlen($pattern);
+ foreach (get_existpages() as $p) {
+ if (strncmp($p, $pattern, $pattern_len) === 0 && pkwk_ctype_digit(substr($p, $pattern_len))) {
+ if ($needs_filetime) {
+ $page_list[] = array('name'=>$p,'filetime'=>get_filetime($p));
+ } else {
+ $page_list[] = array('name'=>$p);
+ }
+ }
+ }
+ return $page_list;
+}
+
+/**
+ * #bugtrack_list plugin itself
+ *
+ * Cache specification
+ * * Enable only for PHP5.4+ (Because of JSON_UNESCAPE_UNICODE)
+ * * Use cached values for articles that have the unchaged filemtime
+ * * Invalidate all cache data everyday
+ */
function plugin_bugtrack_list_convert()
{
global $script, $vars, $_plugin_bugtrack;
-
+ $cache_format_version = 1;
+ $cache_expire_time = 60 * 60 * 24;
+ $cache_refresh_time_prev;
+ static $cache_enabled;
+ if (!isset($cache_enabled)) {
+ $cache_enabled = defined('JSON_UNESCAPED_UNICODE'); // PHP 5.4+
+ }
$page = $vars['page'];
if (func_num_args()) {
list($_page) = func_get_args();
$_page = get_fullname(strip_bracket($_page), $page);
if (is_pagename($_page)) $page = $_page;
}
-
$data = array();
- $pattern = $page . '/';
- $pattern_len = strlen($pattern);
- foreach (get_existpages() as $page)
- if (strpos($page, $pattern) === 0 && is_numeric(substr($page, $pattern_len)))
- array_push($data, plugin_bugtrack_list_pageinfo($page));
-
+ $page_list = plugin_bugtrack_get_page_list($page, true);
+ usort($page_list, '_plugin_bugtrack_list_paganame_compare');
$count_list = count($_plugin_bugtrack['state_list']);
+ $data_map = array();
+ if ($cache_enabled) {
+ // Cache management
+ $data_updated = true;
+ $cache_filepath = CACHE_DIR . encode($page) . '.bugtrack';
+ $json_cached = pkwk_file_get_contents($cache_filepath);
+ if ($json_cached) {
+ $wrapdata = json_decode($json_cached);
+ if (is_object($wrapdata)) {
+ if (isset($wrapdata->version, $wrapdata->pages, $wrapdata->refreshed_at)) {
+ $cache_time_prev = $wrapdata->refreshed_at;
+ if ($cache_format_version == $wrapdata->version
+ && time() < $cache_time_prev + $cache_expire_time) {
+ $data = $wrapdata->pages;
+ $cache_refresh_time_prev = $cache_time_prev;
+ }
+ }
+ }
+ if (is_array($data) && !empty($data)) {
+ $all_ok = true;
+ foreach ($page_list as $i=>$page_info) {
+ list($page_name, $no, $summary, $name, $priority, $state, $category, $filetime) = $data[$i];
+ if ($filetime !== $page_info['filetime'] || $page_name !== $page_info['name']) {
+ $all_ok = false;
+ break;
+ }
+ }
+ if (!$all_ok) {
+ // Clear cache
+ foreach ($data as $d) {
+ $page_name = $d[0];
+ $data_map[$page_name] = $d;
+ }
+ $data = array();
+ }
+ }
+ }
+ }
- $table = array();
- for ($i = 0; $i <= $count_list + 1; ++$i) $table[$i] = array();
-
- foreach ($data as $line) {
- list($page, $no, $summary, $name, $priority, $state, $category) = $line;
- foreach (array('summary', 'name', 'priority', 'state', 'category') as $item)
- $$item = htmlspecialchars($$item);
- $page_link = make_pagelink($page);
+ if (empty($data) || !empty($data_map)) {
+ // No cache
+ foreach ($page_list as $page_info) {
+ $page_name = $page_info['name'];
+ $filled = false;
+ if (isset($data_map[$page_name])) {
+ $d = $data_map[$page_name];
+ list($page_name, $no, $summary, $name, $priority, $state, $category, $filetime) = $d;
+ if ($filetime == $page_info['filetime']) {
+ $data[] = $d;
+ $filled = true;
+ }
+ }
+ if (!$filled) {
+ $data[] = plugin_bugtrack_list_pageinfo($page_info['name'], null, true, $page_info['filetime']);
+ }
+ }
+ foreach ($data as $i=>$line) {
+ list($page_name, $no, $summary, $name, $priority, $state, $category, $filetime, $state_no_cached, $html_cached) = $line;
+ if (isset($state_no_cached) && isset($html_cached)) {
+ continue;
+ }
+ foreach (array('summary', 'name', 'priority', 'state', 'category') as $item)
+ $$item = htmlsc($$item);
+ $page_link = make_pagelink($page_name);
- $state_no = array_search($state, $_plugin_bugtrack['state_sort']);
- if ($state_no === NULL || $state_no === FALSE) $state_no = $count_list;
- $bgcolor = htmlspecialchars($_plugin_bugtrack['state_bgcolor'][$state_no]);
+ $state_no = array_search($state, $_plugin_bugtrack['state_sort']);
+ if ($state_no === NULL || $state_no === FALSE) $state_no = $count_list;
+ $bgcolor = htmlsc($_plugin_bugtrack['state_bgcolor'][$state_no]);
- $row = <<<EOD
+ $row = <<<EOD
<tr>
<td style="background-color:$bgcolor">$page_link</td>
<td style="background-color:$bgcolor">$state</td>
<td style="background-color:$bgcolor">$summary</td>
</tr>
EOD;
- $table[$state_no][$no] = $row;
+ $rec = &$data[$i];
+ $rec[] = $state_no; // color number
+ $rec[] = $row; // HTML content
+ }
+ if ($cache_enabled) {
+ // Save cache
+ if (isset($cache_refresh_time_prev)) {
+ $refreshed_at = $cache_refresh_time_prev;
+ } else {
+ $refreshed_at = time();
+ }
+ $json = array('refreshed_at'=>$refreshed_at, 'pages'=>$data, 'version'=>$cache_format_version);
+ $cache_body = json_encode($json, JSON_UNESCAPED_UNICODE + JSON_UNESCAPED_SLASHES);
+ file_put_contents($cache_filepath, $cache_body, LOCK_EX);
+ }
+ }
+ $table = array();
+ for ($i = 0; $i <= $count_list + 1; ++$i) $table[$i] = array();
+ foreach ($data as $line) {
+ list($page_name, $no, $summary, $name, $priority, $state, $category, $filetime, $state_no, $html) = $line;
+ $table[$state_no][$no] = $html;
}
-
$table_html = ' <tr>' . "\n";
- $bgcolor = htmlspecialchars($_plugin_bugtrack['header_bgcolor']);
+ $bgcolor = htmlsc($_plugin_bugtrack['header_bgcolor']);
foreach (array('pagename', 'state', 'priority', 'category', 'name', 'summary') as $item)
$table_html .= ' <th style="background-color:' . $bgcolor . '">' .
- htmlspecialchars($_plugin_bugtrack[$item]) . '</th>' . "\n";
+ htmlsc($_plugin_bugtrack[$item]) . '</th>' . "\n";
$table_html .= ' </tr>' . "\n";
-
for ($i = 0; $i <= $count_list; ++$i) {
ksort($table[$i], SORT_NUMERIC);
$table_html .= join("\n", $table[$i]);
}
-
return '<table border="1" width="100%">' . "\n" .
$table_html . "\n" .
'</table>';
}
// Get one set of data from a page (or a page moved to $page)
-function plugin_bugtrack_list_pageinfo($page, $no = NULL, $recurse = TRUE)
+function plugin_bugtrack_list_pageinfo($page, $no = NULL, $recurse = TRUE, $filetime = NULL)
{
global $WikiName, $InterWikiName, $BracketName, $_plugin_bugtrack;
$regex = "/move\s*to\s*($WikiName|$InterWikiName|\[\[$BracketName\]\])/";
$match = array();
if ($recurse && preg_match($regex, $source[0], $match))
- return plugin_bugtrack_list_pageinfo(strip_bracket($match[1]), $no, FALSE);
+ return plugin_bugtrack_list_pageinfo(strip_bracket($match[1]), $no, FALSE, $filetime);
$body = join("\n", $source);
foreach(array('summary', 'name', 'priority', 'state', 'category') as $item) {
make_heading($summary);
}
- return array($page, $no, $summary, $name, $priority, $state, $category);
+ return array($page, $no, $summary, $name, $priority, $state, $category, $filetime);
}
-?>