goba Sat Mar 23 17:44:03 2002 EDT Modified files: /phpdoc/scripts revcheck.php Log: Renewed revcheck code, separated logic from presentation [mostly], added color types, revision types, colors to translators table, a new file summary table, removed green files, etc... Please test, there may be some problems under the hood, though it seems OK for the hu translation without maintainer restrictions...
Index: phpdoc/scripts/revcheck.php diff -u phpdoc/scripts/revcheck.php:1.18 phpdoc/scripts/revcheck.php:1.19 --- phpdoc/scripts/revcheck.php:1.18 Fri Mar 22 18:30:33 2002 +++ phpdoc/scripts/revcheck.php Sat Mar 23 17:44:02 2002 @@ -34,14 +34,6 @@ If you specify <maintainer>, the script only checks the files maintaned by the person you add here - Revision comment syntax for translated files: - - <!-- EN-Revision: 1.34 Maintainer: tom Status: ready --> - - If the revision number is not (yet) known: - - <!-- EN-Revision: n/a Maintainer: tom Status: working --> - Read more about Revision comments and related funcionality in the PHP Documentation Howto. @@ -53,206 +45,365 @@ exit; } - // CONFIG SECTION - $docdir = "../"; // Main directory of the PHP documentation (one dir up in cvs) +// Long runtime +set_time_limit(0); + +// A file is criticaly "outdated' if +define("ALERT_REV", 10); // translation is 10 or more revisions behind the en one +define("ALERT_SIZE", 10); // translation is 10 or more kB smaller than the en one +define("ALERT_DATE", -30); // translation is 30 or more days older than the en one + +// Revision marks used to flag files +define("REV_ACTUAL", 1); // actual file +define("REV_NOREV", 2); // file with revision comment without revision +define("REV_CRITICAL", 3); // criticaly old / small / outdated +define("REV_OLD", 4); // outdated file +define("REV_NOTAG", 5); // file without revision comment +define("REV_NOTRANS", 6); // file without translation + +define("REV_CREDIT", 7); // only used in translators list +define("REV_WIP", 8); // only used in translators list + +define("NORMHEAD", 9); // only used in table outputs (css) + +// Colors used to mark files by status (colors for the above types) +$CSS = array( + REV_ACTUAL => "background-color: #68D888; color: #000000;", + REV_NOREV => "background-color: #f4a460; color: #000000;", + REV_CRITICAL => "background-color: #ff6347; color: #000000;", #ff0000 + REV_OLD => "background-color: #eee8aa; color: #000000;", + REV_NOTAG => "background-color: #dcdcdc; color: #000000;", + REV_NOTRANS => "background-color: #dcdcdc; color: #000000;", + REV_CREDIT => "background-color: #dcdcdc; color: #000000;", + REV_WIP => "background-color: #dcdcdc; color: #000000;", + NORMHEAD => "background-color: #666699; color: #ffffff;", +); + +// Option for the link to cvs.php.net: normal: "&f=h" +// long diff: "&f=h&num=10", unified (text): "&f=u" +define("CVS_OPT", "&f=h&num=10"); + +// Initializing variables from parameters +$LANG = $argv[1]; +if ($argc == 3) { + $MAINT = $argv[2]; +} else { + $MAINT = ""; +} - // Warn with red color if - $r_alert = 10; // the translation is $r_alert or more revisions behind the en one - $s_alert = 10; // the translation is $s_alert or more kB smaller than the en one - $t_alert = 30; // the translation is $t_alert or more days older than the en one - - // Option for the link to the cvs.php.net: normal: "&f=h" - // long diff: "&f=h&num=10", unified (text): "&f=u" - $cvs_opt = "&f=h&num=10"; - - /*********************************************************************/ - /* Nothing to modify below this line */ - /*********************************************************************/ - - // Long runtime - set_time_limit(0); - - // Initializing arrays and vars - $missed_files = array(); - $miss_tag = array(); - $t_alert = -1 * $t_alert; - $lang = $argv[1]; - if ($argc == 3) { $maintainer = $argv[2]; } - else { $maintainer = ""; } +// Main directory of the PHP documentation (one dir up +// in cvs). We do need the trailing slash! +$DOCDIR = "../"; - /*********************************************************************/ - /* Here starts the functions part */ - /*********************************************************************/ - - // Grabs the revision tag from the file given - function get_tag($file, $val = "en-rev") - { +// ========================================================================= +// Functions to get revision info and credits from a file +// ========================================================================= + +// Grabs the revision tag from the file given +function get_tag($file, $val = "en-rev") +{ - // Read the first 200 chars, the comment should be at + // Read the first 200 chars. The comment should be at // the begining of the file $fp = @fopen($file, "r") or die ("Unable to read $file."); $line = fread($fp, 200); fclose($fp); - // Checking for english CVS revision tag - if ($val=="en-rev") { - preg_match("/<!-- .Revision: \d+\.(\d+) . -->/", $line, $match); - return ($match[1]); - } - // Checking for the translations "revision tag" - else { - preg_match ("/<!--\s*EN-Revision:\s*\d+\.(\d+)\s*Maintainer:\s*(".$val. - ")\s*Status:\s*(.+)\s*-->/", $line, $match); + // Check for English CVS revision tag (. is for $ in the preg!), + // Return if this was needed (it should be there) + if ($val == "en-rev") { + preg_match("/<!-- .Revision: \d+\.(\d+) . -->/", $line, $match); + return $match[1]; } + + // No match before the preg + $match = array(); + + // Check for the translations "revision tag" + preg_match ("/<!--\s*EN-Revision:\s*\d+\.(\d+)\s*Maintainer:\s*(" + . $val . ")\s*Status:\s*(.+)\s*-->/", + $line, + $match + ); + // The tag with revision number is not found so search - // for n/a revision comment + // for n/a revision comment (comment where revision is not known) if (count($match) == 0) { - preg_match ("'<!--\s*EN-Revision:\s*(n/a)\s*Maintainer:\s*(".$val. - ")\s*Status:\s*(.+)\s*-->'", $line, $match); + preg_match ("'<!--\s*EN-Revision:\s*(n/a)\s*Maintainer:\s*(" + . $val . ")\s*Status:\s*(.+)\s*-->'", + $line, + $match + ); } - return ($match); - } // get_tag() function end - - // Grab CREDITS tag, the place to store previous credits - function get_credits ($file) { + + // Return with found revision info (number, maint, status) + return $match; + +} // get_tag() function end + +// Grab CREDITS tag, the place to store previous credits +function get_credits ($file) { // Read the first 300 chars, the comment should be at - // the begining of the file + // the begining of the file, if it is there $fp = @fopen($file, "r") or die ("Unable to read $file."); $line = fread($fp, 300); fclose($fp); + // Try to find credits info in file, let more credits + // then one, using commas as list separator if (preg_match("'<!--\s*CREDITS:\s*(.+)\s*-->'U", - $line, $match)) { - return (explode(",", $match[1])); + $line, + $match)) { + + // Explode with commas a separators + $credits = explode(",", $match[1]); + + // Trim all elements (let spaces to be + // between credit info) + foreach ($credits as $num => $credit) { + $credits[$num] = trim($credit); + } + + return $credits; + } else { + + // No credits info in this file return array(); } - } // get_credits() end - // Checks a file, and gather stats - function check_file($file, $file_cnt) - { +} // get_credits() end + +// ========================================================================= +// Functions to check file status in translated directory, and store info +// ========================================================================= + +// Collect or return missing files depending on +// the parameters passed to this function +function missing_file() +{ + // Static var to store info, and return if asked + static $missing_files = array(); + global $DOCDIR, $LANG; + + // Return with the missing files, + // in case of no parameters to this function + if (func_num_args() == 0) { + return $missing_files; + } + + // Get the parameters if we have them + list($en_file, $trans_file) = func_get_args(); + + // Compute new index for missing file (name without language dir) + $index = substr($trans_file, strlen($DOCDIR) + strlen($LANG) + 1); + + // Compute new valie for missing file (size and EN revision) + $value = array( + round(filesize($en_file)/1024, 1), + "1." . get_tag($en_file) + ); + + // Push file into array + $missing_files[$index] = $value; + +} // missing_file() function end + +// Collect or return files with missing tags depending on +// the parameters passed to this function +function missing_tag() +{ + // Static var to store info, and return if asked + static $missing_tags = array(); + global $DOCDIR; + + // Return with the file with missing tags, + // in case of no parameters to this function + if (func_num_args() == 0) { + return $missing_tags; + } + + // Get the parameter if we have it + list($trans_file) = func_get_args(); + + // Push file name with missing tag on the list + $missing_tags[] = substr($trans_file, strlen($DOCDIR)); +} + +// Collect files by status mark +function files_by_mark() +{ + // Static var to store info, and return if asked + static $files_by_mark = array(); + + // Return with the file with missing tags, + // in case of no parameters to this function + if (func_num_args() == 0) { + return $files_by_mark; + } + + // Get the parameter if we have it + list($mark, $inc) = func_get_args(); + + // Add one to the count of this type of files + $files_by_mark[$mark] += $inc; + +} + +// Collect files by maintainer and status mark +function files_by_maint() +{ + // Static var to store info, and return if asked + static $files_by_maint = array(); + + // Return with the file with missing tags, + // in case of no parameters to this function + if (func_num_args() == 0) { + return $files_by_maint; + } + + // Get the parameter if we have it + list($mark, $maint) = func_get_args(); + + // Add one to the maintainers files list, + // especially counting this type of file + $files_by_maint[$maint][$mark]++; + +} + +// Checks a file, and gather status info +function get_file_status($file) +{ // The information is contained in these global arrays and vars - global $missed_files, $miss_tag, $lang, $docdir, $r_alert, - $s_alert, $t_alert, $maintainer, $cvs_opt, $plist, - $personinfo; - - // Translated file name check - $t_file = preg_replace( "'^".$docdir."en/'", $docdir.$lang."/", $file ); - if (!file_exists($t_file)) { - $missed_files[substr($t_file, strlen($docdir)+strlen($lang)+1)] = - array(round(filesize($file)/1024, 1), get_tag($file)); - return FALSE; - } - - // Get translated files tag, with maintainer if needed - if (!empty($maintainer)) { - $t_tag = get_tag($t_file, $maintainer); - // Don't count other's Tags as missing - if (count($t_tag) == 0) { - $t_tag = get_tag($t_file, "\\S*"); - if (count($t_tag) > 0) - return FALSE; - } + global $DOCDIR, $LANG, $MAINT; + + // Transform english file name to translated file nme + $trans_file = preg_replace("'^{$DOCDIR}en/'", "{$DOCDIR}{$LANG}/", $file); + + // If we cannot find the file, we push it into the missing files list + if (!@file_exists($trans_file)) { + files_by_mark(REV_NOTRANS, 1); + missing_file($file, $trans_file); + return FALSE; + } + + // If we need to check for a specific translator + if (!empty($MAINT)) { + // Get translated files tag, with maintainer + $trans_tag = get_tag($trans_file, $MAINT); + + // If this is a file belonging to another + // maintainer, than we would not like to + // deal with it anymore + if (count($trans_tag) == 0) { + $trans_tag = get_tag($trans_file, "\\S*"); + // We found a tag for another maintainer + if (count($trans_tag) > 0) { + return FALSE; + } + } + } + // No specific maintainer, check for a revision tag + else { + $trans_tag = get_tag($trans_file, "\\S*"); } - else - $t_tag = get_tag($t_file, "\\S*"); - // No tag found - if (count($t_tag) == 0) { - $miss_tag[] = substr($t_file, strlen($docdir)); - return FALSE; - } - - // Storing values for further processing - $maint = $t_tag[2]; - $en_rev = get_tag($file); - - // Make the maintainer a link - if (isset($plist[$maint])) { - $maintd = '<a href="#maint' . $plist[$maint] . '">' . $maint . '</a>'; - } else { - $maintd = $maint; + // If we found no revision tag, then collect this + // file in the missing tags list + if (count($trans_tag) == 0) { + files_by_mark(REV_NOTAG, 1); + missing_tag($trans_file, $DOCDIR); + return FALSE; + } + + // Distribute values in separate vars for further processing + list(, $this_rev, $this_maint, $this_status) = $trans_tag; + $this_credits = get_credits($trans_file); + + // Add credits to file by maintainer list + foreach ($this_credits as $nick) { + files_by_maint(REV_CREDIT, $nick); } + + // Get translated file name (without directories) + $trans_name = substr($trans_file, strlen($DOCDIR) + strlen($LANG) + 1); - // Get credits comment, and add to array - $credits = get_credits($t_file); - foreach ($credits as $nick) { - $personinfo[trim($nick)]["credits"]++; - } - - // Make diff link if the revision is not n/a - $t_td = substr($t_file, strlen($docdir)+strlen($lang)+1); - if (is_numeric($t_tag[1])) { - $r_diff = intval($en_rev) - intval($t_tag[1]); - $t_rev = "1.".$t_tag[1]; - if ($r_diff != 0) { - $t_td = "<a href=\"http://cvs.php.net/diff.php/". - preg_replace( "'^".$docdir."'", "phpdoc/", $file ). - "?r1=1.$t_tag[1]&r2=1.$en_rev$cvs_opt\">$t_td</a>"; - } + // Get English file revision for revision computing + $en_rev = get_tag($file); + + // If we have a numeric revision number (not n/a), compute rev. diff + if (is_numeric($this_rev)) { + $rev_diff = intval($en_rev) - intval($this_rev); + $trans_rev = "1.{$this_rev}"; + $en_rev = "1.{$en_rev}"; } else { - $r_diff = $t_rev = $t_tag[1]; + // If we have no numeric revision, make all revision + // columns hold the rev from the translated file + $rev_diff = $trans_rev = $this_rev; } // Compute sizes, times and diffs - $en_size = intval(filesize($file) / 1024); - $t_size = intval(filesize($t_file) / 1024); - $s_diff = intval($en_size) - intval($t_size); - $en_date = intval((time() - filemtime($file)) / 86400); - $t_date = intval((time() - filemtime($t_file)) / 86400); - $t_diff = $en_date - $t_date; - - // Taging actuality of files with colors - if ($r_diff === 0) { - $col = "\"#68D888\""; - $personinfo[$maint]["actual"]++; - } elseif ($r_diff == "n/a") { - $col = "\"#f4a460\" class=\"hl\""; - $personinfo[$maint]["norev"]++; - } elseif ($r_diff >= $r_alert || $s_diff >= $s_alert || $t_diff <= $t_alert) { - $col = "\"#ff0000\" class=\"hl\""; - $personinfo[$maint]["veryold"]++; + $en_size = intval(filesize($file) / 1024); + $trans_size = intval(filesize($trans_file) / 1024); + $size_diff = intval($en_size) - intval($trans_size); + + $en_date = intval((time() - filemtime($file)) / 86400); + $trans_date = intval((time() - filemtime($trans_file)) / 86400); + $date_diff = $en_date - $trans_date; + + // Make decision on file category by revision, date and size + if ($rev_diff === 0) { + $status_mark = REV_ACTUAL; + } elseif ($rev_diff === "n/a") { + $status_mark = REV_NOREV; + } elseif ($rev_diff >= ALERT_REV || $size_diff >= ALERT_SIZE || $date_diff <= +ALERT_DATE) { + $status_mark = REV_CRITICAL; } else { - $col ="\"#eee8aa\""; - $personinfo[$maint]["old"]++; + $status_mark = REV_OLD; } + + // Store files by status, and by maintainer too + files_by_mark ($status_mark, 1); + files_by_maint($status_mark, $this_maint); + + return array( + "full_name" => $file, + "short_name" => $trans_name, + "revision" => array($en_rev, $trans_rev, $rev_diff), + "size" => array($en_size, $trans_size, $size_diff), + "date" => array($en_date, $trans_date, $date_diff), + "maintainer" => $this_maint, + "status" => $this_status, + "mark" => $status_mark + ); + - // Write out directory headline - if ($file_cnt == 0) { - $display_dir = preg_replace("'($docdir)(.+)/[^/]*$'", "\\2/", $t_file); - print("<tr><th colspan=\"12\" height=\"3\" bgcolor=\"#666699\">$display_dir</th></tr>"); - } - - // Write out the line for the file into the file - print("<tr>\n <td bgcolor=$col>$t_td</td>\n". - " <td bgcolor=$col> 1.$en_rev</td><td bgcolor=$col> $t_rev</td>\n". - " <td bgcolor=$col align=\"right\"><b>$r_diff</b> </td>\n". - " <td bgcolor=$col align=\"right\">$en_size </td>\n". - " <td bgcolor=$col align=\"right\">$t_size </td>\n". - " <td bgcolor=$col align=\"right\"><b>$s_diff</b> </td>\n". - " <td bgcolor=$col align=\"right\">$en_date </td>\n". - " <td bgcolor=$col align=\"right\">$t_date </td>\n". - " <td bgcolor=$col align=\"right\"><b>$t_diff</b> </td>\n". - " <td bgcolor=$col align=\"center\">$maintd </td>\n". - " <td bgcolor=$col align=\"center\">$t_tag[3] </td>\n</tr>\n"); return TRUE; - } // check_file() end +} // get_file_status() function end + +// ========================================================================= +// A function to check directory status in translated directory +// ========================================================================= + +// Check the status of files in a diretory of phpdoc XML files +// The English directory is passed to this function to check +function get_dir_status($dir, $DOCDIR, $LANG) +{ - // Checks a diretory of phpdoc XML files - function check_dir($dir) - { - global $docdir, $lang; - // Collect files and diretcories in these arrays $directories = array(); - $files = array(); + $files = array(); - // Open and traverse the directory + // Open the directory $handle = @opendir($dir); + + // Walk through all names in the directory while ($file = @readdir($handle)) { + + // If we found a file with one or two point as a name, + // or a CVS directory, skip the file if (preg_match("/^\.{1,2}/",$file) || $file == 'CVS') continue; @@ -261,283 +412,591 @@ else { $files[] = $file; } } + + // Close the directory @closedir($handle); // Sort files and directories sort($directories); sort($files); - // Files first... - $file_cnt = 0; + // Go through files first + $dir_status = array(); foreach ($files as $file) { - if (check_file($dir.$file, $file_cnt)) { $file_cnt++; } + // If the file status is OK, append the status info + if ($file_status = get_file_status("{$dir}{$file}")) { + $dir_status[] = $file_status; + } } - // than the subdirs + // Then go through subdirectories, merging all the info + // coming from subdirs to one array foreach ($directories as $file) { - check_dir($dir.$file."/"); + $dir_status = array_merge( + $dir_status, + get_dir_status("{$dir}{$file}/", $DOCDIR, $LANG) + ); } - } // check_dir() end - - // Get a multidimensional array with tag attributes - function get_attr_array ($tags_attrs) - { + + // Return with collected file info in + // this dir and subdirectories [if any] + return $dir_status; + +} // get_dir_status() function end + +// ========================================================================= +// Functions to read in the translation.xml file and process contents +// ========================================================================= + +// Get a multidimensional array with tag attributes +function parse_attr_string ($tags_attrs) +{ $tag_attrs_processed = array(); + // Go through the tag attributes foreach($tags_attrs as $attrib_list) { + // Get attr name and values preg_match_all("!(.+)=\\s*([\"'])\\s*(.+)\\2!U", $attrib_list, $attribs); + // Assign all attributes to one associative array $attrib_array = array(); foreach ($attribs[1] as $num => $attrname) { $attrib_array[trim($attrname)] = trim($attribs[3][$num]); } + // Collect in order of tags received $tag_attrs_processed[] = $attrib_array; + } + + // Retrun with collected attributes return $tag_attrs_processed; - } // get_attr_array() end - - // Print preformatted (debug function) - function print_pre($var) - { - print("<pre>"); - print_r($var); - print("</pre>"); - } // print_pre() end - /*********************************************************************/ - /* Here starts the program */ - /*********************************************************************/ - - // Check for directory validity - if (!@is_dir($docdir . $lang)) { - die("The $lang language code is not valid"); - } - - // Used regexps here for parsing to be compatible with - // non XML compatible PHP setups - $translation_xml = $docdir . $lang . "/translation.xml"; - $output_charset = 'iso-8859-1'; - $translation = array(); - if (@file_exists($translation_xml)) { +} // parse_attr_string() end + +// Parse the translation.xml file for +// translation related meta information +function parse_translation($DOCDIR, $LANG, $MAINT) +{ + // Path to find translation.xml file, set default values, + // in case we can't find the translation file + $translation_xml = "{$DOCDIR}{$LANG}/translation.xml"; + $output_charset = 'iso-8859-1'; + $translation = array( + "intro" => "", + "persons" => array(), + "files" => array(), + "allfiles" => array(), + ); + + // Check for file availability, return with default + // values, if we cannot find the file + if (!@file_exists($translation_xml)) { + return array($output_charset, $translation); + } + + // Else go on, and load in the file, replacing all + // space type chars with one space $txml = join("", file($translation_xml)); $txml = preg_replace("/\\s+/", " ", $txml); - // Get intro text - if (!empty($maintainer)) - $translation["intro"] = "Personal Statistics for ".$maintainer; - else { + // Get intro text (different for a persons info and + // for a whole group info page) + if (!empty($MAINT)) { + $translation["intro"] = "Personal Statistics for {$MAINT}"; + } else { preg_match("!<intro>(.+)</intro>!s", $txml, $match); $translation["intro"] = trim($match[1]); } - // Get encoding for the output + // Get encoding for the output, from the translation.xml + // file encoding (should be the same as the used encoding + // in HTML) preg_match("!<\?xml(.+)\?>!U", $txml, $match); - $xmlinfo = get_attr_array($match); + $xmlinfo = parse_attr_string($match); $output_charset = $xmlinfo[1]["encoding"]; - // Get persons list - if (!empty($maintainer)) - $pattern = "!<person([^<]+nick=\"$maintainer\".+)/\\s?>!U"; - else + // Get persons list preg pattern, only check for a specific + // maintainer, if the users asked for it + if (!empty($MAINT)) { + $pattern = "!<person([^<]+nick=\"{$MAINT}\".+)/\\s?>!U"; + } else { $pattern = "!<person(.+)/\\s?>!U"; + } + + // Find all persons matching the pattern preg_match_all($pattern, $txml, $matches); - $translation['persons'] = get_attr_array($matches[1]); - foreach($translation['persons'] as $num => $person) { - $plist[$person["nick"]] = $num; - } - $personinfo = array(); - - // Get files list - if (!empty($maintainer)) { - preg_match_all("!<file([^<]+person=\"$maintainer\".+)/\\s?>!U", $txml, $matches); - $translation['files'] = get_attr_array($matches[1]); - // get all others to clear out from available files + $translation['persons'] = parse_attr_string($matches[1]); + + // Get list of work in progress files + if (!empty($MAINT)) { + + // Only check for a specific maintainer, if we were asked to + preg_match_all("!<file([^<]+person=\"{$MAINT}\".+)/\\s?>!U", $txml, $matches); + $translation['files'] = parse_attr_string($matches[1]); + + // Other maintainers wip files need to be cleared from + // available files list in the future, so store that info too. preg_match_all("!<file(.+)/\\s?>!U", $txml, $matches); - $wip_others = get_attr_array($matches[1]); - } - else { + $translation['allfiles'] = parse_attr_string($matches[1]); + + // Provide info about number of WIP files + files_by_mark(REV_WIP, count($translation['allfiles'])); + + } else { + + // Get all wip files preg_match_all("!<file(.+)/\\s?>!U", $txml, $matches); - $translation['files'] = get_attr_array($matches[1]); + $translation['files'] = parse_attr_string($matches[1]); + + // Provide info about number of WIP files + files_by_mark(REV_WIP, count($translation['files'])); + } - } + + // Return with collected info in two vars + return array($output_charset, $translation); + +} // parse_translation() function end() + +// ========================================================================= +// Debug functions for all the functions and code on this page +// ========================================================================= + +// Print preformatted (debug function) +function print_pre($var) +{ + print("<pre>"); + print_r($var); + print("</pre>"); +} // print_pre() function end + +// ========================================================================= +// Start of the program execution +// ========================================================================= + +// Check for directory validity +if (!@is_dir($DOCDIR . $LANG)) { + die("The $LANG language code is not valid"); +} + +// Parse translation.xml file for more information +list($charset, $translation) = parse_translation($DOCDIR, $LANG, $MAINT); - print(" -<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\"> +// Add WIP files to maintainers file count +foreach ($translation["files"] as $num => $fileinfo) { + files_by_maint(REV_WIP, $fileinfo["person"]); +} + +// Get all files status +$files_status = get_dir_status("{$DOCDIR}en/", $DOCDIR, $LANG); + +// Get missing files and files with missing +// tags collected in the previous step +$missing_files = missing_file(); +$missing_tags = missing_tag(); + +// Files counted by mark and maintainer +$files_by_mark = files_by_mark(); +$files_by_maint = files_by_maint(); + +// Figure out generation date +$date = date("r"); + +// ========================================================================= +// Start of HTML page +// ========================================================================= + +print <<<END_OF_MULTILINE +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" +"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd"> <html> <head> <title>PHPDOC Revision-check</title> -<meta http-equiv=\"Content-Type\" content=\"text/html; charset=$output_charset\"> -<style type=\"text/css\"><!-- - h2 {font-family: Arial,Helvetica,sans-serif; color: #FFFFFF; font-size: 28px; } - td,a,p {font-family: Arial,Helvetica,sans-serif; color: #000000; font-size: 14px; } - a.ref {font-family: Arial,Helvetica,sans-serif; color: #FFFFFF; font-size: 14px; } - th {font-family: Arial,Helvetica,sans-serif; color: #FFFFFF; font-size: 14px; font-weight: bold; } -.hl {font-family: Arial,Helvetica,sans-serif; color: #000000; font-size: 14px; font-weight: bold; } -body {margin-left: 0px; margin-right: 0px; margin-top: 0px; margin-bottom: 0px; } +<meta http-equiv="Content-Type" content="text/html; charset={$charset}"> +<style type="text/css"> +<!-- + h2, td, a, p, a.ref, th, .hl { + font-family: Arial,Helvetica,sans-serif; color: #FFFFFF; font-size: 14px; + } + h2 { font-size: 28px; } + td,a,p, th.black { color: #000000; } + th { font-weight: bold; } + .hl { color: #000000; font-weight: bold; } + body { margin: 0px 0px 0px 0px; } //--> </style> </head> -<body bgcolor=\"#F0F0F0\"> -<table width=\"100%\" border=\"0\" cellspacing=\"0\" bgcolor=\"#666699\"> +<body bgcolor="#F0F0F0"> +<table width="100%" border="0" cellspacing="0" bgcolor="#666699"> <tr><td> - <table width=\"100%\" border=\"0\" cellspacing=\"1\" bgcolor=\"#9999CC\"> - <tr><td><h2 align=\"center\">Status of the translated PHP Manual</h2> - <p align=\"center\" style=\"font-size:12px; color:#FFFFFF;\">Generated: ".date("r"). - " / Language: $lang<br> </p> + <table width="100%" border="0" cellspacing="1" bgcolor="#9999CC"> + <tr><td><h2 align="center">Status of the translated PHP Manual</h2> + <p align="center" style="font-size:12px;"> + Generated: {$date} / Language: $LANG<br></p> </td></tr> </table> </td></tr> -</table> <br>"); - -if (isset($translation["intro"])) { +</table> +<p align="center"><a href="#intro">Introduction</a> | +<a href="#translators">Translators</a> | +<a href="#filesummary">File summary by type</a> | +<a href="#files">Files</a> | +<a href="#wip">Work in progress</a> | +<a href="#misstags">Missing revision numbers</a> | +<a href="#missfiles">Untranslated files</a> +</p> +END_OF_MULTILINE; + +// ========================================================================= +// Intro block goes here +// ========================================================================= + +// If we have an introduction text, print it out, with an anchor +if (!empty($translation["intro"])) { + print('<a name="intro"></a>'); print('<table width="800" align="center"><tr><td>' . $translation['intro'] . '</td></tr></table><p></p>'); } -ob_start(); +// ========================================================================= +// Translators table goes here +// ========================================================================= + +// If person list available (valid translation.xml file in lang), print out +// the person list, with respect to the maintainer parameter specified +if (!empty($translation["persons"])) { + +print <<<END_OF_MULTILINE +<a name="translators"></a> +<table width="820" border="0" cellpadding="4" cellspacing="1" align="center"> +<tr> + <th rowspan="2" bgcolor="#666699">Translator's name</th> + <th rowspan="2" bgcolor="#666699">Contact email</th> + <th rowspan="2" bgcolor="#666699">Nick</th> + <th rowspan="2" bgcolor="#666699">CVS</th> + <th colspan="7" bgcolor="#666699">Files maintained</th> +</tr> +<tr> + <th style="{$CSS[REV_CREDIT]}">credits</th> + <th style="{$CSS[REV_ACTUAL]}">actual</th> + <th style="{$CSS[REV_OLD]}">old</th> + <th style="{$CSS[REV_CRITICAL]}">critical</th> + <th style="{$CSS[REV_NOREV]}">norev</th> + <th style="{$CSS[REV_WIP]}">wip</th> + <th style="{$CSS[NORMHEAD]}">sum</th> +</tr> +END_OF_MULTILINE; + + // ' Please leave this comment here -print(" -<table width=\"820\" border=\"0\" cellpadding=\"4\" cellspacing=\"1\" align=\"center\"> + // We will collect the maintainers by nick here + $maint_by_nick = array(); + + // Print out a line for each maintainer (with respect to + // maintainer setting provided in command line) + foreach($translation["persons"] as $num => $person) { + + // Do not print out this person, if a + // specific maintainer info is asked for + if (!empty($MAINT) && $person["nick"] != $MAINT) { + continue; + } + + // Put maintaner number into associative array + // [Used in further tables for referencing] + $maint_by_nick[$person["nick"]] = $num; + + // Decide on the CVS text and the color of the line + if ($person["cvs"] === "yes") { + $cvsu = "x"; + $col = '"#eee8aa"'; + } else { + $cvsu = " "; + $col = '"#dcdcdc"'; + } + + // Try to do some antispam actions + $person["email"] = str_replace( + "@", + "<small>:at:</small>", + $person["email"] + ); + + // Get file info for this person + if (isset($files_by_maint[$person["nick"]])) { + $pi = $files_by_maint[$person["nick"]]; + } else { + $pi = array(); + } + + print("<tr bgcolor=$col>" . + "<td><a name=\"maint$num\">$person[name]</a></td>" . + "<td>$person[email] </td>" . + "<td>$person[nick] </td>" . + "<td align=\"center\">$cvsu </td>" . + "<td align=\"center\">" . $pi[REV_CREDIT] . " </td>" . + "<td align=\"center\">" . $pi[REV_ACTUAL] . " </td>" . + "<td align=\"center\">" . $pi[REV_OLD] . " </td>" . + "<td align=\"center\">" . $pi[REV_CRITICAL] . " </td>" . + "<td align=\"center\">" . $pi[REV_NOREV] . " </td>" . + "<td align=\"center\">" . $pi[REV_WIP] . " </td>" . + "<td align=\"center\">" . array_sum($pi) . " </td>" . + "</tr>\n"); + } + + print "</table>\n<p> </p>\n"; +} + +// ========================================================================= +// Files summary table goes here +// ========================================================================= + +print <<<END_OF_MULTILINE +<a name="filesummary"></a> +<table width="450" border="0" cellpadding="4" cellspacing="1" align="center"> <tr> - <th rowspan=\"2\" bgcolor=\"#666699\"><a name=\"translated\" class=\"ref\">Translated file</a></th> - <th colspan=\"3\" bgcolor=\"#666699\">Revision</th> - <th colspan=\"3\" bgcolor=\"#666699\">Size in kB</th> - <th colspan=\"3\" bgcolor=\"#666699\">Age in days</th> - <th rowspan=\"2\" bgcolor=\"#666699\">Maintainer</th> - <th rowspan=\"2\" bgcolor=\"#666699\">Status</th> + <th bgcolor="#666699">File status type</th> + <th bgcolor="#666699">Number of files</th> + <th bgcolor="#666699">Percent of files</th> </tr> +END_OF_MULTILINE; + +$files_sum = array_sum($files_by_mark); + +$file_types = array( + array (REV_ACTUAL, "Actual files"), + array (REV_OLD, "Old files"), + array (REV_CRITICAL, "Critical files"), + array (REV_WIP, "Work in progress"), + array (REV_NOREV, "Files without revision number"), + array (REV_NOTAG, "Files without revision tag"), + array (REV_NOTRANS, "Files available for translation") +); + +foreach ($file_types as $num => $type) { + $type[] = 'style="' . $CSS[$type[0]] . '"'; + $type[] = intval($files_by_mark[$type[0]]); + $type[] = number_format( + $files_by_mark[$type[0]] * 100 / $files_sum, 2 + ); + +print <<<END_OF_MULTILINE <tr> - <th bgcolor=\"#666699\">en</th> - <th bgcolor=\"#666699\">$lang</th> - <th bgcolor=\"#666699\">diff</th> - <th bgcolor=\"#666699\">en</th> - <th bgcolor=\"#666699\">$lang</th> - <th bgcolor=\"#666699\">diff</th> - <th bgcolor=\"#666699\">en</th> - <th bgcolor=\"#666699\">$lang</th> - <th bgcolor=\"#666699\">diff</th> + <td {$type[2]}>{$type[1]}</td> + <td {$type[2]} align="center">{$type[3]}</td> + <td {$type[2]} align="center">{$type[4]}%</td> </tr> -"); +END_OF_MULTILINE; + +} -// Check the English directory -check_dir($docdir."en/"); +//print_pre($files_by_mark); print("</table>\n<p> </p>\n"); -// If work-in-progress available (valid translation.xml file in lang) -if (isset($translation["files"])) { - $using_date = FALSE; $using_rev = FALSE; - foreach ($translation["files"] as $file) { - if (isset($file["date"])) { $using_date = TRUE; } - if (isset($file["revision"])) { $using_rev = TRUE; } - } - print(" - <table width=\"820\" border=\"0\" cellpadding=\"4\" cellspacing=\"1\" align=\"center\"> - <tr> - <th bgcolor=\"#666699\"><a name=\"wip\" class=\"ref\">Work in progress files</a></th> - <th bgcolor=\"#666699\">Translator</th> - <th bgcolor=\"#666699\">Type</th> - "); - if ($using_date) { print ("<th bgcolor=\"#666699\">Date</th>\n"); } - if ($using_rev) { print ("<th bgcolor=\"#666699\">CO-Revision</th><th bgcolor=\"#666699\">EN-Revision</th>\n"); } - print("</tr>\n"); - - foreach($translation["files"] as $num => $finfo) { - if (isset($plist[$finfo["person"]])) { - $maintd = '<a href="#maint' . $plist[$finfo["person"]] . '">' . $finfo["person"] . '</a>'; - } else { - $maintd = $finfo["person"]; - } - print("<tr bgcolor=\"#DDDDDD\"><td>$finfo[name]</td>" . - "<td>$maintd</td><td>$finfo[type]</td>"); - if ($using_date) { print("<td>$finfo[date]</td>"); } - if ($using_rev) { print("<td>$finfo[revision]</td><td>1." . $missed_files[$finfo["name"]][1] . "</td>"); } - print("</tr>"); - $personinfo[$finfo["person"]]["wip"]++; - $wip_files[$finfo["name"]] = TRUE; - } - - print ("</table>\n<p> </p>\n"); -} +// ========================================================================= +// Files table goes here +// ========================================================================= + +print <<<END_OF_MULTILINE +<a name="files"></a> +<table width="820" border="0" cellpadding="4" cellspacing="1" align="center"> +<tr> + <th rowspan="2" bgcolor="#666699">Translated file</th> + <th colspan="3" bgcolor="#666699">Revision</th> + <th colspan="3" bgcolor="#666699">Size in kB</th> + <th colspan="3" bgcolor="#666699">Age in days</th> + <th rowspan="2" bgcolor="#666699">Maintainer</th> + <th rowspan="2" bgcolor="#666699">Status</th> +</tr> +<tr> + <th bgcolor="#666699">en</th> + <th bgcolor="#666699">$LANG</th> + <th bgcolor="#666699">diff</th> + <th bgcolor="#666699">en</th> + <th bgcolor="#666699">$LANG</th> + <th bgcolor="#666699">diff</th> + <th bgcolor="#666699">en</th> + <th bgcolor="#666699">$LANG</th> + <th bgcolor="#666699">diff</th> +</tr> +END_OF_MULTILINE; + +// This was the previous directory [first] +$prev_dir = $new_dir = "{$DOCDIR}en"; -$file_lists = ob_get_contents(); -ob_end_clean(); +// Go through all files collected +foreach ($files_status as $num => $file) { + + // Do not print out actual files + if ($file["mark"] == REV_ACTUAL) { + continue; + } + + // Make the maintainer a link, if we have that maintainer in the list + if (isset($maint_by_nick[$file["maintainer"]])) { + $file["maintainer"] = '<a href="#maint' . $maint_by_nick[$file["maintainer"]] . + '">' . $file["maintainer"] . '</a>'; + } + + // If we have a 'numeric' revision diff and it is not zero, + // make a link to the CVS repository's diff script + if ($file["revision"][2] != "n/a" && $file["revision"][2] !== 0) { + $file["short_name"] = "<a href=\"http://cvs.php.net/diff.php/" . + preg_replace( "'^".$DOCDIR."'", "phpdoc/", +$file["full_name"]) . + "?r1=" . $file["revision"][1] . + "&r2=" . $file["revision"][0] . + CVS_OPT . "\">" . $file["short_name"] . "</a>"; + } -// If person list available (valid translation.xml file in lang) -if (isset($translation["persons"])) { - print(" - <table width=\"820\" border=\"0\" cellpadding=\"4\" cellspacing=\"1\" align=\"center\"> - <tr> - <th rowspan=\"2\" bgcolor=\"#666699\"><a name=\"translators\" class=\"ref\">Translator's name</a></th> - <th rowspan=\"2\" bgcolor=\"#666699\">Contact email</th> - <th rowspan=\"2\" bgcolor=\"#666699\">Nick</th> - <th rowspan=\"2\" bgcolor=\"#666699\">CVS</th> - <th colspan=\"6\" bgcolor=\"#666699\">Files maintained</th> - </tr> - <tr> - <th bgcolor=\"#666699\">credits</th> - <th bgcolor=\"#666699\">actual</th> - <th bgcolor=\"#666699\">old</th> - <th bgcolor=\"#666699\">veryold</th> - <th bgcolor=\"#666699\">norev</th> - <th bgcolor=\"#666699\">wip</th> - </tr> - "); + // Guess the new directory from the full name of the file + $new_dir = substr($file["full_name"], 0, strrpos($file["full_name"], "/")); + + // If this is a new directory, put out dir headline + if ($new_dir != $prev_dir) { + + // Drop out the unneded parts from the dirname... + $display_dir = str_replace("{$DOCDIR}en/", "", dirname($file["full_name"])); + + // Print out directory header + print "<tr><th colspan=\"12\" height=\"3\" +bgcolor=\"#666699\">$display_dir</th></tr>"; + + // Store the new actual directory + $prev_dir = $new_dir; + } + + // Style attribute for all the cells + $style = 'style="' . $CSS[$file["mark"]] . '"'; + + // Write out the line for the current file + print "<tr>\n <td $style>{$file['short_name']}</td>\n". + " <td $style> {$file['revision'][0]}</td>" . + " <td $style> {$file['revision'][1]}</td>\n". + " <td $style align=\"right\"><b>{$file['revision'][2]}</b> </td>\n". + " <td $style align=\"right\">{$file['size'][0]} </td>\n". + " <td $style align=\"right\">{$file['size'][1]} </td>\n". + " <td $style align=\"right\"><b>{$file['size'][2]}</b> </td>\n". + " <td $style align=\"right\">{$file['date'][0]} </td>\n". + " <td $style align=\"right\">{$file['date'][1]} </td>\n". + " <td $style align=\"right\"><b>{$file['date'][2]}</b> </td>\n". + " <td $style align=\"center\">{$file['maintainer']} </td>\n". + " <td $style align=\"center\">{$file['status']} </td>\n</tr>\n"; + +} + +print("</table>\n<p> </p>\n"); + +// ========================================================================= +// Work in progress table goes here +// ========================================================================= + +// If work-in-progress list is available (valid translation.xml file in lang) +if (count($translation["files"]) != 0) { + + // Figure out, if we need to use optional date and + // revision columns (if there is no file with that parameter, + // we won't include the table column for that) + $using_date = FALSE; $using_rev = FALSE; + foreach ($translation["files"] as $file) { + if (isset($file["date"])) { $using_date = TRUE; } + if (isset($file["revision"])) { $using_rev = TRUE; } + } - foreach($translation["persons"] as $num => $person) { - if ($person["cvs"] === "yes") { $cvsu = "yes"; $col = "\"#eee8aa\""; } - else { $cvsu = "no"; $col = "\"#dcdcdc\""; } - $person["email"] = str_replace("@", "<small>:at:</small>", $person["email"]); - $pi = $personinfo[$person["nick"]]; - print("<tr bgcolor=$col><td><a name=\"maint$num\">$person[name]</a></td>" . - "<td>$person[email] </td><td>$person[nick] </td><td>$cvsu </td>" . - "<td align=\"center\">$pi[credits] </td><td align=\"center\">$pi[actual] </td>". - "<td align=\"center\">$pi[old] </td><td align=\"center\">$pi[veryold] </td>". - "<td align=\"center\">$pi[norev] </td><td align=\"center\">$pi[wip] </td></tr>\n"); - } + // Print out files table header + print ' + <a name="wip"></a> + <table width="820" border="0" cellpadding="4" cellspacing="1" align="center"> + <tr> + <th bgcolor="#666699">Work in progress files</th> + <th bgcolor="#666699">Translator</th> + <th bgcolor="#666699">Type</th> + '; - print ("</table>\n<p> </p>\n"); -} + // Print out date and revision columns if needed + if ($using_date) { + print '<th bgcolor="#666699">Date</th>' . "\n"; + } + if ($using_rev) { + print '<th bgcolor="#666699">CO-Revision</th>' . + '<th bgcolor="#666699">EN-Revision</th>' . "\n"; + } + print "</tr>\n"; + + // Go through files, and print out lines for them + foreach($translation["files"] as $num => $finfo) { + + // If we have a valid maintainer, link to the summary + if (isset($maint_by_nick[$finfo["person"]])) { + $finfo["person"] = '<a href="#maint' . $maint_by_nick[$finfo["person"]] . + '">' . $finfo["person"] . '</a>'; + } + + // Print out the line with the first columns + print "<tr bgcolor=\"#DDDDDD\"><td>$finfo[name]</td>" . + "<td>$finfo[person]</td><td>$finfo[type]</td>"; + + // If we need the date column, print it out + if ($using_date) { + print "<td>$finfo[date]</td>"; + } + + // If we need the revision column, print it out + if ($using_rev) { + print "<td>$finfo[revision]</td><td>1." . + $missing_files[$finfo["name"]][1] . + "</td>"; + } + + // End the line + print "</tr>"; -print($file_lists); + // Collect files in WIP list + $wip_files[$finfo["name"]] = TRUE; + } + + print "</table>\n<p> </p>\n"; +} -// Files without revision comment -$count = count($miss_tag); +// Files translated, but without a revision comment +$count = count($missing_tags); if ($count > 0) { - print("<table width=\"440\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" align=\"center\">\n". - " <tr><th bgcolor=\"#666699\"><b>Files without Revision-comment ($count files):</b></th></tr>\n"); - foreach($miss_tag as $val) { - print(" <tr><td bgcolor=\"#DDDDDD\"> $val</td></tr>\n"); - } - print("</table>\n<p> </p>\n"); -} - -// Clear out work in progress files from available files -if (isset($wip_files)) { - foreach($wip_files as $fname => $one) { - if (isset($missed_files[$fname])) { unset($missed_files[$fname]); } - } -} -if (isset($wip_others)) { - foreach($wip_others as $file => $one) { - if (isset($missed_files[$one['name']])) { unset($missed_files[$one['name']]); } - } + print "<a name=\"misstags\"></a>" . + "<table width=\"440\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" +align=\"center\">\n". + " <tr><th bgcolor=\"#666699\"><b>Files without Revision-comment ($count +files):</b></th></tr>\n"; + foreach($missing_tags as $val) { + print " <tr><td bgcolor=\"#DDDDDD\"> $val</td></tr>\n"; + } + print "</table>\n<p> </p>\n"; +} + +// Merge all work in progress files collected +$wip_files = array_merge( + $translation["files"], // Files for this translator + $translation["allfiles"] // Files for all the translators +); + +// Delete wip entires from available files list +foreach ($wip_files as $file) { + if (isset($missing_files[$file['name']])) { + unset($missing_files[$file['name']]); + } } // Files not translated and not "wip" -$count = count($missed_files); +$count = count($missing_files); if ($count > 0) { - print("<table width=\"440\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" align=\"center\">\n". - " <tr><th colspan=\"2\" bgcolor=\"#666699\"><b><a name=\"avail\" class=\"ref\">Available for translation</a> ($count files):</b></th></tr>\n"); - foreach($missed_files as $file => $info) { - print(" <tr><td bgcolor=\"#DDDDDD\"> $file</td>". - "<td align=\"right\" bgcolor=\"#DDDDDD\">$info[0] kB </td></tr>\n"); - } - print("</table>\n<p> </p>\n"); + print "<a name=\"missfiles\"></a>" . + "<table width=\"440\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" +align=\"center\">\n" . + " <tr><th colspan=\"2\" bgcolor=\"#666699\"><b><a name=\"avail\" +class=\"ref\">" . + " Available for translation</a> ($count files):</b></th></tr>\n"; + foreach($missing_files as $file => $info) { + print " <tr><td bgcolor=\"#DDDDDD\"> $file</td>" . + " <td align=\"right\" bgcolor=\"#DDDDDD\">$info[0] kB + </td></tr>\n"; + } + print "</table>\n<p> </p>\n"; } // All OK, end the file -print("</body>\n</html>\n"); +print "</body>\n</html>\n"; ?>