Merge branch '4.3' into 4.4

* 4.3:
  [DI] Dont cache classes with missing parents
  [HttpClient] Fix a crash when calling CurlHttpClient::__destruct()
  [Validator] Add the missing translations for the Hebrew (\"he\") locale and fix 2 typos
  [FrameworkBundle][Translation] Invalidate cached catalogues when the scanned directories change
This commit is contained in:
Nicolas Grekas 2019-11-08 09:33:02 +01:00
commit 8aaa8c5fc6
13 changed files with 167 additions and 46 deletions

View File

@ -18,6 +18,7 @@ use Symfony\Component\Config\Resource\DirectoryResource;
use Symfony\Component\Config\Resource\FileExistenceResource;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Translation\Formatter\MessageFormatter;
use Symfony\Component\Translation\Loader\YamlFileLoader;
use Symfony\Component\Translation\MessageCatalogue;
class TranslatorTest extends TestCase
@ -244,6 +245,41 @@ class TranslatorTest extends TestCase
$this->assertEquals(new FileExistenceResource('/tmp/I/sure/hope/this/does/not/exist'), $resources[2]);
}
public function testCachedCatalogueIsReDumpedWhenScannedDirectoriesChange()
{
/** @var Translator $translator */
$translator = $this->getTranslator(new YamlFileLoader(), [
'cache_dir' => $this->tmpDir,
'resource_files' => [
'fr' => [
__DIR__.'/../Fixtures/Resources/translations/messages.fr.yml',
],
],
'scanned_directories' => [
__DIR__.'/../Fixtures/Resources/translations/',
],
], 'yml');
// Cached catalogue is dumped
$this->assertSame('répertoire', $translator->trans('folder', [], 'messages', 'fr'));
$translator = $this->getTranslator(new YamlFileLoader(), [
'cache_dir' => $this->tmpDir,
'resource_files' => [
'fr' => [
__DIR__.'/../Fixtures/Resources/translations/messages.fr.yml',
__DIR__.'/../Fixtures/Resources/translations2/ccc.fr.yml',
],
],
'scanned_directories' => [
__DIR__.'/../Fixtures/Resources/translations/',
__DIR__.'/../Fixtures/Resources/translations2/',
],
], 'yml');
$this->assertSame('bar', $translator->trans('foo', [], 'ccc', 'fr'));
}
protected function getCatalogue($locale, $messages, $resources = [])
{
$catalogue = new MessageCatalogue($locale);

View File

@ -82,7 +82,9 @@ class Translator extends BaseTranslator implements WarmableInterface
$this->resourceFiles = $this->options['resource_files'];
$this->scannedDirectories = $this->options['scanned_directories'];
parent::__construct($defaultLocale, $formatter, $this->options['cache_dir'], $this->options['debug']);
parent::__construct($defaultLocale, $formatter, $this->options['cache_dir'], $this->options['debug'], [
'scanned_directories' => $this->scannedDirectories,
]);
}
/**

View File

@ -147,7 +147,7 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
throw $previous;
}
$e = new \ReflectionException("Class $class not found", 0, $previous);
$e = new \ReflectionException(sprintf('Class "%s" not found while loading "%s".', $class, self::$autoloadedClass), 0, $previous);
if (null !== $previous) {
throw $e;

View File

@ -84,7 +84,7 @@ EOF
public function testBadParentWithNoTimestamp()
{
$this->expectException('ReflectionException');
$this->expectExceptionMessage('Class Symfony\Component\Config\Tests\Fixtures\MissingParent not found');
$this->expectExceptionMessage('Class "Symfony\Component\Config\Tests\Fixtures\MissingParent" not found while loading "Symfony\Component\Config\Tests\Fixtures\BadParent".');
$res = new ClassExistenceResource(BadParent::class, false);
$res->isFresh(0);

View File

@ -343,7 +343,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
return null;
}
$resource = null;
$resource = $classReflector = null;
try {
if (isset($this->classReflectors[$class])) {
@ -358,7 +358,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
if ($throw) {
throw $e;
}
$classReflector = false;
}
if ($this->trackResources) {

View File

@ -156,12 +156,7 @@ abstract class FileLoader extends BaseFileLoader
try {
$r = $this->container->getReflectionClass($class);
} catch (\ReflectionException $e) {
$classes[$class] = sprintf(
'While discovering services from namespace "%s", an error was thrown when processing the class "%s": "%s".',
$namespace,
$class,
$e->getMessage()
);
$classes[$class] = $e->getMessage();
continue;
}
// check to make sure the expected class exists

View File

@ -363,7 +363,7 @@ class AutowirePassTest extends TestCase
$pass->process($container);
$this->fail('AutowirePass should have thrown an exception');
} catch (AutowiringFailedException $e) {
$this->assertSame('Cannot autowire service "a": argument "$r" of method "Symfony\Component\DependencyInjection\Tests\Compiler\BadParentTypeHintedArgument::__construct()" has type "Symfony\Component\DependencyInjection\Tests\Compiler\OptionalServiceClass" but this class is missing a parent class (Class Symfony\Bug\NotExistClass not found).', (string) $e->getMessage());
$this->assertRegExp('{^Cannot autowire service "a": argument "\$r" of method "(Symfony\\\\Component\\\\DependencyInjection\\\\Tests\\\\Compiler\\\\)BadParentTypeHintedArgument::__construct\(\)" has type "\1OptionalServiceClass" but this class is missing a parent class \(Class "?Symfony\\\\Bug\\\\NotExistClass"? not found}', (string) $e->getMessage());
}
}

View File

@ -196,9 +196,9 @@ class FileLoaderTest extends TestCase
$this->assertTrue($container->has(MissingParent::class));
$this->assertSame(
['While discovering services from namespace "Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\", an error was thrown when processing the class "Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\MissingParent": "Class Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\MissingClass not found".'],
$container->getDefinition(MissingParent::class)->getErrors()
$this->assertRegExp(
'{Class "?Symfony\\\\Component\\\\DependencyInjection\\\\Tests\\\\Fixtures\\\\Prototype\\\\BadClasses\\\\MissingClass"? not found}',
$container->getDefinition(MissingParent::class)->getErrors()[0]
);
}

View File

@ -327,15 +327,20 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface
public function __destruct()
{
$this->multi->pushedResponses = [];
if (\defined('CURLMOPT_PUSHFUNCTION')) {
curl_multi_setopt($this->multi->handle, CURLMOPT_PUSHFUNCTION, null);
if (\is_resource($this->multi->handle)) {
if (\defined('CURLMOPT_PUSHFUNCTION')) {
curl_multi_setopt($this->multi->handle, CURLMOPT_PUSHFUNCTION, null);
}
$active = 0;
while (CURLM_CALL_MULTI_PERFORM === curl_multi_exec($this->multi->handle, $active));
}
$active = 0;
while (CURLM_CALL_MULTI_PERFORM === curl_multi_exec($this->multi->handle, $active));
foreach ($this->multi->openHandles as [$ch]) {
curl_setopt($ch, CURLOPT_VERBOSE, false);
if (\is_resource($ch)) {
curl_setopt($ch, CURLOPT_VERBOSE, false);
}
}
}

View File

@ -269,6 +269,22 @@ class TranslatorCacheTest extends TestCase
$translator->trans('foo');
}
public function testCachedCatalogueIsReDumpedWhenCacheVaryChange()
{
$translator = new Translator('a', null, $this->tmpDir, false, []);
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', ['foo' => 'bar'], 'a', 'messages');
// Cached catalogue is dumped
$this->assertSame('bar', $translator->trans('foo', [], 'messages', 'a'));
$translator = new Translator('a', null, $this->tmpDir, false, ['vary']);
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', ['foo' => 'ccc'], 'a', 'messages');
$this->assertSame('ccc', $translator->trans('foo', [], 'messages', 'a'));
}
protected function getCatalogue($locale, $messages, $resources = [])
{
$catalogue = new MessageCatalogue($locale);

View File

@ -71,6 +71,8 @@ class Translator implements LegacyTranslatorInterface, TranslatorInterface, Tran
*/
private $debug;
private $cacheVary;
/**
* @var ConfigCacheFactoryInterface|null
*/
@ -86,7 +88,7 @@ class Translator implements LegacyTranslatorInterface, TranslatorInterface, Tran
/**
* @throws InvalidArgumentException If a locale contains invalid characters
*/
public function __construct(?string $locale, MessageFormatterInterface $formatter = null, string $cacheDir = null, bool $debug = false)
public function __construct(?string $locale, MessageFormatterInterface $formatter = null, string $cacheDir = null, bool $debug = false, array $cacheVary = [])
{
if (null === $locale) {
@trigger_error(sprintf('Passing "null" as the $locale argument to %s() is deprecated since Symfony 4.4.', __METHOD__), E_USER_DEPRECATED);
@ -101,6 +103,7 @@ class Translator implements LegacyTranslatorInterface, TranslatorInterface, Tran
$this->formatter = $formatter;
$this->cacheDir = $cacheDir;
$this->debug = $debug;
$this->cacheVary = $cacheVary;
$this->hasIntlFormatter = $formatter instanceof IntlFormatterInterface;
}
@ -190,7 +193,7 @@ class Translator implements LegacyTranslatorInterface, TranslatorInterface, Tran
$this->assertValidLocale($locale);
}
$this->fallbackLocales = $locales;
$this->fallbackLocales = $this->cacheVary['fallback_locales'] = $locales;
}
/**
@ -412,7 +415,7 @@ EOF
private function getCatalogueCachePath(string $locale): string
{
return $this->cacheDir.'/catalogue.'.$locale.'.'.strtr(substr(base64_encode(hash('sha256', serialize($this->fallbackLocales), true)), 0, 7), '/', '_').'.php';
return $this->cacheDir.'/catalogue.'.$locale.'.'.strtr(substr(base64_encode(hash('sha256', serialize($this->cacheVary), true)), 0, 7), '/', '_').'.php';
}
/**

View File

@ -72,7 +72,7 @@
</trans-unit>
<trans-unit id="18">
<source>This value should be {{ limit }} or less.</source>
<target>הערך צריל להכיל {{ limit }} תווים לכל היותר.</target>
<target>הערך צריך להכיל {{ limit }} תווים לכל היותר.</target>
</trans-unit>
<trans-unit id="19">
<source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
@ -84,7 +84,7 @@
</trans-unit>
<trans-unit id="21">
<source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
<target>הערך קצר מידיץ הוא צריך להכיל {{ limit }} תווים לפחות.|הערך קצר מידיץ הוא צריך להכיל {{ limit }} תווים לפחות.</target>
<target>הערך קצר מידי. הוא צריך להכיל {{ limit }} תווים לפחות.|הערך קצר מידיץ הוא צריך להכיל {{ limit }} תווים לפחות.</target>
</trans-unit>
<trans-unit id="22">
<source>This value should not be blank.</source>
@ -224,83 +224,147 @@
</trans-unit>
<trans-unit id="59">
<source>This is not a valid International Bank Account Number (IBAN).</source>
<target>This is not a valid International Bank Account Number (IBAN).</target>
<target>מספר חשבון בנק בינלאומי אינו חוקי (IBAN).</target>
</trans-unit>
<trans-unit id="60">
<source>This value is not a valid ISBN-10.</source>
<target>This value is not a valid ISBN-10.</target>
<target>הערך אינו ערך ISBN-10 חוקי.</target>
</trans-unit>
<trans-unit id="61">
<source>This value is not a valid ISBN-13.</source>
<target>This value is not a valid ISBN-13.</target>
<target>הערך אינו ערך ISBN-13 חוקי.</target>
</trans-unit>
<trans-unit id="62">
<source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
<target>This value is neither a valid ISBN-10 nor a valid ISBN-13.</target>
<target>הערך אינו ערך ISBN-10 חוקי או ערך ISBN-13 חוקי.</target>
</trans-unit>
<trans-unit id="63">
<source>This value is not a valid ISSN.</source>
<target>This value is not a valid ISSN.</target>
<target>הערך אינו ערך ISSN חוקי.</target>
</trans-unit>
<trans-unit id="64">
<source>This value is not a valid currency.</source>
<target>This value is not a valid currency.</target>
<target>הערך אינו ערך מטבע חוקי.</target>
</trans-unit>
<trans-unit id="65">
<source>This value should be equal to {{ compared_value }}.</source>
<target>This value should be equal to {{ compared_value }}.</target>
<target>הערך חייב להיות שווה ל {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="66">
<source>This value should be greater than {{ compared_value }}.</source>
<target>This value should be greater than {{ compared_value }}.</target>
<target>הערך חייב להיות גדול מ {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="67">
<source>This value should be greater than or equal to {{ compared_value }}.</source>
<target>This value should be greater than or equal to {{ compared_value }}.</target>
<target>הערך חייב להיות גדול או שווה ל {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="68">
<source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
<target>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</target>
<target>הערך חייב להיות זהה ל {{ compared_value_type }} {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="69">
<source>This value should be less than {{ compared_value }}.</source>
<target>This value should be less than {{ compared_value }}.</target>
<target>הערך חייב להיות קטן מ {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="70">
<source>This value should be less than or equal to {{ compared_value }}.</source>
<target>This value should be less than or equal to {{ compared_value }}.</target>
<target>הערך חייב להיות קטן או שווה ל {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="71">
<source>This value should not be equal to {{ compared_value }}.</source>
<target>This value should not be equal to {{ compared_value }}.</target>
<target>הערך חייב להיות לא שווה ל {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="72">
<source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
<target>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</target>
<target>הערך חייב להיות לא זהה ל {{ compared_value_type }} {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="73">
<source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
<target>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</target>
<target>היחס של התמונה הוא גדול מדי ({{ ratio }}). היחס המקסימלי האפשרי הוא {{ max_ratio }}.</target>
</trans-unit>
<trans-unit id="74">
<source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
<target>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</target>
<target>היחס של התמונה הוא קטן מדי ({{ ratio }}). היחס המינימלי האפשרי הוא {{ min_ratio }}.</target>
</trans-unit>
<trans-unit id="75">
<source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
<target>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</target>
<target>התמונה מרובעת ({{ width }}x{{ height }}px). אסורות תמונות מרובעות.</target>
</trans-unit>
<trans-unit id="76">
<source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
<target>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</target>
<target>התמונה היא לרוחב ({{ width }}x{{ height }}px). אסורות תמונות לרוחב.</target>
</trans-unit>
<trans-unit id="77">
<source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
<target>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</target>
<target>התמונה היא לאורך ({{ width }}x{{ height }}px). אסורות תמונות לאורך.</target>
</trans-unit>
<trans-unit id="78">
<source>An empty file is not allowed.</source>
<target>An empty file is not allowed.</target>
<target>אסור קובץ ריק.</target>
</trans-unit>
<trans-unit id="79">
<source>The host could not be resolved.</source>
<target>לא הייתה אפשרות לזהות את המארח.</target>
</trans-unit>
<trans-unit id="80">
<source>This value does not match the expected {{ charset }} charset.</source>
<target>הערך אינו תואם למערך התווים {{ charset }} הצפוי.</target>
</trans-unit>
<trans-unit id="81">
<source>This is not a valid Business Identifier Code (BIC).</source>
<target>קוד זיהוי עסקי אינו חוקי (BIC).</target>
</trans-unit>
<trans-unit id="82">
<source>Error</source>
<target>שגיאה</target>
</trans-unit>
<trans-unit id="83">
<source>This is not a valid UUID.</source>
<target>הערך אינו ערך UUID חוקי.</target>
</trans-unit>
<trans-unit id="84">
<source>This value should be a multiple of {{ compared_value }}.</source>
<target>הערך חייב להיות כפולה של {{ compared_value }}.</target>
</trans-unit>
<trans-unit id="85">
<source>This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.</source>
<target>הקוד זיהוי עסקי (BIC) אינו משוייך ל IBAN {{ iban }}.</target>
</trans-unit>
<trans-unit id="86">
<source>This value should be valid JSON.</source>
<target>הערך אינו ערך JSON תקין.</target>
</trans-unit>
<trans-unit id="87">
<source>This collection should contain only unique elements.</source>
<target>האוסף חייב להכיל רק אלמנטים ייחודיים.</target>
</trans-unit>
<trans-unit id="88">
<source>This value should be positive.</source>
<target>הערך חייב להיות חיובי.</target>
</trans-unit>
<trans-unit id="89">
<source>This value should be either positive or zero.</source>
<target>הערך חייב להיות חיובי או אפס.</target>
</trans-unit>
<trans-unit id="90">
<source>This value should be negative.</source>
<target>הערך חייב להיות שלילי.</target>
</trans-unit>
<trans-unit id="91">
<source>This value should be either negative or zero.</source>
<target>הערך חייב להיות שלילי או אפס.</target>
</trans-unit>
<trans-unit id="92">
<source>This value is not a valid timezone.</source>
<target>הערך אינו אזור זמן תקין.</target>
</trans-unit>
<trans-unit id="93">
<source>This password has been leaked in a data breach, it must not be used. Please use another password.</source>
<target>סיסמא זו הודלפה בהדלפת מידע, אסור להשתמש בה. אנא השתמש בסיסמה אחרת.</target>
</trans-unit>
<trans-unit id="94">
<source>This value should be between {{ min }} and {{ max }}.</source>
<target>הערך חייב להיות בין {{ min }} ו- {{ max }}.</target>
</trans-unit>
</body>
</file>