Skip to content

Commit

Permalink
Merge a754de4 into 0619a64
Browse files Browse the repository at this point in the history
  • Loading branch information
haltuf committed Jun 3, 2019
2 parents 0619a64 + a754de4 commit aa29405
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 92 deletions.
42 changes: 24 additions & 18 deletions composer.json
Expand Up @@ -17,17 +17,17 @@
"issues": "https://github.com/kdyby/translation/issues"
},
"require": {
"php": "^7.1",
"kdyby/strict-objects": "^1.0",
"latte/latte": "^2.4.6@dev",
"nette/caching": "^2.5@dev",
"nette/di": "^2.4.10@dev",
"nette/finder": "^2.4.1@dev",
"nette/http": "^2.4.7@dev",
"nette/neon": "^2.4.2@dev",
"nette/php-generator": "^2.6.3@dev || ^3.0.1@dev",
"php": ">=7.1",
"kdyby/strict-objects": "^2.0",
"latte/latte": "^3.0 >3.0.0-RC1",
"nette/caching": "^3.0",
"nette/di": "^3.0",
"nette/finder": "^3.0",
"nette/http": "^3.0",
"nette/neon": "^3.0",
"nette/php-generator": "^3.0.1@dev",
"nette/reflection": "^2.4.2@dev",
"nette/utils": "^2.4.5@dev || ^3.0@dev",
"nette/utils": "^3.0",
"psr/log": "^1.0",
"symfony/translation": "^3.4 || ^4.0",
"symfony/config": "^3.4 || ^4.0"
Expand All @@ -40,15 +40,15 @@
"symfony/yaml": "If you wanna store translations in YAML format - supports multiline strings."
},
"require-dev": {
"nette/application": "^2.4.9@dev",
"nette/bootstrap": "^2.4.5@dev",
"nette/forms": "^2.4.6@dev",
"tracy/tracy": "^2.4.9@dev",
"nette/application": "^3.0",
"nette/bootstrap": "^3.0",
"nette/forms": "^3.0",
"tracy/tracy": "^3.0",
"kdyby/console": "^2.7.1@dev",
"kdyby/monolog": "^1.4.0@dev",
"kdyby/monolog": "dev-refactor-for-new-nette",
"symfony/yaml": "^3.4 || ^4.0",
"symfony/console": "^3.4 || ^4.0",
"nette/tester": "^2.0",
"nette/tester": "^2.2",
"mockery/mockery": "^1.0"
},
"minimum-stability": "dev",
Expand All @@ -70,7 +70,13 @@
},
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
"dev-master": "3.0-dev"
}
}
},
"repositories": [
{
"type": "git",
"url": "https://github.com/haltuf/Monolog.git"
}
]
}
1 change: 0 additions & 1 deletion phpstan.neon
Expand Up @@ -9,6 +9,5 @@ parameters:
- "#Casting to array something that's already array#"
# Other errors
- '#Access to an undefined property Nette\\Http\\SessionSection\|stdClass::\$locale#'
- '#Argument of an invalid type array\|string\|null supplied for foreach, only iterables are supported#'
- '#Parameter \#1 \$locale of method Symfony\\Component\\Translation\\Translator::setLocale\(\) expects string, string\|null given#'
- '#Array \(array\<Symfony\\Component\\Translation\\Loader\\LoaderInterface\>\) does not accept object#'
11 changes: 9 additions & 2 deletions src/Caching/PhpFileStorage.php
Expand Up @@ -23,13 +23,20 @@ class PhpFileStorage extends \Nette\Caching\Storages\FileStorage implements \Net
*/
public $hint;

/**
* Additional cache structure
*/
private const
FILE = 'file',
HANDLE = 'handle';

/**
* Reads cache data from disk.
*
* @param array $meta
* @return mixed
*/
protected function readData($meta)
protected function readData(array $meta)
{
return [
'file' => $meta[self::FILE],
Expand All @@ -43,7 +50,7 @@ protected function readData($meta)
* @param string $key
* @return string
*/
protected function getCacheFile($key)
protected function getCacheFile(string $key): string
{
$cacheKey = substr_replace(
$key,
Expand Down
11 changes: 10 additions & 1 deletion src/CatalogueCompiler.php
Expand Up @@ -158,7 +158,16 @@ protected function compilePhpCache(Translator $translator, array &$availableCata
*/
protected static function load()
{
return include func_get_arg(0);
/**
* Ugly hack because of BC break in Nette\Caching\Storages due to this commit:
* https://github.com/nette/caching/commit/0e5d0699a82a9a25b3daffd832c04b1521544770
* FileStorage no longer escapes the meta head with <?php, which causes Kdyby/Translator
* to print the cache meta head with every translate() call.
**/
ob_start();
$fnc = include func_get_arg(0);
ob_get_clean();
return $fnc;
}

}
5 changes: 3 additions & 2 deletions src/Console/ExtractCommand.php
Expand Up @@ -11,6 +11,7 @@
namespace Kdyby\Translation\Console;

use Kdyby\Translation\MessageCatalogue;
use Nette\DI\Helpers;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
Expand Down Expand Up @@ -84,7 +85,7 @@ protected function validate(InputInterface $input, OutputInterface $output)
return FALSE;
}

$this->scanDirs = $this->serviceLocator->expand($input->getOption('scan-dir'));
$this->scanDirs = Helpers::expand($input->getOption('scan-dir'), $this->serviceLocator->parameters);
foreach ($this->scanDirs as $dir) {
if (!is_dir($dir)) {
$output->writeln(sprintf('<error>Given --scan-dir "%s" does not exists.</error>', $dir));
Expand All @@ -93,7 +94,7 @@ protected function validate(InputInterface $input, OutputInterface $output)
}
}

$this->outputDir = $this->serviceLocator->expand($input->getOption('output-dir'));
$this->outputDir = Helpers::expand($input->getOption('output-dir'), $this->serviceLocator->parameters);
if (!is_dir($this->outputDir) || !is_writable($this->outputDir)) {
$output->writeln(sprintf('<error>Given --output-dir "%s" does not exists or is not writable.</error>', $this->outputDir));

Expand Down
82 changes: 52 additions & 30 deletions src/DI/TranslationExtension.php
Expand Up @@ -32,12 +32,14 @@
use Nette\Bridges\ApplicationLatte\ILatteFactory;
use Nette\Configurator;
use Nette\DI\Compiler;
use Nette\DI\Definitions\FactoryDefinition;
use Nette\DI\Helpers;
use Nette\DI\ServiceDefinition;
use Nette\DI\Statement;
use Nette\PhpGenerator\ClassType as ClassTypeGenerator;
use Nette\PhpGenerator\PhpLiteral;
use Nette\Reflection\ClassType as ReflectionClassType;
use Nette\Schema\Expect;
use Nette\Schema\Schema;
use Nette\Utils\Callback;
use Nette\Utils\Finder;
use Nette\Utils\Validators;
Expand Down Expand Up @@ -96,20 +98,36 @@ class TranslationExtension extends \Nette\DI\CompilerExtension
*/
private $loaders;

public function __construct()
public function getConfigSchema(): Schema
{
$this->defaults['cache'] = new Statement($this->defaults['cache'], ['%tempDir%/cache']);
return Expect::structure([
'whitelist' => Expect::anyOf(Expect::arrayOf('string'), NULL),
'default' => Expect::string('en'),
'logging' => Expect::anyOf(Expect::string(), Expect::bool()),
'fallback' => Expect::arrayOf('string')->default(['en_US']),
'dirs' => Expect::arrayOf('string')->default(['%appDir%/lang', '%appDir%/locale']),
'cache' => Expect::string(PhpFileStorage::class),
'debugger' => Expect::bool(FALSE),
'resolvers' => Expect::array()->default([
self::RESOLVER_SESSION => FALSE,
self::RESOLVER_REQUEST => TRUE,
self::RESOLVER_HEADER => TRUE,
]),
'loaders' => Expect::array(),
])->castTo('array');
}

public function loadConfiguration()
{
$this->loaders = [];

$builder = $this->getContainerBuilder();
$config = $this->getConfig();
/** @var array $config */
$config = $this->config;
$config['cache'] = new Statement($config['cache'], [dirname(Helpers::expand('%tempDir%/cache', $builder->parameters))]);

$translator = $builder->addDefinition($this->prefix('default'))
->setClass(KdybyTranslator::class, [$this->prefix('@userLocaleResolver')])
->setFactory(KdybyTranslator::class, [$this->prefix('@userLocaleResolver')])
->addSetup('?->setTranslator(?)', [$this->prefix('@userLocaleResolver.param'), '@self'])
->addSetup('setDefaultLocale', [$config['default']])
->addSetup('setLocaleWhitelist', [$config['whitelist']]);
Expand All @@ -118,11 +136,11 @@ public function loadConfiguration()
$translator->addSetup('setFallbackLocales', [$config['fallback']]);

$catalogueCompiler = $builder->addDefinition($this->prefix('catalogueCompiler'))
->setClass(CatalogueCompiler::class, self::filterArgs($config['cache']));
->setFactory(CatalogueCompiler::class, self::filterArgs($config['cache']));

if ($config['debugger'] && interface_exists(IBarPanel::class)) {
$builder->addDefinition($this->prefix('panel'))
->setClass(Panel::class, [dirname($builder->expand('%appDir%'))])
->setFactory(Panel::class, [dirname(Helpers::expand('%appDir%', $builder->parameters))])
->addSetup('setLocaleWhitelist', [$config['whitelist']]);

$translator->addSetup('?->register(?)', [$this->prefix('@panel'), '@self']);
Expand Down Expand Up @@ -210,8 +228,9 @@ protected function loadLocaleResolver(array $config)
}

if ($config['debugger'] && interface_exists(IBarPanel::class)) {
$builder->getDefinition($this->prefix('panel'))
->addSetup('setLocaleResolvers', [array_reverse($resolvers)]);
/** @var \Nette\DI\Definitions\ServiceDefinition $panel */
$panel = $builder->getDefinition($this->prefix('panel'));
$panel->addSetup('setLocaleResolvers', [array_reverse($resolvers)]);
}
}

Expand All @@ -221,7 +240,7 @@ protected function loadConsole(array $config)

Validators::assertField($config, 'dirs', 'list');
$builder->addDefinition($this->prefix('console.extract'))
->setClass(ExtractCommand::class)
->setFactory(ExtractCommand::class)
->addSetup('$defaultOutputDir', [reset($config['dirs'])])
->addTag(ConsoleExtension::TAG_COMMAND, 'latte');
}
Expand Down Expand Up @@ -265,14 +284,16 @@ protected function loadExtractors()
public function beforeCompile()
{
$builder = $this->getContainerBuilder();
$config = $this->getConfig();
/** @var array $config */
$config = $this->config;

$this->beforeCompileLogging($config);

$registerToLatte = function (ServiceDefinition $def) {
$def->addSetup('?->onCompile[] = function($engine) { ?::install($engine->getCompiler()); }', ['@self', new PhpLiteral(TranslateMacros::class)]);
$registerToLatte = function (FactoryDefinition $def) {
$def->getResultDefinition()->addSetup('?->onCompile[] = function($engine) { ?::install($engine->getCompiler()); }', ['@self', new PhpLiteral(TranslateMacros::class)]);

$def->addSetup('addProvider', ['translator', $this->prefix('@default')])
$def->getResultDefinition()
->addSetup('addProvider', ['translator', $this->prefix('@default')])
->addSetup('addFilter', ['translate', [$this->prefix('@helpers'), 'translateFilterAware']]);
};

Expand All @@ -281,7 +302,7 @@ public function beforeCompile()
$latteFactoryService = 'nette.latteFactory';
}

if ($builder->hasDefinition($latteFactoryService) && self::isOfType($builder->getDefinition($latteFactoryService)->getClass(), LatteEngine::class)) {
if ($builder->hasDefinition($latteFactoryService) && self::isOfType($builder->getDefinition($latteFactoryService)->getClass(), ILatteFactory::class)) {
$registerToLatte($builder->getDefinition($latteFactoryService));
}

Expand All @@ -291,11 +312,14 @@ public function beforeCompile()

$applicationService = $builder->getByType(Application::class) ?: 'application';
if ($builder->hasDefinition($applicationService)) {
$builder->getDefinition($applicationService)

/** @var \Nette\DI\Definitions\ServiceDefinition $applicationServiceDefinition */
$applicationServiceDefinition = $builder->getDefinition($applicationService);
$applicationServiceDefinition
->addSetup('$service->onRequest[] = ?', [[$this->prefix('@userLocaleResolver.param'), 'onRequest']]);

if ($config['debugger'] && interface_exists(IBarPanel::class)) {
$builder->getDefinition($applicationService)
$applicationServiceDefinition
->addSetup('$self = $this; $service->onStartup[] = function () use ($self) { $self->getService(?); }', [$this->prefix('default')])
->addSetup('$service->onRequest[] = ?', [[$this->prefix('@panel'), 'onRequest']]);
}
Expand All @@ -305,6 +329,7 @@ public function beforeCompile()
Panel::registerBluescreen();
}

/** @var \Nette\DI\Definitions\ServiceDefinition $extractor */
$extractor = $builder->getDefinition($this->prefix('extractor'));
foreach ($builder->findByTag(self::TAG_EXTRACTOR) as $extractorId => $meta) {
Validators::assert($meta, 'string:2..');
Expand All @@ -314,6 +339,7 @@ public function beforeCompile()
$builder->getDefinition($extractorId)->setAutowired(FALSE);
}

/** @var \Nette\DI\Definitions\ServiceDefinition $writer */
$writer = $builder->getDefinition($this->prefix('writer'));
foreach ($builder->findByTag(self::TAG_DUMPER) as $dumperId => $meta) {
Validators::assert($meta, 'string:2..');
Expand All @@ -330,8 +356,9 @@ public function beforeCompile()
$this->loaders[$meta] = $loaderId;
}

$builder->getDefinition($this->prefix('loader'))
->addSetup('injectServiceIds', [$this->loaders]);
/** @var \Nette\DI\Definitions\ServiceDefinition $loaderDefinition */
$loaderDefinition = $builder->getDefinition($this->prefix('loader'));
$loaderDefinition->addSetup('injectServiceIds', [$this->loaders]);

foreach ($this->compiler->getExtensions() as $extension) {
if (!$extension instanceof ITranslationProvider) {
Expand All @@ -341,8 +368,8 @@ public function beforeCompile()
$config['dirs'] = array_merge($config['dirs'], array_values($extension->getTranslationResources()));
}

$config['dirs'] = array_map(function ($dir) {
return str_replace((DIRECTORY_SEPARATOR === '/') ? '\\' : '/', DIRECTORY_SEPARATOR, $dir);
$config['dirs'] = array_map(function ($dir) use ($builder) {
return str_replace((DIRECTORY_SEPARATOR === '/') ? '\\' : '/', DIRECTORY_SEPARATOR, Helpers::expand($dir, $builder->parameters));
}, $config['dirs']);

$dirs = array_values(array_filter($config['dirs'], Callback::closure('is_dir')));
Expand All @@ -358,6 +385,7 @@ public function beforeCompile()
protected function beforeCompileLogging(array $config)
{
$builder = $this->getContainerBuilder();
/** @var \Nette\DI\Definitions\ServiceDefinition $translator */
$translator = $builder->getDefinition($this->prefix('default'));

if ($config['logging'] === TRUE) {
Expand All @@ -379,9 +407,10 @@ protected function beforeCompileLogging(array $config)
protected function loadResourcesFromDirs($dirs)
{
$builder = $this->getContainerBuilder();
$config = $this->getConfig();
$config = $this->config;

$whitelistRegexp = KdybyTranslator::buildWhitelistRegexp($config['whitelist']);
/** @var \Nette\DI\Definitions\ServiceDefinition $translator */
$translator = $builder->getDefinition($this->prefix('default'));

$mask = array_map(function ($value) {
Expand Down Expand Up @@ -419,6 +448,7 @@ protected function validateResource($format, $file, $locale, $domain)
}

try {
/** @var \Nette\DI\Definitions\ServiceDefinition $def */
$def = $builder->getDefinition($this->loaders[$format]);
$refl = ReflectionClassType::from($def->getEntity() ?: $def->getClass());
$method = $refl->getConstructor();
Expand Down Expand Up @@ -451,14 +481,6 @@ public function afterCompile(ClassTypeGenerator $class)
}
}

/**
* {@inheritdoc}
*/
public function getConfig(array $defaults = NULL, $expand = TRUE)
{
return parent::getConfig($this->defaults) + ['fallback' => ['en_US']];
}

private function isRegisteredConsoleExtension()
{
foreach ($this->compiler->getExtensions() as $extension) {
Expand Down
4 changes: 2 additions & 2 deletions src/Diagnostics/Panel.php
Expand Up @@ -80,7 +80,7 @@ public function __construct($rootDir)
*
* @return string
*/
public function getTab()
public function getTab(): ?string
{
return '<span title="Translation"><img width="16px" height="16px" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90DExAuL9uIsPUAAAQ2SURBVFjD7Ze9bxxVFMV/583skjgOIXEaKCNFAgmQ+ExS8qEUCEHH30BBScG/QM1fEmgoAAkoAigSKKFASElHESEFbGcdez7uoXhvZteW7ewmQjRMsTs7s/Pufeece+4d+P/4jw8ddvHq1avv2b5mm02Lr9Y7/gpQBCFDD5YhgsAoRLhHMtHnRYNAAb3yt92//9y3v3x+MFY6LIGIuGYbKedngzAGsPK5Kb8BGRAu9xiuL+zQ6NphsQ5NYB7YhA1jQCObyOHG/3sMlpM0hmGNcmXh7w9PYL5wfsphbCMPaOR7BipEJahV0FHZvZ2D+1i2qY+gYERCZTGZzLdFkLNIht/v72AHGM5Pa85MqowUc4p81PaPo2CgIa9RxOZ8jowDZm0WXo2oBdttN8ihIABC5dPLI7BIQQA5prEGIeYdbnVtSSpD3WCaCCqpMB8jXSshEBFEROZ9TCTvepC/be63HWA2ppNRoJttP1flvkp5BArmNBQl5zSIMJtNRxJEwHqVOF1XGLHVdSQp+0CpAi1UytJVYHteBQ7cm7AgIKnAH7CWhBDrVRqfud91UERLFNPyihQMwaOUIAI5I9D0PU2Xz9frCjs4WVVUMhJstR2SwaUWgvx7VQqyG2b4IoIoO9xsWipllJ6sK1JB7Exd4whmbUcYlCVcRKrVq0DSqCIVRlPZ4SCqO7MHC0Ey1Epiu+k5XafMvbRaFXCgdBxBOIgw202/TyNBtmuHibJRYba6LjuAsgjjCA3UxwWPCEwanRCJ7bYd/eHspFootdwhdvqeJsyegyaCSVK271US2E9BNp8otbTd9STlB89NJvRFmJREJ4K7e0El2Op6NiY1x7GQlpoawihgq+lIZF2s1xWdu9GAcO6Yp6rcE4OcwGDGR7nhUglYRjL32pbOQdMH61VCzgiFc8eUs+2cTIkuoI2MmH20D9TLzEzuTafgwtp0dNXO5FlhsOvSh23zzBPTBfDm4ny0BBBWAInWpSmVmSDzqrEko0TpBwct9W+xGgKL41hWoMeJB/LQsa/JlOYkVDrmAHlpwnF0M6of2gdIC7vUvDUNk1HMbwVRbmo+jA3tOlaYByTYbRJdiG1E3UFFg2IvLxqm67qR1yg71kLflDXvwhHhsxtbSycw2xWffXiPP+/NmFTiGyX21t9m99RbWDCZ1Fy5dAlJeXyz6aOfz48Mzli6aPTp8rMXz/585UVeun7z4WW418Kll0/w9Pk1/t5JTHdh2otpElMl1PX8eP06fdus9ObhQ2g4VBrVxpvvdl/Ovmgacev2Dnf+2GXnxi6zGw/KMJrNJUXPS6fXmCaNw+d8GNV8KHXgp87xyg83tVQCALPvLlvCVUK/3tnh9t3mkw8+/u3Tx3kNu/H6C7z6063lnLBU4dd98NHzF9Z47eKpE4/7Hngw+LHHzveX3zmAyBv/xsvpP+li/lm3bxkuAAAAAElFTkSuQmCC" />'
. $this->translator->getLocale() . ($this->untranslated ? ' <b>(' . count(array_unique($this->untranslated, SORT_REGULAR)) . ' errors)</b>' : '')
Expand All @@ -92,7 +92,7 @@ public function getTab()
*
* @return string
*/
public function getPanel()
public function getPanel(): ?string
{
$h = 'htmlSpecialChars';

Expand Down
2 changes: 1 addition & 1 deletion src/ITranslator.php
Expand Up @@ -16,6 +16,6 @@
interface ITranslator extends \Nette\Localization\ITranslator
{

// function translate($message, $count = NULL, array $parameters = array(), $domain = NULL, $locale = NULL);
// function translate($message, ...$parameters);

}

0 comments on commit aa29405

Please sign in to comment.