[prev in list] [next in list] [prev in thread] [next in thread] 

List:       php-doc-cvs
Subject:    [DOC-CVS] com doc/base: revcheck.php rewrite to use git hashes.: scripts/revcheck.php
From:       André Luis Ferreira da Silva Bacci <ae () php ! net>
Date:       2021-03-19 17:01:21
Message-ID: php-mail-f834f7e4bc5b00c1919a20d530fe31de1189897320 () git ! php ! net
[Download RAW message or body]

Commit:    92a4f3c052af4b40a2fb7a0da14c2b3412257154
Author:    André L F S Bacci <alfsb@users.noreply.github.com>         Fri, 19 Mar 2021 14:01:21 -0300
Parents:   ad67d60e25351a1665232bb7e5e9046052a6eee4
Branches:  master

Link:       http://git.php.net/?p=doc/base.git;a=commitdiff;h=92a4f3c052af4b40a2fb7a0da14c2b3412257154

Log:
revcheck.php rewrite to use git hashes.

Changed paths:
  M  scripts/revcheck.php


["diff_92a4f3c052af4b40a2fb7a0da14c2b3412257154.txt" (text/plain)]

diff --git a/scripts/revcheck.php b/scripts/revcheck.php
index eb739a7b8..99e91a361 100644
--- a/scripts/revcheck.php
+++ b/scripts/revcheck.php
@@ -17,1098 +17,409 @@
   | Authors:    Thomas Sch�fbeck <tom@php.net>                           |
   |             Gabor Hojtsy <goba@php.net>                              |
   |             Mark Kronsbein <mk@php.net>                              |
-  |             Jan Fabry <cheezy@php.net>
+  |             Jan Fabry <cheezy@php.net>                               |
+  |             André L F S Bacci <ae@php.net>                           |
   +----------------------------------------------------------------------+
-
-  $Id$
 */
-if ($argc < 2 || $argc > 4) {
-?>
 
-Check the revision of translated files against
-the actual english xml files, and print statistics
+if ( $argc != 2 )
+{
+    print <<<USAGE
 
-  Usage:
-  <?php echo $argv[0]; ?> <language-code> [<maintainer>] [--show-uptodate]
+  Check the revision of translated files against the actual english XML files
+  and print statistics.
 
-  <language-code> must be a valid language code used
-  in the repository
+  Usage:
+    {$argv[0]} [translation]
 
-  If you specify <maintainer>, the script only checks
-  the files maintained by the person you add here
+  [translation] must be a valid git checkout directory of a translation.
 
-  If you specify --show-uptodate option, the script will
-  also show uptodate files in the common file list
+  Read more about revision comments and related functionality in the
+  PHP Documentation Howto: http://doc.php.net/tutorial/
 
-  Read more about Revision comments and related
-  functionality in the PHP Documentation Howto:
-    http://php.net/dochowto
 
-<?php
-  exit;
+USAGE;
+    exit;
 }
 
-// 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",   3); // translation is  3 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_UPTODATE", 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
+// Initialization
 
-// Colors used to mark files by status (colors for the above types)
-$CSS = array(
-  REV_UPTODATE => "act",
-  REV_NOREV    => "norev",
-  REV_CRITICAL => "crit",
-  REV_OLD      => "old",
-  REV_NOTAG    => "wip",
-  REV_NOTRANS  => "wip",
-  REV_CREDIT   => "wip",
-  REV_WIP      => "wip",
-);
+set_time_limit( 0 );
 
-function init_revisions() {
-	 global $CSS;
-	 return array_fill_keys(array_keys($CSS), 0);
-}
+$root = getcwd();
+$lang = $argv[1];
 
-function init_files_by_maint($persons) {
-  $result = array();
-  foreach($persons as $item) {
-    $result[$item['nick']] = init_revisions();
-  }
+$gitData = []; // filename lang hash,date
 
- 	return $result;
-}
+$enFiles = populateFileTree( 'en' );
+$trFiles = populateFileTree( $lang );
+captureGitValues( 'en'  , $gitData );
+captureGitValues( $lang , $gitData );
 
-$file_sizes_by_mark = $files_by_mark = init_revisions();
+computeSyncStatus( $enFiles , $trFiles , $gitData , $lang );
 
-// Option for the link to svn.php.net:
-define('SVN_OPT', '&amp;view=patch');
-define('SVN_OPT_NOWS', '');
+print_html_all( $enFiles , $trFiles , $lang );
 
-// Initializing variables from parameters
-$LANG = $argv[1];
-$MAINT = "";
-$SHOW_UPTODATE = FALSE;
-if ($argc == 3) {
-	if ($argv[2] == '--show-uptodate') {
-         $SHOW_UPTODATE = TRUE;
-    } else {
-         $MAINT = $argv[2];	
-	}
-} elseif ($argc == 4) {
-    $MAINT = $argv[2];
-    $SHOW_UPTODATE = ($argv[3] == '--show-uptodate');
-}
+// Model
 
-// Main directory of the PHP documentation (depends on the
-// sapi used). We do need the trailing slash!
-if ("cli" === php_sapi_name()) {
-  if (isset($PHPDOCDIR) && is_dir($PHPDOCDIR)) {
-    $DOCDIR = $PHPDOCDIR."/";
-  } else {
-    $DOCDIR = "../";
-  }
-} else {
-  $DOCDIR = "../";
+class FileStatusEnum
+{
+    const Untranslated      = 'Untranslated';
+    const RevTagProblem     = 'RevTagProblem';
+    const TranslatedWip     = 'TranslatedWip';
+    const TranslatedOk      = 'TranslatedOk';
+    const TranslatedOld     = 'TranslatedOld';
+    const TranslatedCritial = 'TranslatedCritial';
+    const ExistsInEnTree    = 'ExistsInEnTree';
 }
-$DOCDIR = "./";
-// =========================================================================
-// Functions to get revision info and credits from a file
-// =========================================================================
-
-// Grabs the revision tag and stores credits from the file given
-function get_tags($file, $val = "en-rev") {
-
-  // Read the first 500 chars. The comment should be at
-  // the begining of the file
-  $fp = @fopen($file, "r") or die ("Unable to read $file.");
-  $line = fread($fp, 500);
-  fclose($fp);
-
-  // Check for English SVN revision tag (. is for $ in the preg!),
-  // Return if this was needed (it should be there)
-  if ($val == "en-rev") {
-    preg_match("/<!-- .Revision: (\d+) . -->/", $line, $match);
-    return $match[1];
-  }
-
-  // Handle credits (only if no maintainer is specified)
-  if ($val == "\\S*") {
-
-    global $files_by_maint;
-
-    // Find credits info, let more credits then one,
-    // using commas as list separator
-    if (preg_match("'<!--\s*CREDITS:\s*(.+)\s*-->'U", $line, $match_credit)) {
-      // Explode with commas a separators
-      $credits = explode(",", $match_credit[1]);
-
-      // Store all elements
-      foreach ($credits as $num => $credit) {
-          $files_by_maint[trim($credit)][REV_CREDIT]++;
-      }
-    }
-  }
-
-  // No match before the preg
-  $match = array();
-
-  // Check for the translations "revision tag"
-  preg_match ("/<!--\s*EN-Revision:\s*(\d+)\s*Maintainer:\s*("
-              . $val . ")\s*Status:\s*(.+)\s*-->/U",
-              $line,
-              $match
-  );
-
-  // The tag with revision number is not found so search
-  // 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*-->'U",
-                  $line,
-                  $match
-      );
-  }
-
-  // Return with found revision info (number, maint, status)
-  return $match;
-
-} // get_tags() function end
-
-
-// =========================================================================
-// Functions to check file status in translated directory, and store info
-// =========================================================================
-
-// Checks a file, and gather status info
-function get_file_status($file) {
-
-  // The information is contained in these global arrays and vars
-  global $DOCDIR, $LANG, $MAINT, $SHOW_UPTODATE, $files_by_mark, $files_by_maint;
-  global $file_sizes_by_mark;
-  global $missing_files, $missing_tags, $using_rev;
-
-  // Transform english file name to translated file name
-  $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]++;
-    $trans_name = substr($trans_file, strlen($DOCDIR) + strlen($LANG) + 1);
-    $size = intval(filesize($file)/1024);
-    $missing_files[$trans_name] = array( $size );
-    $file_sizes_by_mark[REV_NOTRANS] += $size;
-    // compute en-tags just if they're needed in the WIP-Table
-    if($using_rev) {
-            $missing_files[$trans_name][] = get_tags($file);
+class FileStatusInfo
+{
+    public $path;
+    public $name;
+    public $size;
+    public $hash;
+    public $date;
+    public $syncStatus;
+    public $maintainer;
+    public $completion;
+    public $credits;
+
+    public function getKey()
+    {
+        return trim( $this->path . '/' . $this->name , '/' );
     }
-    return FALSE;
-  }
-
-  // No specific maintainer, check for a revision tag
-  if (empty($MAINT)) {
-    $trans_tag = get_tags($trans_file, "\\S*");
-  }
-  // If we need to check for a specific translator
-  else {
-    // Get translated files tag, with maintainer
-    $trans_tag = get_tags($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_tags($trans_file, "\\S*");
-      // We found a tag for another maintainer
-      if (count($trans_tag) > 0) {
-          return FALSE;
-      }
-    }
-  }
-
-  // Compute sizes and diffs
-  $en_size    = intval(filesize($file) / 1024);
-  $trans_size = intval(mb_strlen(file_get_contents($trans_file), 'UTF-8') / 1024);
-  $size_diff  = intval($en_size) - intval($trans_size);
-
-  // 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]++;
-    $file_sizes_by_mark[REV_NOTAG] += $en_size;
-    $missing_tags[] = array(substr($trans_file, strlen($DOCDIR)), $en_size, \
                $trans_size, $size_diff);
-    return FALSE;
-  }
-
-  // Distribute values in separate vars for further processing
-  list(, $this_rev, $this_maint, $this_status) = $trans_tag;
-
-  // Get English file revision
-  $en_rev = get_tags($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  = $this_rev;
-    $en_rev     = $en_rev;
-  } else {
-    // If we have no numeric revision, make all revision
-    // columns hold the rev from the translated file
-    $rev_diff = $trans_rev = $this_rev;
-    $en_rev   = $en_rev;
-  }
-
-  // Compute times and diffs
-  $en_date    = intval((time() - filemtime($file)) / 86400);
-  $trans_date = intval((time() - filemtime($trans_file)) / 86400);
-  $date_diff  = $en_date - $trans_date;
-
-  // If the file is up-to-date
-  if ($rev_diff === 0 && trim($this_status) === "ready") {
-     $status_mark = REV_UPTODATE;
-  }
-  // Or make decision on file category by revision, date and size
-  elseif ($rev_diff >= ALERT_REV || $size_diff >= ALERT_SIZE || $date_diff <= \
                ALERT_DATE) {
-    $status_mark = REV_CRITICAL;
-  } elseif ($rev_diff === "n/a") {
-    $status_mark = REV_NOREV;
-  } elseif ($rev_diff === 0) {
-    $status_mark = REV_WIP;
-  } else {
-    $status_mark = REV_OLD;
-  }
-
-  // Store files by status, and by maintainer too
-  $files_by_mark[$status_mark]++;
-  $files_by_maint[$this_maint][$status_mark]++;
-  $file_sizes_by_mark[$status_mark] += $en_size;
-
-  if (REV_UPTODATE === $status_mark && !$SHOW_UPTODATE) {
-    return FALSE;
-  }
-
-  return array(
-      "full_name"  => $file,
-      "short_name" => basename($trans_file),
-      "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
-  );
-
-} // 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) {
-
-  global $DOCDIR;
-
-  // Collect files and diretcories in these arrays
-  $directories = array();
-  $files       = array();
-
-  // Open the directory
-  $handle = @opendir($dir);
-
-  // Walk through all names in the directory
-  while ($file = @readdir($handle)) {
-
-    if (
-    (!is_dir($dir.'/' .$file) && !in_array(substr($file, -3), array('xml','ent')) && \
                substr($file, -13) != 'PHPEditBackup' )
-    || strpos($file, 'entities.') === 0
-    || $dir == $DOCDIR.'en/chmonly/' || $dir == $DOCDIR.'en/internals/' || $dir == \
                $DOCDIR.'en/internals2/'
-    || $file == 'contributors.ent' || $file == 'contributors.xml'
-    || ($dir == $DOCDIR.'en/appendices/' && ($file == 'reserved.constants.xml' || \
                $file == 'extensions.xml'))
-    || $file == 'README'
-    || $file == 'DO_NOT_TRANSLATE'
-    || $file == 'rsusi.txt'
-    || $file == 'missing-ids.xml'
-    || $file == 'license.xml'
-    || $file == 'versions.xml'
-    ) {
-      continue;
-    }
-
-    if ($file != '.' && $file != '..' && $file != '.svn' && $dir != '/functions') {
-      if (is_dir($dir.'/' .$file)) {
-          $directories[] = $file;
-      } elseif (is_file($dir.'/' .$file)) {
-          $files[] = $file;
-      }
-    }
-
-  }
-
-  // Close the directory
-  @closedir($handle);
-
-  // Sort files and directories
-  sort($directories);
-  sort($files);
+}
 
-  // Go through files first
-  $dir_status = array();
-  foreach ($files as $file) {
-    // If the file status is OK, append the status info
-    if ($file_status = get_file_status($dir.$file)) {
-        $dir_status[] = $file_status;
+function populateFileTree( $lang )
+{
+    $dir = new \DirectoryIterator( $lang );
+    if ( $dir === false )
+    {
+        print "$lang is not a directory.\n";
+        exit;
     }
-  }
-
-  // Then go through subdirectories, merging all the info
-  // coming from subdirs to one array
-  foreach ($directories as $file) {
-    $dir_status = array_merge(
-        $dir_status,
-        get_dir_status($dir.$file.'/')
-    );
-  }
-
-  // Return with collected file info in
-  // this dir and subdirectories [if any]
-  return $dir_status;
-
-} // get_dir_status() function end
-
-
-// Check for files removed in the EN tree, but still living in the translation
-function get_old_files($dir) {
-
-  global $DOCDIR, $LANG;
-
-  // Collect files and diretcories in these arrays
-  $directories = array();
-  $files       = array();
-
-  $special_files = array(
-    // french
-    'LISEZ_MOI.txt',
-    'TRADUCTIONS.txt',
-    'Translators',
-    'translation.xml'
-    // todo: add all missing languages
-  );
-
-  // Open the directory
-  $handle = @opendir($dir);
-
-  // Walk through all names in the directory
-  while ($file = @readdir($handle)) {
+    $cwd = getcwd();
+    $ret = array();
+    chdir( $lang );
+    populateFileTreeRecurse( $lang , "." , $ret );
+    chdir( $cwd );
+    return $ret;
+}
 
-    // If we found a file with one or two point as a name,
-    // a SVN directory, or an editor backup file skip the file
-    if (preg_match("/^\.{1,2}/", $file)
-        || $file == '.svn'
-        || substr($file, -1) == '~' // Emacs backup file
-        || substr($file, -4) == '.new'
-       ) {
-      continue;
+function populateFileTreeRecurse( $lang , $path , & $output )
+{
+    $dir = new DirectoryIterator( $path );
+    if ( $dir === false )
+    {
+        print "$path is not a directory.\n";
+        exit;
     }
-    // skip this files
-    if (in_array($file, $special_files)) {
-      continue;
+    $todoPaths = [];
+    $trimPath = ltrim( $path , "./");
+    foreach( $dir as $entry )
+    {
+        $filename = $entry->getFilename();
+        if ( $filename[0] == '.' )
+            continue;
+        if ( substr( $filename , 0 , 9 ) == "entities." )
+            continue;
+        if ( $entry->isDir() )
+        {
+            $todoPaths[] = $path . '/' . $entry->getFilename();
+            continue;
+        }
+        if ( $entry->isFile() )
+        {
+            $file = new FileStatusInfo;
+            $file->path = $trimPath;
+            $file->name = $filename;
+            $file->size = filesize( $path . '/' . $filename );
+            $file->syncStatus = null;
+            if ( $lang != 'en' )
+                parseRevisionTag( $entry->getPathname() , $file );
+            $output[ $file->getKey() ] = $file;
+        }
     }
+    sort( $todoPaths );
+    foreach( $todoPaths as $path )
+        populateFileTreeRecurse( $lang , $path , $output );
+}
 
-    // Collect files and directories
-    if (is_dir($dir.$file)) {
-      $directories[] = $file;
-    } else {
-      $files[] = $file;
+function parseRevisionTag( $filename , FileStatusInfo $file )
+{
+    $fp = fopen( $filename , "r" );
+    $contents = fread( $fp , 1024 );
+    fclose( $fp );
+    $regex = "/<!--\s*EN-Revision:\s*(.+)\s*Maintainer:\s*(.+)\s*Status:\s*(.+)\s*-->/U";
 +    $match = array();
+    preg_match ( $regex , $contents , $match );
+    if ( count( $match ) == 4 )
+    {
+        $file->hash = trim( $match[1] );
+        $file->maintainer = trim( $match[2] );
+        $file->completion = trim( $match[3] );
     }
-  }
-
-  // Close the directory
-  @closedir($handle);
-
-  // Sort files and directories
-  sort($directories);
-  sort($files);
-
-  // Go through files first
-  $old_files_status = array();
-  foreach ($files as $file) {
-
-    $en_dir = preg_replace("'^".$DOCDIR.$LANG."/'", $DOCDIR."en/", $dir);
-
-    if (!@file_exists($en_dir.$file) ) {
-      $old_files_status[$dir.$file] = array(0=>intval(filesize($dir.$file)/1024));
+    else
+    {
+        $file->hash = null;
+        $file->maintainer = null;
+        $file->completion = null;
     }
+    $regex = "/<!--\s*CREDITS:\s*(.+)\s*-->/U";
+    $match = array();
+    preg_match ( $regex , $contents , $match );
+    if ( count( $match ) == 2 )
+        $file->credits = str_replace( ' ' , '' , trim( $match[1] ) );
+    else
+        $file->credits = '';
+}
 
-  }
-
-  // Then go through subdirectories, merging all the info
-  // coming from subdirs to one array
-  foreach ($directories as $file) {
-    $old_files_status = array_merge(
-        $old_files_status,
-        get_old_files($dir.$file.'/')
-    );
-  }
-
-  return $old_files_status;
-
-} // get_old_files() 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]);
+function captureGitValues( $lang , & $output )
+{
+    $cwd = getcwd();
+    chdir( $lang );
+    $fp = popen( "git --no-pager log --name-only" , "r" );
+    $hash = null;
+    $date = null;
+    $utct = new DateTimeZone( "UTC" );
+    while ( ( $line = fgets( $fp ) ) !== false )
+    {
+        if ( substr( $line , 0 , 7 ) == "commit " )
+        {
+            $hash = trim( substr( $line , 7 ) );
+            continue;
+        }
+        if ( strpos( $line , 'Date:' ) === 0 )
+        {
+            $date = trim( substr( $line , 5 ) );
+            $date = DateTime::createFromFormat ( "D M d H:i:s Y T" , $date );
+            $date->setTime( 0 , 0 );
+            continue;
+        }
+        if ( trim( $line ) == "" )
+            continue;
+        if ( substr( $line , 0 , 4 ) == '    ' )
+            continue;
+        if ( strpos( $line , ': ' ) > 0 )
+            continue;
+        $filename = trim( $line );
+        if ( isset( $output[$filename][$lang] ) )
+            continue;
+        $output[$filename][$lang]['hash'] = $hash;
+        $output[$filename][$lang]['date'] = $date;
     }
-
-    // Collect in order of tags received
-    $tag_attrs_processed[] = $attrib_array;
-
-  }
-
-  // Retrun with collected attributes
-  return $tag_attrs_processed;
-
-} // parse_attr_string() end
-
-// Parse the translation.xml file for
-// translation related meta information
-function parse_translation($DOCDIR, $LANG, $MAINT) {
-
-  global $files_by_mark;
-
-  // 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 (different for a persons info and
-  // for a whole group info page)
-  if (empty($MAINT)) {
-    preg_match("!<intro>(.+)</intro>!s", $txml, $match);
-    $translation["intro"] = trim($match[1]);
-  } else {
-    $translation["intro"] = "Personal Statistics for ".$MAINT;
-  }
-
-  // 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 = parse_attr_string($match);
-  $output_charset = $xmlinfo[1]["encoding"];
-
-  // Get persons list preg pattern, only check for a specific
-  // maintainer, if the users asked for it
-  if (empty($MAINT)) {
-    $pattern = "!<person(.+)/\\s?>!U";
-  } else {
-    $pattern = "!<person([^<]+nick=\"".$MAINT."\".+)/\\s?>!U";
-  }
-
-  // Find all persons matching the pattern
-  preg_match_all($pattern, $txml, $matches);
-  $translation['persons'] = parse_attr_string($matches[1]);
-
-  // Get list of work in progress files
-  if (empty($MAINT)) {
-
-    // Get all wip files
-    preg_match_all("!<file(.+)/\\s?>!U", $txml, $matches);
-    $translation['files'] = parse_attr_string($matches[1]);
-
-    // Provide info about number of WIP files
-    $files_by_mark[REV_WIP] += count($translation['files']);
-
-  } else {
-
-    // 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);
-    $translation['allfiles'] = parse_attr_string($matches[1]);
-
-    // Provide info about number of WIP files
-    $files_by_mark[REV_WIP] += count($translation['allfiles']);
-
-  }
-
-  // Return with collected info in two vars
-  return array($output_charset, $translation);
-
-} // parse_translation() function end()
-
-// =========================================================================
-// Start of the program execution
-// =========================================================================
-
-// Check for directory validity
-if (!@is_dir($DOCDIR . $LANG)) {
-  die("The $LANG language code is not valid");
+    pclose( $fp );
+    chdir( $cwd );
 }
 
-// Parse translation.xml file for more information
-list($charset, $translation) = parse_translation($DOCDIR, $LANG, $MAINT);
-
-// Add WIP files to maintainers file count and figure out,
-// if we need to use optional date and revision columns
-$using_date = FALSE; $using_rev = FALSE;
-$files_by_maint = init_files_by_maint($translation['persons']);
-foreach ($translation["files"] as $num => $fileinfo) {
-  $files_by_maint[$fileinfo["person"]][REV_WIP]++;
-  if (isset($fileinfo["date"]))     { $using_date = TRUE; }
-  if (isset($fileinfo["revision"])) { $using_rev = TRUE; }
+function computeSyncStatus( $enFiles , $trFiles , $gitData , $lang )
+{
+    $now = new DateTime( 'now' );
+    foreach( $enFiles as $filename => $enFile )
+    {
+        if ( isset( $gitData[ $filename ]['en'] ) )
+        {
+            $enFile->hash = $gitData[ $filename ]['en']['hash'];
+            $enFile->date = $gitData[ $filename ]['en']['date'];
+        }
+        else
+            print "Warn: No hash for en/$filename\n";
+        $trFile = isset( $trFiles[ $filename ] ) ? $trFiles[ $filename ] : null;
+        // Untranslated (default)
+        if ( $trFile == null )
+        {
+            $enFile->syncStatus = FileStatusEnum::Untranslated;
+            continue;
+        }
+        else
+        {
+            $trFile->syncStatus = FileStatusEnum::ExistsInEnTree;
+            if ( isset( $gitData[ $filename ][ $lang ] ) )
+                $trFile->date = $gitData[ $filename ][ $lang ]['date'];
+        }
+        // RevTagProblem
+        if ( $trFile->hash == null || ( strlen( $enFile->hash ) != strlen( \
$trFile->hash ) ) ) +        {
+            $enFile->syncStatus = FileStatusEnum::RevTagProblem;
+            continue;
+        }
+        // TranslatedWip
+        if ( $trFile->completion != null && $trFile->completion != "ready" )
+        {
+            $enFile->syncStatus = FileStatusEnum::TranslatedWip;
+            continue;
+        }
+        // TranslatedOk
+        // TranslatedOld
+        // TranslatedCritial
+        if ( $enFile->hash == $trFile->hash )
+            $enFile->syncStatus = FileStatusEnum::TranslatedOk;
+        else
+        {
+            $enFile->syncStatus = FileStatusEnum::TranslatedOld;
+            if ( $enFile->date == null
+              || $trFile->date == null
+              || $now->diff( $enFile->date , true )->days > 30
+              || $now->diff( $trFile->date , true )->days > 30 )
+            {
+                $enFile->syncStatus = FileStatusEnum::TranslatedCritial;
+            }
+        }
+    }
 }
 
-// Get all files status
-$files_status = get_dir_status($DOCDIR."en/");
-
-// Get all old files in <lang> directory
-$old_files = get_old_files($DOCDIR.$LANG."/");
-
-$navbar = "<p class=c><a href=\"#intro\">Introduction</a> | " .
-          "<a href=\"#translators\">Translators</a> | " .
-          "<a href=\"#filesummary\">File summary by type</a> | " .
-          "<a href=\"#files\">Files</a> | ";
-
-if ( count($translation["files"]) != 0 ) {
-  $navbar .= "<a href=\"#wip\">Work in progress</a> | ";
+// Output
+
+function print_html_all( $enFiles , $trFiles , $lang )
+{
+    print_html_header( $lang );
+    //print_html_introduction();
+    //print_html_translations();
+    //print_html_filesumary();
+    print_html_files( $enFiles , $trFiles , $lang );
+    //print_html_wip();
+    //print_html_revtagproblem();
+    //print_html_untranslated();
+    //print_html_notinen();
+    print_html_footer();
 }
 
-$navbar .= "<a href=\"#misstags\">Missing revision numbers</a> | " .
-           "<a href=\"#missfiles\">Untranslated files</a> | " .
-           "<a href=\"#oldfiles\">Old files</a></p>\n";
-
-
-// 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>
+function print_html_header( $lang )
+{
+    $date = date("r");
+    print <<<HTML
+<!DOCTYPE html>
+<html lang="en">
 <head>
-<title>PHPDOC Revision-check</title>
-<meta http-equiv="Content-Type" content="text/html; charset={$charset}">
+<meta charset="utf-8"/>
 <style type="text/css">
-<!--
-h2,td,a,p,a.ref,th { font-family:Arial,Helvetica,sans-serif; font-size:14px; }
-h2,th,a.ref { color:#FFFFFF; }
-td,a,p { color:#000000; }
-h2     { font-size:28px; }
-th     { font-weight:bold; }
-.blue  { background-color:#666699; }
-.act   { background-color:#68D888; }
-.norev { background-color:#f4a460; }
-.old   { background-color:#eee8aa; }
-.crit  { background-color:#ff6347; }
-.wip   { background-color:#dcdcdc; }
-.r     { text-align:right }
-.rb    { text-align:right; font-weight:bold; }
-.c     { text-align:center }
-body   { margin:0px 0px 0px 0px; background-color:#F0F0F0; }
-//-->
+body { margin:0px 0px 0px 0px; background-color:#F0F0F0; font-family: sans-serif; \
text-align: center; } +a { color: black; }
+h1 { color: #FFFFFF; }
+table { margin-left: auto; margin-right: auto; text-align: left; border-spacing: \
1px; } +th { color: white; background-color: #666699; padding: 0.2em; text-align: \
center; vertical-align: middle; } +td { padding: 0.2em 0.3em; }
+.o { white-space: nowrap; overflow: hidden; max-width: 3em; }
+.c { text-align: center; }
+.r { text-align: right; }
+.b { font-weight: bold; }
+.white { color: white; }
+.black { color: black; }
+.bgblue { background-color: #666699;}
+.bggray { background-color: #dcdcdc;}
+.bggreen { background-color: #68d888;}
+.bgorange { background-color: #f4a460;}
+.bgred { background-color: #ff6347;}
+.bgyellow { background-color: #eee8aa;}
 </style>
 </head>
 <body>
-<table width="100%" border="0" cellspacing="0" bgcolor="#666699">
-<tr><td>
-<table width="100%" border="0" cellspacing="1" bgcolor="#9999CC">
-<tr><td><h2 class=c>Status of the translated PHP Manual</h2><p class=c \
style="font-size:12px;">Generated: {$date} &nbsp; / &nbsp; Language: \
                $LANG<br></p></td></tr>
-</table>
-</td></tr>
-</table>
-END_OF_MULTILINE;
 
-print ($navbar);
+<div id="header" style="background-color: #9999CC;">
+<h1 style="margin: 0; padding: 0.5em;">Status of the translated PHP Manual</h1>
+<p style="font-size: small; margin: 0; padding: 1em;">Generated: $date / Language: \
$lang</p> +</div>
 
-// =========================================================================
-// Intro block goes here
-// =========================================================================
-
-// If we have an introduction text, print it out, with an anchor
-if (!empty($translation["intro"])) {
-  echo '<a name="intro"></a>';
-  echo '<table width="800" align="center"><tr><td class=c>' .
-         $translation['intro'] . '</td></tr></table>';
+HTML;
 }
 
-// =========================================================================
-// 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 class=blue>
-<th rowspan=2>Translator's name</th>
-<th rowspan=2>Contact email</th>
-<th rowspan=2>Nick</th>
-<th rowspan=2>V<br>C<br>S</th>
-<th colspan=7>Files maintained</th>
-</tr>
-<tr>
-<th class="{$CSS[REV_CREDIT]}" style="color:#000000">cre-<br>dits</th>
-<th class="{$CSS[REV_UPTODATE]}" style="color:#000000">upto-<br>date</th>
-<th class="{$CSS[REV_OLD]}" style="color:#000000">old</th>
-<th class="{$CSS[REV_CRITICAL]}" style="color:#000000">cri-<br>tical</th>
-<th class="{$CSS[REV_NOREV]}" style="color:#000000">no<br>rev</th>
-<th class="{$CSS[REV_WIP]}" style="color:#000000">wip</th>
-<th class="blue">sum</th>
-</tr>
-END_OF_MULTILINE;
-
-  // ' Please leave this comment here
-
-  // We will collect the maintainers by nick here
-  $maint_by_nick = array();
+function print_html_menu( $href )
+{
+    print <<<HTML
 
-  // Print out a line for each maintainer (with respect to
-  // maintainer setting provided in command line)
-  foreach($translation["persons"] as $num => $person) {
+<a id="$href"/>
+<p><a href="#intro">Introduction</a> | <a href="#translators">Translators</a> | <a \
href="#filesummary">File summary</a> | <a href="#files">Files</a> | <a \
href="#wip">Work in progress</a> | <a href="#revtag">Revision tag problem</a> | <a \
href="#untranslated">Untranslated files</a> | <a href="#notinen">Not in EN \
tree</a></p>  
-    // 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 SVN text and the color of the line
-    if (isset($person["vcs"]) && $person["vcs"] === "yes") {
-      $svnu = "x";
-      $col = "old";
-    } else {
-      $svnu = "&nbsp;";
-      $col = "wip";
-    }
-
-    // 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();
-    }
-
-    echo "<tr class=$col>" .
-          "<td><a name=\"maint$num\">$person[name]</a></td>" .
-          "<td>$person[email]</td>" .
-          "<td>$person[nick]</td>" .
-          "<td class=c>$svnu</td>" .
-          "<td class=c>" . $pi[REV_CREDIT]   . "</td>" .
-          "<td class=c>" . $pi[REV_UPTODATE] . "</td>" .
-          "<td class=c>" . $pi[REV_OLD]      . "</td>" .
-          "<td class=c>" . $pi[REV_CRITICAL] . "</td>" .
-          "<td class=c>" . $pi[REV_NOREV]    . "</td>" .
-          "<td class=c>" . $pi[REV_WIP]      . "</td>" .
-          "<th class=blue>" . array_sum($pi) . "</th>" .
-          "</tr>\n";
-  }
-
-  echo "</table>\n<p>&nbsp;</p>\n";
+HTML;
 }
 
-// =========================================================================
-// Files summary table goes here
-// =========================================================================
-
-// Do not print out file summary table, if we are printing out a page
-// for only one maintainer (his personal summary is in the table above)
-if (empty($MAINT)) {
-
-print <<<END_OF_MULTILINE
-<a name="filesummary"></a>
-<table width="450" border="0" cellpadding="4" cellspacing="1" align="center">
-<tr class=blue>
-<th>File status type</th>
-<th>Number of files</th>
-<th>Percent of files</th>
-<th>Size of files (kB)</th>
-<th>Percent of size</th>
-</tr>
-END_OF_MULTILINE;
-
-  $files_sum = array_sum($files_by_mark);
-  $file_sizes_sum = array_sum($file_sizes_by_mark);
-
-  $file_types = array(
-    array (REV_UPTODATE, "Up to date 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) {
-    echo "<tr class=".$CSS[$type[0]].">".
-              "<td>".$type[1]."</td>".
-              "<td class=c>".intval($files_by_mark[$type[0]])."</td>".
-              "<td class=c>".number_format($files_by_mark[$type[0]] * 100 / \
                $files_sum, 2 ).
-              "%</td>".
-              "<td class=c>".intval($file_sizes_by_mark[$type[0]])."</td>".
-              "<td class=c>".number_format($file_sizes_by_mark[$type[0]] * 100 / \
                $file_sizes_sum, 2).
-              "%</td></tr>\n";
-  }
-
-  echo "<tr class=blue><th>Files \
total</th><th>$files_sum</th><th>100%</th><th>$file_sizes_sum</th><th>100%</th></tr>\n".
                
-                "</table>\n<p>&nbsp;</p>\n";
-
+function print_html_footer()
+{
+    print <<<HTML
+</body>
+</html>
+HTML;
 }
 
-echo $navbar."<p>&nbsp;</p>\n";
-
-// =========================================================================
-// Files table goes here
-// =========================================================================
-
-if (count($files_status) != 0) {
-
-print <<<END_OF_MULTILINE
-<a name="files"></a>
-<table width="820" border="0" cellpadding="4" cellspacing="1" align="center">
-<tr class=blue>
-<th rowspan=2>Translated file</th>
-<th colspan=2>Revision</th>
-<th colspan=3>Size in kB</th>
-<th colspan=3>Age in days</th>
-<th rowspan=2>Maintainer</th>
-<th rowspan=2>Status</th>
-</tr>
-<tr class=blue>
-<th>en</th>
-<th>$LANG</th>
-<th>en</th>
-<th>$LANG</th>
-<th>diff</th>
-<th>en</th>
-<th>$LANG</th>
-<th>diff</th>
-</tr>
-END_OF_MULTILINE;
-
-  // This was the previous directory [first]
-  $prev_dir = false;
-
-  // Go through all files collected
-  foreach ($files_status as $num => $file) {
-
-    // 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 SVN repository's diff script
-    if ($file["revision"][2] != "n/a" && $file["revision"][2] !== 0) {
-      $url = 'http://svn.php.net/viewvc/' .
-             preg_replace( "'^".$DOCDIR."en/'", 'phpdoc/en/trunk/', \
                $file['full_name']) .
-             '?r1=' . $file['revision'][1] . '&amp;r2=' . $file['revision'][0];
-      $url_ws = $url . SVN_OPT_NOWS;
-      $url   .= SVN_OPT;
-
-      $file['short_name'] = '<a href="' . $url . '">'. $file["short_name"] . '</a> \
                '.
-                            '<a href="' . $url_ws . '">[NoWS]</a>';
+function print_html_files( $enFiles , $trFiles , $lang )
+{
+    print_html_menu( 'files' );
+    print <<<HTML
+<table>
+ <tr>
+  <th rowspan="2">Translated file</th>
+  <th colspan="2">Hash</th>
+  <th colspan="3">Size in kB</th>
+  <th colspan="3">Age in days</th>
+  <th rowspan="2">Maintainer</th>
+  <th rowspan="2">Status</th>
+ </tr>
+ <tr>
+  <th>en</th>
+  <th>$lang</th>
+  <th>en</th>
+  <th>$lang</th>
+  <th>diff</th>
+  <th>en</th>
+  <th>$lang</th>
+  <th>diff</th>
+ </tr>
+
+HTML;
+
+    $now = new DateTime( 'now' );
+    $path = null;
+    foreach( $enFiles as $key => $en )
+    {
+        if ( $en->syncStatus == FileStatusEnum::TranslatedOk )
+            continue;
+        if ( $en->syncStatus == FileStatusEnum::Untranslated )
+            continue;
+        $tr = $trFiles[ $key ];
+        if ( $path !== $en->path )
+        {
+            $path = $en->path;
+            $path2 = $path == '' ? '/' : $path;
+            print " <tr><th colspan='11' class='blue c'>$path2</th></tr>";
+        }
+        switch( $en->syncStatus )
+        {
+            case FileStatusEnum::RevTagProblem:     $bg = 'bgorange'; break;
+            case FileStatusEnum::TranslatedOk:      $bg = 'bggreen' ; break;
+            case FileStatusEnum::TranslatedOld:     $bg = 'bgyellow'; break;
+            case FileStatusEnum::TranslatedCritial: $bg = 'bgred'   ; break;
+            default:                                $bg = 'bggray'  ; break;
+        }
+        $df = "https://git.php.net/?p=doc/en.git;a=blobdiff;f=$key;hb={$en->hash};hpb={$tr->hash};";
 +        $nm = "<a href='$df'>{$en->name}</a>";
+        if ( $en->syncStatus == FileStatusEnum::RevTagProblem )
+            $nm = $en->name;
+        $h1 = "<a href='http://git.php.net/?p=doc/en.git;a=blob;f=$key;hb={$en->hash}'>{$en->hash}</a>";
 +        $h2 = "<a href='http://git.php.net/?p=doc/en.git;a=blob;f=$key;hb={$tr->hash}'>{$tr->hash}</a>";
 +        $s1 = $en->size < 1024 ? 1 : floor( $en->size / 1024 );
+        $s2 = $tr->size < 1024 ? 1 : floor( $tr->size / 1024 );
+        $s3 = $s2 - $s1;
+        $a1 = $now->diff( $en->date )->days;
+        $a2 = $now->diff( $tr->date )->days;
+        $a3 = $a2 - $a1;
+        $ma = $tr->maintainer;
+        $st = $tr->completion;
+        print <<<HTML
+ <tr class="$bg">
+  <td class="l">$nm</td>
+  <td class="o">$h1</td>
+  <td class="o">$h2</td>
+  <td class="r">$s1</td>
+  <td class="r">$s2</td>
+  <td class="r">$s3</td>
+  <td class="r">$a1</td>
+  <td class="r">$a2</td>
+  <td class="r">$a3</td>
+  <td class="c">$ma</td>
+  <td class="c">$st</td>
+ </tr>
+HTML;
     }
-
-    // Guess the new directory from the full name of the file
-    $new_dir = dirname($file["full_name"]);
-
-    // If this is a new directory, put out old dir lines
-    if ($new_dir !== $prev_dir) {
-      if (isset($lines)) {
-        echo $prev_diplay_dir;
-        echo " ($line_number)</th></tr>";
-        echo $lines;
-      }
-
-      $lines = '';
-      $line_number = 0;
-
-      // Store the new actual directory
-      $prev_dir = $new_dir;
-    }
-    // Drop out the unneeded parts from the dirname, special case for root dir...
-    $display_dir = str_replace(array($DOCDIR."en/", $DOCDIR."en"), array("", '/'), \
                dirname($file["full_name"]));
-    $prev_diplay_dir = "<tr class=blue><th colspan=12>$display_dir";
-
-    // Save the line for the current file (get file name shorter)
-    $lines .= "<tr class={$CSS[$file['mark']]}><td>{$file['short_name']}</td>".
-          "<td> {$file['revision'][0]}</td>" .
-          "<td> {$file['revision'][1]}</td>".
-          "<td class=r>{$file['size'][0]} </td>".
-          "<td class=r>{$file['size'][1]} </td>".
-          "<td class=rb>{$file['size'][2]} </td>".
-          "<td class=r>{$file['date'][0]} </td>".
-          "<td class=r>{$file['date'][1]} </td>".
-          "<td class=rb>{$file['date'][2]} </td>".
-          "<td class=c>{$file['maintainer']}</td>".
-          "<td class=c>".trim($file['status'])."</td></tr>\n";
-     $line_number++;
-
-  }
-
-  // echo the last dir and $lines
-  echo "$prev_diplay_dir ($line_number)</th></tr>";
-  echo $lines;
-
-  echo "</table>\n<p>&nbsp;</p>\n$navbar<p>&nbsp;</p>\n";
-
+    print "</table>\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) {
-
-  // Print out files table header
-  echo "<a name=\"wip\"></a>\n" .
-  "<table width=\"820\" border=\"0\" cellpadding=\"4\" cellspacing=\"1\" \
                align=\"center\">\n" .
-  "<tr class=blue>".
-  "<th>Work in progress files</th>".
-  "<th>Translator</th>".
-  "<th>Type</th>";
-
-  // Print out date and revision columns if needed
-  if ($using_date) {
-    echo '<th>Date</th>';
-  }
-  if ($using_rev) {
-    echo '<th>CO-Revision</th>' .
-            '<th>EN-Revision</th>';
-  }
-  echo "</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
-    echo  "<tr class=wip><td>$finfo[name]</td>" .
-          "<td>$finfo[person]</td><td>$finfo[type]</td>";
-
-    // If we need the date column, print it out
-    if ($using_date) {
-      echo "<td>$finfo[date]</td>";
-    }
-
-    // If we need the revision column, print it out
-    if ($using_rev) {
-      echo "<td>$finfo[revision]</td><td>" .
-            $missing_files[$finfo["name"]][1] .
-            "</td>";
-    }
-
-    // End the line
-    echo "</tr>\n";
-
-    // Collect files in WIP list
-    $wip_files[$finfo["name"]] = TRUE;
-  }
-
-  echo "</table>\n<p>&nbsp;</p>\n$navbar<p>&nbsp;</p>\n";
-
-}
-
-// Files translated, but without a revision comment
-if (isset($missing_tags)) {
-    $count = count($missing_tags);
-} else {
-    $count = 0;
-}
-
-if ($count > 0) {
-  echo  "<a name=\"misstags\"></a>" .
-        "<table width=\"400\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" \
                align=\"center\">\n".
-        "<tr class=blue><th rowspan=2>Files without Revision-comment ($count \
                files):</th>".
-        "<th colspan=3>Sizes in kB</th></tr>\n".
-        "<tr class=blue><th>en</th><th>$LANG</th><th>diff</th></tr>\n";
-
-  foreach($missing_tags as $val) {
-
-    // Shorten the filename (we have directory headers)
-    $short_file = basename($val[0]);
-
-    // Guess the new directory from the full name of the file
-    $new_dir = dirname($val[0]);
-
-    // If this is a new directory, put out dir headline
-    if ($new_dir != $prev_dir) {
-
-        // Print out directory header
-        echo "<tr class=blue><th colspan=4>$new_dir</th></tr>\n";
-
-        // Store the new actual directory
-        $prev_dir = $new_dir;
-    }
-    echo  "<tr class=wip><td>$short_file</td><td class=r>$val[1]</td>".
-          "<td class=r>$val[2]</td><td class=r>$val[3]</td></tr>\n";
-  }
-
-  echo "</table>\n<p>&nbsp;</p>\n$navbar<p>&nbsp;</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($missing_files);
-if ($count > 0) {
-
-  echo  "<a name=\"missfiles\"></a>" .
-        "<table width=\"400\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" \
                align=\"center\">\n" .
-        "<tr class=blue><th><a name=\"avail\" class=\"ref\">" .
-        " Available for translation</a> ($count files):</th><th>kB</th></tr>\n";
-
-  foreach($missing_files as $file => $info) {
-    // Shorten the filename (we have directory headers)
-    $short_file = basename($file);
-
-    // Guess the new directory from the full name of the file
-    $new_dir = dirname($file);
-
-    // If this is a new directory, put out dir headline
-    if ($new_dir != $prev_dir) {
-
-        // Print out directory header if not "."
-        echo "<tr class=blue><th colspan=2>$new_dir</th></tr>\n";
-
-        // Store the new actual directory
-        $prev_dir = $new_dir;
-    }
-
-    echo "<tr class=wip><td><a \
href=\"http://svn.php.net/viewvc/phpdoc/en/trunk/$file?view=markup\">$short_file</a></td>" \
                .
-          "<td class=r>$info[0]</td></tr>\n";
-  }
-  echo "</table>\n<p>&nbsp;</p>\n$navbar<p>&nbsp;</p>\n";
-
-}
-
-// Files not in EN tree
-$count = count($old_files);
-
-if ($count > 0) {
-
-  print "<a name=\"oldfiles\"></a>" .
-        "<table width=\"400\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\" \
                align=\"center\">\n" .
-        "<tr class=blue><th><a name=\"notEn\" class=\"ref\">" .
-        " Not in EN Tree</a> ($count files):</th><th>kB</th></tr>\n";
-
-  foreach($old_files as $file => $info) {
-
-    // Shorten the filename (we have directory headers)
-    $short_file = basename($file);
-
-    // Guess the new directory from the full name of the file
-    $new_dir = dirname($file);
-
-    // If this is a new directory, put out dir headline
-    if ($new_dir != $prev_dir) {
-
-        // Print out directory header if not "."
-        echo "<tr class=blue><th colspan=2>$new_dir</th></tr>\n";
-
-        // Store the new actual directory
-        $prev_dir = $new_dir;
-    }
-
-    echo "<tr class=wip><td>$short_file</td>" .
-          "<td class=r>$info[0]</td></tr>\n";
-  }
-  echo "</table>\n<p>&nbsp;</p>\n$navbar<p>&nbsp;</p>\n";
-
-}
-
-
-// All OK, end the file
-echo "</body>\n</html>\n";
-
-?>



-- 
PHP Documentation Commits Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic