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:
Nicolas Grekas 2019-02-19 19:29:52 +01:00
commit 374c8b0063
23 changed files with 440 additions and 77 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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
*/

View File

@ -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;

View File

@ -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);

View File

@ -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']);

View File

@ -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()
{

View File

@ -124,7 +124,7 @@ class SymfonyQuestionHelperTest extends AbstractQuestionHelperTest
/**
* @expectedException \Symfony\Component\Console\Exception\RuntimeException
* @expectedExceptionMessage Aborted
* @expectedExceptionMessage Aborted.
*/
public function testAskThrowsExceptionOnMissingInput()
{

View File

@ -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([]);
}

View File

@ -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);
}
}
}

View File

@ -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];
}
}
}
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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": {

View File

@ -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";
}

View File

@ -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;
/**

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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;
}
}