MessageGroupCache.php
Go to the documentation of this file.00001 <?php
00018 class MessageGroupCache {
00019 const NO_SOURCE = 1;
00020 const NO_CACHE = 2;
00021 const CHANGED = 3;
00022
00026 protected $group;
00027
00031 protected $cache;
00032
00036 protected $code;
00037
00043 public function __construct( $group, $code = 'en' ) {
00044 if ( is_object( $group ) ) {
00045 $this->group = $group;
00046 } else {
00047 $this->group = MessageGroups::getGroup( $group );
00048 }
00049 $this->code = $code;
00050 }
00051
00056 public function exists() {
00057 return file_exists( $this->getCacheFileName() );
00058 }
00059
00064 public function getKeys() {
00065 return unserialize( $this->open()->get( '#keys' ) );
00066 }
00067
00072 public function getTimestamp() {
00073 return $this->open()->get( '#created' );
00074 }
00075
00080 public function getUpdateTimestamp() {
00081 return $this->open()->get( '#updated' );
00082 }
00083
00089 public function get( $key ) {
00090 return $this->open()->get( $key );
00091 }
00092
00097 public function create( $created = false ) {
00098 $this->close();
00099
00100 $messages = $this->group->load( $this->code );
00101 if ( !count( $messages ) && !( $this->group instanceof SingleFileBasedMessageGroup ) ) {
00102 if ( $this->exists() ) {
00103
00104 unlink( $this->getCacheFileName() );
00105 }
00106
00107 return;
00108 }
00109 $hash = md5( file_get_contents( $this->group->getSourceFilePath( $this->code ) ) );
00110
00111 $cache = CdbWriter::open( $this->getCacheFileName() );
00112 $keys = array_keys( $messages );
00113 $cache->set( '#keys', serialize( $keys ) );
00114
00115 foreach ( $messages as $key => $value ) {
00116 $cache->set( $key, $value );
00117 }
00118
00119 $cache->set( '#created', $created ? $created : wfTimestamp() );
00120 $cache->set( '#updated', wfTimestamp() );
00121 $cache->set( '#filehash', $hash );
00122 $cache->set( '#msgcount', count( $messages ) );
00123 ksort( $messages );
00124 $cache->set( '#msghash', md5( serialize( $messages ) ) );
00125 $cache->set( '#version', '3' );
00126 $cache->close();
00127 }
00128
00136 public function isValid( &$reason = 0 ) {
00137 $group = $this->group;
00138 $groupId = $group->getId();
00139
00140 $filename = $group->getSourceFilePath( $this->code );
00141
00142 if ( $group instanceof SingleFileBasedMessageGroup ) {
00143 $source = $group->getFFS()->read( $this->code ) !== false;
00144 } else {
00145 static $globCache = null;
00146 if ( !isset( $globCache[$groupId] ) ) {
00147 $pattern = $group->getSourceFilePath( '*' );
00148 $globCache[$groupId] = array_flip( glob( $pattern, GLOB_NOESCAPE ) );
00149
00150 $globCache[$groupId][$group->getSourceFilePath( 'en' )] = true;
00151 }
00152 $source = isset( $globCache[$groupId][$filename] );
00153 }
00154
00155 $cache = $this->exists();
00156
00157
00158 if ( !$cache && !$source ) {
00159 return true;
00160 } elseif ( !$cache && $source ) {
00161 $reason = self::NO_CACHE;
00162
00163 return false;
00164 } elseif ( $cache && !$source ) {
00165 $reason = self::NO_SOURCE;
00166
00167 return false;
00168 } elseif ( filemtime( $filename ) <= $this->get( '#updated' ) ) {
00169 return true;
00170 }
00171
00172
00173 $created = $this->get( '#created' );
00174
00175
00176 $newhash = md5( file_get_contents( $filename ) );
00177 if ( $this->get( '#filehash' ) === $newhash ) {
00178
00179 $this->create( $created );
00180
00181 return true;
00182 }
00183
00184
00185 $messages = $group->load( $this->code );
00186
00187 $count = intval( $this->get( '#msgcount' ) );
00188 if ( $count !== count( $messages ) ) {
00189
00190 $reason = self::CHANGED;
00191
00192 return false;
00193 }
00194
00195
00196 ksort( $messages );
00197 if ( $this->get( '#msghash' ) === md5( serialize( $messages ) ) ) {
00198
00199 $this->create( $created );
00200
00201 return true;
00202 }
00203
00204 $reason = self::CHANGED;
00205
00206 return false;
00207 }
00208
00213 protected function open() {
00214 if ( $this->cache === null ) {
00215 $this->cache = CdbReader::open( $this->getCacheFileName() );
00216 if ( $this->cache->get( '#version' ) !== '3' ) {
00217 $this->updateCacheFormat( $this->cache );
00218 $this->close();
00219
00220 return $this->open();
00221 }
00222 }
00223
00224 return $this->cache;
00225 }
00226
00230 protected function close() {
00231 if ( $this->cache !== null ) {
00232 $this->cache->close();
00233 $this->cache = null;
00234 }
00235 }
00236
00241 protected function getCacheFileName() {
00242 $cacheFileName = "translate_groupcache-{$this->group->getId()}-{$this->code}.cdb";
00243
00244 return TranslateUtils::cacheFile( $cacheFileName );
00245 }
00246
00251 protected function updateCacheFormat( $oldcache ) {
00252
00253 $conv = array(
00254 '#keys' => $oldcache->get( '<|keys#>' ),
00255 '#created' => $oldcache->get( '<|timestamp#>' ),
00256 '#updated' => wfTimestamp(),
00257 '#filehash' => $oldcache->get( '<|hash#>' ),
00258 '#version' => '3',
00259 );
00260 $conv['#msgcount'] = count( $conv['#keys'] );
00261
00262 $messages = array();
00263 foreach ( unserialize( $conv['#keys'] ) as $key ) {
00264 $messages[$key] = $oldcache->get( $key );
00265 }
00266
00267 ksort( $messages );
00268 $conv['#msghash'] = md5( serialize( $messages ) );
00269 $oldcache->close();
00270
00271
00272 $cache = CdbWriter::open( $this->getCacheFileName() );
00273 foreach ( $conv as $key => $value ) {
00274 $cache->set( $key, $value );
00275 }
00276 foreach ( $messages as $key => $value ) {
00277 $cache->set( $key, $value );
00278 }
00279 $cache->close();
00280 }
00281 }