FileLoader::getResolverName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 2
c 2
b 0
f 0
dl 0
loc 3
rs 10
ccs 2
cts 2
cp 1
cc 1
nc 1
nop 0
crap 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Nexendrie\Translation\Loaders;
5
6
use Nette\Utils\Finder;
7
use Nette\Utils\Strings;
8
use Nexendrie\Translation\ILocaleResolver;
9
use Nexendrie\Translation\Resolvers\ManualLocaleResolver;
10
use Nexendrie\Translation\ISettableLocaleResolver;
11
use Nexendrie\Translation\InvalidFolderException;
12
use Nexendrie\Translation\FolderNotSetException;
13
use Nette\Utils\Arrays;
14
use Nexendrie\Translation\IFileLoader;
15
16
/**
17
 * Generic file translations loader
18
 * Loads texts from {$this->extension} files
19
 * You need to define method parseFile() which processes individual file
20
 *
21
 * @author Jakub Konečný
22
 * @property string $lang
23
 * @property-read array $texts
24
 * @property string[] $folders
25
 * @property-read array $resources
26
 * @method void onLanguageChange(FileLoader $loader, string $oldLang, string $newLang)
27
 * @method void onFoldersChange(FileLoader $loader, string[] $folders)
28
 * @method void onLoad(FileLoader $loader, string $lang)
29
 */
30 1
abstract class FileLoader implements IFileLoader {
31
  use \Nette\SmartObject;
32
33
  protected const DOMAIN_MASK = "%domain%";
34
  protected const LANGUAGE_MASK = "%language%";
35
36
  public string $defaultLang = "en";
37
  protected ?string $loadedLang = null;
38
  protected array $texts = [];
39
  /** @var string[] */
40
  protected array $folders = [];
41
  protected ILocaleResolver $resolver;
42
  protected array $resources = [];
43
  protected string $extension;
44
  /** @var callable[] */
45
  public array $onLanguageChange = [];
46
  /** @var callable[] */
47
  public array $onFoldersChange = [];
48
  /** @var callable[] */
49
  public array $onLoad = [];
50
  
51
  /**
52
   * @param string[] $folders
53
   */
54
  public function __construct(ILocaleResolver $resolver = null, array $folders = []) {
55 1
    $this->setFolders($folders);
0 ignored issues
show
Deprecated Code introduced by
The function Nexendrie\Translation\Lo...ileLoader::setFolders() has been deprecated: Access the property directly ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

55
    /** @scrutinizer ignore-deprecated */ $this->setFolders($folders);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
56 1
    $this->resolver = $resolver ?? new ManualLocaleResolver();
57 1
  }
58
59
  /**
60
   * @deprecated Access the property directly
61
   */
62
  public function getLang(): string {
63 1
    return $this->resolver->resolve() ?? $this->defaultLang;
64
  }
65
66
  /**
67
   * @deprecated Access the property directly
68
   */
69
  public function setLang(string $lang): void {
70 1
    if(is_a($this->resolver, ISettableLocaleResolver::class)) {
71 1
      $oldLang = $this->lang;
72 1
      $this->resolver->setLang($lang);
73 1
      $this->onLanguageChange($this, $oldLang, $lang);
74
    }
75 1
  }
76
77
  /**
78
   * @deprecated Access the property directly
79
   */
80
  public function getDefaultLang(): string {
81 1
    return $this->defaultLang;
82
  }
83
84
  /**
85
   * @deprecated Access the property directly
86
   */
87
  public function setDefaultLang(string $defaultLang): void {
88 1
    $this->defaultLang = $defaultLang;
89 1
  }
90
  
91
  /**
92
   * @return string[]
93
   * @deprecated Access the property directly
94
   */
95
  public function getFolders(): array {
96 1
    return $this->folders;
97
  }
98
  
99
  /**
100
   * @param string[] $folders
101
   * @throws InvalidFolderException
102
   * @deprecated Access the property directly
103
   */
104
  public function setFolders(array $folders): void {
105 1
    foreach($folders as $folder) {
106 1
      if(!is_dir($folder)) {
107 1
        throw new InvalidFolderException("Folder $folder does not exist.");
108
      }
109 1
      $this->folders[] = $folder;
110
    }
111 1
    $this->onFoldersChange($this, $folders);
112 1
  }
113
  
114
  protected function addResource(string $filename, string $domain): void {
115 1
    if(!isset($this->resources[$domain]) || !in_array($filename, $this->resources[$domain], true)) {
116 1
      $this->resources[$domain][] = $filename;
117
    }
118 1
  }
119
120
  /**
121
   * @deprecated Access the property directly
122
   */
123
  public function getResources(): array {
124 1
    return $this->resources;
125
  }
126
  
127
  /**
128
   * Parse individual file
129
   */
130
  abstract protected function parseFile(string $filename): array;
131
  
132
  /**
133
   * Load texts from one text domain
134
   */
135
  protected function loadDomain(string $name): array {
136 1
    $return = [];
137 1
    $defaultLang = $this->defaultLang;
138 1
    $defaultFilename = $this->getLanguageFilenameMask();
139 1
    $defaultFilename = str_replace([static::DOMAIN_MASK, static::LANGUAGE_MASK, ], [$name, $defaultLang, ], $defaultFilename);
0 ignored issues
show
introduced by
Line exceeds 120 characters; contains 126 characters
Loading history...
140 1
    $files = Finder::findFiles($defaultFilename)
141 1
      ->from($this->folders);
142
    /** @var \SplFileInfo $file */
143 1
    foreach($files as $file) {
144 1
      $default = $this->parseFile($file->getPathname());
145 1
      $this->addResource($file->getPathname(), $name);
146 1
      $lang = [];
147 1
      $filename = str_replace($defaultLang, $this->lang, $defaultFilename);
148 1
      $filename = str_replace($defaultFilename, $filename, $file->getPathname());
149 1
      if($this->lang != $defaultLang && is_file($filename)) {
150 1
        $lang = $this->parseFile($filename);
151 1
        $this->addResource($filename, $name);
152
      }
153 1
      $return = Arrays::mergeTree($return, Arrays::mergeTree($lang, $default));
154
    }
155 1
    return $return;
156
  }
157
  
158
  /**
159
   * Load all texts
160
   *
161
   * @throws FolderNotSetException
162
   */
163
  protected function loadTexts(): void {
164 1
    if($this->lang === $this->loadedLang) {
165 1
      return;
166
    }
167 1
    if(count($this->folders) === 0) {
168 1
      throw new FolderNotSetException("Folder for translations was not set.");
169
    }
170 1
    $default = $this->defaultLang;
171 1
    $this->resources = $texts = [];
172 1
    $mask = $this->getLanguageFilenameMask();
173 1
    $mask = str_replace([static::DOMAIN_MASK, static::LANGUAGE_MASK, ], ["*", $default, ], $mask);
174 1
    $files = Finder::findFiles($mask)
175 1
      ->from($this->folders);
176
    /** @var \SplFileInfo $file */
177 1
    foreach($files as $file) {
178 1
      $domain = $file->getBasename((string) Strings::after($mask, "*"));
179 1
      $texts[$domain] = $this->loadDomain($domain);
180
    }
181 1
    $this->texts = $texts;
182 1
    $this->loadedLang = $this->lang;
183 1
    $this->onLoad($this, $this->lang);
184 1
  }
185
186
  /**
187
   * @deprecated Access the property directly
188
   */
189
  public function getTexts(): array {
190 1
    $this->loadTexts();
191 1
    return $this->texts;
192
  }
193
  
194
  public function getResolverName(): string {
195 1
    $class = get_class($this->resolver);
196 1
    return (string) Strings::after($class, '\\', -1);
197
  }
198
199
  protected function getLanguageFilenameMask(): string {
200 1
    return static::DOMAIN_MASK . "." . static::LANGUAGE_MASK . "." . $this->extension;
201
  }
202
  
203
  /**
204
   * @return string[]
205
   * @throws FolderNotSetException
206
   */
207
  public function getAvailableLanguages(): array {
208 1
    if(count($this->folders) === 0) {
209 1
      throw new FolderNotSetException("Folder for translations was not set.");
210
    }
211 1
    $languages = [];
212 1
    $extension = $this->extension;
213 1
    $mask = $this->getLanguageFilenameMask();
214 1
    $mask = str_replace([static::DOMAIN_MASK, static::LANGUAGE_MASK, ], "*", $mask);
215 1
    $files = Finder::findFiles($mask)
216 1
      ->from($this->folders);
217
    /** @var \SplFileInfo $file */
218 1
    foreach($files as $file) {
219 1
      $filename = $file->getBasename(".$extension");
220 1
      $lang = (string) Strings::after($filename, ".");
221 1
      if(!in_array($lang, $languages, true)) {
222 1
        $languages[] = $lang;
223
      }
224
    }
225 1
    return $languages;
226
  }
227
}
228
?>