dataReader = $dataReader; $this->cacheReader = $cacheReader; $this->missingKey = $missingKey; } public function initialize(bool $useCache) : bool { $loaded = $useCache && $this->fromReader($this->cacheReader) ?: $this->fromReader($this->dataReader); if ( ! $useCache ) { $this->cacheReader->save($this->locale, $this->data); } return $loaded; } public function fromKey(string $key, array $variables) : ?string { if ( null === ( $string = $this->get($key) ) ) { $string = $this->missingKey ? $this->missingKey->get($key) : null; } if (is_array($string)) { $string = json_encode($string); } return $string && $variables ? $this->placeVariables($string, $variables) : $string; } public function get(string $key) { # Testing full locale key first if ( null === ( $string = Iterate::arrayGet($this->data, "{$this->locale}.$key", static::DELIMITER)) ) { # Fallback on language only $string = Iterate::arrayGet($this->data, "{$this->language}.$key", static::DELIMITER); } return $string; } public function set(string $key, $value) { $cache = explode(static::DELIMITER, $key); while ( ! empty($cache) ) { $imp = implode(static::DELIMITER, $cache); array_pop($cache); unset( $this->cache[$imp] ); } $this->cache[$key] = $value; return Iterate::arraySet($this->data, $key, $value, static::DELIMITER); } public function locale(?string $set = null) { $locale = $set === null ? ( $this->locale ?? null ) : $this->locale = strtolower(explode(".", $this->locale)[0]); if ( $set !== null ) { $this->language = explode('_', $locale)[0]; } return $locale; } protected function mergeData($data) : void { $this->data = array_replace_recursive($this->data, Iterate::splitKeys($data)); } protected function fromReader(Reader\ReaderInterface $reader) : bool { foreach($reader->pathList as $path) { foreach(Iterate::files($path) as $item) { if ( $reader->accept($item->getExtension() )) { if ( null !== ( $data = $reader->load( $item ) )) { if ( $reader->filenameAsKey ) { # Adding folder to full key $filekey = ltrim(substr($item->getPathname(), strlen($path)), DIRECTORY_SEPARATOR); # Removing extension $filekey = substr($filekey, 0, strrpos($filekey, '.')); # Replacing directory separator with dots $filekey = str_replace(DIRECTORY_SEPARATOR, '.', $filekey); $this->mergeData([ '{' . $filekey . '}' => $data ]); } else { $this->mergeData($data); } } } } } return false; } protected function placeVariables(string $string, array $parameters) { if ( preg_match_all('~{$(.*?)}~si', $string, $matches, PREG_SET_ORDER) ) { $search = []; foreach($matches as $item) { $search[ $item[0] ] = Iterate::arrayGet($parameters, $item[1]); } return str_replace(array_keys($search), array_values($search), $string); } return $string; } }