Merge branch '4.2'
* 4.2: [Console] Fix command testing with missing inputs [Validator] Sync no/nb translation files [Translation] Added a script to display the status of translations [Validator] Added missing translations for Norwegian (\"no\") locale #30179 [Security\Guard] bump lowest version of security-core [TwigBridge] Fix test Remove unnecessary ProgressBar stdout writes (fixes flickering) [Validator] improve translations for albanian ("sq") locale [VarDumper] fix serializing Stub instances [Validator] Added missing use statement for UnexpectedTypeException Don't resolve the Deprecation error handler mode until a deprecation is triggered bug #30245 fix lost namespace in eval (fizzka) fix lost namespace in eval [Twig] removed usage of non-namespaced classes added missing dot Update validators.lt.xlf #30172 Add the missing validation translations for the Luxembourgish … [Debug][ErrorHandler] Preserve next error handler
This commit is contained in:
commit
374c8b0063
@ -108,9 +108,7 @@ class DeprecationErrorHandler
|
||||
*/
|
||||
public function handleError($type, $msg, $file, $line, $context = [])
|
||||
{
|
||||
$mode = $this->getMode();
|
||||
|
||||
if ((E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) || self::MODE_DISABLED === $mode) {
|
||||
if ((E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) || self::MODE_DISABLED === $mode = $this->getMode()) {
|
||||
$ErrorHandler = self::$utilPrefix.'ErrorHandler';
|
||||
|
||||
return $ErrorHandler::handleError($type, $msg, $file, $line, $context);
|
||||
|
@ -16,6 +16,7 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
|
||||
use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
|
||||
use Twig\Environment;
|
||||
use Twig\Error\LoaderError;
|
||||
use Twig\Markup;
|
||||
use Twig\Profiler\Dumper\HtmlDumper;
|
||||
use Twig\Profiler\Profile;
|
||||
@ -70,7 +71,7 @@ class TwigDataCollector extends DataCollector implements LateDataCollectorInterf
|
||||
if ($profile->isTemplate()) {
|
||||
try {
|
||||
$template = $this->twig->load($name = $profile->getName());
|
||||
} catch (\Twig_Error_Loader $e) {
|
||||
} catch (LoaderError $e) {
|
||||
$template = null;
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ class TransNodeTest extends TestCase
|
||||
protected function getVariableGetterWithStrictCheck($name)
|
||||
{
|
||||
if (Environment::MAJOR_VERSION >= 2) {
|
||||
return sprintf('(isset($context["%1$s"]) || array_key_exists("%1$s", $context) ? $context["%1$s"] : (function () { throw new %2$s(\'Variable "%1$s" does not exist.\', 0, $this->source); })())', $name, Environment::VERSION_ID >= 20700 ? '\Twig\Error\RuntimeError' : 'Twig_Error_Runtime');
|
||||
return sprintf('(isset($context["%1$s"]) || array_key_exists("%1$s", $context) ? $context["%1$s"] : (function () { throw new %2$s(\'Variable "%1$s" does not exist.\', 0, $this->source); })())', $name, Environment::VERSION_ID >= 20700 ? 'RuntimeError' : 'Twig_Error_Runtime');
|
||||
}
|
||||
|
||||
return sprintf('($context["%s"] ?? $this->getContext($context, "%1$s"))', $name);
|
||||
|
@ -16,7 +16,9 @@ use PHPUnit\Framework\TestCase;
|
||||
// Auto-adapt to PHPUnit 8 that added a `void` return-type to the tearDown method
|
||||
|
||||
if (method_exists(\ReflectionMethod::class, 'hasReturnType') && (new \ReflectionMethod(TestCase::class, 'tearDown'))->hasReturnType()) {
|
||||
eval('
|
||||
eval('
|
||||
namespace Symfony\Bundle\FrameworkBundle\Test;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
@ -399,20 +399,17 @@ final class ProgressBar
|
||||
$lines = floor(Helper::strlen($message) / $this->terminal->getWidth()) + $this->formatLineCount + 1;
|
||||
$this->output->clear($lines);
|
||||
} else {
|
||||
// Move the cursor to the beginning of the line
|
||||
$this->output->write("\x0D");
|
||||
|
||||
// Erase the line
|
||||
$this->output->write("\x1B[2K");
|
||||
|
||||
// Erase previous lines
|
||||
if ($this->formatLineCount > 0) {
|
||||
$this->output->write(str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount));
|
||||
$message = str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount).$message;
|
||||
}
|
||||
|
||||
// Move the cursor to the beginning of the line and erase the line
|
||||
$message = "\x0D\x1B[2K$message";
|
||||
}
|
||||
}
|
||||
} elseif ($this->step > 0) {
|
||||
$this->output->writeln('');
|
||||
$message = PHP_EOL.$message;
|
||||
}
|
||||
|
||||
$this->firstRun = false;
|
||||
|
@ -126,7 +126,7 @@ class QuestionHelper extends Helper
|
||||
if (false === $ret) {
|
||||
$ret = fgets($inputStream, 4096);
|
||||
if (false === $ret) {
|
||||
throw new RuntimeException('Aborted');
|
||||
throw new RuntimeException('Aborted.');
|
||||
}
|
||||
$ret = trim($ret);
|
||||
}
|
||||
@ -213,8 +213,10 @@ class QuestionHelper extends Helper
|
||||
while (!feof($inputStream)) {
|
||||
$c = fread($inputStream, 1);
|
||||
|
||||
// Backspace Character
|
||||
if ("\177" === $c) {
|
||||
// as opposed to fgets(), fread() returns an empty string when the stream content is empty, not false.
|
||||
if (false === $c || ('' === $ret && '' === $c && null === $question->getDefault())) {
|
||||
throw new RuntimeException('Aborted.');
|
||||
} elseif ("\177" === $c) { // Backspace Character
|
||||
if (0 === $numMatches && 0 !== $i) {
|
||||
--$i;
|
||||
// Move cursor backwards
|
||||
@ -339,7 +341,7 @@ class QuestionHelper extends Helper
|
||||
shell_exec(sprintf('stty %s', $sttyMode));
|
||||
|
||||
if (false === $value) {
|
||||
throw new RuntimeException('Aborted');
|
||||
throw new RuntimeException('Aborted.');
|
||||
}
|
||||
|
||||
$value = trim($value);
|
||||
|
@ -60,9 +60,8 @@ class CommandTester
|
||||
}
|
||||
|
||||
$this->input = new ArrayInput($input);
|
||||
if ($this->inputs) {
|
||||
$this->input->setStream(self::createStream($this->inputs));
|
||||
}
|
||||
// Use an in-memory input stream even if no inputs are set so that QuestionHelper::ask() does not rely on the blocking STDIN.
|
||||
$this->input->setStream(self::createStream($this->inputs));
|
||||
|
||||
if (isset($options['interactive'])) {
|
||||
$this->input->setInteractive($options['interactive']);
|
||||
|
@ -549,7 +549,7 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Console\Exception\RuntimeException
|
||||
* @expectedExceptionMessage Aborted
|
||||
* @expectedExceptionMessage Aborted.
|
||||
*/
|
||||
public function testAskThrowsExceptionOnMissingInput()
|
||||
{
|
||||
@ -559,7 +559,17 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Console\Exception\RuntimeException
|
||||
* @expectedExceptionMessage Aborted
|
||||
* @expectedExceptionMessage Aborted.
|
||||
*/
|
||||
public function testAskThrowsExceptionOnMissingInputForChoiceQuestion()
|
||||
{
|
||||
$dialog = new QuestionHelper();
|
||||
$dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream('')), $this->createOutputInterface(), new ChoiceQuestion('Choice', ['a', 'b']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Console\Exception\RuntimeException
|
||||
* @expectedExceptionMessage Aborted.
|
||||
*/
|
||||
public function testAskThrowsExceptionOnMissingInputWithValidator()
|
||||
{
|
||||
|
@ -124,7 +124,7 @@ class SymfonyQuestionHelperTest extends AbstractQuestionHelperTest
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Console\Exception\RuntimeException
|
||||
* @expectedExceptionMessage Aborted
|
||||
* @expectedExceptionMessage Aborted.
|
||||
*/
|
||||
public function testAskThrowsExceptionOnMissingInput()
|
||||
{
|
||||
|
@ -17,6 +17,7 @@ use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Helper\HelperSet;
|
||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||
use Symfony\Component\Console\Output\Output;
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
@ -139,7 +140,7 @@ class CommandTesterTest extends TestCase
|
||||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @expectedMessage Aborted
|
||||
* @expectedExceptionMessage Aborted.
|
||||
*/
|
||||
public function testCommandWithWrongInputsNumber()
|
||||
{
|
||||
@ -153,13 +154,40 @@ class CommandTesterTest extends TestCase
|
||||
$command->setHelperSet(new HelperSet([new QuestionHelper()]));
|
||||
$command->setCode(function ($input, $output) use ($questions, $command) {
|
||||
$helper = $command->getHelper('question');
|
||||
$helper->ask($input, $output, new ChoiceQuestion('choice', ['a', 'b']));
|
||||
$helper->ask($input, $output, new Question($questions[0]));
|
||||
$helper->ask($input, $output, new Question($questions[1]));
|
||||
$helper->ask($input, $output, new Question($questions[2]));
|
||||
});
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$tester->setInputs(['a', 'Bobby', 'Fine']);
|
||||
$tester->execute([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @expectedExceptionMessage Aborted.
|
||||
*/
|
||||
public function testCommandWithQuestionsButNoInputs()
|
||||
{
|
||||
$questions = [
|
||||
'What\'s your name?',
|
||||
'How are you?',
|
||||
'Where do you come from?',
|
||||
];
|
||||
|
||||
$command = new Command('foo');
|
||||
$command->setHelperSet(new HelperSet([new QuestionHelper()]));
|
||||
$command->setCode(function ($input, $output) use ($questions, $command) {
|
||||
$helper = $command->getHelper('question');
|
||||
$helper->ask($input, $output, new ChoiceQuestion('choice', ['a', 'b']));
|
||||
$helper->ask($input, $output, new Question($questions[0]));
|
||||
$helper->ask($input, $output, new Question($questions[1]));
|
||||
$helper->ask($input, $output, new Question($questions[2]));
|
||||
});
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$tester->setInputs(['Bobby', 'Fine']);
|
||||
$tester->execute([]);
|
||||
}
|
||||
|
||||
|
@ -492,6 +492,11 @@ class ErrorHandler
|
||||
if ($this->isRecursive) {
|
||||
$log = 0;
|
||||
} else {
|
||||
if (!\defined('HHVM_VERSION')) {
|
||||
$currentErrorHandler = set_error_handler('var_dump');
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
try {
|
||||
$this->isRecursive = true;
|
||||
$level = ($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG;
|
||||
@ -500,7 +505,7 @@ class ErrorHandler
|
||||
$this->isRecursive = false;
|
||||
|
||||
if (!\defined('HHVM_VERSION')) {
|
||||
set_error_handler([$this, __FUNCTION__]);
|
||||
set_error_handler($currentErrorHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,12 +12,12 @@
|
||||
namespace Symfony\Component\Debug\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
use Psr\Log\NullLogger;
|
||||
use Symfony\Component\Debug\BufferingLogger;
|
||||
use Symfony\Component\Debug\ErrorHandler;
|
||||
use Symfony\Component\Debug\Exception\SilencedErrorContext;
|
||||
use Symfony\Component\Debug\Tests\Fixtures\ErrorHandlerThatUsesThePreviousOne;
|
||||
use Symfony\Component\Debug\Tests\Fixtures\LoggerThatSetAnErrorHandler;
|
||||
|
||||
/**
|
||||
@ -508,26 +508,40 @@ class ErrorHandlerTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider errorHandlerIsNotLostWhenLoggingProvider
|
||||
* @dataProvider errorHandlerWhenLoggingProvider
|
||||
*/
|
||||
public function testErrorHandlerIsNotLostWhenLogging($customErrorHandlerHasBeenPreviouslyDefined, LoggerInterface $logger)
|
||||
public function testErrorHandlerWhenLogging($previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined)
|
||||
{
|
||||
try {
|
||||
if ($customErrorHandlerHasBeenPreviouslyDefined) {
|
||||
if ($previousHandlerWasDefined) {
|
||||
set_error_handler('count');
|
||||
}
|
||||
|
||||
$logger = $loggerSetsAnotherHandler ? new LoggerThatSetAnErrorHandler() : new NullLogger();
|
||||
|
||||
$handler = ErrorHandler::register();
|
||||
$handler->setDefaultLogger($logger);
|
||||
|
||||
if ($nextHandlerIsDefined) {
|
||||
$handler = ErrorHandlerThatUsesThePreviousOne::register();
|
||||
}
|
||||
|
||||
@trigger_error('foo', E_USER_DEPRECATED);
|
||||
@trigger_error('bar', E_USER_DEPRECATED);
|
||||
|
||||
$this->assertSame([$handler, 'handleError'], set_error_handler('var_dump'));
|
||||
|
||||
if ($logger instanceof LoggerThatSetAnErrorHandler) {
|
||||
$this->assertCount(2, $logger->cleanLogs());
|
||||
}
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
if ($customErrorHandlerHasBeenPreviouslyDefined) {
|
||||
if ($previousHandlerWasDefined) {
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
if ($nextHandlerIsDefined) {
|
||||
restore_error_handler();
|
||||
}
|
||||
} finally {
|
||||
@ -536,13 +550,14 @@ class ErrorHandlerTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function errorHandlerIsNotLostWhenLoggingProvider()
|
||||
public function errorHandlerWhenLoggingProvider()
|
||||
{
|
||||
return [
|
||||
[false, new NullLogger()],
|
||||
[true, new NullLogger()],
|
||||
[false, new LoggerThatSetAnErrorHandler()],
|
||||
[true, new LoggerThatSetAnErrorHandler()],
|
||||
];
|
||||
foreach ([false, true] as $previousHandlerWasDefined) {
|
||||
foreach ([false, true] as $loggerSetsAnotherHandler) {
|
||||
foreach ([false, true] as $nextHandlerIsDefined) {
|
||||
yield [$previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Debug\Tests\Fixtures;
|
||||
|
||||
class ErrorHandlerThatUsesThePreviousOne
|
||||
{
|
||||
private static $previous;
|
||||
|
||||
public static function register()
|
||||
{
|
||||
$handler = new static();
|
||||
|
||||
self::$previous = set_error_handler([$handler, 'handleError']);
|
||||
|
||||
return $handler;
|
||||
}
|
||||
|
||||
public function handleError($type, $message, $file, $line, $context)
|
||||
{
|
||||
return \call_user_func(self::$previous, $type, $message, $file, $line, $context);
|
||||
}
|
||||
}
|
@ -2,13 +2,14 @@
|
||||
|
||||
namespace Symfony\Component\Debug\Tests\Fixtures;
|
||||
|
||||
use Psr\Log\AbstractLogger;
|
||||
use Symfony\Component\Debug\BufferingLogger;
|
||||
|
||||
class LoggerThatSetAnErrorHandler extends AbstractLogger
|
||||
class LoggerThatSetAnErrorHandler extends BufferingLogger
|
||||
{
|
||||
public function log($level, $message, array $context = [])
|
||||
{
|
||||
set_error_handler('is_string');
|
||||
parent::log($level, $message, $context);
|
||||
restore_error_handler();
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"symfony/security-core": "~3.4|~4.0",
|
||||
"symfony/security-core": "~3.4.22|^4.2.3",
|
||||
"symfony/security-http": "~3.4|~4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
$usageInstructions = <<<END
|
||||
|
||||
Usage instructions
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
$ cd symfony-code-root-directory/
|
||||
|
||||
# show the translation status of all locales
|
||||
$ php translation-status.php
|
||||
|
||||
# show the translation status of all locales and all their missing translations
|
||||
$ php translation-status.php -v
|
||||
|
||||
# show the status of a single locale
|
||||
$ php translation-status.php fr
|
||||
|
||||
# show the status of a single locale and all its missing translations
|
||||
$ php translation-status.php fr -v
|
||||
|
||||
END;
|
||||
|
||||
$config = [
|
||||
// if TRUE, the full list of missing translations is displayed
|
||||
'verbose_output' => false,
|
||||
// NULL = analyze all locales
|
||||
'locale_to_analyze' => null,
|
||||
// the reference files all the other translations are compared to
|
||||
'original_files' => [
|
||||
'src/Symfony/Component/Form/Resources/translations/validators.en.xlf',
|
||||
'src/Symfony/Component/Security/Core/Resources/translations/security.en.xlf',
|
||||
'src/Symfony/Component/Validator/Resources/translations/validators.en.xlf',
|
||||
],
|
||||
];
|
||||
|
||||
$argc = $_SERVER['argc'];
|
||||
$argv = $_SERVER['argv'];
|
||||
|
||||
if ($argc > 3) {
|
||||
echo str_replace('translation-status.php', $argv[0], $usageInstructions);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
foreach (array_slice($argv, 1) as $argumentOrOption) {
|
||||
if (0 === strpos($argumentOrOption, '-')) {
|
||||
$config['verbose_output'] = true;
|
||||
} else {
|
||||
$config['locale_to_analyze'] = $argumentOrOption;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($config['original_files'] as $originalFilePath) {
|
||||
if (!file_exists($originalFilePath)) {
|
||||
echo sprintf('The following file does not exist. Make sure that you execute this command at the root dir of the Symfony code repository.%s %s', PHP_EOL, $originalFilePath);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
$totalMissingTranslations = 0;
|
||||
|
||||
foreach ($config['original_files'] as $originalFilePath) {
|
||||
$translationFilePaths = findTranslationFiles($originalFilePath, $config['locale_to_analyze']);
|
||||
$translationStatus = calculateTranslationStatus($originalFilePath, $translationFilePaths);
|
||||
|
||||
$totalMissingTranslations += array_sum(array_map(function ($translation) {
|
||||
return \count($translation['missingKeys']);
|
||||
}, array_values($translationStatus)));
|
||||
|
||||
printTranslationStatus($originalFilePath, $translationStatus, $config['verbose_output']);
|
||||
}
|
||||
|
||||
exit($totalMissingTranslations > 0 ? 1 : 0);
|
||||
|
||||
function findTranslationFiles($originalFilePath, $localeToAnalyze)
|
||||
{
|
||||
$translations = [];
|
||||
|
||||
$translationsDir = dirname($originalFilePath);
|
||||
$originalFileName = basename($originalFilePath);
|
||||
$translationFileNamePattern = str_replace('.en.', '.*.', $originalFileName);
|
||||
|
||||
$translationFiles = glob($translationsDir.'/'.$translationFileNamePattern);
|
||||
foreach ($translationFiles as $filePath) {
|
||||
$locale = extractLocaleFromFilePath($filePath);
|
||||
|
||||
if (null !== $localeToAnalyze && $locale !== $localeToAnalyze) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$translations[$locale] = $filePath;
|
||||
}
|
||||
|
||||
return $translations;
|
||||
}
|
||||
|
||||
function calculateTranslationStatus($originalFilePath, $translationFilePaths)
|
||||
{
|
||||
$translationStatus = [];
|
||||
$allTranslationKeys = extractTranslationKeys($originalFilePath);
|
||||
|
||||
foreach ($translationFilePaths as $locale => $translationPath) {
|
||||
$translatedKeys = extractTranslationKeys($translationPath);
|
||||
$missingKeys = array_diff_key($allTranslationKeys, $translatedKeys);
|
||||
|
||||
$translationStatus[$locale] = [
|
||||
'total' => \count($allTranslationKeys),
|
||||
'translated' => \count($translatedKeys),
|
||||
'missingKeys' => $missingKeys,
|
||||
];
|
||||
}
|
||||
|
||||
return $translationStatus;
|
||||
}
|
||||
|
||||
function printTranslationStatus($originalFilePath, $translationStatus, $verboseOutput)
|
||||
{
|
||||
printTitle($originalFilePath);
|
||||
printTable($translationStatus, $verboseOutput);
|
||||
echo PHP_EOL.PHP_EOL;
|
||||
}
|
||||
|
||||
function extractLocaleFromFilePath($filePath)
|
||||
{
|
||||
$parts = explode('.', $filePath);
|
||||
|
||||
return $parts[count($parts) - 2];
|
||||
}
|
||||
|
||||
function extractTranslationKeys($filePath)
|
||||
{
|
||||
$translationKeys = [];
|
||||
$contents = new \SimpleXMLElement(file_get_contents($filePath));
|
||||
|
||||
foreach ($contents->file->body->{'trans-unit'} as $translationKey) {
|
||||
$translationId = (string) $translationKey['id'];
|
||||
$translationKey = (string) $translationKey->source;
|
||||
|
||||
$translationKeys[$translationId] = $translationKey;
|
||||
}
|
||||
|
||||
return $translationKeys;
|
||||
}
|
||||
|
||||
function printTitle($title)
|
||||
{
|
||||
echo $title.PHP_EOL;
|
||||
echo str_repeat('=', strlen($title)).PHP_EOL.PHP_EOL;
|
||||
}
|
||||
|
||||
function printTable($translations, $verboseOutput)
|
||||
{
|
||||
$longestLocaleNameLength = max(array_map('strlen', array_keys($translations)));
|
||||
|
||||
foreach ($translations as $locale => $translation) {
|
||||
$isTranslationCompleted = $translation['translated'] === $translation['total'];
|
||||
if ($isTranslationCompleted) {
|
||||
textColorGreen();
|
||||
}
|
||||
|
||||
echo sprintf('| Locale: %-'.$longestLocaleNameLength.'s | Translated: %d/%d', $locale, $translation['translated'], $translation['total']).PHP_EOL;
|
||||
|
||||
textColorNormal();
|
||||
|
||||
if (true === $verboseOutput && \count($translation['missingKeys']) > 0) {
|
||||
echo str_repeat('-', 80).PHP_EOL;
|
||||
echo '| Missing Translations:'.PHP_EOL;
|
||||
|
||||
foreach ($translation['missingKeys'] as $id => $content) {
|
||||
echo sprintf('| (id=%s) %s', $id, $content).PHP_EOL;
|
||||
}
|
||||
|
||||
echo str_repeat('-', 80).PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function textColorGreen()
|
||||
{
|
||||
echo "\033[32m";
|
||||
}
|
||||
|
||||
function textColorNormal()
|
||||
{
|
||||
echo "\033[0m";
|
||||
}
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedValueException;
|
||||
|
||||
/**
|
||||
|
@ -322,6 +322,18 @@
|
||||
<source>This is not a valid UUID.</source>
|
||||
<target>Dëst ass keng gëlteg UUID.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="84">
|
||||
<source>This value should be a multiple of {{ compared_value }}.</source>
|
||||
<target>Dëse Wäert sollt e puer vun {{ compared_value }} sinn.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="85">
|
||||
<source>This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.</source>
|
||||
<target>Dëse "Business Identifier Code" (BIC) ass net mat IBAN verbonnen {{ iban }}.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="86">
|
||||
<source>This value should be valid JSON.</source>
|
||||
<target>Dëse Wäert sollt gëlteg JSON.</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -302,10 +302,38 @@
|
||||
<source>An empty file is not allowed.</source>
|
||||
<target>Failas negali būti tuščias.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="79">
|
||||
<source>The host could not be resolved.</source>
|
||||
<target>Serveris nepasiekiamas.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="80">
|
||||
<source>This value does not match the expected {{ charset }} charset.</source>
|
||||
<target>Ši reikšmė neatitinka {{ charset }} koduotės.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="81">
|
||||
<source>This is not a valid Business Identifier Code (BIC).</source>
|
||||
<target>Bendrovės Identifikavimo Kodas (BIC) nėra tinkamas.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="82">
|
||||
<source>Error</source>
|
||||
<target>Klaida</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="83">
|
||||
<source>This is not a valid UUID.</source>
|
||||
<target>Ši reikšmė nėra tinkamas UUID.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="84">
|
||||
<source>This value should be a multiple of {{ compared_value }}.</source>
|
||||
<target>Ši reikšmė turi būti skaičiaus {{ compared_value }} kartotinis.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="85">
|
||||
<source>This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.</source>
|
||||
<target>Šis bendrovės identifikavimo kodas (BIC) nesusijęs su IBAN {{ iban }}.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="86">
|
||||
<source>This value should be valid JSON.</source>
|
||||
<target>Ši reikšmė turi būti tinkamo JSON formato.</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -314,6 +314,26 @@
|
||||
<source>This is not a valid Business Identifier Code (BIC).</source>
|
||||
<target>Dette er ikke en gyldig BIC.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="82">
|
||||
<source>Error</source>
|
||||
<target>Feil</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="83">
|
||||
<source>This is not a valid UUID.</source>
|
||||
<target>Dette er ikke en gyldig UUID.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="84">
|
||||
<source>This value should be a multiple of {{ compared_value }}.</source>
|
||||
<target>Verdien skal være flertall av {{ compared_value }}.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="85">
|
||||
<source>This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.</source>
|
||||
<target>Business Identifier Code (BIC) er ikke tilknyttet en IBAN {{ iban }}.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="86">
|
||||
<source>This value should be valid JSON.</source>
|
||||
<target>Verdien er ikke gyldig JSON.</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -314,6 +314,26 @@
|
||||
<source>This is not a valid Business Identifier Code (BIC).</source>
|
||||
<target>Dette er ikke en gyldig BIC.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="82">
|
||||
<source>Error</source>
|
||||
<target>Feil</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="83">
|
||||
<source>This is not a valid UUID.</source>
|
||||
<target>Dette er ikke en gyldig UUID.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="84">
|
||||
<source>This value should be a multiple of {{ compared_value }}.</source>
|
||||
<target>Verdien skal være flertall av {{ compared_value }}.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="85">
|
||||
<source>This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.</source>
|
||||
<target>Business Identifier Code (BIC) er ikke tilknyttet en IBAN {{ iban }}.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="86">
|
||||
<source>This value should be valid JSON.</source>
|
||||
<target>Verdien er ikke gyldig JSON.</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -24,15 +24,15 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="6">
|
||||
<source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
|
||||
<target>Duhet të zgjedhni së paku {{ limit }} alternativa.|Duhet të zgjedhni së paku {{ limit }} alternativa.</target>
|
||||
<target>Duhet të zgjedhni së paku {{ limit }} alternativë.|Duhet të zgjedhni së paku {{ limit }} alternativa.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="7">
|
||||
<source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
|
||||
<target>Duhet të zgjedhni më së shumti {{ limit }} alternativa.|Duhet të zgjedhni më së shumti {{ limit }} alternativa.</target>
|
||||
<target>Duhet të zgjedhni më së shumti {{ limit }} alternativë.|Duhet të zgjedhni më së shumti {{ limit }} alternativa.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="8">
|
||||
<source>One or more of the given values is invalid.</source>
|
||||
<target>Një apo më shumë nga vlerat e dhëna nuk janë të sakta.</target>
|
||||
<target>Një apo më shumë nga vlerat e dhëna janë të pavlefshme.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="9">
|
||||
<source>This field was not expected.</source>
|
||||
@ -40,7 +40,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="10">
|
||||
<source>This field is missing.</source>
|
||||
<target>Kjo fushë është zhdukur.</target>
|
||||
<target>Kjo fushë mungon.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="11">
|
||||
<source>This value is not a valid date.</source>
|
||||
@ -52,7 +52,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="13">
|
||||
<source>This value is not a valid email address.</source>
|
||||
<target>Kjo vlerë nuk është e-mail adresë e vlefshme.</target>
|
||||
<target>Kjo vlerë nuk është adresë email-i e vlefshme.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="14">
|
||||
<source>The file could not be found.</source>
|
||||
@ -64,11 +64,11 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="16">
|
||||
<source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
|
||||
<target>File është shumë i madh ({{ size }} {{ suffix }}). Madhësia më e madhe e lejuar është {{ limit }} {{ suffix }}.</target>
|
||||
<target>File është shumë i madh ({{ size }} {{ suffix }}). Madhësia maksimale e lejuar është {{ limit }} {{ suffix }}.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="17">
|
||||
<source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
|
||||
<target>Lloji mime i files nuk është i vlefshëm ({{ type }}). Llojet mime të lejuara janë {{ types }}.</target>
|
||||
<target>Lloji mime i file-it është i pavlefshëm ({{ type }}). Llojet mime të lejuara janë {{ types }}.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="18">
|
||||
<source>This value should be {{ limit }} or less.</source>
|
||||
@ -76,7 +76,7 @@
|
||||
</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>
|
||||
<target>Kjo vlerë është shumë e gjatë. Duhet t'i ketë {{ limit }} ose më pak karaktere.|Kjo vlerë është shumë e gjatë. Duhet t'i ketë {{ limit }} ose më pak karaktere.</target>
|
||||
<target>Kjo vlerë është shumë e gjatë. Duhet të përmbaj {{ limit }} karakter ose më pak.|Kjo vlerë është shumë e gjatë. Duhet të përmbaj {{ limit }} karaktere ose më pak.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="20">
|
||||
<source>This value should be {{ limit }} or more.</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>Kjo vlerë është shumë e shkurtër. Duhet t'i ketë {{ limit }} ose më shumë karaktere.|Kjo vlerë është shumë e shkurtër. Duhet t'i ketë {{ limit }} ose më shumë karaktere.</target>
|
||||
<target>Kjo vlerë është shumë e shkurtër. Duhet të përmbaj {{ limit }} karakter ose më shumë.|Kjo vlerë është shumë e shkurtër. Duhet të përmbaj {{ limit }} karaktere ose më shumë.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="22">
|
||||
<source>This value should not be blank.</source>
|
||||
@ -136,7 +136,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="37">
|
||||
<source>This is not a valid IP address.</source>
|
||||
<target>Kjo vlerë nuk është IP adresë e vlefshme.</target>
|
||||
<target>Kjo adresë IP nuk është e vlefshme.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="38">
|
||||
<source>This value is not a valid language.</source>
|
||||
@ -144,7 +144,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="39">
|
||||
<source>This value is not a valid locale.</source>
|
||||
<target>Kjo vlerë nuk është përcaktim rajonal i vlefshëm.</target>
|
||||
<target>Kjo vlerë nuk është nje locale i vlefshëm.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="40">
|
||||
<source>This value is not a valid country.</source>
|
||||
@ -156,7 +156,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="42">
|
||||
<source>The size of the image could not be detected.</source>
|
||||
<target>Madhësia e këtij imazhi nuk mund të zbulohet.</target>
|
||||
<target>Madhësia e imazhit nuk mund të zbulohet.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="43">
|
||||
<source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
|
||||
@ -180,7 +180,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="48">
|
||||
<source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
|
||||
<target>Kjo vlerë duhet të ketë saktësisht {{ limit }} karaktere.|Kjo vlerë duhet të ketë saktësisht {{ limit }} karaktere.</target>
|
||||
<target>Kjo vlerë duhet të ketë saktësisht {{ limit }} karakter.|Kjo vlerë duhet të ketë saktësisht {{ limit }} karaktere.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="49">
|
||||
<source>The file was only partially uploaded.</source>
|
||||
@ -200,27 +200,27 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="53">
|
||||
<source>A PHP extension caused the upload to fail.</source>
|
||||
<target>Një ekstenzion i PHP-së bëri të dështojë ngarkimi i files.</target>
|
||||
<target>Një ekstension i PHP-së shkaktoi dështimin e ngarkimit.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="54">
|
||||
<source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
|
||||
<target>Ky kolekcion duhet të përmbajë {{ limit }} ose më shumë elemente.|Ky kolekcion duhet të përmbajë {{ limit }} ose më shumë elemente.</target>
|
||||
<target>Ky koleksion duhet të përmbajë {{ limit }} element ose më shumë.|Ky koleksion duhet të përmbajë {{ limit }} elemente ose më shumë.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="55">
|
||||
<source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
|
||||
<target>Ky kolekcion duhet të përmbajë {{ limit }} ose më pak elemente.|Ky kolekcion duhet të përmbajë {{ limit }} ose më pak elemente.</target>
|
||||
<target>Ky koleksion duhet të përmbajë {{ limit }} element ose më pak.|Ky koleksion duhet të përmbajë {{ limit }} elemente ose më pak.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="56">
|
||||
<source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
|
||||
<target>Ky kolekcion duhet të përmbajë saktësisht {{ limit }} elemente.|Ky kolekcion duhet të përmbajë saktësisht {{ limit }} elemente.</target>
|
||||
<target>Ky koleksion duhet të përmbajë saktësisht {{ limit }} element.|Ky koleksion duhet të përmbajë saktësisht {{ limit }} elemente.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="57">
|
||||
<source>Invalid card number.</source>
|
||||
<target>Numër kartele i pavlefshëm.</target>
|
||||
<target>Numër karte i pavlefshëm.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="58">
|
||||
<source>Unsupported card type or invalid card number.</source>
|
||||
<target>Lloj kartele i pambështetur ose numër kartele i pavlefshëm.</target>
|
||||
<target>Lloj karte i papranuar ose numër karte i pavlefshëm.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="59">
|
||||
<source>This is not a valid International Bank Account Number (IBAN).</source>
|
||||
@ -292,11 +292,11 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="76">
|
||||
<source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
|
||||
<target>Imazhi është i orientuar nga landscape ({{ width }}x{{ height }}px). Imazhet e orientuara nga landscape nuk lejohen.</target>
|
||||
<target>Imazhi është i orientuar horizontalisht ({{ width }}x{{ height }}px). Imazhet e orientuara horizontalisht nuk lejohen.</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>Imazhi është portret i orientuar ({{ width }}x{{ height }}px). Imazhet orientuese të portretit nuk lejohen.</target>
|
||||
<target>Imazhi është i orientuar vertikalisht ({{ width }}x{{ height }}px). Imazhet orientuara vertikalisht nuk lejohen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="78">
|
||||
<source>An empty file is not allowed.</source>
|
||||
@ -304,15 +304,15 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="79">
|
||||
<source>The host could not be resolved.</source>
|
||||
<target>Probleme me Host</target>
|
||||
<target>Host-i nuk mund te zbulohej.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="80">
|
||||
<source>This value does not match the expected {{ charset }} charset.</source>
|
||||
<target>Kjo vlerë nuk përputhet me karakteret {{ charset }} e pritura.</target>
|
||||
<target>Kjo vlerë nuk përputhet me kodifikimin e karaktereve {{ charset }} që pritej.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="81">
|
||||
<source>This is not a valid Business Identifier Code (BIC).</source>
|
||||
<target>Ky nuk është një Kod i Identifikueshëm i Biznesit (BIC).</target>
|
||||
<target>Ky nuk është një Kod Identifikues i Biznesit (BIC) i vleflshem.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="82">
|
||||
<source>Error</source>
|
||||
@ -320,7 +320,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="83">
|
||||
<source>This is not a valid UUID.</source>
|
||||
<target>Kjo nuk është një UUID e vlefshme.</target>
|
||||
<target>Ky nuk është një UUID i vlefshëm.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="84">
|
||||
<source>This value should be a multiple of {{ compared_value }}.</source>
|
||||
|
@ -39,22 +39,29 @@ class Stub
|
||||
public $position = 0;
|
||||
public $attr = [];
|
||||
|
||||
private static $defaultProperties = [];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
$this->serialized = [$this->class, $this->position, $this->cut, $this->type, $this->value, $this->handle, $this->refCount, $this->attr];
|
||||
$properties = [];
|
||||
|
||||
return ['serialized'];
|
||||
}
|
||||
if (!isset(self::$defaultProperties[$c = \get_class($this)])) {
|
||||
self::$defaultProperties[$c] = get_class_vars($c);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
list($this->class, $this->position, $this->cut, $this->type, $this->value, $this->handle, $this->refCount, $this->attr) = $this->serialized;
|
||||
unset($this->serialized);
|
||||
foreach ((new \ReflectionClass($c))->getStaticProperties() as $k => $v) {
|
||||
unset(self::$defaultProperties[$c][$k]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (self::$defaultProperties[$c] as $k => $v) {
|
||||
if ($this->$k !== $v) {
|
||||
$properties[] = $k;
|
||||
}
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user