[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |