These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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\Console\DI\ConsoleExtension; |
||
14 | use Kdyby\Monolog\Logger as KdybyLogger; |
||
15 | use Kdyby\Translation\Caching\PhpFileStorage; |
||
16 | use Kdyby\Translation\CatalogueCompiler; |
||
17 | use Kdyby\Translation\CatalogueFactory; |
||
18 | use Kdyby\Translation\Console\ExtractCommand; |
||
19 | use Kdyby\Translation\Diagnostics\Panel; |
||
20 | use Kdyby\Translation\FallbackResolver; |
||
21 | use Kdyby\Translation\IUserLocaleResolver; |
||
22 | use Kdyby\Translation\Latte\TranslateMacros; |
||
23 | use Kdyby\Translation\LocaleResolver\AcceptHeaderResolver; |
||
24 | use Kdyby\Translation\LocaleResolver\ChainResolver; |
||
25 | use Kdyby\Translation\LocaleResolver\LocaleParamResolver; |
||
26 | use Kdyby\Translation\LocaleResolver\SessionResolver; |
||
27 | use Kdyby\Translation\TemplateHelpers; |
||
28 | use Kdyby\Translation\TranslationLoader; |
||
29 | use Kdyby\Translation\Translator as KdybyTranslator; |
||
30 | use Latte\Engine as LatteEngine; |
||
31 | use Nette\Application\Application; |
||
32 | use Nette\Bridges\ApplicationLatte\ILatteFactory; |
||
33 | use Nette\Configurator; |
||
34 | use Nette\DI\Compiler; |
||
35 | use Nette\DI\Helpers; |
||
36 | use Nette\DI\ServiceDefinition; |
||
37 | use Nette\DI\Statement; |
||
38 | use Nette\PhpGenerator\ClassType as ClassTypeGenerator; |
||
39 | use Nette\PhpGenerator\PhpLiteral; |
||
40 | use Nette\Reflection\ClassType as ReflectionClassType; |
||
41 | use Nette\Utils\Callback; |
||
42 | use Nette\Utils\Finder; |
||
43 | use Nette\Utils\Validators; |
||
44 | use Symfony\Component\Translation\Extractor\ChainExtractor; |
||
45 | use Symfony\Component\Translation\Formatter\MessageFormatter; |
||
46 | use Symfony\Component\Translation\Loader\LoaderInterface; |
||
47 | use Symfony\Component\Translation\MessageSelector; |
||
48 | use Symfony\Component\Translation\Writer\TranslationWriter; |
||
49 | use Tracy\Debugger; |
||
50 | use Tracy\IBarPanel; |
||
51 | |||
52 | class TranslationExtension extends \Nette\DI\CompilerExtension |
||
53 | { |
||
54 | |||
55 | use \Kdyby\StrictObjects\Scream; |
||
56 | |||
57 | /** @deprecated */ |
||
58 | const LOADER_TAG = self::TAG_LOADER; |
||
59 | /** @deprecated */ |
||
60 | const DUMPER_TAG = self::TAG_DUMPER; |
||
61 | /** @deprecated */ |
||
62 | const EXTRACTOR_TAG = self::TAG_EXTRACTOR; |
||
63 | |||
64 | const TAG_LOADER = 'translation.loader'; |
||
65 | const TAG_DUMPER = 'translation.dumper'; |
||
66 | const TAG_EXTRACTOR = 'translation.extractor'; |
||
67 | |||
68 | const RESOLVER_REQUEST = 'request'; |
||
69 | const RESOLVER_HEADER = 'header'; |
||
70 | const RESOLVER_SESSION = 'session'; |
||
71 | |||
72 | /** |
||
73 | * @var mixed[] |
||
74 | */ |
||
75 | public $defaults = [ |
||
76 | 'whitelist' => NULL, // array('cs', 'en'), |
||
77 | 'default' => 'en', |
||
78 | 'logging' => NULL, // TRUE for psr/log, or string for kdyby/monolog channel |
||
79 | // 'fallback' => array('en_US', 'en'), // using custom merge strategy becase Nette's config merger appends lists of values |
||
80 | 'dirs' => ['%appDir%/lang', '%appDir%/locale'], |
||
81 | 'cache' => PhpFileStorage::class, |
||
82 | 'debugger' => '%debugMode%', |
||
83 | 'resolvers' => [ |
||
84 | self::RESOLVER_SESSION => FALSE, |
||
85 | self::RESOLVER_REQUEST => TRUE, |
||
86 | self::RESOLVER_HEADER => TRUE, |
||
87 | ], |
||
88 | 'loaders' => [], |
||
89 | ]; |
||
90 | |||
91 | /** |
||
92 | * @var array |
||
93 | */ |
||
94 | private $loaders; |
||
95 | |||
96 | public function __construct() |
||
97 | { |
||
98 | $this->defaults['cache'] = new Statement($this->defaults['cache'], ['%tempDir%/cache']); |
||
99 | } |
||
100 | |||
101 | public function loadConfiguration() |
||
102 | { |
||
103 | $this->loaders = []; |
||
104 | |||
105 | $builder = $this->getContainerBuilder(); |
||
106 | $config = $this->getConfig(); |
||
107 | |||
108 | $translator = $builder->addDefinition($this->prefix('default')) |
||
0 ignored issues
–
show
|
|||
109 | ->setClass(KdybyTranslator::class, [$this->prefix('@userLocaleResolver')]) |
||
110 | ->addSetup('?->setTranslator(?)', [$this->prefix('@userLocaleResolver.param'), '@self']) |
||
111 | ->addSetup('setDefaultLocale', [$config['default']]) |
||
112 | ->addSetup('setLocaleWhitelist', [$config['whitelist']]); |
||
113 | |||
114 | Validators::assertField($config, 'fallback', 'list'); |
||
115 | $translator->addSetup('setFallbackLocales', [$config['fallback']]); |
||
116 | |||
117 | $catalogueCompiler = $builder->addDefinition($this->prefix('catalogueCompiler')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
118 | ->setClass(CatalogueCompiler::class, self::filterArgs($config['cache'])); |
||
119 | |||
120 | if ($config['debugger'] && interface_exists(IBarPanel::class)) { |
||
121 | $builder->addDefinition($this->prefix('panel')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
122 | ->setClass(Panel::class, [dirname($builder->expand('%appDir%'))]) |
||
0 ignored issues
–
show
|
|||
123 | ->addSetup('setLocaleWhitelist', [$config['whitelist']]); |
||
124 | |||
125 | $translator->addSetup('?->register(?)', [$this->prefix('@panel'), '@self']); |
||
126 | $catalogueCompiler->addSetup('enableDebugMode'); |
||
127 | } |
||
128 | |||
129 | $this->loadLocaleResolver($config); |
||
130 | |||
131 | $builder->addDefinition($this->prefix('helpers')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
132 | ->setClass(TemplateHelpers::class) |
||
133 | ->setFactory($this->prefix('@default') . '::createTemplateHelpers'); |
||
134 | |||
135 | $builder->addDefinition($this->prefix('fallbackResolver')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
136 | ->setClass(FallbackResolver::class); |
||
137 | |||
138 | $builder->addDefinition($this->prefix('catalogueFactory')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
139 | ->setClass(CatalogueFactory::class); |
||
140 | |||
141 | $builder->addDefinition($this->prefix('selector')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
142 | ->setClass(MessageSelector::class); |
||
143 | |||
144 | $builder->addDefinition($this->prefix('formatter')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
145 | ->setClass(MessageFormatter::class); |
||
146 | |||
147 | $builder->addDefinition($this->prefix('extractor')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
148 | ->setClass(ChainExtractor::class); |
||
149 | |||
150 | $this->loadExtractors(); |
||
151 | |||
152 | $builder->addDefinition($this->prefix('writer')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
153 | ->setClass(TranslationWriter::class); |
||
154 | |||
155 | $this->loadDumpers(); |
||
156 | |||
157 | $builder->addDefinition($this->prefix('loader')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
158 | ->setClass(TranslationLoader::class); |
||
159 | |||
160 | $loaders = $this->loadFromFile(__DIR__ . '/config/loaders.neon'); |
||
161 | $this->loadLoaders($loaders, $config['loaders'] ?: array_keys($loaders)); |
||
0 ignored issues
–
show
It seems like
$loaders defined by $this->loadFromFile(__DI...'/config/loaders.neon') on line 160 can also be of type string ; however, Kdyby\Translation\DI\Tra...xtension::loadLoaders() does only seem to accept array , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.
Loading history...
|
|||
162 | |||
163 | if ($this->isRegisteredConsoleExtension()) { |
||
164 | $this->loadConsole($config); |
||
165 | } |
||
166 | } |
||
167 | |||
168 | protected function loadLocaleResolver(array $config) |
||
169 | { |
||
170 | $builder = $this->getContainerBuilder(); |
||
171 | |||
172 | $builder->addDefinition($this->prefix('userLocaleResolver.param')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
173 | ->setClass(LocaleParamResolver::class) |
||
174 | ->setAutowired(FALSE); |
||
175 | |||
176 | $builder->addDefinition($this->prefix('userLocaleResolver.acceptHeader')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
177 | ->setClass(AcceptHeaderResolver::class); |
||
178 | |||
179 | $builder->addDefinition($this->prefix('userLocaleResolver.session')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
180 | ->setClass(SessionResolver::class); |
||
181 | |||
182 | $chain = $builder->addDefinition($this->prefix('userLocaleResolver')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
183 | ->setClass(IUserLocaleResolver::class) |
||
184 | ->setFactory(ChainResolver::class); |
||
185 | |||
186 | $resolvers = []; |
||
187 | View Code Duplication | if ($config['resolvers'][self::RESOLVER_HEADER]) { |
|
188 | $resolvers[] = $this->prefix('@userLocaleResolver.acceptHeader'); |
||
189 | $chain->addSetup('addResolver', [$this->prefix('@userLocaleResolver.acceptHeader')]); |
||
190 | } |
||
191 | |||
192 | View Code Duplication | if ($config['resolvers'][self::RESOLVER_REQUEST]) { |
|
193 | $resolvers[] = $this->prefix('@userLocaleResolver.param'); |
||
194 | $chain->addSetup('addResolver', [$this->prefix('@userLocaleResolver.param')]); |
||
195 | } |
||
196 | |||
197 | View Code Duplication | if ($config['resolvers'][self::RESOLVER_SESSION]) { |
|
198 | $resolvers[] = $this->prefix('@userLocaleResolver.session'); |
||
199 | $chain->addSetup('addResolver', [$this->prefix('@userLocaleResolver.session')]); |
||
200 | } |
||
201 | |||
202 | if ($config['debugger'] && interface_exists(IBarPanel::class)) { |
||
203 | $builder->getDefinition($this->prefix('panel')) |
||
204 | ->addSetup('setLocaleResolvers', [array_reverse($resolvers)]); |
||
205 | } |
||
206 | } |
||
207 | |||
208 | protected function loadConsole(array $config) |
||
209 | { |
||
210 | $builder = $this->getContainerBuilder(); |
||
211 | |||
212 | Validators::assertField($config, 'dirs', 'list'); |
||
213 | $builder->addDefinition($this->prefix('console.extract')) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
214 | ->setClass(ExtractCommand::class) |
||
215 | ->addSetup('$defaultOutputDir', [reset($config['dirs'])]) |
||
216 | ->addTag(ConsoleExtension::TAG_COMMAND, 'latte'); |
||
0 ignored issues
–
show
'latte' is of type string , but the function expects a boolean .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
217 | } |
||
218 | |||
219 | View Code Duplication | protected function loadDumpers() |
|
220 | { |
||
221 | $builder = $this->getContainerBuilder(); |
||
222 | |||
223 | foreach ($this->loadFromFile(__DIR__ . '/config/dumpers.neon') as $format => $class) { |
||
0 ignored issues
–
show
The expression
$this->loadFromFile(__DI...'/config/dumpers.neon') of type array|string is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
Loading history...
|
|||
224 | $builder->addDefinition($this->prefix('dumper.' . $format)) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
225 | ->setClass($class) |
||
226 | ->addTag(self::TAG_DUMPER, $format); |
||
0 ignored issues
–
show
$format is of type integer|string , but the function expects a boolean .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
227 | } |
||
228 | } |
||
229 | |||
230 | protected function loadLoaders(array $loaders, array $allowed) |
||
231 | { |
||
232 | $builder = $this->getContainerBuilder(); |
||
233 | |||
234 | foreach ($loaders as $format => $class) { |
||
235 | if (array_search($format, $allowed) === FALSE) { |
||
236 | continue; |
||
237 | } |
||
238 | $builder->addDefinition($this->prefix('loader.' . $format)) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
239 | ->setClass($class) |
||
240 | ->addTag(self::TAG_LOADER, $format); |
||
0 ignored issues
–
show
$format is of type integer|string , but the function expects a boolean .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
241 | } |
||
242 | } |
||
243 | |||
244 | View Code Duplication | protected function loadExtractors() |
|
245 | { |
||
246 | $builder = $this->getContainerBuilder(); |
||
247 | |||
248 | foreach ($this->loadFromFile(__DIR__ . '/config/extractors.neon') as $format => $class) { |
||
0 ignored issues
–
show
The expression
$this->loadFromFile(__DI...onfig/extractors.neon') of type array|string is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
Loading history...
|
|||
249 | $builder->addDefinition($this->prefix('extractor.' . $format)) |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::setClass() has been deprecated with message: Use setType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
250 | ->setClass($class) |
||
251 | ->addTag(self::TAG_EXTRACTOR, $format); |
||
0 ignored issues
–
show
$format is of type integer|string , but the function expects a boolean .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
252 | } |
||
253 | } |
||
254 | |||
255 | public function beforeCompile() |
||
256 | { |
||
257 | $builder = $this->getContainerBuilder(); |
||
258 | $config = $this->getConfig(); |
||
259 | |||
260 | $this->beforeCompileLogging($config); |
||
261 | |||
262 | $registerToLatte = function (ServiceDefinition $def) { |
||
263 | $def->addSetup('?->onCompile[] = function($engine) { ?::install($engine->getCompiler()); }', ['@self', new PhpLiteral(TranslateMacros::class)]); |
||
264 | |||
265 | $def->addSetup('addProvider', ['translator', $this->prefix('@default')]) |
||
266 | ->addSetup('addFilter', ['translate', [$this->prefix('@helpers'), 'translateFilterAware']]); |
||
267 | }; |
||
268 | |||
269 | $latteFactoryService = $builder->getByType(ILatteFactory::class); |
||
270 | if (!$latteFactoryService || !self::isOfType($builder->getDefinition($latteFactoryService)->getClass(), LatteEngine::class)) { |
||
0 ignored issues
–
show
The expression
$latteFactoryService of type string|null is loosely compared to false ; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
The method
Nette\DI\ServiceDefinition::getClass() has been deprecated with message: Use getType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
271 | $latteFactoryService = 'nette.latteFactory'; |
||
272 | } |
||
273 | |||
274 | if ($builder->hasDefinition($latteFactoryService) && self::isOfType($builder->getDefinition($latteFactoryService)->getClass(), LatteEngine::class)) { |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::getClass() has been deprecated with message: Use getType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
275 | $registerToLatte($builder->getDefinition($latteFactoryService)); |
||
276 | } |
||
277 | |||
278 | if ($builder->hasDefinition('nette.latte')) { |
||
279 | $registerToLatte($builder->getDefinition('nette.latte')); |
||
280 | } |
||
281 | |||
282 | $applicationService = $builder->getByType(Application::class) ?: 'application'; |
||
283 | if ($builder->hasDefinition($applicationService)) { |
||
284 | $builder->getDefinition($applicationService) |
||
285 | ->addSetup('$service->onRequest[] = ?', [[$this->prefix('@userLocaleResolver.param'), 'onRequest']]); |
||
286 | |||
287 | if ($config['debugger'] && interface_exists(IBarPanel::class)) { |
||
288 | $builder->getDefinition($applicationService) |
||
289 | ->addSetup('$self = $this; $service->onStartup[] = function () use ($self) { $self->getService(?); }', [$this->prefix('default')]) |
||
290 | ->addSetup('$service->onRequest[] = ?', [[$this->prefix('@panel'), 'onRequest']]); |
||
291 | } |
||
292 | } |
||
293 | |||
294 | if (class_exists(Debugger::class)) { |
||
295 | Panel::registerBluescreen(); |
||
296 | } |
||
297 | |||
298 | $extractor = $builder->getDefinition($this->prefix('extractor')); |
||
299 | View Code Duplication | foreach ($builder->findByTag(self::TAG_EXTRACTOR) as $extractorId => $meta) { |
|
300 | Validators::assert($meta, 'string:2..'); |
||
301 | |||
302 | $extractor->addSetup('addExtractor', [$meta, '@' . $extractorId]); |
||
303 | |||
304 | $builder->getDefinition($extractorId)->setAutowired(FALSE); |
||
305 | } |
||
306 | |||
307 | $writer = $builder->getDefinition($this->prefix('writer')); |
||
308 | View Code Duplication | foreach ($builder->findByTag(self::TAG_DUMPER) as $dumperId => $meta) { |
|
309 | Validators::assert($meta, 'string:2..'); |
||
310 | |||
311 | $writer->addSetup('addDumper', [$meta, '@' . $dumperId]); |
||
312 | |||
313 | $builder->getDefinition($dumperId)->setAutowired(FALSE); |
||
314 | } |
||
315 | |||
316 | $this->loaders = []; |
||
317 | foreach ($builder->findByTag(self::TAG_LOADER) as $loaderId => $meta) { |
||
318 | Validators::assert($meta, 'string:2..'); |
||
319 | $builder->getDefinition($loaderId)->setAutowired(FALSE); |
||
320 | $this->loaders[$meta] = $loaderId; |
||
321 | } |
||
322 | |||
323 | $builder->getDefinition($this->prefix('loader')) |
||
324 | ->addSetup('injectServiceIds', [$this->loaders]); |
||
325 | |||
326 | foreach ($this->compiler->getExtensions() as $extension) { |
||
327 | if (!$extension instanceof ITranslationProvider) { |
||
328 | continue; |
||
329 | } |
||
330 | |||
331 | $config['dirs'] = array_merge($config['dirs'], array_values($extension->getTranslationResources())); |
||
332 | } |
||
333 | |||
334 | $config['dirs'] = array_map(function ($dir) { |
||
335 | return str_replace((DIRECTORY_SEPARATOR === '/') ? '\\' : '/', DIRECTORY_SEPARATOR, $dir); |
||
336 | }, $config['dirs']); |
||
337 | |||
338 | $dirs = array_values(array_filter($config['dirs'], Callback::closure('is_dir'))); |
||
339 | if (count($dirs) > 0) { |
||
340 | foreach ($dirs as $dir) { |
||
341 | $builder->addDependency($dir); |
||
342 | } |
||
343 | |||
344 | $this->loadResourcesFromDirs($dirs); |
||
345 | } |
||
346 | } |
||
347 | |||
348 | protected function beforeCompileLogging(array $config) |
||
349 | { |
||
350 | $builder = $this->getContainerBuilder(); |
||
351 | $translator = $builder->getDefinition($this->prefix('default')); |
||
352 | |||
353 | if ($config['logging'] === TRUE) { |
||
354 | $translator->addSetup('injectPsrLogger'); |
||
355 | |||
356 | } elseif (is_string($config['logging'])) { // channel for kdyby/monolog |
||
357 | $translator->addSetup('injectPsrLogger', [ |
||
358 | new Statement(sprintf('@%s::channel', KdybyLogger::class), [$config['logging']]), |
||
359 | ]); |
||
360 | |||
361 | } elseif ($config['logging'] !== NULL) { |
||
362 | throw new \Kdyby\Translation\InvalidArgumentException(sprintf( |
||
363 | 'Invalid config option for logger. Valid are TRUE for general psr/log or string for kdyby/monolog channel, but %s was given', |
||
364 | $config['logging'] |
||
365 | )); |
||
366 | } |
||
367 | } |
||
368 | |||
369 | protected function loadResourcesFromDirs($dirs) |
||
370 | { |
||
371 | $builder = $this->getContainerBuilder(); |
||
372 | $config = $this->getConfig(); |
||
373 | |||
374 | $whitelistRegexp = KdybyTranslator::buildWhitelistRegexp($config['whitelist']); |
||
375 | $translator = $builder->getDefinition($this->prefix('default')); |
||
376 | |||
377 | $mask = array_map(function ($value) { |
||
378 | return '*.*.' . $value; |
||
379 | }, array_keys($this->loaders)); |
||
380 | |||
381 | foreach (Finder::findFiles($mask)->from($dirs) as $file) { |
||
382 | /** @var \SplFileInfo $file */ |
||
383 | if (!preg_match('~^(?P<domain>.*?)\.(?P<locale>[^\.]+)\.(?P<format>[^\.]+)$~', $file->getFilename(), $m)) { |
||
384 | continue; |
||
385 | } |
||
386 | |||
387 | if ($whitelistRegexp && !preg_match($whitelistRegexp, $m['locale']) && $builder->parameters['productionMode']) { |
||
388 | continue; // ignore in production mode, there is no need to pass the ignored resources |
||
389 | } |
||
390 | |||
391 | $this->validateResource($m['format'], $file->getPathname(), $m['locale'], $m['domain']); |
||
392 | $translator->addSetup('addResource', [$m['format'], $file->getPathname(), $m['locale'], $m['domain']]); |
||
393 | $builder->addDependency($file->getPathname()); |
||
394 | } |
||
395 | } |
||
396 | |||
397 | /** |
||
398 | * @param string $format |
||
399 | * @param string $file |
||
400 | * @param string $locale |
||
401 | * @param string $domain |
||
402 | */ |
||
403 | protected function validateResource($format, $file, $locale, $domain) |
||
404 | { |
||
405 | $builder = $this->getContainerBuilder(); |
||
406 | |||
407 | if (!isset($this->loaders[$format])) { |
||
408 | return; |
||
409 | } |
||
410 | |||
411 | try { |
||
412 | $def = $builder->getDefinition($this->loaders[$format]); |
||
413 | $refl = ReflectionClassType::from($def->getEntity() ?: $def->getClass()); |
||
0 ignored issues
–
show
The method
Nette\DI\ServiceDefinition::getClass() has been deprecated with message: Use getType() instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
414 | $method = $refl->getConstructor(); |
||
415 | if ($method !== NULL && $method->getNumberOfRequiredParameters() > 1) { |
||
416 | return; |
||
417 | } |
||
418 | |||
419 | $loader = $refl->newInstance(); |
||
420 | if (!$loader instanceof LoaderInterface) { |
||
421 | return; |
||
422 | } |
||
423 | |||
424 | } catch (\ReflectionException $e) { |
||
425 | return; |
||
426 | } |
||
427 | |||
428 | try { |
||
429 | $loader->load($file, $locale, $domain); |
||
430 | |||
431 | } catch (\Exception $e) { |
||
432 | throw new \Kdyby\Translation\InvalidResourceException(sprintf('Resource %s is not valid and cannot be loaded.', $file), 0, $e); |
||
433 | } |
||
434 | } |
||
435 | |||
436 | public function afterCompile(ClassTypeGenerator $class) |
||
437 | { |
||
438 | $initialize = $class->getMethod('initialize'); |
||
439 | if (class_exists(Debugger::class)) { |
||
440 | $initialize->addBody('?::registerBluescreen();', [new PhpLiteral(Panel::class)]); |
||
441 | } |
||
442 | } |
||
443 | |||
444 | /** |
||
445 | * {@inheritdoc} |
||
446 | */ |
||
447 | public function getConfig(array $defaults = NULL, $expand = TRUE) |
||
0 ignored issues
–
show
|
|||
448 | { |
||
449 | return parent::getConfig($this->defaults) + ['fallback' => ['en_US']]; |
||
450 | } |
||
451 | |||
452 | private function isRegisteredConsoleExtension() |
||
453 | { |
||
454 | foreach ($this->compiler->getExtensions() as $extension) { |
||
455 | if ($extension instanceof ConsoleExtension) { |
||
456 | return TRUE; |
||
457 | } |
||
458 | } |
||
459 | |||
460 | return FALSE; |
||
461 | } |
||
462 | |||
463 | /** |
||
464 | * @param \Nette\Configurator $configurator |
||
465 | */ |
||
466 | public static function register(Configurator $configurator) |
||
467 | { |
||
468 | $configurator->onCompile[] = function ($config, Compiler $compiler) { |
||
469 | $compiler->addExtension('translation', new TranslationExtension()); |
||
470 | }; |
||
471 | } |
||
472 | |||
473 | /** |
||
474 | * @param string|\stdClass $statement |
||
475 | * @return \Nette\DI\Statement[] |
||
476 | */ |
||
477 | protected static function filterArgs($statement) |
||
478 | { |
||
479 | return Helpers::filterArguments([is_string($statement) ? new Statement($statement) : $statement]); |
||
480 | } |
||
481 | |||
482 | /** |
||
483 | * @param string|NULL $class |
||
484 | * @param string $type |
||
485 | * @return bool |
||
486 | */ |
||
487 | private static function isOfType($class, $type) |
||
488 | { |
||
489 | return $class !== NULL && ($class === $type || is_subclass_of($class, $type)); |
||
490 | } |
||
491 | |||
492 | } |
||
493 |
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.