[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/extensions/LocalisationUpdate/ -> Updater.php (source)

   1  <?php
   2  /**
   3   * @file
   4   * @author Niklas Laxström
   5   * @license GPL-2.0+
   6   */
   7  
   8  /**
   9   * Executes the localisation update.
  10   */
  11  class LU_Updater {
  12      /**
  13       * Whether the path is a pattern and thus we need to use appropriate
  14       * code for fetching directories.
  15       *
  16       * @param string $path Url
  17       * @return bool
  18       */
  19  	public function isDirectory( $path ) {
  20          $filename = basename( $path );
  21          return strpos( $filename, '*' ) !== false;
  22      }
  23  
  24      /**
  25       * Expands repository relative path to full url with the given repository
  26       * patterns. Extra variables in $info are used as variables and will be
  27       * replaced the pattern.
  28       *
  29       * @param array $info Component information.
  30       * @param array $repos Repository information.
  31       * @return string
  32       */
  33  	public function expandRemotePath( $info, $repos ) {
  34          $pattern = $repos[$info['repo']];
  35          unset( $info['repo'], $info['orig'] );
  36  
  37          // This assumes all other keys are used as variables
  38          // in the pattern. For example name -> %NAME%.
  39          $keys = array();
  40          foreach ( array_keys( $info ) as $key ) {
  41              $keys[] = '%' . strtoupper( $key ) . '%';
  42          }
  43  
  44          $values = array_values( $info );
  45          return str_replace( $keys, $values, $pattern );
  46      }
  47  
  48      /**
  49       * Parses translations from given list of files.
  50       *
  51       * @param LU_ReaderFactory $readerFactory Factory to construct parsers.
  52       * @param array $files List of files with their contents as array values.
  53       * @return array List of translations indexed by language code.
  54       */
  55  	public function readMessages( LU_ReaderFactory $readerFactory, array $files ) {
  56          $messages = array();
  57  
  58          foreach ( $files as $filename => $contents ) {
  59              $reader = $readerFactory->getReader( $filename );
  60              try {
  61                  $parsed = $reader->parse( $contents );
  62              } catch ( Exception $e ) {
  63                  trigger_error( __METHOD__ . ": Unable to parse messages from $filename", E_USER_WARNING );
  64                  continue;
  65              }
  66  
  67              foreach ( $parsed as $code => $langMessages ) {
  68                  if ( !isset( $messages[$code] ) ) {
  69                      $messages[$code] = array();
  70                  }
  71                  $messages[$code] = array_merge( $messages[$code], $langMessages );
  72              }
  73  
  74              $c = array_sum( array_map( 'count', $parsed ) );
  75              // Useful for debugging, maybe create interface to pass this to the script?
  76              #echo "$filename with " . get_class( $reader ) . " and $c\n";
  77          }
  78  
  79          return $messages;
  80      }
  81  
  82      /**
  83       * Find new and changed translations in $remote and returns them.
  84       *
  85       * @param array $origin
  86       * @param array $remote
  87       * @param array [$blacklist] Array of message keys to ignore, keys as as array keys.
  88       * @return array
  89       */
  90  	public function findChangedTranslations( $origin, $remote, $blacklist = array() ) {
  91          $changed = array();
  92          foreach ( $remote as $key => $value ) {
  93              if ( isset( $blacklist[$key] ) ) {
  94                  continue;
  95              }
  96  
  97              if ( !isset( $origin[$key] ) || $value !== $origin[$key] ) {
  98                  $changed[$key] = $value;
  99              }
 100          }
 101          return $changed;
 102      }
 103  
 104      /**
 105       * Fetches files from given Url pattern.
 106       *
 107       * @param LU_FetcherFactory $factory Factory to construct fetchers.
 108       * @param string $path Url to the file or pattern of files.
 109       * @return array List of Urls with file contents as path.
 110       */
 111  	public function fetchFiles( LU_FetcherFactory $factory, $path ) {
 112          $fetcher = $factory->getFetcher( $path );
 113  
 114          if ( $this->isDirectory( $path ) ) {
 115              $files = $fetcher->fetchDirectory( $path );
 116          } else {
 117              $files = array( $path => $fetcher->fetchFile( $path ) );
 118          }
 119  
 120          // Remove files which were not found
 121          return array_filter( $files );
 122      }
 123  
 124  	public function execute(
 125          LU_Finder $finder,
 126          LU_ReaderFactory $readerFactory,
 127          LU_FetcherFactory $fetcherFactory,
 128          array $repos
 129      ) {
 130  
 131          $components = $finder->getComponents();
 132  
 133          $updatedMessages = array();
 134  
 135          foreach ( $components as $key => $info ) {
 136              $originFiles = $this->fetchFiles( $fetcherFactory, $info['orig'] );
 137              $remoteFiles = $this->fetchFiles( $fetcherFactory, $this->expandRemotePath( $info, $repos ) );
 138  
 139              if ( $remoteFiles === array() ) {
 140                  // Small optimization: if nothing to compare with, skip
 141                  continue;
 142              }
 143  
 144              $originMessages = $this->readMessages( $readerFactory, $originFiles );
 145              $remoteMessages = $this->readMessages( $readerFactory, $remoteFiles );
 146  
 147              if ( !isset( $remoteMessages['en'] ) ) {
 148                  // Could not find remote messages
 149                  continue;
 150              }
 151  
 152              // If remote translation in English is not present or differs, we do not want
 153              // translations for other languages for those messages, as they are either not
 154              // used in this version of code or can be incompatible.
 155              $forbiddenKeys = $this->findChangedTranslations(
 156                  $originMessages['en'],
 157                  $remoteMessages['en']
 158              );
 159  
 160              // We never accept updates for English strings
 161              unset( $originMessages['en'], $remoteMessages['en'] );
 162  
 163              // message: string in all languages; translation: string in one language.
 164              foreach ( $remoteMessages as $language => $remoteTranslations ) {
 165                  // Check for completely new languages
 166                  $originTranslations = array();
 167                  if ( isset( $originMessages[$language] ) ) {
 168                      $originTranslations = $originMessages[$language];
 169                  }
 170  
 171                  $updatedTranslations = $this->findChangedTranslations(
 172                      $originTranslations,
 173                      $remoteTranslations,
 174                      $forbiddenKeys
 175                  );
 176  
 177                  // Avoid empty arrays
 178                  if ( $updatedTranslations === array() ) {
 179                      continue;
 180                  }
 181  
 182                  if ( !isset( $updatedMessages[$language] ) ) {
 183                      $updatedMessages[$language] = array();
 184                  }
 185  
 186                  // In case of conflicts, which should not exist, this prefers the
 187                  // first translation seen.
 188                  $updatedMessages[$language] += $updatedTranslations;
 189              }
 190          }
 191  
 192          return $updatedMessages;
 193      }
 194  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1