MediaWiki  1.23.15
LocalisationCache.php
Go to the documentation of this file.
1 <?php
23 define( 'MW_LC_VERSION', 2 );
24 
39  private $conf;
40 
46  private $manualRecache = false;
47 
51  private $forceRecache = false;
52 
59  protected $data = array();
60 
66  private $store;
67 
75  private $loadedItems = array();
76 
81  private $loadedSubitems = array();
82 
88  private $initialisedLangs = array();
89 
95  private $shallowFallbacks = array();
96 
100  private $recachedLangs = array();
101 
105  static public $allKeys = array(
106  'fallback', 'namespaceNames', 'bookstoreList',
107  'magicWords', 'messages', 'rtl', 'capitalizeAllNouns', 'digitTransformTable',
108  'separatorTransformTable', 'fallback8bitEncoding', 'linkPrefixExtension',
109  'linkTrail', 'linkPrefixCharset', 'namespaceAliases',
110  'dateFormats', 'datePreferences', 'datePreferenceMigrationMap',
111  'defaultDateFormat', 'extraUserToggles', 'specialPageAliases',
112  'imageFiles', 'preloadedMessages', 'namespaceGenderAliases',
113  'digitGroupingPattern', 'pluralRules', 'pluralRuleTypes', 'compiledPluralRules',
114  );
115 
120  static public $mergeableMapKeys = array( 'messages', 'namespaceNames',
121  'dateFormats', 'imageFiles', 'preloadedMessages'
122  );
123 
127  static public $mergeableListKeys = array( 'extraUserToggles' );
128 
133  static public $mergeableAliasListKeys = array( 'specialPageAliases' );
134 
140  static public $optionalMergeKeys = array( 'bookstoreList' );
141 
145  static public $magicWordKeys = array( 'magicWords' );
146 
150  static public $splitKeys = array( 'messages' );
151 
155  static public $preloadedKeys = array( 'dateFormats', 'namespaceNames' );
156 
161  private $pluralRules = null;
162 
175  private $pluralRuleTypes = null;
176 
177  private $mergeableKeys = null;
178 
187  function __construct( $conf ) {
188  global $wgCacheDirectory;
189 
190  $this->conf = $conf;
191  $storeConf = array();
192  if ( !empty( $conf['storeClass'] ) ) {
193  $storeClass = $conf['storeClass'];
194  } else {
195  switch ( $conf['store'] ) {
196  case 'files':
197  case 'file':
198  $storeClass = 'LCStoreCDB';
199  break;
200  case 'db':
201  $storeClass = 'LCStoreDB';
202  break;
203  case 'accel':
204  $storeClass = 'LCStoreAccel';
205  break;
206  case 'detect':
207  $storeClass = $wgCacheDirectory ? 'LCStoreCDB' : 'LCStoreDB';
208  break;
209  default:
210  throw new MWException(
211  'Please set $wgLocalisationCacheConf[\'store\'] to something sensible.' );
212  }
213  }
214 
215  wfDebugLog( 'caches', get_class( $this ) . ": using store $storeClass" );
216  if ( !empty( $conf['storeDirectory'] ) ) {
217  $storeConf['directory'] = $conf['storeDirectory'];
218  }
219 
220  $this->store = new $storeClass( $storeConf );
221  foreach ( array( 'manualRecache', 'forceRecache' ) as $var ) {
222  if ( isset( $conf[$var] ) ) {
223  $this->$var = $conf[$var];
224  }
225  }
226  }
227 
234  public function isMergeableKey( $key ) {
235  if ( $this->mergeableKeys === null ) {
236  $this->mergeableKeys = array_flip( array_merge(
237  self::$mergeableMapKeys,
238  self::$mergeableListKeys,
239  self::$mergeableAliasListKeys,
240  self::$optionalMergeKeys,
241  self::$magicWordKeys
242  ) );
243  }
244 
245  return isset( $this->mergeableKeys[$key] );
246  }
247 
257  public function getItem( $code, $key ) {
258  if ( !isset( $this->loadedItems[$code][$key] ) ) {
259  wfProfileIn( __METHOD__ . '-load' );
260  $this->loadItem( $code, $key );
261  wfProfileOut( __METHOD__ . '-load' );
262  }
263 
264  if ( $key === 'fallback' && isset( $this->shallowFallbacks[$code] ) ) {
265  return $this->shallowFallbacks[$code];
266  }
267 
268  return $this->data[$code][$key];
269  }
270 
278  public function getSubitem( $code, $key, $subkey ) {
279  if ( !isset( $this->loadedSubitems[$code][$key][$subkey] ) &&
280  !isset( $this->loadedItems[$code][$key] )
281  ) {
282  wfProfileIn( __METHOD__ . '-load' );
283  $this->loadSubitem( $code, $key, $subkey );
284  wfProfileOut( __METHOD__ . '-load' );
285  }
286 
287  if ( isset( $this->data[$code][$key][$subkey] ) ) {
288  return $this->data[$code][$key][$subkey];
289  } else {
290  return null;
291  }
292  }
293 
306  public function getSubitemList( $code, $key ) {
307  if ( in_array( $key, self::$splitKeys ) ) {
308  return $this->getSubitem( $code, 'list', $key );
309  } else {
310  $item = $this->getItem( $code, $key );
311  if ( is_array( $item ) ) {
312  return array_keys( $item );
313  } else {
314  return false;
315  }
316  }
317  }
318 
324  protected function loadItem( $code, $key ) {
325  if ( !isset( $this->initialisedLangs[$code] ) ) {
326  $this->initLanguage( $code );
327  }
328 
329  // Check to see if initLanguage() loaded it for us
330  if ( isset( $this->loadedItems[$code][$key] ) ) {
331  return;
332  }
333 
334  if ( isset( $this->shallowFallbacks[$code] ) ) {
335  $this->loadItem( $this->shallowFallbacks[$code], $key );
336 
337  return;
338  }
339 
340  if ( in_array( $key, self::$splitKeys ) ) {
341  $subkeyList = $this->getSubitem( $code, 'list', $key );
342  foreach ( $subkeyList as $subkey ) {
343  if ( isset( $this->data[$code][$key][$subkey] ) ) {
344  continue;
345  }
346  $this->data[$code][$key][$subkey] = $this->getSubitem( $code, $key, $subkey );
347  }
348  } else {
349  $this->data[$code][$key] = $this->store->get( $code, $key );
350  }
351 
352  $this->loadedItems[$code][$key] = true;
353  }
354 
361  protected function loadSubitem( $code, $key, $subkey ) {
362  if ( !in_array( $key, self::$splitKeys ) ) {
363  $this->loadItem( $code, $key );
364 
365  return;
366  }
367 
368  if ( !isset( $this->initialisedLangs[$code] ) ) {
369  $this->initLanguage( $code );
370  }
371 
372  // Check to see if initLanguage() loaded it for us
373  if ( isset( $this->loadedItems[$code][$key] ) ||
374  isset( $this->loadedSubitems[$code][$key][$subkey] )
375  ) {
376  return;
377  }
378 
379  if ( isset( $this->shallowFallbacks[$code] ) ) {
380  $this->loadSubitem( $this->shallowFallbacks[$code], $key, $subkey );
381 
382  return;
383  }
384 
385  $value = $this->store->get( $code, "$key:$subkey" );
386  $this->data[$code][$key][$subkey] = $value;
387  $this->loadedSubitems[$code][$key][$subkey] = true;
388  }
389 
397  public function isExpired( $code ) {
398  if ( $this->forceRecache && !isset( $this->recachedLangs[$code] ) ) {
399  wfDebug( __METHOD__ . "($code): forced reload\n" );
400 
401  return true;
402  }
403 
404  $deps = $this->store->get( $code, 'deps' );
405  $keys = $this->store->get( $code, 'list' );
406  $preload = $this->store->get( $code, 'preload' );
407  // Different keys may expire separately, at least in LCStoreAccel
408  if ( $deps === null || $keys === null || $preload === null ) {
409  wfDebug( __METHOD__ . "($code): cache missing, need to make one\n" );
410 
411  return true;
412  }
413 
414  foreach ( $deps as $dep ) {
415  // Because we're unserializing stuff from cache, we
416  // could receive objects of classes that don't exist
417  // anymore (e.g. uninstalled extensions)
418  // When this happens, always expire the cache
419  if ( !$dep instanceof CacheDependency || $dep->isExpired() ) {
420  wfDebug( __METHOD__ . "($code): cache for $code expired due to " .
421  get_class( $dep ) . "\n" );
422 
423  return true;
424  }
425  }
426 
427  return false;
428  }
429 
435  protected function initLanguage( $code ) {
436  if ( isset( $this->initialisedLangs[$code] ) ) {
437  return;
438  }
439 
440  $this->initialisedLangs[$code] = true;
441 
442  # If the code is of the wrong form for a Messages*.php file, do a shallow fallback
443  if ( !Language::isValidBuiltInCode( $code ) ) {
444  $this->initShallowFallback( $code, 'en' );
445 
446  return;
447  }
448 
449  # Recache the data if necessary
450  if ( !$this->manualRecache && $this->isExpired( $code ) ) {
451  if ( Language::isSupportedLanguage( $code ) ) {
452  $this->recache( $code );
453  } elseif ( $code === 'en' ) {
454  throw new MWException( 'MessagesEn.php is missing.' );
455  } else {
456  $this->initShallowFallback( $code, 'en' );
457  }
458 
459  return;
460  }
461 
462  # Preload some stuff
463  $preload = $this->getItem( $code, 'preload' );
464  if ( $preload === null ) {
465  if ( $this->manualRecache ) {
466  // No Messages*.php file. Do shallow fallback to en.
467  if ( $code === 'en' ) {
468  throw new MWException( 'No localisation cache found for English. ' .
469  'Please run maintenance/rebuildLocalisationCache.php.' );
470  }
471  $this->initShallowFallback( $code, 'en' );
472 
473  return;
474  } else {
475  throw new MWException( 'Invalid or missing localisation cache.' );
476  }
477  }
478  $this->data[$code] = $preload;
479  foreach ( $preload as $key => $item ) {
480  if ( in_array( $key, self::$splitKeys ) ) {
481  foreach ( $item as $subkey => $subitem ) {
482  $this->loadedSubitems[$code][$key][$subkey] = true;
483  }
484  } else {
485  $this->loadedItems[$code][$key] = true;
486  }
487  }
488  }
489 
496  public function initShallowFallback( $primaryCode, $fallbackCode ) {
497  $this->data[$primaryCode] =& $this->data[$fallbackCode];
498  $this->loadedItems[$primaryCode] =& $this->loadedItems[$fallbackCode];
499  $this->loadedSubitems[$primaryCode] =& $this->loadedSubitems[$fallbackCode];
500  $this->shallowFallbacks[$primaryCode] = $fallbackCode;
501  }
502 
510  protected function readPHPFile( $_fileName, $_fileType ) {
511  wfProfileIn( __METHOD__ );
512  // Disable APC caching
514  $_apcEnabled = ini_set( 'apc.cache_by_default', '0' );
516 
517  include $_fileName;
518 
520  ini_set( 'apc.cache_by_default', $_apcEnabled );
522 
523  if ( $_fileType == 'core' || $_fileType == 'extension' ) {
524  $data = compact( self::$allKeys );
525  } elseif ( $_fileType == 'aliases' ) {
526  $data = compact( 'aliases' );
527  } else {
528  wfProfileOut( __METHOD__ );
529  throw new MWException( __METHOD__ . ": Invalid file type: $_fileType" );
530  }
531  wfProfileOut( __METHOD__ );
532 
533  return $data;
534  }
535 
542  public function readJSONFile( $fileName ) {
543  wfProfileIn( __METHOD__ );
544 
545  if ( !is_readable( $fileName ) ) {
546  wfProfileOut( __METHOD__ );
547 
548  return array();
549  }
550 
551  $json = file_get_contents( $fileName );
552  if ( $json === false ) {
553  wfProfileOut( __METHOD__ );
554 
555  return array();
556  }
557 
558  $data = FormatJson::decode( $json, true );
559  if ( $data === null ) {
560  wfProfileOut( __METHOD__ );
561 
562  throw new MWException( __METHOD__ . ": Invalid JSON file: $fileName" );
563  }
564 
565  // Remove keys starting with '@', they're reserved for metadata and non-message data
566  foreach ( $data as $key => $unused ) {
567  if ( $key === '' || $key[0] === '@' ) {
568  unset( $data[$key] );
569  }
570  }
571 
572  wfProfileOut( __METHOD__ );
573 
574  // The JSON format only supports messages, none of the other variables, so wrap the data
575  return array( 'messages' => $data );
576  }
577 
582  public function getCompiledPluralRules( $code ) {
583  $rules = $this->getPluralRules( $code );
584  if ( $rules === null ) {
585  return null;
586  }
587  try {
588  $compiledRules = CLDRPluralRuleEvaluator::compile( $rules );
589  } catch ( CLDRPluralRuleError $e ) {
590  wfDebugLog( 'l10n', $e->getMessage() );
591 
592  return array();
593  }
594 
595  return $compiledRules;
596  }
597 
603  public function getPluralRules( $code ) {
604  if ( $this->pluralRules === null ) {
605  $this->loadPluralFiles();
606  }
607  if ( !isset( $this->pluralRules[$code] ) ) {
608  return null;
609  } else {
610  return $this->pluralRules[$code];
611  }
612  }
613 
619  public function getPluralRuleTypes( $code ) {
620  if ( $this->pluralRuleTypes === null ) {
621  $this->loadPluralFiles();
622  }
623  if ( !isset( $this->pluralRuleTypes[$code] ) ) {
624  return null;
625  } else {
626  return $this->pluralRuleTypes[$code];
627  }
628  }
629 
633  protected function loadPluralFiles() {
634  global $IP;
635  $cldrPlural = "$IP/languages/data/plurals.xml";
636  $mwPlural = "$IP/languages/data/plurals-mediawiki.xml";
637  // Load CLDR plural rules
638  $this->loadPluralFile( $cldrPlural );
639  if ( file_exists( $mwPlural ) ) {
640  // Override or extend
641  $this->loadPluralFile( $mwPlural );
642  }
643  }
644 
649  protected function loadPluralFile( $fileName ) {
650  $doc = new DOMDocument;
651  $doc->load( $fileName );
652  $rulesets = $doc->getElementsByTagName( "pluralRules" );
653  foreach ( $rulesets as $ruleset ) {
654  $codes = $ruleset->getAttribute( 'locales' );
655  $rules = array();
656  $ruleTypes = array();
657  $ruleElements = $ruleset->getElementsByTagName( "pluralRule" );
658  foreach ( $ruleElements as $elt ) {
659  $ruleType = $elt->getAttribute( 'count' );
660  if ( $ruleType === 'other' ) {
661  // Don't record "other" rules, which have an empty condition
662  continue;
663  }
664  $rules[] = $elt->nodeValue;
665  $ruleTypes[] = $ruleType;
666  }
667  foreach ( explode( ' ', $codes ) as $code ) {
668  $this->pluralRules[$code] = $rules;
669  $this->pluralRuleTypes[$code] = $ruleTypes;
670  }
671  }
672  }
673 
679  protected function readSourceFilesAndRegisterDeps( $code, &$deps ) {
680  global $IP;
681  wfProfileIn( __METHOD__ );
682 
683 
684  // This reads in the PHP i18n file with non-messages l10n data
685  $fileName = Language::getMessagesFileName( $code );
686  if ( !file_exists( $fileName ) ) {
687  $data = array();
688  } else {
689  $deps[] = new FileDependency( $fileName );
690  $data = $this->readPHPFile( $fileName, 'core' );
691  }
692 
693  # Load CLDR plural rules for JavaScript
694  $data['pluralRules'] = $this->getPluralRules( $code );
695  # And for PHP
696  $data['compiledPluralRules'] = $this->getCompiledPluralRules( $code );
697  # Load plural rule types
698  $data['pluralRuleTypes'] = $this->getPluralRuleTypes( $code );
699 
700  $deps['plurals'] = new FileDependency( "$IP/languages/data/plurals.xml" );
701  $deps['plurals-mw'] = new FileDependency( "$IP/languages/data/plurals-mediawiki.xml" );
702 
703  wfProfileOut( __METHOD__ );
704 
705  return $data;
706  }
707 
715  protected function mergeItem( $key, &$value, $fallbackValue ) {
716  if ( !is_null( $value ) ) {
717  if ( !is_null( $fallbackValue ) ) {
718  if ( in_array( $key, self::$mergeableMapKeys ) ) {
719  $value = $value + $fallbackValue;
720  } elseif ( in_array( $key, self::$mergeableListKeys ) ) {
721  $value = array_unique( array_merge( $fallbackValue, $value ) );
722  } elseif ( in_array( $key, self::$mergeableAliasListKeys ) ) {
723  $value = array_merge_recursive( $value, $fallbackValue );
724  } elseif ( in_array( $key, self::$optionalMergeKeys ) ) {
725  if ( !empty( $value['inherit'] ) ) {
726  $value = array_merge( $fallbackValue, $value );
727  }
728 
729  if ( isset( $value['inherit'] ) ) {
730  unset( $value['inherit'] );
731  }
732  } elseif ( in_array( $key, self::$magicWordKeys ) ) {
733  $this->mergeMagicWords( $value, $fallbackValue );
734  }
735  }
736  } else {
737  $value = $fallbackValue;
738  }
739  }
740 
745  protected function mergeMagicWords( &$value, $fallbackValue ) {
746  foreach ( $fallbackValue as $magicName => $fallbackInfo ) {
747  if ( !isset( $value[$magicName] ) ) {
748  $value[$magicName] = $fallbackInfo;
749  } else {
750  $oldSynonyms = array_slice( $fallbackInfo, 1 );
751  $newSynonyms = array_slice( $value[$magicName], 1 );
752  $synonyms = array_values( array_unique( array_merge(
753  $newSynonyms, $oldSynonyms ) ) );
754  $value[$magicName] = array_merge( array( $fallbackInfo[0] ), $synonyms );
755  }
756  }
757  }
758 
772  protected function mergeExtensionItem( $codeSequence, $key, &$value, $fallbackValue ) {
773  $used = false;
774  foreach ( $codeSequence as $code ) {
775  if ( isset( $fallbackValue[$code] ) ) {
776  $this->mergeItem( $key, $value, $fallbackValue[$code] );
777  $used = true;
778  }
779  }
780 
781  return $used;
782  }
783 
790  public function recache( $code ) {
791  global $wgExtensionMessagesFiles, $wgMessagesDirs;
792  wfProfileIn( __METHOD__ );
793 
794  if ( !$code ) {
795  wfProfileOut( __METHOD__ );
796  throw new MWException( "Invalid language code requested" );
797  }
798  $this->recachedLangs[$code] = true;
799 
800  # Initial values
801  $initialData = array_combine(
802  self::$allKeys,
803  array_fill( 0, count( self::$allKeys ), null ) );
804  $coreData = $initialData;
805  $deps = array();
806 
807  # Load the primary localisation from the source file
808  $data = $this->readSourceFilesAndRegisterDeps( $code, $deps );
809  if ( $data === false ) {
810  wfDebug( __METHOD__ . ": no localisation file for $code, using fallback to en\n" );
811  $coreData['fallback'] = 'en';
812  } else {
813  wfDebug( __METHOD__ . ": got localisation for $code from source\n" );
814 
815  # Merge primary localisation
816  foreach ( $data as $key => $value ) {
817  $this->mergeItem( $key, $coreData[$key], $value );
818  }
819  }
820 
821  # Fill in the fallback if it's not there already
822  if ( is_null( $coreData['fallback'] ) ) {
823  $coreData['fallback'] = $code === 'en' ? false : 'en';
824  }
825  if ( $coreData['fallback'] === false ) {
826  $coreData['fallbackSequence'] = array();
827  } else {
828  $coreData['fallbackSequence'] = array_map( 'trim', explode( ',', $coreData['fallback'] ) );
829  $len = count( $coreData['fallbackSequence'] );
830 
831  # Ensure that the sequence ends at en
832  if ( $coreData['fallbackSequence'][$len - 1] !== 'en' ) {
833  $coreData['fallbackSequence'][] = 'en';
834  }
835 
836  # Load the fallback localisation item by item and merge it
837  foreach ( $coreData['fallbackSequence'] as $fbCode ) {
838  # Load the secondary localisation from the source file to
839  # avoid infinite cycles on cyclic fallbacks
840  $fbData = $this->readSourceFilesAndRegisterDeps( $fbCode, $deps );
841  if ( $fbData === false ) {
842  continue;
843  }
844 
845  foreach ( self::$allKeys as $key ) {
846  if ( !isset( $fbData[$key] ) ) {
847  continue;
848  }
849 
850  if ( is_null( $coreData[$key] ) || $this->isMergeableKey( $key ) ) {
851  $this->mergeItem( $key, $coreData[$key], $fbData[$key] );
852  }
853  }
854  }
855  }
856 
857  $codeSequence = array_merge( array( $code ), $coreData['fallbackSequence'] );
858 
859  # Load core messages and the extension localisations.
860  wfProfileIn( __METHOD__ . '-extensions' );
861  $allData = $initialData;
862  foreach ( $wgMessagesDirs as $dirs ) {
863  foreach ( (array)$dirs as $dir ) {
864  foreach ( $codeSequence as $csCode ) {
865  $fileName = "$dir/$csCode.json";
866  $data = $this->readJSONFile( $fileName );
867 
868  foreach ( $data as $key => $item ) {
869  $this->mergeItem( $key, $allData[$key], $item );
870  }
871 
872  $deps[] = new FileDependency( $fileName );
873  }
874  }
875  }
876 
877  foreach ( $wgExtensionMessagesFiles as $extension => $fileName ) {
878  if ( isset( $wgMessagesDirs[$extension] ) ) {
879  # Already loaded the JSON files for this extension; skip the PHP shim
880  continue;
881  }
882 
883  $data = $this->readPHPFile( $fileName, 'extension' );
884  $used = false;
885 
886  foreach ( $data as $key => $item ) {
887  if ( $this->mergeExtensionItem( $codeSequence, $key, $allData[$key], $item ) ) {
888  $used = true;
889  }
890  }
891 
892  if ( $used ) {
893  $deps[] = new FileDependency( $fileName );
894  }
895  }
896 
897  # Merge core data into extension data
898  foreach ( $coreData as $key => $item ) {
899  $this->mergeItem( $key, $allData[$key], $item );
900  }
901  wfProfileOut( __METHOD__ . '-extensions' );
902 
903  # Add cache dependencies for any referenced globals
904  $deps['wgExtensionMessagesFiles'] = new GlobalDependency( 'wgExtensionMessagesFiles' );
905  $deps['wgMessagesDirs'] = new GlobalDependency( 'wgMessagesDirs' );
906  $deps['version'] = new ConstantDependency( 'MW_LC_VERSION' );
907 
908  # Add dependencies to the cache entry
909  $allData['deps'] = $deps;
910 
911  # Replace spaces with underscores in namespace names
912  $allData['namespaceNames'] = str_replace( ' ', '_', $allData['namespaceNames'] );
913 
914  # And do the same for special page aliases. $page is an array.
915  foreach ( $allData['specialPageAliases'] as &$page ) {
916  $page = str_replace( ' ', '_', $page );
917  }
918  # Decouple the reference to prevent accidental damage
919  unset( $page );
920 
921  # If there were no plural rules, return an empty array
922  if ( $allData['pluralRules'] === null ) {
923  $allData['pluralRules'] = array();
924  }
925  if ( $allData['compiledPluralRules'] === null ) {
926  $allData['compiledPluralRules'] = array();
927  }
928  # If there were no plural rule types, return an empty array
929  if ( $allData['pluralRuleTypes'] === null ) {
930  $allData['pluralRuleTypes'] = array();
931  }
932 
933  # Set the list keys
934  $allData['list'] = array();
935  foreach ( self::$splitKeys as $key ) {
936  $allData['list'][$key] = array_keys( $allData[$key] );
937  }
938  # Run hooks
939  $purgeBlobs = true;
940  wfRunHooks( 'LocalisationCacheRecache', array( $this, $code, &$allData, &$purgeBlobs ) );
941 
942  if ( is_null( $allData['namespaceNames'] ) ) {
943  wfProfileOut( __METHOD__ );
944  throw new MWException( __METHOD__ . ': Localisation data failed sanity check! ' .
945  'Check that your languages/messages/MessagesEn.php file is intact.' );
946  }
947 
948  # Set the preload key
949  $allData['preload'] = $this->buildPreload( $allData );
950 
951  # Save to the process cache and register the items loaded
952  $this->data[$code] = $allData;
953  foreach ( $allData as $key => $item ) {
954  $this->loadedItems[$code][$key] = true;
955  }
956 
957  # Save to the persistent cache
958  wfProfileIn( __METHOD__ . '-write' );
959  $this->store->startWrite( $code );
960  foreach ( $allData as $key => $value ) {
961  if ( in_array( $key, self::$splitKeys ) ) {
962  foreach ( $value as $subkey => $subvalue ) {
963  $this->store->set( "$key:$subkey", $subvalue );
964  }
965  } else {
966  $this->store->set( $key, $value );
967  }
968  }
969  $this->store->finishWrite();
970  wfProfileOut( __METHOD__ . '-write' );
971 
972  # Clear out the MessageBlobStore
973  # HACK: If using a null (i.e. disabled) storage backend, we
974  # can't write to the MessageBlobStore either
975  if ( $purgeBlobs && !$this->store instanceof LCStoreNull ) {
977  }
978 
979  wfProfileOut( __METHOD__ );
980  }
981 
990  protected function buildPreload( $data ) {
991  $preload = array( 'messages' => array() );
992  foreach ( self::$preloadedKeys as $key ) {
993  $preload[$key] = $data[$key];
994  }
995 
996  foreach ( $data['preloadedMessages'] as $subkey ) {
997  if ( isset( $data['messages'][$subkey] ) ) {
998  $subitem = $data['messages'][$subkey];
999  } else {
1000  $subitem = null;
1001  }
1002  $preload['messages'][$subkey] = $subitem;
1003  }
1004 
1005  return $preload;
1006  }
1007 
1013  public function unload( $code ) {
1014  unset( $this->data[$code] );
1015  unset( $this->loadedItems[$code] );
1016  unset( $this->loadedSubitems[$code] );
1017  unset( $this->initialisedLangs[$code] );
1018  unset( $this->shallowFallbacks[$code] );
1019 
1020  foreach ( $this->shallowFallbacks as $shallowCode => $fbCode ) {
1021  if ( $fbCode === $code ) {
1022  $this->unload( $shallowCode );
1023  }
1024  }
1025  }
1026 
1030  public function unloadAll() {
1031  foreach ( $this->initialisedLangs as $lang => $unused ) {
1032  $this->unload( $lang );
1033  }
1034  }
1035 
1039  public function disableBackend() {
1040  $this->store = new LCStoreNull;
1041  $this->manualRecache = false;
1042  }
1043 }
1044 
1062 interface LCStore {
1068  function get( $code, $key );
1069 
1074  function startWrite( $code );
1075 
1079  function finishWrite();
1080 
1087  function set( $key, $value );
1088 }
1089 
1095 class LCStoreAccel implements LCStore {
1096  private $currentLang;
1097  private $keys;
1099  public function __construct() {
1100  $this->cache = wfGetCache( CACHE_ACCEL );
1101  }
1103  public function get( $code, $key ) {
1104  $k = wfMemcKey( 'l10n', $code, 'k', $key );
1105  $r = $this->cache->get( $k );
1106 
1107  return $r === false ? null : $r;
1108  }
1110  public function startWrite( $code ) {
1111  $k = wfMemcKey( 'l10n', $code, 'l' );
1112  $keys = $this->cache->get( $k );
1113  if ( $keys ) {
1114  foreach ( $keys as $k ) {
1115  $this->cache->delete( $k );
1116  }
1117  }
1118  $this->currentLang = $code;
1119  $this->keys = array();
1120  }
1122  public function finishWrite() {
1123  if ( $this->currentLang ) {
1124  $k = wfMemcKey( 'l10n', $this->currentLang, 'l' );
1125  $this->cache->set( $k, array_keys( $this->keys ) );
1126  }
1127  $this->currentLang = null;
1128  $this->keys = array();
1129  }
1131  public function set( $key, $value ) {
1132  if ( $this->currentLang ) {
1133  $k = wfMemcKey( 'l10n', $this->currentLang, 'k', $key );
1134  $this->keys[$k] = true;
1135  $this->cache->set( $k, $value );
1136  }
1137  }
1138 }
1139 
1144 class LCStoreDB implements LCStore {
1145  private $currentLang;
1146  private $writesDone = false;
1147 
1151  private $dbw;
1152  private $batch;
1153  private $readOnly = false;
1154 
1155  public function get( $code, $key ) {
1156  if ( $this->writesDone ) {
1157  $db = wfGetDB( DB_MASTER );
1158  } else {
1159  $db = wfGetDB( DB_SLAVE );
1160  }
1161  $row = $db->selectRow( 'l10n_cache', array( 'lc_value' ),
1162  array( 'lc_lang' => $code, 'lc_key' => $key ), __METHOD__ );
1163  if ( $row ) {
1164  return unserialize( $db->decodeBlob( $row->lc_value ) );
1165  } else {
1166  return null;
1167  }
1168  }
1169 
1170  public function startWrite( $code ) {
1171  if ( $this->readOnly ) {
1172  return;
1173  }
1174 
1175  if ( !$code ) {
1176  throw new MWException( __METHOD__ . ": Invalid language \"$code\"" );
1177  }
1178 
1179  $this->dbw = wfGetDB( DB_MASTER );
1180  try {
1181  $this->dbw->begin( __METHOD__ );
1182  $this->dbw->delete( 'l10n_cache', array( 'lc_lang' => $code ), __METHOD__ );
1183  } catch ( DBQueryError $e ) {
1184  if ( $this->dbw->wasReadOnlyError() ) {
1185  $this->readOnly = true;
1186  $this->dbw->rollback( __METHOD__ );
1187 
1188  return;
1189  } else {
1190  throw $e;
1191  }
1192  }
1193 
1194  $this->currentLang = $code;
1195  $this->batch = array();
1196  }
1197 
1198  public function finishWrite() {
1199  if ( $this->readOnly ) {
1200  return;
1201  }
1202 
1203  if ( $this->batch ) {
1204  $this->dbw->insert( 'l10n_cache', $this->batch, __METHOD__ );
1205  }
1206 
1207  $this->dbw->commit( __METHOD__ );
1208  $this->currentLang = null;
1209  $this->dbw = null;
1210  $this->batch = array();
1211  $this->writesDone = true;
1212  }
1213 
1214  public function set( $key, $value ) {
1215  if ( $this->readOnly ) {
1216  return;
1217  }
1218 
1219  if ( is_null( $this->currentLang ) ) {
1220  throw new MWException( __CLASS__ . ': must call startWrite() before calling set()' );
1221  }
1222 
1223  $this->batch[] = array(
1224  'lc_lang' => $this->currentLang,
1225  'lc_key' => $key,
1226  'lc_value' => $this->dbw->encodeBlob( serialize( $value ) ) );
1227 
1228  if ( count( $this->batch ) >= 100 ) {
1229  $this->dbw->insert( 'l10n_cache', $this->batch, __METHOD__ );
1230  $this->batch = array();
1231  }
1232  }
1233 }
1234 
1247 class LCStoreCDB implements LCStore {
1249  private $readers;
1252  private $writer;
1253 
1255  private $currentLang;
1256 
1258  private $directory;
1259 
1260  function __construct( $conf = array() ) {
1261  global $wgCacheDirectory;
1262 
1263  if ( isset( $conf['directory'] ) ) {
1264  $this->directory = $conf['directory'];
1265  } else {
1266  $this->directory = $wgCacheDirectory;
1267  }
1268  }
1269 
1270  public function get( $code, $key ) {
1271  if ( !isset( $this->readers[$code] ) ) {
1272  $fileName = $this->getFileName( $code );
1273 
1274  $this->readers[$code] = false;
1275  if ( file_exists( $fileName ) ) {
1276  try {
1277  $this->readers[$code] = CdbReader::open( $fileName );
1278  } catch ( CdbException $e ) {
1279  wfDebug( __METHOD__ . ": unable to open cdb file for reading\n" );
1280  }
1281  }
1282  }
1283 
1284  if ( !$this->readers[$code] ) {
1285  return null;
1286  } else {
1287  $value = false;
1288  try {
1289  $value = $this->readers[$code]->get( $key );
1290  } catch ( CdbException $e ) {
1291  wfDebug( __METHOD__ . ": CdbException caught, error message was "
1292  . $e->getMessage() . "\n" );
1293  }
1294  if ( $value === false ) {
1295  return null;
1296  }
1297 
1298  return unserialize( $value );
1299  }
1300  }
1301 
1302  public function startWrite( $code ) {
1303  if ( !file_exists( $this->directory ) ) {
1304  if ( !wfMkdirParents( $this->directory, null, __METHOD__ ) ) {
1305  throw new MWException( "Unable to create the localisation store " .
1306  "directory \"{$this->directory}\"" );
1307  }
1308  }
1309 
1310  // Close reader to stop permission errors on write
1311  if ( !empty( $this->readers[$code] ) ) {
1312  $this->readers[$code]->close();
1313  }
1314 
1315  try {
1316  $this->writer = CdbWriter::open( $this->getFileName( $code ) );
1317  } catch ( CdbException $e ) {
1318  throw new MWException( $e->getMessage() );
1319  }
1320  $this->currentLang = $code;
1321  }
1322 
1323  public function finishWrite() {
1324  // Close the writer
1325  try {
1326  $this->writer->close();
1327  } catch ( CdbException $e ) {
1328  throw new MWException( $e->getMessage() );
1329  }
1330  $this->writer = null;
1331  unset( $this->readers[$this->currentLang] );
1332  $this->currentLang = null;
1333  }
1334 
1335  public function set( $key, $value ) {
1336  if ( is_null( $this->writer ) ) {
1337  throw new MWException( __CLASS__ . ': must call startWrite() before calling set()' );
1338  }
1339  try {
1340  $this->writer->set( $key, serialize( $value ) );
1341  } catch ( CdbException $e ) {
1342  throw new MWException( $e->getMessage() );
1343  }
1344  }
1345 
1346  protected function getFileName( $code ) {
1347  if ( strval( $code ) === '' || strpos( $code, '/' ) !== false ) {
1348  throw new MWException( __METHOD__ . ": Invalid language \"$code\"" );
1349  }
1350 
1351  return "{$this->directory}/l10n_cache-$code.cdb";
1352  }
1354 
1358 class LCStoreNull implements LCStore {
1359  public function get( $code, $key ) {
1360  return null;
1361  }
1362 
1363  public function startWrite( $code ) {
1364  }
1365 
1366  public function finishWrite() {
1367  }
1368 
1369  public function set( $key, $value ) {
1370  }
1372 
1382  private $fileCache = array();
1389  private $mruLangs = array();
1390 
1394  private $maxLoadedLangs = 10;
1401  protected function readPHPFile( $fileName, $fileType ) {
1402  $serialize = $fileType === 'core';
1403  if ( !isset( $this->fileCache[$fileName][$fileType] ) ) {
1404  $data = parent::readPHPFile( $fileName, $fileType );
1405 
1406  if ( $serialize ) {
1407  $encData = serialize( $data );
1408  } else {
1409  $encData = $data;
1410  }
1411 
1412  $this->fileCache[$fileName][$fileType] = $encData;
1413 
1414  return $data;
1415  } elseif ( $serialize ) {
1416  return unserialize( $this->fileCache[$fileName][$fileType] );
1417  } else {
1418  return $this->fileCache[$fileName][$fileType];
1419  }
1420  }
1427  public function getItem( $code, $key ) {
1428  unset( $this->mruLangs[$code] );
1429  $this->mruLangs[$code] = true;
1430 
1431  return parent::getItem( $code, $key );
1432  }
1433 
1440  public function getSubitem( $code, $key, $subkey ) {
1441  unset( $this->mruLangs[$code] );
1442  $this->mruLangs[$code] = true;
1443 
1444  return parent::getSubitem( $code, $key, $subkey );
1445  }
1446 
1450  public function recache( $code ) {
1451  parent::recache( $code );
1452  unset( $this->mruLangs[$code] );
1453  $this->mruLangs[$code] = true;
1454  $this->trimCache();
1455  }
1456 
1460  public function unload( $code ) {
1461  unset( $this->mruLangs[$code] );
1462  parent::unload( $code );
1463  }
1464 
1468  protected function trimCache() {
1469  while ( count( $this->data ) > $this->maxLoadedLangs && count( $this->mruLangs ) ) {
1470  reset( $this->mruLangs );
1471  $code = key( $this->mruLangs );
1472  wfDebug( __METHOD__ . ": unloading $code\n" );
1473  $this->unload( $code );
1474  }
1475  }
1476 }
FileDependency
Definition: CacheDependency.php:151
LocalisationCacheBulkLoad\unload
unload( $code)
Definition: LocalisationCache.php:1454
LocalisationCache\loadSubitem
loadSubitem( $code, $key, $subkey)
Load a subitem into the cache.
Definition: LocalisationCache.php:360
LCStoreAccel\__construct
__construct()
Definition: LocalisationCache.php:1098
LocalisationCache\$initialisedLangs
$initialisedLangs
An array where presence of a key indicates that that language has been initialised.
Definition: LocalisationCache.php:87
LocalisationCache\$manualRecache
$manualRecache
True if recaching should only be done on an explicit call to recache().
Definition: LocalisationCache.php:46
LocalisationCache\initLanguage
initLanguage( $code)
Initialise a language in this object.
Definition: LocalisationCache.php:434
LCStoreCDB
LCStore implementation which stores data as a collection of CDB files in the directory given by $wgCa...
Definition: LocalisationCache.php:1245
DB_MASTER
const DB_MASTER
Definition: Defines.php:56
LocalisationCache\$conf
$conf
Configuration associative array.
Definition: LocalisationCache.php:39
data
and how to run hooks for an and one after Each event has a preferably in CamelCase For ArticleDelete hook A clump of code and data that should be run when an event happens This can be either a function and a chunk of data
Definition: hooks.txt:6
directory
The most up to date schema for the tables in the database will always be tables sql in the maintenance directory
Definition: schema.txt:2
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
LocalisationCache\__construct
__construct( $conf)
Constructor.
Definition: LocalisationCache.php:186
wfMkdirParents
wfMkdirParents( $dir, $mode=null, $caller=null)
Make directory, and make all parent directories if they don't exist.
Definition: GlobalFunctions.php:2637
LCStoreDB\$batch
$batch
Definition: LocalisationCache.php:1150
wfGetDB
& wfGetDB( $db, $groups=array(), $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:3714
LocalisationCache\isExpired
isExpired( $code)
Returns true if the cache identified by $code is missing or expired.
Definition: LocalisationCache.php:396
LocalisationCache\getSubitemList
getSubitemList( $code, $key)
Get the list of subitem keys for a given item.
Definition: LocalisationCache.php:305
wfDebugLog
wfDebugLog( $logGroup, $text, $dest='all')
Send a line to a supplementary debug log file, if configured, or main debug log if not.
Definition: GlobalFunctions.php:1087
wfProfileIn
wfProfileIn( $functionname)
Begin profiling of a function.
Definition: Profiler.php:33
LCStoreAccel\startWrite
startWrite( $code)
Start a write transaction.
Definition: LocalisationCache.php:1109
wfSuppressWarnings
wfSuppressWarnings( $end=false)
Reference-counted warning suppression.
Definition: GlobalFunctions.php:2434
CACHE_ACCEL
const CACHE_ACCEL
Definition: Defines.php:115
LocalisationCache\$recachedLangs
$recachedLangs
An array where the keys are codes that have been recached by this instance.
Definition: LocalisationCache.php:99
wfGetCache
wfGetCache( $inputType)
Get a cache object.
Definition: GlobalFunctions.php:4013
LocalisationCacheBulkLoad\getItem
getItem( $code, $key)
Definition: LocalisationCache.php:1421
LCStoreCDB\getFileName
getFileName( $code)
Definition: LocalisationCache.php:1340
LCStoreAccel
LCStore implementation which uses PHP accelerator to store data.
Definition: LocalisationCache.php:1094
ConstantDependency
Definition: CacheDependency.php:249
LCStoreDB\$writesDone
$writesDone
Definition: LocalisationCache.php:1145
LCStore
Interface for the persistence layer of LocalisationCache.
Definition: LocalisationCache.php:1061
Language\getMessagesFileName
static getMessagesFileName( $code)
Definition: Language.php:4090
LocalisationCache\$mergeableAliasListKeys
static $mergeableAliasListKeys
Keys for items which contain an array of arrays of equivalent aliases for each subitem.
Definition: LocalisationCache.php:132
cache
you have access to all of the normal MediaWiki so you can get a DB use the cache
Definition: maintenance.txt:52
LocalisationCache\readSourceFilesAndRegisterDeps
readSourceFilesAndRegisterDeps( $code, &$deps)
Read the data from the source files for a given language, and register the relevant dependencies in t...
Definition: LocalisationCache.php:678
LocalisationCache\getItem
getItem( $code, $key)
Get a cache item.
Definition: LocalisationCache.php:256
LocalisationCacheBulkLoad\$fileCache
$fileCache
A cache of the contents of data files.
Definition: LocalisationCache.php:1376
LCStoreCDB\$directory
bool string $directory
Cache directory.
Definition: LocalisationCache.php:1252
LCStore\startWrite
startWrite( $code)
Start a write transaction.
LCStoreCDB\finishWrite
finishWrite()
Finish a write transaction.
Definition: LocalisationCache.php:1317
LocalisationCacheBulkLoad\$maxLoadedLangs
$maxLoadedLangs
Maximum number of languages that may be loaded into $this->data.
Definition: LocalisationCache.php:1388
GlobalDependency
Definition: CacheDependency.php:225
LocalisationCache\recache
recache( $code)
Load localisation data for a given language for both core and extensions and save it to the persisten...
Definition: LocalisationCache.php:789
LocalisationCacheBulkLoad
A localisation cache optimised for loading large amounts of data for many languages.
Definition: LocalisationCache.php:1371
LocalisationCacheBulkLoad\getSubitem
getSubitem( $code, $key, $subkey)
Definition: LocalisationCache.php:1434
LocalisationCache\readJSONFile
readJSONFile( $fileName)
Read a JSON file containing localisation messages.
Definition: LocalisationCache.php:541
LocalisationCacheBulkLoad\readPHPFile
readPHPFile( $fileName, $fileType)
Definition: LocalisationCache.php:1395
LocalisationCache\$pluralRules
$pluralRules
Associative array of cached plural rules.
Definition: LocalisationCache.php:160
LocalisationCache\mergeExtensionItem
mergeExtensionItem( $codeSequence, $key, &$value, $fallbackValue)
Given an array mapping language code to localisation value, such as is found in extension *....
Definition: LocalisationCache.php:771
key
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add in any and then calling but I prefer the flexibility This should also do the output encoding The system allocates a global one in $wgOut Title Represents the title of an and does all the work of translating among various forms such as plain database key
Definition: design.txt:25
LCStoreCDB\$readers
CdbReader[] $readers
Definition: LocalisationCache.php:1246
LCStoreCDB\$writer
CdbWriter $writer
Definition: LocalisationCache.php:1248
LocalisationCache\$preloadedKeys
static $preloadedKeys
Keys which are loaded automatically by initLanguage()
Definition: LocalisationCache.php:154
LocalisationCache\getPluralRules
getPluralRules( $code)
Get the plural rules for a given language from the XML files.
Definition: LocalisationCache.php:602
LocalisationCacheBulkLoad\recache
recache( $code)
Definition: LocalisationCache.php:1444
FormatJson\decode
static decode( $value, $assoc=false)
Decodes a JSON string.
Definition: FormatJson.php:126
LCStoreAccel\finishWrite
finishWrite()
Finish a write transaction.
Definition: LocalisationCache.php:1121
MWException
MediaWiki exception.
Definition: MWException.php:26
wfMemcKey
wfMemcKey()
Get a cache key.
Definition: GlobalFunctions.php:3635
DBQueryError
Definition: DatabaseError.php:306
LocalisationCache\unload
unload( $code)
Unload the data for a given language from the object cache.
Definition: LocalisationCache.php:1012
wfRestoreWarnings
wfRestoreWarnings()
Restore error level to previous value.
Definition: GlobalFunctions.php:2464
LocalisationCache\mergeMagicWords
mergeMagicWords(&$value, $fallbackValue)
Definition: LocalisationCache.php:744
batch
linkcache txt The LinkCache class maintains a list of article titles and the information about whether or not the article exists in the database This is used to mark up links when displaying a page If the same link appears more than once on any page then it only has to be looked up once In most cases link lookups are done in batches with the LinkBatch class or the equivalent in so the link cache is mostly useful for short snippets of parsed and for links in the navigation areas of the skin The link cache was formerly used to track links used in a document for the purposes of updating the link tables This application is now deprecated To create a batch
Definition: linkcache.txt:14
LCStoreCDB\__construct
__construct( $conf=array())
Definition: LocalisationCache.php:1254
CLDRPluralRuleError
The exception class for all the classes in this file.
Definition: CLDRPluralRuleError.php:17
LCStoreDB\$readOnly
$readOnly
Definition: LocalisationCache.php:1151
wfProfileOut
wfProfileOut( $functionname='missing')
Stop profiling of a function.
Definition: Profiler.php:46
LCStore\finishWrite
finishWrite()
Finish a write transaction.
wfRunHooks
wfRunHooks( $event, array $args=array(), $deprecatedVersion=null)
Call hook functions defined in $wgHooks.
Definition: GlobalFunctions.php:4066
LocalisationCache\disableBackend
disableBackend()
Disable the storage backend.
Definition: LocalisationCache.php:1038
LCStoreCDB\startWrite
startWrite( $code)
Start a write transaction.
Definition: LocalisationCache.php:1296
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
LocalisationCache\getCompiledPluralRules
getCompiledPluralRules( $code)
Get the compiled plural rules for a given language from the XML files.
Definition: LocalisationCache.php:581
LCStoreAccel\$keys
$keys
Definition: LocalisationCache.php:1096
$dirs
$dirs
Definition: mergeMessageFileList.php:163
LocalisationCache\$optionalMergeKeys
static $optionalMergeKeys
Keys for items which contain an associative array, and may be merged if the primary value contains th...
Definition: LocalisationCache.php:139
LocalisationCache\$loadedItems
$loadedItems
A 2-d associative array, code/key, where presence indicates that the item is loaded.
Definition: LocalisationCache.php:74
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
CdbWriter\open
static open( $fileName)
Open a writer and return a subclass instance.
Definition: Cdb.php:112
LocalisationCache\readPHPFile
readPHPFile( $_fileName, $_fileType)
Read a PHP file containing localisation data.
Definition: LocalisationCache.php:509
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:188
wfDebug
wfDebug( $text, $dest='all')
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:980
Language\isValidBuiltInCode
static isValidBuiltInCode( $code)
Returns true if a language code is of a valid form for the purposes of internal customisation of Medi...
Definition: Language.php:363
LCStoreDB
LCStore implementation which uses the standard DB functions to store data.
Definition: LocalisationCache.php:1143
LocalisationCache\$mergeableMapKeys
static $mergeableMapKeys
Keys for items which consist of associative arrays, which may be merged by a fallback sequence.
Definition: LocalisationCache.php:119
LCStoreNull\startWrite
startWrite( $code)
Start a write transaction.
Definition: LocalisationCache.php:1357
LocalisationCache\buildPreload
buildPreload( $data)
Build the preload item from the given pre-cache data.
Definition: LocalisationCache.php:989
writer
An extension writer
Definition: hooks.txt:51
LocalisationCacheBulkLoad\trimCache
trimCache()
Unload cached languages until there are less than $this->maxLoadedLangs.
Definition: LocalisationCache.php:1462
LocalisationCache\$mergeableKeys
$mergeableKeys
Definition: LocalisationCache.php:176
$value
$value
Definition: styleTest.css.php:45
DatabaseBase
Database abstraction object.
Definition: Database.php:219
LCStoreDB\startWrite
startWrite( $code)
Start a write transaction.
Definition: LocalisationCache.php:1168
CLDRPluralRuleEvaluator\compile
static compile(array $rules)
Convert a set of rules to a compiled form which is optimised for fast evaluation.
Definition: CLDRPluralRuleEvaluator.php:55
LocalisationCache\loadPluralFile
loadPluralFile( $fileName)
Load a plural XML file with the given filename, compile the relevant rules, and save the compiled rul...
Definition: LocalisationCache.php:648
LocalisationCache
Class for caching the contents of localisation files, Messages*.php and *.i18n.php.
Definition: LocalisationCache.php:37
LCStoreNull
Null store backend, used to avoid DB errors during install.
Definition: LocalisationCache.php:1352
LocalisationCache\$forceRecache
$forceRecache
True to treat all files as expired until they are regenerated by this object.
Definition: LocalisationCache.php:51
LocalisationCache\loadItem
loadItem( $code, $key)
Load an item into the cache.
Definition: LocalisationCache.php:323
CacheDependency
Definition: CacheDependency.php:135
LocalisationCache\$pluralRuleTypes
$pluralRuleTypes
Associative array of cached plural rule types.
Definition: LocalisationCache.php:174
LCStoreCDB\$currentLang
string $currentLang
Current language code *.
Definition: LocalisationCache.php:1250
LCStoreDB\$currentLang
$currentLang
Definition: LocalisationCache.php:1144
CdbReader
Read from a CDB file.
Definition: Cdb.php:28
DB_SLAVE
const DB_SLAVE
Definition: Defines.php:55
CdbReader\open
static open( $fileName)
Open a file and return a subclass instance.
Definition: Cdb.php:41
CdbException
Exception for Cdb errors.
Definition: Cdb.php:159
$dir
if(count( $args)==0) $dir
Definition: importImages.php:49
LCStoreDB\finishWrite
finishWrite()
Finish a write transaction.
Definition: LocalisationCache.php:1196
LocalisationCacheBulkLoad\$mruLangs
$mruLangs
Most recently used languages.
Definition: LocalisationCache.php:1383
LocalisationCache\initShallowFallback
initShallowFallback( $primaryCode, $fallbackCode)
Create a fallback from one language to another, without creating a complete persistent cache.
Definition: LocalisationCache.php:495
$wgExtensionMessagesFiles
$wgExtensionMessagesFiles['ExtensionNameMagic']
Definition: magicword.txt:43
CacheDependency\isExpired
isExpired()
Returns true if the dependency is expired, false otherwise.
CdbWriter
Write to a CDB file.
Definition: Cdb.php:88
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
LocalisationCache\isMergeableKey
isMergeableKey( $key)
Returns true if the given key is mergeable, that is, if it is an associative array which can be merge...
Definition: LocalisationCache.php:233
LocalisationCache\mergeItem
mergeItem( $key, &$value, $fallbackValue)
Merge two localisation values, a primary and a fallback, overwriting the primary value in place.
Definition: LocalisationCache.php:714
$keys
$keys
Definition: testCompression.php:63
LocalisationCache\unloadAll
unloadAll()
Unload all data.
Definition: LocalisationCache.php:1029
LocalisationCache\getPluralRuleTypes
getPluralRuleTypes( $code)
Get the plural rule types for a given language from the XML files.
Definition: LocalisationCache.php:618
LocalisationCache\$data
$data
The cache data.
Definition: LocalisationCache.php:59
Language\isSupportedLanguage
static isSupportedLanguage( $code)
Checks whether any localisation is available for that language tag in MediaWiki (MessagesXx....
Definition: Language.php:261
LCStoreDB\$dbw
DatabaseBase $dbw
Definition: LocalisationCache.php:1149
LocalisationCache\$splitKeys
static $splitKeys
Keys for items where the subitems are stored in the backend separately.
Definition: LocalisationCache.php:149
LocalisationCache\$mergeableListKeys
static $mergeableListKeys
Keys for items which are a numbered array.
Definition: LocalisationCache.php:126
LocalisationCache\getSubitem
getSubitem( $code, $key, $subkey)
Get a subitem, for instance a single message for a given language.
Definition: LocalisationCache.php:277
$IP
$IP
Definition: WebStart.php:92
LocalisationCache\$shallowFallbacks
$shallowFallbacks
An array mapping non-existent pseudo-languages to fallback languages.
Definition: LocalisationCache.php:94
LocalisationCache\$loadedSubitems
$loadedSubitems
A 3-d associative array, code/key/subkey, where presence indicates that the subitem is loaded.
Definition: LocalisationCache.php:80
LocalisationCache\loadPluralFiles
loadPluralFiles()
Load the plural XML files.
Definition: LocalisationCache.php:632
LCStoreNull\finishWrite
finishWrite()
Finish a write transaction.
Definition: LocalisationCache.php:1360
MessageBlobStore\clear
static clear()
Definition: MessageBlobStore.php:243
LCStoreAccel\$currentLang
$currentLang
Definition: LocalisationCache.php:1095
LocalisationCache\$allKeys
static $allKeys
All item keys.
Definition: LocalisationCache.php:104
LocalisationCache\$magicWordKeys
static $magicWordKeys
Keys for items that are formatted like $magicWords.
Definition: LocalisationCache.php:144
$e
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:1632
LocalisationCache\$store
LCStore $store
The persistent store object.
Definition: LocalisationCache.php:65