MediaWiki master
LCStoreStaticArray.php
Go to the documentation of this file.
1<?php
22
29class LCStoreStaticArray implements LCStore {
31 private $currentLang = null;
32
34 private $data = [];
35
37 private $fname = null;
38
40 private $directory;
41
42 public function __construct( $conf = [] ) {
43 $this->directory = $conf['directory'];
44 }
45
46 public function startWrite( $code ) {
47 if ( !is_dir( $this->directory ) && !wfMkdirParents( $this->directory, null, __METHOD__ ) ) {
48 throw new RuntimeException( "Unable to create the localisation store " .
49 "directory \"{$this->directory}\"" );
50 }
51
52 $this->currentLang = $code;
53 $this->fname = $this->directory . '/' . $code . '.l10n.php';
54 $this->data[$code] = [];
55 if ( is_file( $this->fname ) ) {
56 $this->data[$code] = require $this->fname;
57 }
58 }
59
60 public function set( $key, $value ) {
61 $this->data[$this->currentLang][$key] = self::encode( $value );
62 }
63
70 private static function isValueArray( array $arr ) {
71 foreach ( $arr as $value ) {
72 if ( is_scalar( $value )
73 || $value === null
74 || ( is_array( $value ) && self::isValueArray( $value ) )
75 ) {
76 continue;
77 }
78 return false;
79 }
80 return true;
81 }
82
90 public static function encode( $value ) {
91 if ( is_array( $value ) && self::isValueArray( $value ) ) {
92 // Type: scalar [v]alue.
93 // Optimization: Write large arrays as one value to avoid recursive decoding cost.
94 return [ 'v', $value ];
95 }
96 if ( is_array( $value ) || is_object( $value ) ) {
97 // Type: [s]serialized.
98 // Optimization: Avoid recursive decoding cost. Write arrays with an objects
99 // as one serialised value.
100 return [ 's', serialize( $value ) ];
101 }
102 if ( is_scalar( $value ) || $value === null ) {
103 // Optimization: Reduce file size by not wrapping scalar values.
104 return $value;
105 }
106
107 throw new RuntimeException( 'Cannot encode ' . var_export( $value, true ) );
108 }
109
117 public static function decode( $encoded ) {
118 if ( !is_array( $encoded ) ) {
119 // Unwrapped scalar value
120 return $encoded;
121 }
122
123 [ $type, $data ] = $encoded;
124
125 switch ( $type ) {
126 case 'v':
127 // Value array (1.35+) or unwrapped scalar value (1.32 and earlier)
128 return $data;
129 case 's':
130 return unserialize( $data );
131 case 'a':
132 // Support: MediaWiki 1.34 and earlier (older file format)
133 return array_map( [ __CLASS__, 'decode' ], $data );
134 default:
135 throw new RuntimeException(
136 'Unable to decode ' . var_export( $encoded, true ) );
137 }
138 }
139
140 public function finishWrite() {
141 $writer = new StaticArrayWriter();
142 $out = $writer->create(
143 $this->data[$this->currentLang],
144 'Generated by LCStoreStaticArray.php -- do not edit!'
145 );
146 // Don't just write to the file, since concurrent requests may see a partial file (T304515).
147 // Write to a file in the same filesystem so that it can be atomically moved.
148 $tmpFileName = "{$this->fname}.tmp." . getmypid() . '.' . mt_rand();
149 file_put_contents( $tmpFileName, $out );
150 rename( $tmpFileName, $this->fname );
151 // Release the data to manage the memory in rebuildLocalisationCache
152 unset( $this->data[$this->currentLang] );
153 $this->currentLang = null;
154 $this->fname = null;
155 }
156
157 public function get( $code, $key ) {
158 if ( !array_key_exists( $code, $this->data ) ) {
159 $fname = $this->directory . '/' . $code . '.l10n.php';
160 if ( !is_file( $fname ) ) {
161 return null;
162 }
163 $this->data[$code] = require $fname;
164 }
165 $data = $this->data[$code];
166 if ( array_key_exists( $key, $data ) ) {
167 return self::decode( $data[$key] );
168 }
169 return null;
170 }
171}
wfMkdirParents( $dir, $mode=null, $caller=null)
Make directory, and make all parent directories if they don't exist.
Localisation cache storage based on PHP files and static arrays.
finishWrite()
Finish a cache write transaction.
static encode( $value)
Encodes a value into an array format.
static decode( $encoded)
Decode something that was encoded with 'encode'.
startWrite( $code)
Start a cache write transaction.
Format a static PHP array to be written to a file.
Interface for the persistence layer of LocalisationCache.
Definition LCStore.php:40