1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This file is part of the Kdyby (http://www.kdyby.org) |
5
|
|
|
* |
6
|
|
|
* Copyright (c) 2008 Filip Procházka ([email protected]) |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the file license.txt that was distributed with this source code. |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace Kdyby\Translation\DI; |
12
|
|
|
|
13
|
|
|
use Kdyby; |
14
|
|
|
use Kdyby\Translation\InvalidResourceException; |
15
|
|
|
use Nette; |
16
|
|
|
use Nette\DI\Statement; |
17
|
|
|
use Nette\PhpGenerator as Code; |
18
|
|
|
use Nette\Reflection; |
19
|
|
|
use Nette\Utils\Callback; |
20
|
|
|
use Nette\Utils\Finder; |
21
|
|
|
use Nette\Utils\Strings; |
22
|
|
|
use Nette\Utils\Validators; |
23
|
|
|
use Symfony\Component\Translation\Loader\LoaderInterface; |
24
|
|
|
use Tracy; |
25
|
|
|
|
26
|
|
|
|
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @author Filip Procházka <[email protected]> |
30
|
|
|
*/ |
31
|
|
|
class TranslationExtension extends Nette\DI\CompilerExtension |
32
|
|
|
{ |
33
|
|
|
|
34
|
|
|
/** @deprecated */ |
35
|
|
|
const LOADER_TAG = self::TAG_LOADER; |
36
|
|
|
/** @deprecated */ |
37
|
|
|
const DUMPER_TAG = self::TAG_DUMPER; |
38
|
|
|
/** @deprecated */ |
39
|
|
|
const EXTRACTOR_TAG = self::TAG_EXTRACTOR; |
40
|
|
|
|
41
|
|
|
const TAG_LOADER = 'translation.loader'; |
42
|
|
|
const TAG_DUMPER = 'translation.dumper'; |
43
|
|
|
const TAG_EXTRACTOR = 'translation.extractor'; |
44
|
|
|
|
45
|
|
|
const RESOLVER_REQUEST = 'request'; |
46
|
|
|
const RESOLVER_HEADER = 'header'; |
47
|
|
|
const RESOLVER_SESSION = 'session'; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @var array |
51
|
|
|
*/ |
52
|
|
|
public $defaults = [ |
53
|
|
|
'whitelist' => NULL, // array('cs', 'en'), |
|
|
|
|
54
|
|
|
'default' => 'en', |
55
|
|
|
'logging' => NULL, // TRUE for psr/log, or string for kdyby/monolog channel |
56
|
|
|
// 'fallback' => array('en_US', 'en'), // using custom merge strategy becase Nette's config merger appends lists of values |
|
|
|
|
57
|
|
|
'dirs' => ['%appDir%/lang', '%appDir%/locale'], |
58
|
|
|
'cache' => 'Kdyby\Translation\Caching\PhpFileStorage', |
59
|
|
|
'debugger' => '%debugMode%', |
60
|
|
|
'resolvers' => [ |
61
|
|
|
self::RESOLVER_SESSION => FALSE, |
62
|
|
|
self::RESOLVER_REQUEST => TRUE, |
63
|
|
|
self::RESOLVER_HEADER => TRUE, |
64
|
|
|
], |
65
|
|
|
'loaders' => [] |
66
|
|
|
]; |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* @var array |
70
|
|
|
*/ |
71
|
|
|
private $loaders; |
72
|
|
|
|
73
|
|
|
|
74
|
|
|
|
75
|
|
|
public function __construct() |
76
|
|
|
{ |
77
|
|
|
$this->defaults['cache'] = new Statement($this->defaults['cache'], ['%tempDir%/cache']); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
|
81
|
|
|
|
82
|
|
|
public function loadConfiguration() |
83
|
|
|
{ |
84
|
|
|
$this->loaders = []; |
85
|
|
|
|
86
|
|
|
$builder = $this->getContainerBuilder(); |
87
|
|
|
$config = $this->getConfig(); |
88
|
|
|
|
89
|
|
|
$translator = $builder->addDefinition($this->prefix('default')) |
90
|
|
|
->setClass('Kdyby\Translation\Translator', [$this->prefix('@userLocaleResolver')]) |
91
|
|
|
->addSetup('?->setTranslator(?)', [$this->prefix('@userLocaleResolver.param'), '@self']) |
92
|
|
|
->addSetup('setDefaultLocale', [$config['default']]) |
93
|
|
|
->addSetup('setLocaleWhitelist', [$config['whitelist']]); |
94
|
|
|
|
95
|
|
|
Validators::assertField($config, 'fallback', 'list'); |
96
|
|
|
$translator->addSetup('setFallbackLocales', [$config['fallback']]); |
97
|
|
|
|
98
|
|
|
$catalogueCompiler = $builder->addDefinition($this->prefix('catalogueCompiler')) |
99
|
|
|
->setClass('Kdyby\Translation\CatalogueCompiler', self::filterArgs($config['cache'])); |
100
|
|
|
|
101
|
|
|
if ($config['debugger'] && interface_exists('Tracy\IBarPanel')) { |
102
|
|
|
$builder->addDefinition($this->prefix('panel')) |
103
|
|
|
->setClass('Kdyby\Translation\Diagnostics\Panel', [dirname($builder->expand('%appDir%'))]) |
|
|
|
|
104
|
|
|
->addSetup('setLocaleWhitelist', [$config['whitelist']]); |
105
|
|
|
|
106
|
|
|
$translator->addSetup('?->register(?)', [$this->prefix('@panel'), '@self']); |
107
|
|
|
$catalogueCompiler->addSetup('enableDebugMode'); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
$this->loadLocaleResolver($config); |
111
|
|
|
|
112
|
|
|
$builder->addDefinition($this->prefix('helpers')) |
113
|
|
|
->setClass('Kdyby\Translation\TemplateHelpers') |
114
|
|
|
->setFactory($this->prefix('@default') . '::createTemplateHelpers'); |
115
|
|
|
|
116
|
|
|
$builder->addDefinition($this->prefix('fallbackResolver')) |
117
|
|
|
->setClass('Kdyby\Translation\FallbackResolver'); |
118
|
|
|
|
119
|
|
|
$builder->addDefinition($this->prefix('catalogueFactory')) |
120
|
|
|
->setClass('Kdyby\Translation\CatalogueFactory'); |
121
|
|
|
|
122
|
|
|
$builder->addDefinition($this->prefix('selector')) |
123
|
|
|
->setClass('Symfony\Component\Translation\MessageSelector'); |
124
|
|
|
|
125
|
|
|
$builder->addDefinition($this->prefix('extractor')) |
126
|
|
|
->setClass('Symfony\Component\Translation\Extractor\ChainExtractor'); |
127
|
|
|
|
128
|
|
|
$this->loadExtractors(); |
129
|
|
|
|
130
|
|
|
$builder->addDefinition($this->prefix('writer')) |
131
|
|
|
->setClass('Symfony\Component\Translation\Writer\TranslationWriter'); |
132
|
|
|
|
133
|
|
|
$this->loadDumpers(); |
134
|
|
|
|
135
|
|
|
$builder->addDefinition($this->prefix('loader')) |
136
|
|
|
->setClass('Kdyby\Translation\TranslationLoader'); |
137
|
|
|
|
138
|
|
|
$loaders = $this->loadFromFile(__DIR__ . '/config/loaders.neon'); |
139
|
|
|
$this->loadLoaders($loaders, $config['loaders'] ? : array_keys($loaders)); |
|
|
|
|
140
|
|
|
|
141
|
|
|
if ($this->isRegisteredConsoleExtension()) { |
142
|
|
|
$this->loadConsole($config); |
143
|
|
|
} |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
|
147
|
|
|
|
148
|
|
|
protected function loadLocaleResolver(array $config) |
149
|
|
|
{ |
150
|
|
|
$builder = $this->getContainerBuilder(); |
151
|
|
|
|
152
|
|
|
$builder->addDefinition($this->prefix('userLocaleResolver.param')) |
153
|
|
|
->setClass('Kdyby\Translation\LocaleResolver\LocaleParamResolver') |
154
|
|
|
->setAutowired(FALSE); |
155
|
|
|
|
156
|
|
|
$builder->addDefinition($this->prefix('userLocaleResolver.acceptHeader')) |
157
|
|
|
->setClass('Kdyby\Translation\LocaleResolver\AcceptHeaderResolver'); |
158
|
|
|
|
159
|
|
|
$builder->addDefinition($this->prefix('userLocaleResolver.session')) |
160
|
|
|
->setClass('Kdyby\Translation\LocaleResolver\SessionResolver'); |
161
|
|
|
|
162
|
|
|
$chain = $builder->addDefinition($this->prefix('userLocaleResolver')) |
163
|
|
|
->setClass('Kdyby\Translation\IUserLocaleResolver') |
164
|
|
|
->setFactory('Kdyby\Translation\LocaleResolver\ChainResolver'); |
165
|
|
|
|
166
|
|
|
$resolvers = []; |
167
|
|
View Code Duplication |
if ($config['resolvers'][self::RESOLVER_HEADER]) { |
|
|
|
|
168
|
|
|
$resolvers[] = $this->prefix('@userLocaleResolver.acceptHeader'); |
169
|
|
|
$chain->addSetup('addResolver', [$this->prefix('@userLocaleResolver.acceptHeader')]); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
View Code Duplication |
if ($config['resolvers'][self::RESOLVER_REQUEST]) { |
|
|
|
|
173
|
|
|
$resolvers[] = $this->prefix('@userLocaleResolver.param'); |
174
|
|
|
$chain->addSetup('addResolver', [$this->prefix('@userLocaleResolver.param')]); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
View Code Duplication |
if ($config['resolvers'][self::RESOLVER_SESSION]) { |
|
|
|
|
178
|
|
|
$resolvers[] = $this->prefix('@userLocaleResolver.session'); |
179
|
|
|
$chain->addSetup('addResolver', [$this->prefix('@userLocaleResolver.session')]); |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
if ($config['debugger'] && interface_exists('Tracy\IBarPanel')) { |
183
|
|
|
$builder->getDefinition($this->prefix('panel')) |
184
|
|
|
->addSetup('setLocaleResolvers', [array_reverse($resolvers)]); |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
|
189
|
|
|
|
190
|
|
|
protected function loadConsole(array $config) |
191
|
|
|
{ |
192
|
|
|
$builder = $this->getContainerBuilder(); |
193
|
|
|
|
194
|
|
|
Validators::assertField($config, 'dirs', 'list'); |
195
|
|
|
$builder->addDefinition($this->prefix('console.extract')) |
196
|
|
|
->setClass('Kdyby\Translation\Console\ExtractCommand') |
197
|
|
|
->addSetup('$defaultOutputDir', [reset($config['dirs'])]) |
198
|
|
|
->addTag('kdyby.console.command', 'latte'); |
|
|
|
|
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
|
202
|
|
|
|
203
|
|
View Code Duplication |
protected function loadDumpers() |
|
|
|
|
204
|
|
|
{ |
205
|
|
|
$builder = $this->getContainerBuilder(); |
206
|
|
|
|
207
|
|
|
foreach ($this->loadFromFile(__DIR__ . '/config/dumpers.neon') as $format => $class) { |
|
|
|
|
208
|
|
|
$builder->addDefinition($this->prefix('dumper.' . $format)) |
209
|
|
|
->setClass($class) |
210
|
|
|
->addTag(self::TAG_DUMPER, $format); |
|
|
|
|
211
|
|
|
} |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
|
215
|
|
|
|
216
|
|
|
protected function loadLoaders(array $loaders, array $allowed) |
217
|
|
|
{ |
218
|
|
|
$builder = $this->getContainerBuilder(); |
219
|
|
|
|
220
|
|
|
foreach ($loaders as $format => $class) { |
221
|
|
|
if (array_search($format, $allowed) === FALSE) { |
222
|
|
|
continue; |
223
|
|
|
} |
224
|
|
|
$builder->addDefinition($this->prefix('loader.' . $format)) |
225
|
|
|
->setClass($class) |
226
|
|
|
->addTag(self::TAG_LOADER, $format); |
|
|
|
|
227
|
|
|
} |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
|
231
|
|
|
|
232
|
|
View Code Duplication |
protected function loadExtractors() |
|
|
|
|
233
|
|
|
{ |
234
|
|
|
$builder = $this->getContainerBuilder(); |
235
|
|
|
|
236
|
|
|
foreach ($this->loadFromFile(__DIR__ . '/config/extractors.neon') as $format => $class) { |
|
|
|
|
237
|
|
|
$builder->addDefinition($this->prefix('extractor.' . $format)) |
238
|
|
|
->setClass($class) |
239
|
|
|
->addTag(self::TAG_EXTRACTOR, $format); |
|
|
|
|
240
|
|
|
} |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
|
244
|
|
|
|
245
|
|
|
public function beforeCompile() |
246
|
|
|
{ |
247
|
|
|
$builder = $this->getContainerBuilder(); |
248
|
|
|
$config = $this->getConfig(); |
249
|
|
|
|
250
|
|
|
$this->beforeCompileLogging($config); |
251
|
|
|
|
252
|
|
|
$registerToLatte = function (Nette\DI\ServiceDefinition $def) { |
253
|
|
|
$def->addSetup('?->onCompile[] = function($engine) { Kdyby\Translation\Latte\TranslateMacros::install($engine->getCompiler()); }', ['@self']); |
254
|
|
|
|
255
|
|
|
$def->addSetup('addProvider', ['translator', $this->prefix('@default')]) |
256
|
|
|
->addSetup('addFilter', ['translate', [$this->prefix('@helpers'), 'translateFilterAware']]); |
257
|
|
|
}; |
258
|
|
|
|
259
|
|
|
$latteFactoryService = $builder->getByType('Nette\Bridges\ApplicationLatte\ILatteFactory'); |
260
|
|
|
if (!$latteFactoryService || !self::isOfType($builder->getDefinition($latteFactoryService)->getClass(), 'Latte\engine')) { |
|
|
|
|
261
|
|
|
$latteFactoryService = 'nette.latteFactory'; |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
if ($builder->hasDefinition($latteFactoryService) && self::isOfType($builder->getDefinition($latteFactoryService)->getClass(), 'Latte\Engine')) { |
265
|
|
|
$registerToLatte($builder->getDefinition($latteFactoryService)); |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
if ($builder->hasDefinition('nette.latte')) { |
269
|
|
|
$registerToLatte($builder->getDefinition('nette.latte')); |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
$applicationService = $builder->getByType('Nette\Application\Application') ?: 'application'; |
273
|
|
|
if ($builder->hasDefinition($applicationService)) { |
274
|
|
|
$builder->getDefinition($applicationService) |
275
|
|
|
->addSetup('$service->onRequest[] = ?', [[$this->prefix('@userLocaleResolver.param'), 'onRequest']]); |
276
|
|
|
|
277
|
|
|
if ($config['debugger'] && interface_exists('Tracy\IBarPanel')) { |
278
|
|
|
$builder->getDefinition($applicationService) |
279
|
|
|
->addSetup('$self = $this; $service->onStartup[] = function () use ($self) { $self->getService(?); }', [$this->prefix('default')]) |
280
|
|
|
->addSetup('$service->onRequest[] = ?', [[$this->prefix('@panel'), 'onRequest']]); |
281
|
|
|
} |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
if (class_exists('Tracy\Debugger')) { |
285
|
|
|
Kdyby\Translation\Diagnostics\Panel::registerBluescreen(); |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
$extractor = $builder->getDefinition($this->prefix('extractor')); |
289
|
|
View Code Duplication |
foreach ($builder->findByTag(self::TAG_EXTRACTOR) as $extractorId => $meta) { |
|
|
|
|
290
|
|
|
Validators::assert($meta, 'string:2..'); |
291
|
|
|
|
292
|
|
|
$extractor->addSetup('addExtractor', [$meta, '@' . $extractorId]); |
293
|
|
|
|
294
|
|
|
$builder->getDefinition($extractorId)->setAutowired(FALSE); |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
$writer = $builder->getDefinition($this->prefix('writer')); |
298
|
|
View Code Duplication |
foreach ($builder->findByTag(self::TAG_DUMPER) as $dumperId => $meta) { |
|
|
|
|
299
|
|
|
Validators::assert($meta, 'string:2..'); |
300
|
|
|
|
301
|
|
|
$writer->addSetup('addDumper', [$meta, '@' . $dumperId]); |
302
|
|
|
|
303
|
|
|
$builder->getDefinition($dumperId)->setAutowired(FALSE); |
304
|
|
|
} |
305
|
|
|
|
306
|
|
|
$this->loaders = []; |
307
|
|
|
foreach ($builder->findByTag(self::TAG_LOADER) as $loaderId => $meta) { |
308
|
|
|
Validators::assert($meta, 'string:2..'); |
309
|
|
|
$builder->getDefinition($loaderId)->setAutowired(FALSE); |
310
|
|
|
$this->loaders[$meta] = $loaderId; |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
$builder->getDefinition($this->prefix('loader')) |
314
|
|
|
->addSetup('injectServiceIds', [$this->loaders]); |
315
|
|
|
|
316
|
|
|
foreach ($this->compiler->getExtensions() as $extension) { |
317
|
|
|
if (!$extension instanceof ITranslationProvider) { |
318
|
|
|
continue; |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
$config['dirs'] = array_merge($config['dirs'], array_values($extension->getTranslationResources())); |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
$config['dirs'] = array_map(function ($dir) { |
325
|
|
|
return str_replace((DIRECTORY_SEPARATOR === '/') ? '\\' : '/', DIRECTORY_SEPARATOR, $dir); |
326
|
|
|
}, $config['dirs']); |
327
|
|
|
|
328
|
|
|
if ($dirs = array_values(array_filter($config['dirs'], Callback::closure('is_dir')))) { |
329
|
|
|
foreach ($dirs as $dir) { |
330
|
|
|
$builder->addDependency($dir); |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
$this->loadResourcesFromDirs($dirs); |
334
|
|
|
} |
335
|
|
|
} |
336
|
|
|
|
337
|
|
|
|
338
|
|
|
|
339
|
|
|
protected function beforeCompileLogging(array $config) |
340
|
|
|
{ |
341
|
|
|
$builder = $this->getContainerBuilder(); |
342
|
|
|
$translator = $builder->getDefinition($this->prefix('default')); |
343
|
|
|
|
344
|
|
|
if ($config['logging'] === TRUE) { |
345
|
|
|
$translator->addSetup('injectPsrLogger'); |
346
|
|
|
|
347
|
|
|
} elseif (is_string($config['logging'])) { // channel for kdyby/monolog |
348
|
|
|
$translator->addSetup('injectPsrLogger', [ |
349
|
|
|
new Statement('@Kdyby\Monolog\Logger::channel', [$config['logging']]), |
350
|
|
|
]); |
351
|
|
|
|
352
|
|
|
} elseif ($config['logging'] !== NULL) { |
353
|
|
|
throw new Kdyby\Translation\InvalidArgumentException(sprintf( |
354
|
|
|
"Invalid config option for logger. Valid are TRUE for general psr/log or string for kdyby/monolog channel, but %s was given", |
355
|
|
|
$config['logging'] |
356
|
|
|
)); |
357
|
|
|
} |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
|
361
|
|
|
|
362
|
|
|
protected function loadResourcesFromDirs($dirs) |
363
|
|
|
{ |
364
|
|
|
$builder = $this->getContainerBuilder(); |
365
|
|
|
$config = $this->getConfig(); |
366
|
|
|
|
367
|
|
|
$whitelistRegexp = Kdyby\Translation\Translator::buildWhitelistRegexp($config['whitelist']); |
368
|
|
|
$translator = $builder->getDefinition($this->prefix('default')); |
369
|
|
|
|
370
|
|
|
$mask = array_map(function ($value) { |
371
|
|
|
return '*.*.' . $value; |
372
|
|
|
}, array_keys($this->loaders)); |
373
|
|
|
|
374
|
|
|
foreach (Finder::findFiles($mask)->from($dirs) as $file) { |
375
|
|
|
/** @var \SplFileInfo $file */ |
376
|
|
|
if (!$m = Strings::match($file->getFilename(), '~^(?P<domain>.*?)\.(?P<locale>[^\.]+)\.(?P<format>[^\.]+)$~')) { |
377
|
|
|
continue; |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
if ($whitelistRegexp && !preg_match($whitelistRegexp, $m['locale']) && $builder->parameters['productionMode']) { |
|
|
|
|
381
|
|
|
continue; // ignore in production mode, there is no need to pass the ignored resources |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
$this->validateResource($m['format'], $file->getPathname(), $m['locale'], $m['domain']); |
385
|
|
|
$translator->addSetup('addResource', [$m['format'], $file->getPathname(), $m['locale'], $m['domain']]); |
386
|
|
|
$builder->addDependency($file->getPathname()); |
387
|
|
|
} |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
|
391
|
|
|
|
392
|
|
|
/** |
393
|
|
|
* @param string $format |
394
|
|
|
* @param string $file |
395
|
|
|
* @param string $locale |
396
|
|
|
* @param string $domain |
397
|
|
|
*/ |
398
|
|
|
protected function validateResource($format, $file, $locale, $domain) |
399
|
|
|
{ |
400
|
|
|
$builder = $this->getContainerBuilder(); |
401
|
|
|
|
402
|
|
|
if (!isset($this->loaders[$format])) { |
403
|
|
|
return; |
404
|
|
|
} |
405
|
|
|
|
406
|
|
|
try { |
407
|
|
|
$def = $builder->getDefinition($this->loaders[$format]); |
408
|
|
|
$refl = Reflection\ClassType::from($def->getEntity() ?: $def->getClass()); |
409
|
|
|
if (($method = $refl->getConstructor()) && $method->getNumberOfRequiredParameters() > 1) { |
410
|
|
|
return; |
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
$loader = $refl->newInstance(); |
414
|
|
|
if (!$loader instanceof LoaderInterface) { |
415
|
|
|
return; |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
} catch (\ReflectionException $e) { |
419
|
|
|
return; |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
try { |
423
|
|
|
$loader->load($file, $locale, $domain); |
424
|
|
|
|
425
|
|
|
} catch (\Exception $e) { |
426
|
|
|
throw new InvalidResourceException("Resource $file is not valid and cannot be loaded.", 0, $e); |
427
|
|
|
} |
428
|
|
|
} |
429
|
|
|
|
430
|
|
|
|
431
|
|
|
|
432
|
|
|
public function afterCompile(Code\ClassType $class) |
433
|
|
|
{ |
434
|
|
|
$initialize = $class->getMethod('initialize'); |
435
|
|
|
if (class_exists('Tracy\Debugger')) { |
436
|
|
|
$initialize->addBody('Kdyby\Translation\Diagnostics\Panel::registerBluescreen();'); |
437
|
|
|
} |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
|
441
|
|
|
|
442
|
|
|
/** |
443
|
|
|
* {@inheritdoc} |
444
|
|
|
*/ |
445
|
|
|
public function getConfig(array $defaults = NULL, $expand = TRUE) |
|
|
|
|
446
|
|
|
{ |
447
|
|
|
return parent::getConfig($this->defaults) + ['fallback' => ['en_US']]; |
448
|
|
|
} |
449
|
|
|
|
450
|
|
|
|
451
|
|
|
|
452
|
|
|
private function isRegisteredConsoleExtension() |
453
|
|
|
{ |
454
|
|
|
foreach ($this->compiler->getExtensions() as $extension) { |
455
|
|
|
if ($extension instanceof Kdyby\Console\DI\ConsoleExtension) { |
|
|
|
|
456
|
|
|
return TRUE; |
457
|
|
|
} |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
return FALSE; |
461
|
|
|
} |
462
|
|
|
|
463
|
|
|
|
464
|
|
|
|
465
|
|
|
/** |
466
|
|
|
* @param \Nette\Configurator $configurator |
467
|
|
|
*/ |
468
|
|
|
public static function register(Nette\Configurator $configurator) |
469
|
|
|
{ |
470
|
|
|
$configurator->onCompile[] = function ($config, Nette\DI\Compiler $compiler) { |
471
|
|
|
$compiler->addExtension('translation', new TranslationExtension()); |
472
|
|
|
}; |
473
|
|
|
} |
474
|
|
|
|
475
|
|
|
|
476
|
|
|
|
477
|
|
|
/** |
478
|
|
|
* @param string|\stdClass $statement |
479
|
|
|
* @return Nette\DI\Statement[] |
480
|
|
|
*/ |
481
|
|
|
protected static function filterArgs($statement) |
482
|
|
|
{ |
483
|
|
|
return \Nette\DI\Helpers::filterArguments([is_string($statement) ? new Nette\DI\Statement($statement) : $statement]); |
484
|
|
|
} |
485
|
|
|
|
486
|
|
|
|
487
|
|
|
|
488
|
|
|
/** |
489
|
|
|
* @param string $class |
490
|
|
|
* @param string $type |
491
|
|
|
* @return bool |
492
|
|
|
*/ |
493
|
|
|
private static function isOfType($class, $type) |
494
|
|
|
{ |
495
|
|
|
return $class === $type || is_subclass_of($class, $type); |
|
|
|
|
496
|
|
|
} |
497
|
|
|
|
498
|
|
|
} |
499
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.