: * De-specialized the original code (hardcoded -> config vars) * Stripped $PageUrl vars in template * Allowed space after label ("Label : content") * Limited parsing to the PITS header (leave out the comments below) * Allowed links in any table fields (ex: [[~Author]]) * Stripped LF and other spaces between HTML lines (avoid vspace) * Added HTML entities charset for some systems (mainly NTFS ?) 0.21 - Modifications by Didier Lebrun : * Fixed label parsing for i18n charsets * Fixed description entry in edit template (LF problem) * Transfered default values from edit template to form template * Suppressed unuseful $PitsGroup global var * Added (:pitstrail[ PageName|Label]:) markup and assorted function 0.22 - Modification by Fabrice Mousset * Fixed (:pitlist:) makeup (directive ==> directives) * Fixed misspelled variable $PitsIDLenght ==> $PitsIDLength * Fixed PITS page list to add $PitsIDLength into scan pattern * Fixed FmtPitsList() function when no PITS are defined (deadlock) * Fixed PitsTrail() function when less than 2 PITS are defined (deadlock) 0.23 - Modification by Fabrice Mousset * Fixed html code output to remove '\' miss placed * Added $PitsNoItemText variable to personalize output when no PITS present 0.24 2013-05-09 - Modification by Peter Bowers * Added backslashes back into the template that had gotten removed. * Swapped preg_split with a call to ParseArgs() in FmtPitsList to standardize arg handling * Standardized version handling with $RecipeInfo, get rid of define(PITS_VERSION, ...), switched to (preferred) date-named version */ $RecipeInfo['PITS']['Version'] = '2013-05-09'; # ---- Config vars ---- # ## These vars can be overriden in the PITS group configuration file ## (local/YourPITSGroupName.php). Whenever you see something like: ## SDV($SomeVar, "default setup"); ## you must put in your config something like: ## $SomeVar = "custom setup"; ## SDV() is a just PmWiki function allowing to set a default value ## when none has been setup in the config. ## Number of chars for page names SDV($PitsIDLength, 5); ## Template for empty PITS list SDV($PitsNoItemText, "No bugs ;-)"); ## Label to field name mapping. Labels and names can be whatever you like, ## as long as they are consistent through all configuration vars. SDV($PitsLabels, array( 'Summary' => 'summary', 'Created' => 'created', 'Status' => 'status', 'Category' => 'category', 'From' => 'author', 'Assigned' => 'assigned', 'Priority' => 'priority', 'Version' => 'version', 'OS' => 'os', 'Description' => 'description' )); ## Template for the input form SDV($PitsFormTemplateFmt, "
Author:
Summary:
Category:
Priority: Low High
PmWiki Version:
OS/Webserver/
PHP Version:
Description:
"); ## Template for filling the edit box with input data ## "----" MUST be present at the end to separate the entries from the ## eventual comments that could be added afterwards. SDV($PitsEditTemplateFmt, " Summary: \$summary Created: \$created Status: \$status Category: \$category From: [[~\$author]] Assigned: \$assigned Priority: \$priority Version: \$version OS: \$os Description:[[<<]]\$description ---- !!!Comments ---- (:pitstrail:) "); ## Template for list table. ## The "(/)PitsListItemFmt" tags MUST be present as delimiters of the entry part. SDV($PitsListTemplateFmt, "
Issue# Created Category Version Priority Status Summary
[[\$name]] \$created \$category \$version \$priority \$status \$summary
"); ## HTML styles SDV($PitsStylesFmt, " .pitsform {} .pitsform td.label { text-align:right; font-weight:bold; } .pitsform td.input {} .pitspage {} .pitspage span.label {} .pitspage span.data {} .pitslist {} .pitslist th { background-color:#eeeeee; } .pitslist th a { text-decoration:none; } "); ## Edit form top message SDV($PitsEditMessageFmt, "

Please review and make any edits to your issue below, then press 'Save'.

"); ## Fields that can be filtered by name=criteria args SDV($PitsListFilters, array('summary','created','status','category','priority','version')); ## Criteria used for default and complementary sorting after explicit criteria SDV($PitsListDefaultSort, array('-priority','status','category','name')); ## Charset for HTML entities conversion ('ISO-8859-1' usually, 'UTF-8' on NTFS systems) SDV($PitsHtmlEntitiesCharset, 'ISO-8859-1'); # ---- end of Config vars ---- # $HTMLStylesFmt[] = $PitsStylesFmt; markup('pitsform', 'inline', '/\\(:pitsform:\\)/e', "Keep(PitsForm(\$pagename))"); markup('pitslist', 'directives', '/\\(:pitslist\\s*(.*?):\\)/e', "FmtPitsList('', \$pagename, array('q' => PSS('$1')))"); markup('pitsread', 'directives', '/^('.implode('|', array_keys($PitsLabels)) . ')\s*:(.*)/', "<:block>
$1: $2
"); markup('pitstrail', ']#', $tmpl); if(count($sect) != 3) Abort("\$PitsListTemplateFmt MUST have 3 sections !"); $out[] = FmtPageName(array_shift($sect), $pagename); $argopts = ParseArgs($opt['q']); foreach ($argopts as $k=>$v) { if ($k && $v && $k != '#') $opt[strtolower($k)] = $v; } # foreach($terms as $t) # { # if (trim($t) == '') # continue; # if (preg_match('/([^\'":=]*)[:=]([\'"]?)(.*?)\\2$/', $t,$match)) # $opt[strtolower($match[1])] = $match[3]; # } $n = 0; $plist = array(); foreach($pitslist as $p) { $page = ReadPage($p); list($head) = preg_split('/\n----/', $page['text'], 0); preg_match_all('/(^|\n)([^:]*):(\s*\\[\\[<<\\]\\])?([^\n]*)/', $head,$match); $fields = array(); for($i = 0; $i < count($match[2]); $i++) $fields[$PitsLabels[trim($match[2][$i])]] = htmlentities(trim($match[4][$i]), ENT_QUOTES, $PitsHtmlEntitiesCharset); foreach($PitsListFilters as $h) { if (!@$opt[$h]) continue; foreach(preg_split('/[ ,]/', $opt[$h]) as $t) { if (substr($t, 0, 1) != '-' && substr($t, 0, 1) != '!') { if (strpos(strtolower(@$fields[$h]), strtolower($t)) === false) continue 3; } else if (strpos(strtolower(@$fields[$h]), strtolower(substr($t,1))) !== false) continue 3; } } $plist[$n] = $fields; list(, $plist[$n]['name']) = explode('.', $p); $n++; } if($n == 0) { return FmtPageName($PitsNoItemText, $pagename); } $cmp = CreateOrderFunction(implode(',', array_merge(array(@$opt['order']), (array)$PitsListDefaultSort))); usort($plist, $cmp); $tr = array_shift($sect); foreach($plist as $p) { $out[] = PitsEvalTemplate($p,$tr); } $out[] = array_shift($sect); return FmtPageName(implode('', $out), $pagename); } ## This function creates a WikiTrail based on the current page number function PitsTrail($pagename, $trailindex='') { global $PitsIDLength; list($group, $name) = explode('.', $pagename); trim($trailindex); if(empty($trailindex)) $trailindex = $group; $trailindex = '[[' . $trailindex . ']]'; # $pitslist = ListPages("/^$group\\.\\d+$/"); $pitslist = ListPages("/^$group\\.\\d{" . $PitsIDLength . "}$/"); ## There must be at least 2 PITS to display the trail! if(count($pitslist) < 2) return ""; sort($pitslist); $i = @$name-1; list(,$min) = explode('.', array_shift($pitslist)); for($i; $i >= @$min; $i--) { $prev = sprintf("%0" . $PitsIDLength . "d", @$i); if(PageExists("$group.$prev")) { $prev = '[[' . $prev . ']]'; break; } $prev = ''; } $i = @$name+1; list(,$max) = explode('.', array_pop($pitslist)); for($i; $i <= @$max; $i++) { $next = sprintf("%0" . $PitsIDLength . "d", @$i); if(PageExists("$group.$next")) { $next = '[[' . $next . ']]'; break; } $next = ''; } return "<< $prev | $trailindex | $next >>"; } ## This function creates specialized ordering functions needed to ## (more efficiently) perform sorts on arbitrary sets of criteria. function CreateOrderFunction($order) { $code = ''; foreach(preg_split('/[\\s,|]+/', strtolower($order), -1, PREG_SPLIT_NO_EMPTY) as $o) { if (substr($o, 0, 1) == '-') { $r = '-'; $o = substr($o, 1); } else $r=''; if (preg_match('/\\W/', $o)) continue; $code .= "\$c=strcasecmp(@\$x['$o'],@\$y['$o']); if (\$c!=0) return $r\$c;\n"; } $code .= "return 0;\n"; return create_function('$x,$y', $code); } ## This function is used to evaluate the templates while insulating their ## vars from potential name conflicts function PitsEvalTemplate($hash, $tmpl) { global $Author,$Now; foreach($hash as $k=>$v) $$k = $v; return(@eval("return(\"$tmpl\");")); } ?>