diff --git a/.phpstorm.meta.php b/.phpstorm.meta.php new file mode 100644 index 0000000000..d7457b481a --- /dev/null +++ b/.phpstorm.meta.php @@ -0,0 +1,16 @@ + '@', + ])); + override(\MetaModel::GetObject(0), map([ + '' => '@', + ])); +} diff --git a/application/datamodel.application.xml b/application/datamodel.application.xml index e20a1a95b5..206fbe40a7 100644 --- a/application/datamodel.application.xml +++ b/application/datamodel.application.xml @@ -849,5 +849,221 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att + + + Dashlet + + + + + + + + + + + + + + + + + {{query.selected_class}} + + + + + + + + + + bars + + + + + + + + + + + + + + + + + + + + + {{query.selected_class}} + + + + + {{aggregation_function.value != 'count'}} + + + + + {{query.selected_class}} + numeric + + + + + + + + + + + + + + + + + + {{order_by.value = 'function'}} + + + + + + + + + + + + + + + + + + desc + + + + + Dashlet + + + + + bizmodel + + + + + + Dashlet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{query.selected_class}} + enum + + + + + + + + + + {{query.selected_class}} + {{group_by.value}} + + + + + + + Dashlet + + + + + + + + + + + + + Dashlet + + + + + + + + + + + + + + + + + true + + + + false + + + + + + + Dashlet + + + + + + + + + + + diff --git a/application/utils.inc.php b/application/utils.inc.php index ea226e9958..7eea304916 100644 --- a/application/utils.inc.php +++ b/application/utils.inc.php @@ -1900,6 +1900,12 @@ public static function DoPostRequest($sUrl, $aData, $sOptionnalHeaders = null, & return $response; } + public static function QuoteForPHP(string $sValue): string + { + $sEscaped = str_replace(['\\', "'"], ['\\\\', "\\'"], $sValue); + return "'$sEscaped'"; + } + /** * Get a standard list of character sets * diff --git a/composer.json b/composer.json index fba023a2f9..53ddd14f03 100644 --- a/composer.json +++ b/composer.json @@ -31,6 +31,7 @@ "symfony/mailer": "^6.4", "symfony/security-csrf": "^6.4", "symfony/twig-bundle": "~6.4.0", + "symfony/validator" : "^6.4", "symfony/yaml": "~6.4.0", "tecnickcom/tcpdf": "^6.6.0", "thenetworg/oauth2-azure": "^2.0" diff --git a/composer.lock b/composer.lock index 6262f6cf6f..19705628ac 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "26fa7aa920057d080bcc0948bf052fda", + "content-hash" : "3e627286597661542dd598499c2bcc36", "packages": [ { "name": "apereo/phpcas", @@ -4984,6 +4984,107 @@ "time": "2025-07-10T08:14:14+00:00" }, { + "name" : "symfony/validator", + "version" : "v6.4.29", + "source" : { + "type" : "git", + "url" : "https://github.com/symfony/validator.git", + "reference" : "99df8a769e64e399f510166141ea74f450e8dd1d" + }, + "dist" : { + "type" : "zip", + "url" : "https://api.github.com/repos/symfony/validator/zipball/99df8a769e64e399f510166141ea74f450e8dd1d", + "reference" : "99df8a769e64e399f510166141ea74f450e8dd1d", + "shasum" : "" + }, + "require" : { + "php" : ">=8.1", + "symfony/deprecation-contracts" : "^2.5|^3", + "symfony/polyfill-ctype" : "~1.8", + "symfony/polyfill-mbstring" : "~1.0", + "symfony/polyfill-php83" : "^1.27", + "symfony/translation-contracts" : "^2.5|^3" + }, + "conflict" : { + "doctrine/annotations" : "<1.13", + "doctrine/lexer" : "<1.1", + "symfony/dependency-injection" : "<5.4", + "symfony/expression-language" : "<5.4", + "symfony/http-kernel" : "<5.4", + "symfony/intl" : "<5.4", + "symfony/property-info" : "<5.4", + "symfony/translation" : "<5.4.35|>=6.0,<6.3.12|>=6.4,<6.4.3|>=7.0,<7.0.3", + "symfony/yaml" : "<5.4" + }, + "require-dev" : { + "doctrine/annotations" : "^1.13|^2", + "egulias/email-validator" : "^2.1.10|^3|^4", + "symfony/cache" : "^5.4|^6.0|^7.0", + "symfony/config" : "^5.4|^6.0|^7.0", + "symfony/console" : "^5.4|^6.0|^7.0", + "symfony/dependency-injection" : "^5.4|^6.0|^7.0", + "symfony/expression-language" : "^5.4|^6.0|^7.0", + "symfony/finder" : "^5.4|^6.0|^7.0", + "symfony/http-client" : "^5.4|^6.0|^7.0", + "symfony/http-foundation" : "^5.4|^6.0|^7.0", + "symfony/http-kernel" : "^5.4|^6.0|^7.0", + "symfony/intl" : "^5.4|^6.0|^7.0", + "symfony/mime" : "^5.4|^6.0|^7.0", + "symfony/property-access" : "^5.4|^6.0|^7.0", + "symfony/property-info" : "^5.4|^6.0|^7.0", + "symfony/translation" : "^5.4.35|~6.3.12|^6.4.3|^7.0.3", + "symfony/yaml" : "^5.4|^6.0|^7.0" + }, + "type" : "library", + "autoload" : { + "psr-4" : { + "Symfony\\Component\\Validator\\" : "" + }, + "exclude-from-classmap" : [ + "/Tests/", + "/Resources/bin/" + ] + }, + "notification-url" : "https://packagist.org/downloads/", + "license" : [ + "MIT" + ], + "authors" : [ + { + "name" : "Fabien Potencier", + "email" : "fabien@symfony.com" + }, + { + "name" : "Symfony Community", + "homepage" : "https://symfony.com/contributors" + } + ], + "description" : "Provides tools to validate values", + "homepage" : "https://symfony.com", + "support" : { + "source" : "https://github.com/symfony/validator/tree/v6.4.29" + }, + "funding" : [ + { + "url" : "https://symfony.com/sponsor", + "type" : "custom" + }, + { + "url" : "https://github.com/fabpot", + "type" : "github" + }, + { + "url" : "https://github.com/nicolas-grekas", + "type" : "github" + }, + { + "url" : "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type" : "tidelift" + } + ], + "time" : "2025-11-06T20:26:06+00:00" + }, + { "name": "symfony/var-dumper", "version": "v6.4.26", "source": { diff --git a/core/designdocument.class.inc.php b/core/designdocument.class.inc.php index 2e324f38b5..e6fdc0162b 100644 --- a/core/designdocument.class.inc.php +++ b/core/designdocument.class.inc.php @@ -41,7 +41,7 @@ /** * Class \Combodo\iTop\DesignDocument * - * A design document is the DOM tree that modelize behaviors. One of its + * A design document is the DOM tree that models behaviors. One of its * characteristics is that it can be altered by the mean of the same kind of document. * */ diff --git a/core/log.class.inc.php b/core/log.class.inc.php index b79703ebff..0e4962c432 100644 --- a/core/log.class.inc.php +++ b/core/log.class.inc.php @@ -691,6 +691,28 @@ public static function MockStaticObjects($oFileLog, $oMetaModelConfig = null) static::$m_oMockMetaModelConfig = $oMetaModelConfig; } + public static function Exception(string $sMessage, throwable $oException, string $sChannel = null, array $aContext = []): void + { + $aErrorLogs = []; + $aErrorLogs[] = static::PrepareErrorLog($sMessage, $oException, $aContext); + $oException = $oException->getPrevious(); + while ($oException !== null) { + $aErrorLogs[] = static::PrepareErrorLog($oException->getMessage(), $oException, $aContext, true); + $oException = $oException->getPrevious(); + } + $aErrorLogs = array_reverse($aErrorLogs); + foreach ($aErrorLogs as $aErrorLog) { + static::Error($aErrorLog['message'], $sChannel, $aErrorLog['context']); + } + } + + private static function PrepareErrorLog(string $sMessage, throwable $oException, array $aContext, bool $isPrevious = false): array + { + $aContext['Error Message'] = $oException->getMessage(); + $aContext['Stack Trace'] = $oException->getTraceAsString(); + return ['message' => ($isPrevious ? "Previous " : '')."Exception: $sMessage", 'context' => $aContext]; + } + public static function Error($sMessage, $sChannel = null, $aContext = []) { static::Log(self::LEVEL_ERROR, $sMessage, $sChannel, $aContext); diff --git a/core/modelreflection.class.inc.php b/core/modelreflection.class.inc.php index 3e10c0bdd4..2103e00812 100644 --- a/core/modelreflection.class.inc.php +++ b/core/modelreflection.class.inc.php @@ -55,6 +55,11 @@ abstract public function GetParentClass($sClass); abstract public function GetFiltersList($sClass); abstract public function IsValidFilterCode($sClass, $sFilterCode); + /** + * @since 3.3.0 + */ + abstract public function IsAbstract($sClass): bool; + /** * @param string $sOQL * @@ -148,7 +153,7 @@ public function ListAttributes($sClass, $sScope = null) $sAttributeClass = get_class($oAttDef); if ($aScope != null) { foreach ($aScope as $sScopeClass) { - if (($sAttributeClass == $sScopeClass) || is_subclass_of($sAttributeClass, $sScopeClass)) { + if (is_a($sAttributeClass, $sScopeClass, true)) { $aAttributes[$sAttCode] = $sAttributeClass; break; } @@ -230,6 +235,11 @@ public function IsValidFilterCode($sClass, $sFilterCode) return MetaModel::IsValidFilterCode($sClass, $sFilterCode); } + public function IsAbstract($sClass): bool + { + return MetaModel::IsAbstract($sClass); + } + public function GetQuery($sOQL) { return new QueryReflectionRuntime($sOQL, $this); diff --git a/core/oql/expression.class.inc.php b/core/oql/expression.class.inc.php index ef5f829469..0b017791aa 100644 --- a/core/oql/expression.class.inc.php +++ b/core/oql/expression.class.inc.php @@ -2103,12 +2103,18 @@ public function RenderExpression($bForSQL = false, &$aArgs = null, $bRetrofitPar /** * Evaluate the value of the expression + * * @param array $aArgs - * @throws \Exception if terms cannot be evaluated as scalars -*/ + * + * @return mixed + * @throws \MissingQueryArgument + */ public function Evaluate(array $aArgs) { - throw new Exception('not implemented yet'); + if (!isset($aArgs[$this->m_sName])) { + throw new MissingQueryArgument('Missing variable expression argument', array('expecting'=>$this->m_sName)); + } + return $aArgs[$this->m_sName]; } /** diff --git a/core/oql/oqlexception.class.inc.php b/core/oql/oqlexception.class.inc.php index 4df947e4b5..e940d9dbe3 100644 --- a/core/oql/oqlexception.class.inc.php +++ b/core/oql/oqlexception.class.inc.php @@ -72,9 +72,15 @@ public function __construct($sIssue, $sInput, $iLine, $iCol, $sUnexpected, $aExp } else { - $sExpectations = '{'.implode(', ', $this->m_aExpecting).'}'; + $sMessage = "$sIssue - found '{$this->m_sUnexpected}' at $iCol in '$sInput'"; + if (count($this->m_aExpecting) < 30) { + $sExpectations = '{'.implode(', ', $this->m_aExpecting).'}'; + $sMessage .= ', expecting '.json_encode($sExpectations); + } $sSuggest = self::FindClosestString($this->m_sUnexpected, $this->m_aExpecting); - $sMessage = "$sIssue - found '{$this->m_sUnexpected}' at $iCol in '$sInput', expecting $sExpectations, I would suggest to use '$sSuggest'"; + if (strlen($sSuggest) > 0) { + $sMessage .= ", I would suggest to use ".json_encode($sSuggest); + } } // make sure everything is assigned properly @@ -155,5 +161,3 @@ static public function FindClosestString($sInput, $aDictionary) return $sRet; } } - -?> diff --git a/core/oql/oqlquery.class.inc.php b/core/oql/oqlquery.class.inc.php index 24889d3560..f29899ff48 100644 --- a/core/oql/oqlquery.class.inc.php +++ b/core/oql/oqlquery.class.inc.php @@ -57,15 +57,15 @@ public function GetPos() { return $this->m_iPos; } - + public function __toString() { return $this->m_sValue; - } + } } /** - * + * * Store hexadecimal values as strings so that we can support 64-bit values * */ @@ -77,12 +77,12 @@ public function __construct($sValue) { $this->m_sValue = $sValue; } - + public function __toString() { return $this->m_sValue; } - + } class OqlJoinSpec @@ -109,6 +109,7 @@ public function GetClass() { return $this->m_oClass->GetValue(); } + public function GetClassAlias() { return $this->m_oClassAlias->GetValue(); @@ -118,6 +119,7 @@ public function GetClassDetails() { return $this->m_oClass; } + public function GetClassAliasDetails() { return $this->m_oClassAlias; @@ -127,10 +129,12 @@ public function GetLeftField() { return $this->m_oLeftField; } + public function GetRightField() { return $this->m_oRightField; } + public function GetOperator() { return $this->m_sOperator; @@ -146,8 +150,9 @@ interface CheckableExpression * @param ModelReflection $oModelReflection MetaModel to consider * @param array $aAliases Aliases to class names (for the current query) * @param string $sSourceQuery For the reporting + * * @throws OqlNormalizeException - */ + */ public function Check(ModelReflection $oModelReflection, $aAliases, $sSourceQuery); } @@ -168,13 +173,11 @@ public function Check(ModelReflection $oModelReflection, $aAliases, $sSourceQuer $this->m_oRightExpr->Check($oModelReflection, $aAliases, $sSourceQuery); // Only field MATCHES scalar is allowed - if (!$this->m_oLeftExpr instanceof FieldExpression) - { + if (!$this->m_oLeftExpr instanceof FieldExpression) { throw new OqlNormalizeException('Only "field MATCHES string" syntax is allowed', $sSourceQuery, new OqlName($this->m_oLeftExpr->RenderExpression(true), 0)); } // Only field MATCHES scalar is allowed - if (!$this->m_oRightExpr instanceof ScalarExpression && !$this->m_oRightExpr instanceof VariableOqlExpression) - { + if (!$this->m_oRightExpr instanceof ScalarExpression && !$this->m_oRightExpr instanceof VariableOqlExpression) { throw new OqlNormalizeException('Only "field MATCHES string" syntax is allowed', $sSourceQuery, new OqlName($this->m_oRightExpr->RenderExpression(true), 0)); } } @@ -198,7 +201,7 @@ class NestedQueryOqlExpression extends NestedQueryExpression implements Checkabl * * @param OQLObjectQuery $oOQLObjectQuery */ - public function __construct($oOQLObjectQuery ) + public function __construct($oOQLObjectQuery) { parent::__construct($oOQLObjectQuery->ToDBSearch("")); $this->m_oOQLObjectQuery = $oOQLObjectQuery; @@ -232,8 +235,7 @@ class FieldOqlExpression extends FieldExpression implements CheckableExpression public function __construct($oName, $oParent = null) { - if (is_null($oParent)) - { + if (is_null($oParent)) { $oParent = new OqlName('', 0); } $this->m_oParent = $oParent; @@ -256,37 +258,28 @@ public function Check(ModelReflection $oModelReflection, $aAliases, $sSourceQuer { $sClassAlias = $this->GetParent(); $sFltCode = $this->GetName(); - if (empty($sClassAlias)) - { + if (empty($sClassAlias)) { // Try to find an alias // Build an array of field => array of aliases $aFieldClasses = array(); - foreach($aAliases as $sAlias => $sReal) - { - foreach($oModelReflection->GetFiltersList($sReal) as $sAnFltCode) - { + foreach ($aAliases as $sAlias => $sReal) { + foreach ($oModelReflection->GetFiltersList($sReal) as $sAnFltCode) { $aFieldClasses[$sAnFltCode][] = $sAlias; } } - if (!array_key_exists($sFltCode, $aFieldClasses)) - { + if (!array_key_exists($sFltCode, $aFieldClasses)) { throw new OqlNormalizeException('Unknown filter code', $sSourceQuery, $this->GetNameDetails(), array_keys($aFieldClasses)); } - if (count($aFieldClasses[$sFltCode]) > 1) - { + if (count($aFieldClasses[$sFltCode]) > 1) { throw new OqlNormalizeException('Ambiguous filter code', $sSourceQuery, $this->GetNameDetails()); } $sClassAlias = $aFieldClasses[$sFltCode][0]; - } - else - { - if (!array_key_exists($sClassAlias, $aAliases)) - { + } else { + if (!array_key_exists($sClassAlias, $aAliases)) { throw new OqlNormalizeException('Unknown class [alias]', $sSourceQuery, $this->GetParentDetails(), array_keys($aAliases)); } $sClass = $aAliases[$sClassAlias]; - if (!$oModelReflection->IsValidFilterCode($sClass, $sFltCode)) - { + if (!$oModelReflection->IsValidFilterCode($sClass, $sFltCode)) { throw new OqlNormalizeException('Unknown filter code', $sSourceQuery, $this->GetNameDetails(), $oModelReflection->GetFiltersList($sClass)); } } @@ -305,8 +298,7 @@ class ListOqlExpression extends ListExpression implements CheckableExpression { public function Check(ModelReflection $oModelReflection, $aAliases, $sSourceQuery) { - foreach ($this->GetItems() as $oItemExpression) - { + foreach ($this->GetItems() as $oItemExpression) { $oItemExpression->Check($oModelReflection, $aAliases, $sSourceQuery); } } @@ -316,8 +308,7 @@ class FunctionOqlExpression extends FunctionExpression implements CheckableExpre { public function Check(ModelReflection $oModelReflection, $aAliases, $sSourceQuery) { - foreach ($this->GetArgs() as $oArgExpression) - { + foreach ($this->GetArgs() as $oArgExpression) { $oArgExpression->Check($oModelReflection, $aAliases, $sSourceQuery); } } @@ -350,6 +341,7 @@ abstract public function Check(ModelReflection $oModelReflection, $sSourceQuery) * Determine the class * * @param ModelReflection $oModelReflection MetaModel to consider + * * @return string * @throws Exception */ @@ -392,6 +384,7 @@ public function GetSelectedClasses() * Determine the class * * @param ModelReflection $oModelReflection MetaModel to consider + * * @return string * @throws Exception */ @@ -415,6 +408,7 @@ public function GetClassDetails() { return $this->m_oClass; } + public function GetClassAliasDetails() { return $this->m_oClassAlias; @@ -424,6 +418,7 @@ public function GetJoins() { return $this->m_aJoins; } + public function GetCondition() { return $this->m_oCondition; @@ -432,44 +427,37 @@ public function GetCondition() /** * Recursively check the validity of the expression with regard to the data model * and the query in which it is used - * - * @param ModelReflection $oModelReflection MetaModel to consider + * + * @param ModelReflection $oModelReflection MetaModel to consider + * * @throws OqlNormalizeException - */ + */ public function Check(ModelReflection $oModelReflection, $sSourceQuery, $aParentAliases = array()) { $sClass = $this->GetClass($oModelReflection); $sClassAlias = $this->GetClassAlias(); - if (!$oModelReflection->IsValidClass($sClass)) - { + if (!$oModelReflection->IsValidClass($sClass)) { throw new UnknownClassOqlException($sSourceQuery, $this->GetClassDetails(), $oModelReflection->GetClasses()); } - $aAliases = array_merge(array($sClassAlias => $sClass),$aParentAliases); + $aAliases = array_merge(array($sClassAlias => $sClass), $aParentAliases); $aJoinSpecs = $this->GetJoins(); - if (is_array($aJoinSpecs)) - { - foreach ($aJoinSpecs as $oJoinSpec) - { + if (is_array($aJoinSpecs)) { + foreach ($aJoinSpecs as $oJoinSpec) { $sJoinClass = $oJoinSpec->GetClass(); $sJoinClassAlias = $oJoinSpec->GetClassAlias(); - if (!$oModelReflection->IsValidClass($sJoinClass)) - { + if (!$oModelReflection->IsValidClass($sJoinClass)) { throw new UnknownClassOqlException($sSourceQuery, $oJoinSpec->GetClassDetails(), $oModelReflection->GetClasses()); } - if (array_key_exists($sJoinClassAlias, $aAliases)) - { - if ($sJoinClassAlias != $sJoinClass) - { + if (array_key_exists($sJoinClassAlias, $aAliases)) { + if ($sJoinClassAlias != $sJoinClass) { throw new OqlNormalizeException('Duplicate class alias', $sSourceQuery, $oJoinSpec->GetClassAliasDetails()); - } - else - { + } else { throw new OqlNormalizeException('Duplicate class name', $sSourceQuery, $oJoinSpec->GetClassDetails()); } - } + } // Assumption: ext key on the left only !!! // normalization should take care of this @@ -480,85 +468,74 @@ public function Check(ModelReflection $oModelReflection, $sSourceQuery, $aParent $oRightField = $oJoinSpec->GetRightField(); $sToClass = $oRightField->GetParent(); $sPKeyDescriptor = $oRightField->GetName(); - if ($sPKeyDescriptor != 'id') - { + if ($sPKeyDescriptor != 'id') { throw new OqlNormalizeException('Wrong format for Join clause (right hand), expecting an id', $sSourceQuery, $oRightField->GetNameDetails(), array('id')); } $aAliases[$sJoinClassAlias] = $sJoinClass; - if (!array_key_exists($sFromClass, $aAliases)) - { + if (!array_key_exists($sFromClass, $aAliases)) { throw new OqlNormalizeException('Unknown class in join condition (left expression)', $sSourceQuery, $oLeftField->GetParentDetails(), array_keys($aAliases)); } - if (!array_key_exists($sToClass, $aAliases)) - { + if (!array_key_exists($sToClass, $aAliases)) { throw new OqlNormalizeException('Unknown class in join condition (right expression)', $sSourceQuery, $oRightField->GetParentDetails(), array_keys($aAliases)); } $aExtKeys = $oModelReflection->ListAttributes($aAliases[$sFromClass], \Combodo\iTop\Core\AttributeDefinition\AttributeExternalKey::class); $aObjKeys = $oModelReflection->ListAttributes($aAliases[$sFromClass], \Combodo\iTop\Core\AttributeDefinition\AttributeObjectKey::class); $aAllKeys = array_merge($aExtKeys, $aObjKeys); - if (!array_key_exists($sExtKeyAttCode, $aAllKeys)) - { + if (!array_key_exists($sExtKeyAttCode, $aAllKeys)) { throw new OqlNormalizeException('Unknown key in join condition (left expression)', $sSourceQuery, $oLeftField->GetNameDetails(), array_keys($aAllKeys)); } - if ($sFromClass == $sJoinClassAlias) - { + if ($sFromClass == $sJoinClassAlias) { if (array_key_exists($sExtKeyAttCode, $aExtKeys)) // Skip that check for object keys { $sTargetClass = $oModelReflection->GetAttributeProperty($aAliases[$sFromClass], $sExtKeyAttCode, 'targetclass'); - if(!$oModelReflection->IsSameFamilyBranch($aAliases[$sToClass], $sTargetClass)) - { + if (!$oModelReflection->IsSameFamilyBranch($aAliases[$sToClass], $sTargetClass)) { throw new OqlNormalizeException("The joined class ($aAliases[$sFromClass]) is not compatible with the external key, which is pointing to $sTargetClass", $sSourceQuery, $oLeftField->GetNameDetails()); } } - } - else - { + } else { $sOperator = $oJoinSpec->GetOperator(); - switch($sOperator) - { + switch ($sOperator) { case '=': - $iOperatorCode = TREE_OPERATOR_EQUALS; - break; + $iOperatorCode = TREE_OPERATOR_EQUALS; + break; case 'BELOW': - $iOperatorCode = TREE_OPERATOR_BELOW; - break; + $iOperatorCode = TREE_OPERATOR_BELOW; + break; case 'BELOW_STRICT': - $iOperatorCode = TREE_OPERATOR_BELOW_STRICT; - break; + $iOperatorCode = TREE_OPERATOR_BELOW_STRICT; + break; case 'NOT_BELOW': - $iOperatorCode = TREE_OPERATOR_NOT_BELOW; - break; + $iOperatorCode = TREE_OPERATOR_NOT_BELOW; + break; case 'NOT_BELOW_STRICT': - $iOperatorCode = TREE_OPERATOR_NOT_BELOW_STRICT; - break; + $iOperatorCode = TREE_OPERATOR_NOT_BELOW_STRICT; + break; case 'ABOVE': - $iOperatorCode = TREE_OPERATOR_ABOVE; - break; + $iOperatorCode = TREE_OPERATOR_ABOVE; + break; case 'ABOVE_STRICT': - $iOperatorCode = TREE_OPERATOR_ABOVE_STRICT; - break; + $iOperatorCode = TREE_OPERATOR_ABOVE_STRICT; + break; case 'NOT_ABOVE': - $iOperatorCode = TREE_OPERATOR_NOT_ABOVE; - break; + $iOperatorCode = TREE_OPERATOR_NOT_ABOVE; + break; case 'NOT_ABOVE_STRICT': - $iOperatorCode = TREE_OPERATOR_NOT_ABOVE_STRICT; - break; + $iOperatorCode = TREE_OPERATOR_NOT_ABOVE_STRICT; + break; } if (array_key_exists($sExtKeyAttCode, $aExtKeys)) // Skip that check for object keys { $sTargetClass = $oModelReflection->GetAttributeProperty($aAliases[$sFromClass], $sExtKeyAttCode, 'targetclass'); - if(!$oModelReflection->IsSameFamilyBranch($aAliases[$sToClass], $sTargetClass)) - { + if (!$oModelReflection->IsSameFamilyBranch($aAliases[$sToClass], $sTargetClass)) { throw new OqlNormalizeException("The joined class ($aAliases[$sToClass]) is not compatible with the external key, which is pointing to $sTargetClass", $sSourceQuery, $oLeftField->GetNameDetails()); } } $aAttList = $oModelReflection->ListAttributes($aAliases[$sFromClass]); $sAttType = $aAttList[$sExtKeyAttCode]; - if(($iOperatorCode != TREE_OPERATOR_EQUALS) && !is_subclass_of($sAttType, \Combodo\iTop\Core\AttributeDefinition\AttributeHierarchicalKey::class) && ($sAttType != \Combodo\iTop\Core\AttributeDefinition\AttributeHierarchicalKey::class)) - { + if (($iOperatorCode != TREE_OPERATOR_EQUALS) && !is_a($sAttType, \Combodo\iTop\Core\AttributeDefinition\AttributeHierarchicalKey::class, true)) { throw new OqlNormalizeException("The specified tree operator $sOperator is not applicable to the key", $sSourceQuery, $oLeftField->GetNameDetails()); } } @@ -567,26 +544,23 @@ public function Check(ModelReflection $oModelReflection, $sSourceQuery, $aParent // Check the select information // - foreach ($this->GetSelectedClasses() as $oClassDetails) - { + foreach ($this->GetSelectedClasses() as $oClassDetails) { $sClassToSelect = $oClassDetails->GetValue(); - if (!array_key_exists($sClassToSelect, $aAliases)) - { + if (!array_key_exists($sClassToSelect, $aAliases)) { throw new OqlNormalizeException('Unknown class [alias]', $sSourceQuery, $oClassDetails, array_keys($aAliases)); } } // Check the condition tree // - if ($this->m_oCondition instanceof Expression) - { + if ($this->m_oCondition instanceof Expression) { $this->m_oCondition->Check($oModelReflection, $aAliases, $sSourceQuery); } } /** * Make the relevant DBSearch instance (FromOQL) - */ + */ public function ToDBSearch($sQuery) { $sClass = $this->GetClass(new ModelReflectionRuntime()); @@ -594,6 +568,7 @@ public function ToDBSearch($sQuery) $oSearch = new DBObjectSearch($sClass, $sClassAlias); $oSearch->InitFromOqlQuery($this, $sQuery); + return $oSearch; } } @@ -606,19 +581,15 @@ public function __construct(OqlObjectQuery $oLeftQuery, OqlQuery $oRightQueryOrU { parent::__construct(); $this->aQueries[] = $oLeftQuery; - if ($oRightQueryOrUnion instanceof OqlUnionQuery) - { - foreach ($oRightQueryOrUnion->GetQueries() as $oSingleQuery) - { + if ($oRightQueryOrUnion instanceof OqlUnionQuery) { + foreach ($oRightQueryOrUnion->GetQueries() as $oSingleQuery) { $this->aQueries[] = $oSingleQuery; } - } - else - { + } else { $this->aQueries[] = $oRightQueryOrUnion; } } - + public function GetQueries() { return $this->aQueries; @@ -627,66 +598,54 @@ public function GetQueries() /** * Check the validity of the expression with regard to the data model * and the query in which it is used - * - * @param ModelReflection $oModelReflection MetaModel to consider + * + * @param ModelReflection $oModelReflection MetaModel to consider + * * @throws OqlNormalizeException - */ + */ public function Check(ModelReflection $oModelReflection, $sSourceQuery) { $aColumnToClasses = array(); - foreach ($this->aQueries as $iQuery => $oQuery) - { + foreach ($this->aQueries as $iQuery => $oQuery) { $oQuery->Check($oModelReflection, $sSourceQuery); $aAliasToClass = array($oQuery->GetClassAlias() => $oQuery->GetClass($oModelReflection)); $aJoinSpecs = $oQuery->GetJoins(); - if (is_array($aJoinSpecs)) - { - foreach ($aJoinSpecs as $oJoinSpec) - { + if (is_array($aJoinSpecs)) { + foreach ($aJoinSpecs as $oJoinSpec) { $aAliasToClass[$oJoinSpec->GetClassAlias()] = $oJoinSpec->GetClass(); } } $aSelectedClasses = $oQuery->GetSelectedClasses(); - if ($iQuery != 0) - { - if (count($aSelectedClasses) < count($aColumnToClasses)) - { + if ($iQuery != 0) { + if (count($aSelectedClasses) < count($aColumnToClasses)) { $oLastClass = end($aSelectedClasses); throw new OqlNormalizeException('Too few selected classes in the subquery', $sSourceQuery, $oLastClass); } - if (count($aSelectedClasses) > count($aColumnToClasses)) - { + if (count($aSelectedClasses) > count($aColumnToClasses)) { $oLastClass = end($aSelectedClasses); throw new OqlNormalizeException('Too many selected classes in the subquery', $sSourceQuery, $oLastClass); } } - foreach ($aSelectedClasses as $iColumn => $oClassDetails) - { + foreach ($aSelectedClasses as $iColumn => $oClassDetails) { $sAlias = $oClassDetails->GetValue(); $sClass = $aAliasToClass[$sAlias]; $aColumnToClasses[$iColumn][] = array( - 'alias' => $sAlias, - 'class' => $sClass, + 'alias' => $sAlias, + 'class' => $sClass, 'class_name' => $oClassDetails, ); } } - foreach ($aColumnToClasses as $iColumn => $aClasses) - { + foreach ($aColumnToClasses as $iColumn => $aClasses) { $sRootClass = null; - foreach ($aClasses as $iQuery => $aData) - { - if ($iQuery == 0) - { + foreach ($aClasses as $iQuery => $aData) { + if ($iQuery == 0) { // Establish the reference $sRootClass = $oModelReflection->GetRootClass($aData['class']); - } - else - { - if ($oModelReflection->GetRootClass($aData['class']) != $sRootClass) - { + } else { + if ($oModelReflection->GetRootClass($aData['class']) != $sRootClass) { $aSubclasses = $oModelReflection->EnumChildClasses($sRootClass, ENUM_CHILD_CLASSES_ALL); throw new OqlNormalizeException('Incompatible classes: could not find a common ancestor', $sSourceQuery, $aData['class_name'], $aSubclasses); } @@ -699,21 +658,21 @@ public function Check(ModelReflection $oModelReflection, $sSourceQuery) * Determine the class * * @param ModelReflection $oModelReflection MetaModel to consider + * * @return string * @throws Exception */ public function GetClass(ModelReflection $oModelReflection) { $aFirstColClasses = array(); - foreach ($this->aQueries as $iQuery => $oQuery) - { + foreach ($this->aQueries as $iQuery => $oQuery) { $aFirstColClasses[] = $oQuery->GetClass($oModelReflection); } $sClass = self::GetLowestCommonAncestor($oModelReflection, $aFirstColClasses); - if (is_null($sClass)) - { + if (is_null($sClass)) { throw new Exception('Could not determine the class of the union query. This issue should have been detected earlier by calling OqlQuery::Check()'); } + return $sClass; } @@ -726,6 +685,7 @@ public function GetClass(ModelReflection $oModelReflection) public function GetClassAlias() { $sAlias = $this->aQueries[0]->GetClassAlias(); + return $sAlias; } @@ -735,29 +695,25 @@ public function GetClassAlias() * * @param ModelReflection $oModelReflection MetaModel to consider * @param array $aClasses Flat list of classes + * * @return string the lowest common ancestor amongst classes, null if none has been found * @throws Exception */ public static function GetLowestCommonAncestor(ModelReflection $oModelReflection, $aClasses) { $sAncestor = null; - foreach($aClasses as $sClass) - { - if (is_null($sAncestor)) - { + foreach ($aClasses as $sClass) { + if (is_null($sAncestor)) { // first loop $sAncestor = $sClass; - } - elseif ($oModelReflection->GetRootClass($sClass) != $oModelReflection->GetRootClass($sAncestor)) - { + } elseif ($oModelReflection->GetRootClass($sClass) != $oModelReflection->GetRootClass($sAncestor)) { $sAncestor = null; break; - } - else - { + } else { $sAncestor = self::LowestCommonAncestor($oModelReflection, $sAncestor, $sClass); } } + return $sAncestor; } @@ -766,37 +722,32 @@ public static function GetLowestCommonAncestor(ModelReflection $oModelReflection */ protected static function LowestCommonAncestor(ModelReflection $oModelReflection, $sClassA, $sClassB) { - if ($sClassA == $sClassB) - { + if ($sClassA == $sClassB) { $sRet = $sClassA; - } - elseif (in_array($sClassA, $oModelReflection->EnumChildClasses($sClassB))) - { + } elseif (in_array($sClassA, $oModelReflection->EnumChildClasses($sClassB))) { $sRet = $sClassB; - } - elseif (in_array($sClassB, $oModelReflection->EnumChildClasses($sClassA))) - { + } elseif (in_array($sClassB, $oModelReflection->EnumChildClasses($sClassA))) { $sRet = $sClassA; - } - else - { + } else { // Recurse $sRet = self::LowestCommonAncestor($oModelReflection, $sClassA, $oModelReflection->GetParentClass($sClassB)); } + return $sRet; } + /** * Make the relevant DBSearch instance (FromOQL) - */ + */ public function ToDBSearch($sQuery) { $aSearches = array(); - foreach ($this->aQueries as $oQuery) - { + foreach ($this->aQueries as $oQuery) { $aSearches[] = $oQuery->ToDBSearch($sQuery); } $oSearch = new DBUnionSearch($aSearches); + return $oSearch; } } diff --git a/css/backoffice/blocks-integrations/field/_field-with-field.scss b/css/backoffice/blocks-integrations/field/_field-with-field.scss index fb2d7ea3e5..73709adbef 100644 --- a/css/backoffice/blocks-integrations/field/_field-with-field.scss +++ b/css/backoffice/blocks-integrations/field/_field-with-field.scss @@ -4,7 +4,7 @@ */ $ibo-field--spacing-top--with-same-block: $ibo-spacing-500 !default; -.ibo-field + .ibo-field { +.ibo-field + .ibo-field:not(:empty) { margin-top: $ibo-field--spacing-top--with-same-block; } diff --git a/css/backoffice/components/_form.scss b/css/backoffice/components/_form.scss index d80fdd96a2..c732bebd8f 100644 --- a/css/backoffice/components/_form.scss +++ b/css/backoffice/components/_form.scss @@ -6,4 +6,72 @@ .ibo-prop-header { @extend %ibo-font-size-150; padding-bottom: 14px; -} \ No newline at end of file +} + +.help-text{ + padding: 1px 5px; + background-color: #d7e3f8; + border: 1px solid #c6e7f5; + border-radius: 5px; + margin: 5px 0; + font-size: 0.9em; +} + +.form-error ul{ + padding: 1px 5px; + background-color: #f8d7da; + border: 1px solid #f5c6cb; + border-radius: 5px; + margin: 5px 0; + font-size: 0.9em; +} + +.subform{ + background-color: #efefef; + border-radius: 5px; + padding: 10px; +} + +.form-buttons{ + margin: 20px 0; +} + +.form select{ + padding: 0; + overflow-y: auto; +} + +.form select option{ + height: 30px; + display: flex; + align-items: center; +} + +.turbo-refreshing{ + opacity: .5; +} + +.ibo-field legend{ + margin-top: 24px; +} + +collection-entry-element { + margin-top: 8px; + display: block; + padding: 10px 10px; + background-color: #f5f5f5; + border-radius: 5px; +} +.ts-control{ + height: auto; + min-height: 30px; +} + +.ibo-form-actions > .ibo-button > span{ + margin-right: 5px; +} + +.ibo-form textarea{ + resize: vertical; +} + diff --git a/css/backoffice/vendors/_tomselect.scss b/css/backoffice/vendors/_tomselect.scss new file mode 100644 index 0000000000..74cdeddf2e --- /dev/null +++ b/css/backoffice/vendors/_tomselect.scss @@ -0,0 +1,3 @@ +@import "../../../node_modules/tom-select/dist/scss/tom-select.scss"; + +$select-color-item-active-border: $ibo-input--focus--border-color; \ No newline at end of file diff --git a/data/.compilation-symlinks b/data/.compilation-symlinks new file mode 100644 index 0000000000..e69de29bb2 diff --git a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php index a2a33fd89e..02ee530a22 100644 --- a/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php +++ b/datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php @@ -30,7 +30,7 @@ // Identification // 'label' => 'Database maintenance tools', - 'category' => 'business', + 'category' => 'Application management', // Setup // diff --git a/datamodels/2.x/itop-config/src/Controller/ConfigEditorController.php b/datamodels/2.x/itop-config/src/Controller/ConfigEditorController.php index c45c4f0157..aba7d2eb86 100644 --- a/datamodels/2.x/itop-config/src/Controller/ConfigEditorController.php +++ b/datamodels/2.x/itop-config/src/Controller/ConfigEditorController.php @@ -28,6 +28,7 @@ class ConfigEditorController extends Controller public function __construct() { parent::__construct(MODULESROOT.static::MODULE_NAME.'/templates', static::MODULE_NAME); + $this->SetDebugAllowed(false); } public function OperationEdit(): void diff --git a/datamodels/2.x/itop-core-update/module.itop-core-update.php b/datamodels/2.x/itop-core-update/module.itop-core-update.php index 9e4272e342..d243de6871 100644 --- a/datamodels/2.x/itop-core-update/module.itop-core-update.php +++ b/datamodels/2.x/itop-core-update/module.itop-core-update.php @@ -30,7 +30,7 @@ // Identification // 'label' => 'iTop Core Update', - 'category' => 'business', + 'category' => 'Application management', // Setup // diff --git a/dictionaries/en.dictionary.itop.ui.php b/dictionaries/en.dictionary.itop.ui.php index 2f6b66450f..e3949b0fa4 100644 --- a/dictionaries/en.dictionary.itop.ui.php +++ b/dictionaries/en.dictionary.itop.ui.php @@ -1333,6 +1333,7 @@ 'UI:DashletGroupBy:Prop-GroupBy:DayOfMonth' => 'Day of month for %1$s', 'UI:DashletGroupBy:Prop-GroupBy:Select-Hour' => '%1$s (hour)', 'UI:DashletGroupBy:Prop-GroupBy:Select-Month' => '%1$s (month)', + 'UI:DashletGroupBy:Prop-GroupBy:Select-Year' => '%1$s (year)', 'UI:DashletGroupBy:Prop-GroupBy:Select-DayOfWeek' => '%1$s (day of week)', 'UI:DashletGroupBy:Prop-GroupBy:Select-DayOfMonth' => '%1$s (day of month)', 'UI:DashletGroupBy:MissingGroupBy' => 'Please select the field on which the objects will be grouped together', @@ -1653,6 +1654,8 @@ 'UI:Search:Criteria:Raw:FilteredOn' => 'Filtered on %1$s', 'UI:StateChanged' => 'State changed', + + 'UI:AddSubTree' => 'Add entry', ]); // diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php index c6d3782fb2..9fe2da13ce 100644 --- a/dictionaries/fr.dictionary.itop.ui.php +++ b/dictionaries/fr.dictionary.itop.ui.php @@ -1279,6 +1279,7 @@ 'UI:DashletGroupBy:Prop-GroupBy:DayOfMonth' => 'Jour du mois pour %1$s', 'UI:DashletGroupBy:Prop-GroupBy:Select-Hour' => '%1$s (heure)', 'UI:DashletGroupBy:Prop-GroupBy:Select-Month' => '%1$s (mois)', + 'UI:DashletGroupBy:Prop-GroupBy:Select-Year' => '%1$s (année)', 'UI:DashletGroupBy:Prop-GroupBy:Select-DayOfWeek' => '%1$s (jour de la semaine)', 'UI:DashletGroupBy:Prop-GroupBy:Select-DayOfMonth' => '%1$s (jour du mois)', 'UI:DashletGroupBy:MissingGroupBy' => 'Veuillez sélectionner le champ sur lequel les objets seront groupés', @@ -1544,7 +1545,8 @@ 'UI:Search:Criteria:HierarchicalKey:ChildrenIncluded:Hint' => 'Les descendants des objets sélectionnés seront inclus.', 'UI:Search:Criteria:Raw:Filtered' => 'Filtré', 'UI:Search:Criteria:Raw:FilteredOn' => 'Filtré sur %1$s', - 'UI:StateChanged' => 'Etat modifié', + 'UI:StateChanged' => 'État modifié', + 'UI:AddSubTree' => 'Ajouter une entrée', ]); // diff --git a/dictionaries/ui/components/input/en.dictionary.itop.input.php b/dictionaries/ui/components/input/en.dictionary.itop.input.php index 7cc0e228d4..e7acd64b46 100644 --- a/dictionaries/ui/components/input/en.dictionary.itop.input.php +++ b/dictionaries/ui/components/input/en.dictionary.itop.input.php @@ -19,8 +19,15 @@ */ // Input -Dict::Add('EN US', 'English', 'English', [ - 'UI:Component:Input:ChangeNotAllowed' => 'This change is not allowed', - 'UI:Component:Input:Password:DoesNotMatch' => 'Passwords do not match', - 'UI:Component:Input:Set:MinimumItems' => 'Minimum %1$s item(s) required', -]); +Dict::Add( + 'EN US', + 'English', + 'English', + [ + 'UI:Component:Input:ChangeNotAllowed' => 'This change is not allowed', + 'UI:Component:Input:Password:DoesNotMatch' => 'Passwords do not match', + 'UI:Component:Input:Set:MinimumItems' => 'Minimum %1$s item(s) required', + + 'UI:Component:Input:Select:Select_item' => 'Select an item...', + ] +); diff --git a/dictionaries/ui/components/input/fr.dictionary.itop.input.php b/dictionaries/ui/components/input/fr.dictionary.itop.input.php index c17c791125..eb8dd5f61a 100644 --- a/dictionaries/ui/components/input/fr.dictionary.itop.input.php +++ b/dictionaries/ui/components/input/fr.dictionary.itop.input.php @@ -10,8 +10,15 @@ /** * */ -Dict::Add('FR FR', 'French', 'Français', [ - 'UI:Component:Input:ChangeNotAllowed' => 'Cette modification n\'est pas autorisée', - 'UI:Component:Input:Password:DoesNotMatch' => 'Les mots de passe ne correspondent pas', - 'UI:Component:Input:Set:MinimumItems' => 'Minimum %1$s élément(s) requis', -]); +Dict::Add( + 'FR FR', + 'French', + 'Français', + [ + 'UI:Component:Input:ChangeNotAllowed' => 'Cette modification n\'est pas autorisée', + 'UI:Component:Input:Password:DoesNotMatch' => 'Les mots de passe ne correspondent pas', + 'UI:Component:Input:Set:MinimumItems' => 'Minimum %1$s élément(s) requis', + + 'UI:Component:Input:Select:Select_item' => 'Sélectionnez un élément...', + ] +); diff --git a/js/forms/choices_element.js b/js/forms/choices_element.js new file mode 100644 index 0000000000..eb1dd9133e --- /dev/null +++ b/js/forms/choices_element.js @@ -0,0 +1,45 @@ +class ChoicesElement extends HTMLSelectElement { + + // register the custom element + static { + customElements.define('choices-element', ChoicesElement, {extends: 'select'}); + } + + plugins = []; + connectedCallback() { + + if (this.tomselect) { + return; + } + + if (this.getAttribute('multiple')) { + this.plugins.push('remove_button'); + } + + const options = { + plugins: this.plugins, + wrapperClass: 'ts-wrapper ibo-input-wrapper ibo-input-select-wrapper--with-buttons ibo-input-select-autocomplete-wrapper', + controlClass: 'ts-control ibo-input ibo-input-select ibo-input-select-autocomplete', + dropdownParent: 'body', + render: { + dropdown: function (data, escape) { + return `
`; + } + } + }; + + if (this.getAttribute('data-tom-select-disable-auto-complete')) { + // options.controlInput = null; + } + if (this.getAttribute('data-tom-select-max-items-selected') && this.getAttribute('data-tom-select-max-items-selected') !== '') { + options.maxItems = parseInt(this.getAttribute('data-tom-select-max-items-selected')); + } + if (this.getAttribute('data-tom-select-placehelder')) { + options.placeholder = this.getAttribute('data-tom-select-placehelder'); + } + + new TomSelect(this, options); + } +} + + diff --git a/js/forms/collection_element.js b/js/forms/collection_element.js new file mode 100644 index 0000000000..5a32d86661 --- /dev/null +++ b/js/forms/collection_element.js @@ -0,0 +1,39 @@ +class CollectionElement extends HTMLElement { + + #eBtnAdd; + + // register the custom element + static { + customElements.define('collection-element', CollectionElement); + } + + addFormToCollection(e) { + const collectionHolder = document.querySelector('.'+e.currentTarget.dataset.collectionHolderClass); + const item = document.createElement('div'); + + const collectionHolderList = collectionHolder.querySelector('[role="list"]'); + + item.innerHTML = collectionHolder + .dataset + .prototype + .replace( + /__name__/g, + collectionHolder.dataset.index + ); + + collectionHolderList.appendChild(item.firstChild); + collectionHolder.dataset.index++; + + this.querySelectorAll('collection-entry-element').forEach((entry) => { + console.log('test'); + entry.updateButtonStates(); + }); + } + + /** connectedCallback **/ + connectedCallback() { + this.#eBtnAdd = this.querySelector('.add_item_link'); + this.#eBtnAdd.addEventListener('click', this.addFormToCollection.bind(this)); + } + +} diff --git a/js/forms/collection_entry_element.js b/js/forms/collection_entry_element.js new file mode 100644 index 0000000000..190aa5300e --- /dev/null +++ b/js/forms/collection_entry_element.js @@ -0,0 +1,112 @@ +class CollectionEntryElement extends HTMLElement { + + // Button elements + #eBtnDelete; + #eBtnMoveUp; + #eBtnMoveDown; + + // register the custom element + static { + customElements.define('collection-entry-element', CollectionEntryElement); + } + + /** connectedCallback **/ + connectedCallback() { + + if ((this.dataset.new || this.dataset.allowDelete) && this.#eBtnDelete === undefined) { + this.#eBtnDelete = this.#createButton('Remove', 'ibo-button ibo-is-regular ibo-is-danger'); + this.#eBtnDelete.addEventListener('click', this.#removeCollectionItem.bind(this)); + this.appendChild(this.#eBtnDelete); + } + + if (this.dataset.allowOrdering) { + if (this.#eBtnMoveUp === undefined) { + this.#eBtnMoveUp = this.#createButton('Move Up', 'ibo-button ibo-is-regular'); + this.#eBtnMoveUp.addEventListener('click', this.#moveUp.bind(this)); + this.appendChild(this.#eBtnMoveUp); + } + if (this.#eBtnMoveDown === undefined) { + this.#eBtnMoveDown = this.#createButton('Move Down', 'ibo-button ibo-is-regular'); + this.#eBtnMoveDown.addEventListener('click', this.#moveDown.bind(this)); + this.appendChild(this.#eBtnMoveDown); + } + } + + this.updateButtonStates(); + } + + /** + * Update the state of the buttons (enabled/disabled). + * + */ + updateButtonStates() { + + if (this.dataset.allowOrdering) { + + if (this.previousElementSibling === null) { + this.#eBtnMoveUp.setAttribute('disabled', 'disabled'); + } else { + this.#eBtnMoveUp.removeAttribute('disabled'); + } + + if (this.nextElementSibling === null) { + this.#eBtnMoveDown.setAttribute('disabled', 'disabled'); + } else { + this.#eBtnMoveDown.removeAttribute('disabled'); + } + + } + + } + + /** + * Create a button element. + * + * @param label + * @param className + * @returns {HTMLButtonElement} + */ + #createButton(label, className) { + + const btnElement = document.createElement('button'); + btnElement.type = 'button'; + btnElement.className = className; + btnElement.textContent = label; + + return btnElement; + } + + /** + * Move this collection item up. + * + */ + #moveUp() { + const prev = this.previousElementSibling; + if (prev) { + this.parentNode.insertBefore(this, prev); + this.updateButtonStates(); + prev.updateButtonStates(); + } + } + + /** + * Move this collection item down. + * + */ + #moveDown() { + const next = this.nextElementSibling; + if (next) { + this.parentNode.insertBefore(next, this); + this.updateButtonStates(); + next.updateButtonStates(); + } + } + + /** + * Remove this collection item. + * + */ + #removeCollectionItem() { + this.remove(); + } +} diff --git a/js/forms/form_element.js b/js/forms/form_element.js new file mode 100644 index 0000000000..679b0cf067 --- /dev/null +++ b/js/forms/form_element.js @@ -0,0 +1,95 @@ +class FormElement extends HTMLFormElement +{ + static #TURBO_REFRESHING_CLASS = 'turbo-refreshing'; + static #TURBO_TRIGGER_FIELD = '_turbo_trigger'; + + #aFormBlockDataTransmittedData = {}; + + // register the custom element + static { + customElements.define('itop-form-element', FormElement, {extends: 'form'}); + } + + TriggerTurbo(oElement) { + + // Get the name and id of the element triggering turbo + const sName = oElement.getAttribute('name'); + const sId = oElement.getAttribute('id'); + + if(FormElement.IsCheckbox(oElement) || this.#aFormBlockDataTransmittedData[sName] !== oElement.value) { + + // Refresh UI + this.#StartRefreshingUI(sId); + + // Pre Submit + this.#PreSubmitTurboForm(sName); + + // Submit + oElement.form.requestSubmit(); + + // Post Submit + this.#PostSubmitTurboForm(sName) + + this.#aFormBlockDataTransmittedData[sName] = oElement.value; + } + + } + + /** + * Start refreshing UI. + * + * @param sId + * @constructor + */ + #StartRefreshingUI(sId) + { + Array.from(this.querySelectorAll(`.ibo-content-block`)).forEach(block => { + if(block.dataset.impactedBy !== undefined){ + const aImpactedBy = block.dataset.impactedBy.split(','); + if(aImpactedBy.includes(sId)){ + block.classList.add(FormElement.#TURBO_REFRESHING_CLASS); + } + } + }); + } + + /** + * Pre submit the form. + * Set the turbo trigger field in the form and disable validation + * + * @param sName + * @constructor + */ + #PreSubmitTurboForm(sName) + { + this.querySelector(`[name="${this.getAttribute("name")}[${FormElement.#TURBO_TRIGGER_FIELD}]"]`).value = sName; + this.setAttribute('novalidate', true); + } + + /** + * Post submit the form. + * Reset the turbo trigger field and restore form validation. + * + * @param sName + * @constructor + */ + #PostSubmitTurboForm(sName) + { + this.querySelector(`[name="${this.getAttribute("name")}[${FormElement.#TURBO_TRIGGER_FIELD}]"]`).value = null; + this.removeAttribute('novalidate'); + } + + /** + * + * @param oElement + * @returns {boolean} + */ + static IsCheckbox (oElement) + { + return oElement instanceof HTMLInputElement + && oElement.getAttribute('type') === 'checkbox' + } + +} + + diff --git a/js/forms/oql_element.js b/js/forms/oql_element.js new file mode 100644 index 0000000000..b2350e1595 --- /dev/null +++ b/js/forms/oql_element.js @@ -0,0 +1,123 @@ +class OqlElement extends HTMLTextAreaElement { + + static #DEBONCE = 400; + + // register the custom element + static{ + customElements.define('oql-element', OqlElement, {extends: 'textarea'}); + } + + // variables + #url = '../pages/ajax.render.php?route=oql.validate_query'; + #iconValid = 'fa-check-double'; + #iconNotValid = 'fa-exclamation-triangle'; + #debounceTimer = null; + #debounce = OqlElement.#DEBONCE; + + /** connectedCallback **/ + connectedCallback() { + this.addEventListener('input', this.#onInput.bind(this)); + this.#callValidateQuery(); + + this.addEventListener('focus', this.#onFocus.bind(this)); + + const oBtnBook = this.closest('.ibo-content-block').querySelector('[data-role="ibo-button"][data-action="book"]'); + oBtnBook.addEventListener('click', this.#search.bind(this)) + + const oBtnRun = this.closest('.ibo-content-block').querySelector('[data-role="ibo-button"][data-action="run"]'); + oBtnRun.addEventListener('click', this.#run.bind(this)) + } + + /** + * Call oql verification with debounce when input event is fired. + */ + #onInput() { + if (this.#debounceTimer) clearTimeout(this.#debounceTimer); + this.#debounceTimer = setTimeout(() => { + this.#callValidateQuery(true); + }, this.#debounce); + } + + /** + * Call oql verification with debounce when focus event is fired. + */ + #onFocus() { + this.#callValidateQuery(); + } + + /** + * Call the ajax to validate the query. + * + * @param fireChange flag to handle change event + */ + #callValidateQuery(fireChange = false) { + + fetch(this.#url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Combodo-Ajax': true + }, + body: JSON.stringify({ + query: this.value + }) + }) + .then(response => response.json()) + .then(response => { + // fire change event only if the query is valid + if (fireChange && response.is_valid){ + this.#fireChangeEvent(); + } + // update the icon color + const fieldEl = this.closest('.ibo-field'); + const marqueeEl = fieldEl.querySelector('[role="marquee"]'); + marqueeEl.style.color = response.is_valid ? 'green' : 'orange'; + marqueeEl.classList.toggle(this.#iconNotValid, !response.is_valid); + marqueeEl.classList.toggle(this.#iconValid, response.is_valid); + marqueeEl.setAttribute('title', response.is_valid ? Dict.S(this.dataset.validQueryText) : Dict.S(this.dataset.invalidQueryText)); + }); + } + + /** + * Fire a change event. + */ + #fireChangeEvent() { + const changeEvent = new Event('change', { bubbles: true, cancelable: true }); + this.dispatchEvent(changeEvent); + } + + #search(){ + const sId = this.getAttribute('id'); + const sDialogId = `ac_dlg_${sId}`; + + const sModalTitle = Dict.S(this.dataset.modalTitleText); + const sEmptyText = Dict.S(this.dataset.emptyText); + + // Instance the widget + const oACWidget = new ExtKeyWidget(sId, 'QueryOQL', 'SELECT QueryOQL WHERE is_template = \'yes\'', sModalTitle, true, null, null, true, true, 'oql'); + oACWidget.emptyHtml = `

<${sEmptyText}/p>

`; + + // Store in window to be accessible from dialog + window[`oACWidget_${sId}`] = oACWidget; + + // Open the dialog + if ($(`#${sDialogId}`).length === 0) + { + $('body').append(`
`); + $(`#${sDialogId}`).dialog({ + width: $(window).width()*0.8, + height: $(window).height()*0.8, + autoOpen: false, + modal: true, + resizeStop: oACWidget.UpdateSizes, + }); + } + + // Start searching + oACWidget.Search(); + } + + #run(){ + window.open('../pages/run_query.php?expression=' + encodeURI(this.value), '_blank'); + } +} diff --git a/js/forms/turbo_stream_event_element.js b/js/forms/turbo_stream_event_element.js new file mode 100644 index 0000000000..d440b39e66 --- /dev/null +++ b/js/forms/turbo_stream_event_element.js @@ -0,0 +1,26 @@ +class TurboStreamEvent extends HTMLElement { + + // register the custom element + static { + customElements.define('turbo-stream-event', TurboStreamEvent); + } + + constructor() { + super(); + + this.style.display = 'none'; + + const event = new CustomEvent("itop:TurboStreamEvent", { + detail: { + id: this.getAttribute('id'), + form_id: this.dataset.formId, + block_class: this.dataset.formBlockClass, + view_data: this.dataset.viewData, + valid: this.dataset.valid, + }, + }); + + document.dispatchEvent(event); + } + +} diff --git a/lib/composer/autoload_classmap.php b/lib/composer/autoload_classmap.php index c338b2bcc1..977cf54b2b 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -244,6 +244,10 @@ 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Toolbar\\ToolbarSpacer\\ToolbarSpacer' => $baseDir . '/sources/Application/UI/Base/Component/Toolbar/ToolbarSpacer/ToolbarSpacer.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Toolbar\\ToolbarSpacer\\ToolbarSpacerUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/Toolbar/ToolbarSpacer/ToolbarSpacerUIBlockFactory.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Toolbar\\ToolbarUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/Toolbar/ToolbarUIBlockFactory.php', + 'Combodo\\iTop\\Application\\UI\\Base\\Component\\TurboForm\\TurboForm' => $baseDir . '/sources/Application/UI/Base/Component/TurboForm/TurboForm.php', + 'Combodo\\iTop\\Application\\UI\\Base\\Component\\TurboForm\\TurboFormUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/TurboForm/TurboFormUIBlockFactory.php', + 'Combodo\\iTop\\Application\\UI\\Base\\Component\\TurboUpdate\\TurboStream' => $baseDir . '/sources/Application/UI/Base/Component/TurboStream/TurboStream.php', + 'Combodo\\iTop\\Application\\UI\\Base\\Component\\TurboUpdate\\TurboStreamUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/TurboStream/TurboStreamUIBlockFactory.php', 'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityEntry\\ActivityEntry' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityEntry/ActivityEntry.php', 'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityEntry\\ActivityEntryFactory' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityEntry/ActivityEntryFactory.php', 'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityEntry\\CMDBChangeOp\\CMDBChangeOpAttachmentAddedFactory' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityEntry/CMDBChangeOp/CMDBChangeOpAttachmentAddedFactory.php', @@ -341,6 +345,7 @@ 'Combodo\\iTop\\Controller\\AjaxRenderController' => $baseDir . '/sources/Controller/AjaxRenderController.php', 'Combodo\\iTop\\Controller\\Base\\Layout\\ActivityPanelController' => $baseDir . '/sources/Controller/Base/Layout/ActivityPanelController.php', 'Combodo\\iTop\\Controller\\Base\\Layout\\ObjectController' => $baseDir . '/sources/Controller/Base/Layout/ObjectController.php', + 'Combodo\\iTop\\Controller\\Base\\Layout\\OqlController' => $baseDir . '/sources/Controller/Base/Layout/OqlController.php', 'Combodo\\iTop\\Controller\\Links\\LinkSetController' => $baseDir . '/sources/Controller/Links/LinkSetController.php', 'Combodo\\iTop\\Controller\\Newsroom\\iTopNewsroomController' => $baseDir . '/sources/Controller/Newsroom/iTopNewsroomController.php', 'Combodo\\iTop\\Controller\\Notifications\\ActionController' => $baseDir . '/sources/Controller/Notifications/ActionController.php', @@ -473,8 +478,103 @@ 'Combodo\\iTop\\Form\\Validator\\MultipleChoicesValidator' => $baseDir . '/sources/Form/Validator/MultipleChoicesValidator.php', 'Combodo\\iTop\\Form\\Validator\\NotEmptyExtKeyValidator' => $baseDir . '/sources/Form/Validator/NotEmptyExtKeyValidator.php', 'Combodo\\iTop\\Form\\Validator\\SelectObjectValidator' => $baseDir . '/sources/Form/Validator/SelectObjectValidator.php', + 'Combodo\\iTop\\Forms\\Block\\AbstractFormBlock' => $baseDir . '/sources/Forms/Block/AbstractFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\AbstractTypeFormBlock' => $baseDir . '/sources/Forms/Block/AbstractTypeFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\CheckboxFormBlock' => $baseDir . '/sources/Forms/Block/Base/CheckboxFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFormBlock' => $baseDir . '/sources/Forms/Block/Base/ChoiceFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFromInputsBlock' => $baseDir . '/sources/Forms/Block/Base/ChoiceFromInputsBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\CollectionBlock' => $baseDir . '/sources/Forms/Block/Base/CollectionBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\DateFormBlock' => $baseDir . '/sources/Forms/Block/Base/DateFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\DateTimeFormBlock' => $baseDir . '/sources/Forms/Block/Base/DateTimeFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\FormBlock' => $baseDir . '/sources/Forms/Block/Base/FormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\HiddenFormBlock' => $baseDir . '/sources/Forms/Block/Base/HiddenFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\IntegerFormBlock' => $baseDir . '/sources/Forms/Block/Base/IntegerFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\NumberFormBlock' => $baseDir . '/sources/Forms/Block/Base/NumberFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\TextAreaFormBlock' => $baseDir . '/sources/Forms/Block/Base/TextAreaFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => $baseDir . '/sources/Forms/Block/Base/TextFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeTypeChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeTypeChoiceFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeValueChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\Dashlet\\AggregateFunctionFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/Dashlet/AggregateFunctionFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\Dashlet\\ClassAttributeGroupByFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/Dashlet/ClassAttributeGroupByFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\LabelFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/LabelFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/OqlFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Expression\\AbstractExpressionFormBlock' => $baseDir . '/sources/Forms/Block/Expression/AbstractExpressionFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Expression\\BooleanExpressionFormBlock' => $baseDir . '/sources/Forms/Block/Expression/BooleanExpressionFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Expression\\NumberExpressionFormBlock' => $baseDir . '/sources/Forms/Block/Expression/NumberExpressionFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Expression\\StringExpressionFormBlock' => $baseDir . '/sources/Forms/Block/Expression/StringExpressionFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\FormBlockException' => $baseDir . '/sources/Forms/Block/FormBlockException.php', + 'Combodo\\iTop\\Forms\\Block\\FormBlockHelper' => $baseDir . '/sources/Forms/Block/FormBlockHelper.php', + 'Combodo\\iTop\\Forms\\Block\\FormBlockService' => $baseDir . '/sources/Forms/Block/FormBlockService.php', + 'Combodo\\iTop\\Forms\\Block\\IFormBlock' => $baseDir . '/sources/Forms/Block/IFormBlock.php', + 'Combodo\\iTop\\Forms\\Compiler\\FormsCompiler' => $baseDir . '/sources/Forms/Compiler/FormsCompiler.php', + 'Combodo\\iTop\\Forms\\Compiler\\FormsCompilerException' => $baseDir . '/sources/Forms/Compiler/FormsCompilerException.php', + 'Combodo\\iTop\\Forms\\Controller\\FormsController' => $baseDir . '/sources/Forms/Controller/FormsController.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\DependencyHandler' => $baseDir . '/sources/Forms/FormBuilder/DependencyHandler.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\DependencyMap' => $baseDir . '/sources/Forms/FormBuilder/DependencyMap.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\FormBuilder' => $baseDir . '/sources/Forms/FormBuilder/FormBuilder.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\FormBuilderException' => $baseDir . '/sources/Forms/FormBuilder/FormBuilderException.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\FormHelper' => $baseDir . '/sources/Forms/FormBuilder/FormHelper.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\FormTypeExtension' => $baseDir . '/sources/Forms/FormBuilder/FormTypeExtension.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\ResolvedFormType' => $baseDir . '/sources/Forms/FormBuilder/ResolvedFormType.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\ResolvedFormTypeFactory' => $baseDir . '/sources/Forms/FormBuilder/ResolvedFormTypeFactory.php', + 'Combodo\\iTop\\Forms\\FormType\\Base\\ChoiceFormType' => $baseDir . '/sources/Forms/FormType/Base/ChoiceFormType.php', + 'Combodo\\iTop\\Forms\\FormType\\Base\\CollectionFormType' => $baseDir . '/sources/Forms/FormType/Base/CollectionFormType.php', + 'Combodo\\iTop\\Forms\\FormType\\Base\\FormType' => $baseDir . '/sources/Forms/FormType/Base/FormType.php', + 'Combodo\\iTop\\Forms\\FormType\\DataModel\\OqlFormType' => $baseDir . '/sources/Forms/FormType/DataModel/OqlFormType.php', + 'Combodo\\iTop\\Forms\\FormType\\FormTypeHelper' => $baseDir . '/sources/Forms/FormType/FormTypeHelper.php', + 'Combodo\\iTop\\Forms\\Forms' => $baseDir . '/sources/Forms/Forms.php', + 'Combodo\\iTop\\Forms\\FormsException' => $baseDir . '/sources/Forms/FormsException.php', + 'Combodo\\iTop\\Forms\\IO\\AbstractFormIO' => $baseDir . '/sources/Forms/IO/AbstractFormIO.php', + 'Combodo\\iTop\\Forms\\IO\\Converter\\AbstractConverter' => $baseDir . '/sources/Forms/IO/Converter/AbstractConverter.php', + 'Combodo\\iTop\\Forms\\IO\\Converter\\ChoiceValueToLabelConverter' => $baseDir . '/sources/Forms/IO/Converter/ChoiceValueToLabelConverter.php', + 'Combodo\\iTop\\Forms\\IO\\Converter\\CollectionToCountConverter' => $baseDir . '/sources/Forms/IO/Converter/CollectionToCountConverter.php', + 'Combodo\\iTop\\Forms\\IO\\Converter\\OqlToClassConverter' => $baseDir . '/sources/Forms/IO/Converter/OqlToClassConverter.php', + 'Combodo\\iTop\\Forms\\IO\\FormBinding' => $baseDir . '/sources/Forms/IO/FormBinding.php', + 'Combodo\\iTop\\Forms\\IO\\FormBlockIOException' => $baseDir . '/sources/Forms/IO/FormBlockIOException.php', + 'Combodo\\iTop\\Forms\\IO\\FormInput' => $baseDir . '/sources/Forms/IO/FormInput.php', + 'Combodo\\iTop\\Forms\\IO\\FormOutput' => $baseDir . '/sources/Forms/IO/FormOutput.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\AbstractIOFormat' => $baseDir . '/sources/Forms/IO/Format/AbstractIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\AttributeIOFormat' => $baseDir . '/sources/Forms/IO/Format/AttributeIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\AttributeTypeArrayIOFormat' => $baseDir . '/sources/Forms/IO/Format/AttributeTypeArrayIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\AttributeTypeIOFormat' => $baseDir . '/sources/Forms/IO/Format/AttributeTypeIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\BooleanIOFormat' => $baseDir . '/sources/Forms/IO/Format/BooleanIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\ClassIOFormat' => $baseDir . '/sources/Forms/IO/Format/ClassIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\IntegerIOFormat' => $baseDir . '/sources/Forms/IO/Format/IntegerIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\NumberIOFormat' => $baseDir . '/sources/Forms/IO/Format/NumberIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\StringIOFormat' => $baseDir . '/sources/Forms/IO/Format/StringIOFormat.php', + 'Combodo\\iTop\\Forms\\Register\\IORegister' => $baseDir . '/sources/Forms/Register/IORegister.php', + 'Combodo\\iTop\\Forms\\Register\\Option' => $baseDir . '/sources/Forms/Register/Option.php', + 'Combodo\\iTop\\Forms\\Register\\OptionsRegister' => $baseDir . '/sources/Forms/Register/OptionsRegister.php', + 'Combodo\\iTop\\Forms\\Register\\RegisterException' => $baseDir . '/sources/Forms/Register/RegisterException.php', 'Combodo\\iTop\\Forms\\Twig\\Extension\\FormCompatibilityExtension' => $baseDir . '/sources/Forms/Twig/Extension/FormCompatibilityExtension.php', + 'Combodo\\iTop\\Forms\\Validator\\AttributeExist' => $baseDir . '/sources/Forms/Validator/AttributeExist.php', + 'Combodo\\iTop\\Forms\\Validator\\AttributeExistValidator' => $baseDir . '/sources/Forms/Validator/AttributeExistValidator.php', 'Combodo\\iTop\\PhpParser\\Evaluation\\PhpExpressionEvaluator' => $baseDir . '/sources/PhpParser/Evaluation/PhpExpressionEvaluator.php', + 'Combodo\\iTop\\PropertyTree\\AbstractProperty' => $baseDir . '/sources/PropertyTree/AbstractProperty.php', + 'Combodo\\iTop\\PropertyTree\\Property' => $baseDir . '/sources/PropertyTree/Property.php', + 'Combodo\\iTop\\PropertyTree\\PropertyTree' => $baseDir . '/sources/PropertyTree/PropertyTree.php', + 'Combodo\\iTop\\PropertyTree\\PropertyTreeDesign' => $baseDir . '/sources/PropertyTree/PropertyTreeDesign.php', + 'Combodo\\iTop\\PropertyTree\\PropertyTreeException' => $baseDir . '/sources/PropertyTree/PropertyTreeException.php', + 'Combodo\\iTop\\PropertyTree\\PropertyTreeFactory' => $baseDir . '/sources/PropertyTree/PropertyTreeFactory.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\AbstractValueType' => $baseDir . '/sources/PropertyTree/ValueType/AbstractValueType.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeAggregateFunction' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeAggregateFunction.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeBoolean' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeBoolean.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeChoice' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeChoice.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeChoiceFromInput' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeChoiceFromInput.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClass' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeClass.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClassAttribute' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeClassAttribute.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClassAttributeGroupBy' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeClassAttributeGroupBy.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClassAttributeValue' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeClassAttributeValue.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeCollection' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeCollection.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeFactory' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeFactory.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeIcon' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeIcon.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeInteger' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeInteger.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeLabel' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeLabel.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeOQL' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeOQL.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeProfileName' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeProfileName.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeString' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeString.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeText' => $baseDir . '/sources/PropertyTree/ValueType/ValueTypeText.php', 'Combodo\\iTop\\Renderer\\BlockRenderer' => $baseDir . '/sources/Renderer/BlockRenderer.php', 'Combodo\\iTop\\Renderer\\Bootstrap\\BsFieldRendererMappings' => $baseDir . '/sources/Renderer/Bootstrap/BsFieldRendererMappings.php', 'Combodo\\iTop\\Renderer\\Bootstrap\\BsFormRenderer' => $baseDir . '/sources/Renderer/Bootstrap/BsFormRenderer.php', @@ -497,6 +597,8 @@ 'Combodo\\iTop\\Service\\Base\\ObjectRepository' => $baseDir . '/sources/Service/Base/ObjectRepository.php', 'Combodo\\iTop\\Service\\Base\\iDataPostProcessor' => $baseDir . '/sources/Service/Base/iDataPostProcessor.php', 'Combodo\\iTop\\Service\\Cache\\DataModelDependantCache' => $baseDir . '/sources/Service/Cache/DataModelDependantCache.php', + 'Combodo\\iTop\\Service\\DependencyInjection\\DIException' => $baseDir . '/sources/Service/DependencyInjection/DIException.php', + 'Combodo\\iTop\\Service\\DependencyInjection\\DIService' => $baseDir . '/sources/Service/DependencyInjection/DIService.php', 'Combodo\\iTop\\Service\\Events\\Description\\EventDataDescription' => $baseDir . '/sources/Service/Events/Description/EventDataDescription.php', 'Combodo\\iTop\\Service\\Events\\Description\\EventDescription' => $baseDir . '/sources/Service/Events/Description/EventDescription.php', 'Combodo\\iTop\\Service\\Events\\EventData' => $baseDir . '/sources/Service/Events/EventData.php', @@ -3071,6 +3173,227 @@ 'Symfony\\Component\\String\\Slugger\\AsciiSlugger' => $vendorDir . '/symfony/string/Slugger/AsciiSlugger.php', 'Symfony\\Component\\String\\Slugger\\SluggerInterface' => $vendorDir . '/symfony/string/Slugger/SluggerInterface.php', 'Symfony\\Component\\String\\UnicodeString' => $vendorDir . '/symfony/string/UnicodeString.php', + 'Symfony\\Component\\Validator\\Attribute\\HasNamedArguments' => $vendorDir . '/symfony/validator/Attribute/HasNamedArguments.php', + 'Symfony\\Component\\Validator\\Command\\DebugCommand' => $vendorDir . '/symfony/validator/Command/DebugCommand.php', + 'Symfony\\Component\\Validator\\Constraint' => $vendorDir . '/symfony/validator/Constraint.php', + 'Symfony\\Component\\Validator\\ConstraintValidator' => $vendorDir . '/symfony/validator/ConstraintValidator.php', + 'Symfony\\Component\\Validator\\ConstraintValidatorFactory' => $vendorDir . '/symfony/validator/ConstraintValidatorFactory.php', + 'Symfony\\Component\\Validator\\ConstraintValidatorFactoryInterface' => $vendorDir . '/symfony/validator/ConstraintValidatorFactoryInterface.php', + 'Symfony\\Component\\Validator\\ConstraintValidatorInterface' => $vendorDir . '/symfony/validator/ConstraintValidatorInterface.php', + 'Symfony\\Component\\Validator\\ConstraintViolation' => $vendorDir . '/symfony/validator/ConstraintViolation.php', + 'Symfony\\Component\\Validator\\ConstraintViolationInterface' => $vendorDir . '/symfony/validator/ConstraintViolationInterface.php', + 'Symfony\\Component\\Validator\\ConstraintViolationList' => $vendorDir . '/symfony/validator/ConstraintViolationList.php', + 'Symfony\\Component\\Validator\\ConstraintViolationListInterface' => $vendorDir . '/symfony/validator/ConstraintViolationListInterface.php', + 'Symfony\\Component\\Validator\\Constraints\\AbstractComparison' => $vendorDir . '/symfony/validator/Constraints/AbstractComparison.php', + 'Symfony\\Component\\Validator\\Constraints\\AbstractComparisonValidator' => $vendorDir . '/symfony/validator/Constraints/AbstractComparisonValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\All' => $vendorDir . '/symfony/validator/Constraints/All.php', + 'Symfony\\Component\\Validator\\Constraints\\AllValidator' => $vendorDir . '/symfony/validator/Constraints/AllValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\AtLeastOneOf' => $vendorDir . '/symfony/validator/Constraints/AtLeastOneOf.php', + 'Symfony\\Component\\Validator\\Constraints\\AtLeastOneOfValidator' => $vendorDir . '/symfony/validator/Constraints/AtLeastOneOfValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Bic' => $vendorDir . '/symfony/validator/Constraints/Bic.php', + 'Symfony\\Component\\Validator\\Constraints\\BicValidator' => $vendorDir . '/symfony/validator/Constraints/BicValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Blank' => $vendorDir . '/symfony/validator/Constraints/Blank.php', + 'Symfony\\Component\\Validator\\Constraints\\BlankValidator' => $vendorDir . '/symfony/validator/Constraints/BlankValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Callback' => $vendorDir . '/symfony/validator/Constraints/Callback.php', + 'Symfony\\Component\\Validator\\Constraints\\CallbackValidator' => $vendorDir . '/symfony/validator/Constraints/CallbackValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\CardScheme' => $vendorDir . '/symfony/validator/Constraints/CardScheme.php', + 'Symfony\\Component\\Validator\\Constraints\\CardSchemeValidator' => $vendorDir . '/symfony/validator/Constraints/CardSchemeValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Cascade' => $vendorDir . '/symfony/validator/Constraints/Cascade.php', + 'Symfony\\Component\\Validator\\Constraints\\Choice' => $vendorDir . '/symfony/validator/Constraints/Choice.php', + 'Symfony\\Component\\Validator\\Constraints\\ChoiceValidator' => $vendorDir . '/symfony/validator/Constraints/ChoiceValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Cidr' => $vendorDir . '/symfony/validator/Constraints/Cidr.php', + 'Symfony\\Component\\Validator\\Constraints\\CidrValidator' => $vendorDir . '/symfony/validator/Constraints/CidrValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Collection' => $vendorDir . '/symfony/validator/Constraints/Collection.php', + 'Symfony\\Component\\Validator\\Constraints\\CollectionValidator' => $vendorDir . '/symfony/validator/Constraints/CollectionValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Composite' => $vendorDir . '/symfony/validator/Constraints/Composite.php', + 'Symfony\\Component\\Validator\\Constraints\\Compound' => $vendorDir . '/symfony/validator/Constraints/Compound.php', + 'Symfony\\Component\\Validator\\Constraints\\CompoundValidator' => $vendorDir . '/symfony/validator/Constraints/CompoundValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Count' => $vendorDir . '/symfony/validator/Constraints/Count.php', + 'Symfony\\Component\\Validator\\Constraints\\CountValidator' => $vendorDir . '/symfony/validator/Constraints/CountValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Country' => $vendorDir . '/symfony/validator/Constraints/Country.php', + 'Symfony\\Component\\Validator\\Constraints\\CountryValidator' => $vendorDir . '/symfony/validator/Constraints/CountryValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\CssColor' => $vendorDir . '/symfony/validator/Constraints/CssColor.php', + 'Symfony\\Component\\Validator\\Constraints\\CssColorValidator' => $vendorDir . '/symfony/validator/Constraints/CssColorValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Currency' => $vendorDir . '/symfony/validator/Constraints/Currency.php', + 'Symfony\\Component\\Validator\\Constraints\\CurrencyValidator' => $vendorDir . '/symfony/validator/Constraints/CurrencyValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Date' => $vendorDir . '/symfony/validator/Constraints/Date.php', + 'Symfony\\Component\\Validator\\Constraints\\DateTime' => $vendorDir . '/symfony/validator/Constraints/DateTime.php', + 'Symfony\\Component\\Validator\\Constraints\\DateTimeValidator' => $vendorDir . '/symfony/validator/Constraints/DateTimeValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\DateValidator' => $vendorDir . '/symfony/validator/Constraints/DateValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\DisableAutoMapping' => $vendorDir . '/symfony/validator/Constraints/DisableAutoMapping.php', + 'Symfony\\Component\\Validator\\Constraints\\DivisibleBy' => $vendorDir . '/symfony/validator/Constraints/DivisibleBy.php', + 'Symfony\\Component\\Validator\\Constraints\\DivisibleByValidator' => $vendorDir . '/symfony/validator/Constraints/DivisibleByValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Email' => $vendorDir . '/symfony/validator/Constraints/Email.php', + 'Symfony\\Component\\Validator\\Constraints\\EmailValidator' => $vendorDir . '/symfony/validator/Constraints/EmailValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\EnableAutoMapping' => $vendorDir . '/symfony/validator/Constraints/EnableAutoMapping.php', + 'Symfony\\Component\\Validator\\Constraints\\EqualTo' => $vendorDir . '/symfony/validator/Constraints/EqualTo.php', + 'Symfony\\Component\\Validator\\Constraints\\EqualToValidator' => $vendorDir . '/symfony/validator/Constraints/EqualToValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Existence' => $vendorDir . '/symfony/validator/Constraints/Existence.php', + 'Symfony\\Component\\Validator\\Constraints\\Expression' => $vendorDir . '/symfony/validator/Constraints/Expression.php', + 'Symfony\\Component\\Validator\\Constraints\\ExpressionLanguageProvider' => $vendorDir . '/symfony/validator/Constraints/ExpressionLanguageProvider.php', + 'Symfony\\Component\\Validator\\Constraints\\ExpressionLanguageSyntax' => $vendorDir . '/symfony/validator/Constraints/ExpressionLanguageSyntax.php', + 'Symfony\\Component\\Validator\\Constraints\\ExpressionLanguageSyntaxValidator' => $vendorDir . '/symfony/validator/Constraints/ExpressionLanguageSyntaxValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\ExpressionSyntax' => $vendorDir . '/symfony/validator/Constraints/ExpressionSyntax.php', + 'Symfony\\Component\\Validator\\Constraints\\ExpressionSyntaxValidator' => $vendorDir . '/symfony/validator/Constraints/ExpressionSyntaxValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\ExpressionValidator' => $vendorDir . '/symfony/validator/Constraints/ExpressionValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\File' => $vendorDir . '/symfony/validator/Constraints/File.php', + 'Symfony\\Component\\Validator\\Constraints\\FileValidator' => $vendorDir . '/symfony/validator/Constraints/FileValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\GreaterThan' => $vendorDir . '/symfony/validator/Constraints/GreaterThan.php', + 'Symfony\\Component\\Validator\\Constraints\\GreaterThanOrEqual' => $vendorDir . '/symfony/validator/Constraints/GreaterThanOrEqual.php', + 'Symfony\\Component\\Validator\\Constraints\\GreaterThanOrEqualValidator' => $vendorDir . '/symfony/validator/Constraints/GreaterThanOrEqualValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\GreaterThanValidator' => $vendorDir . '/symfony/validator/Constraints/GreaterThanValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\GroupSequence' => $vendorDir . '/symfony/validator/Constraints/GroupSequence.php', + 'Symfony\\Component\\Validator\\Constraints\\GroupSequenceProvider' => $vendorDir . '/symfony/validator/Constraints/GroupSequenceProvider.php', + 'Symfony\\Component\\Validator\\Constraints\\Hostname' => $vendorDir . '/symfony/validator/Constraints/Hostname.php', + 'Symfony\\Component\\Validator\\Constraints\\HostnameValidator' => $vendorDir . '/symfony/validator/Constraints/HostnameValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Iban' => $vendorDir . '/symfony/validator/Constraints/Iban.php', + 'Symfony\\Component\\Validator\\Constraints\\IbanValidator' => $vendorDir . '/symfony/validator/Constraints/IbanValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\IdenticalTo' => $vendorDir . '/symfony/validator/Constraints/IdenticalTo.php', + 'Symfony\\Component\\Validator\\Constraints\\IdenticalToValidator' => $vendorDir . '/symfony/validator/Constraints/IdenticalToValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Image' => $vendorDir . '/symfony/validator/Constraints/Image.php', + 'Symfony\\Component\\Validator\\Constraints\\ImageValidator' => $vendorDir . '/symfony/validator/Constraints/ImageValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Ip' => $vendorDir . '/symfony/validator/Constraints/Ip.php', + 'Symfony\\Component\\Validator\\Constraints\\IpValidator' => $vendorDir . '/symfony/validator/Constraints/IpValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\IsFalse' => $vendorDir . '/symfony/validator/Constraints/IsFalse.php', + 'Symfony\\Component\\Validator\\Constraints\\IsFalseValidator' => $vendorDir . '/symfony/validator/Constraints/IsFalseValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\IsNull' => $vendorDir . '/symfony/validator/Constraints/IsNull.php', + 'Symfony\\Component\\Validator\\Constraints\\IsNullValidator' => $vendorDir . '/symfony/validator/Constraints/IsNullValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\IsTrue' => $vendorDir . '/symfony/validator/Constraints/IsTrue.php', + 'Symfony\\Component\\Validator\\Constraints\\IsTrueValidator' => $vendorDir . '/symfony/validator/Constraints/IsTrueValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Isbn' => $vendorDir . '/symfony/validator/Constraints/Isbn.php', + 'Symfony\\Component\\Validator\\Constraints\\IsbnValidator' => $vendorDir . '/symfony/validator/Constraints/IsbnValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Isin' => $vendorDir . '/symfony/validator/Constraints/Isin.php', + 'Symfony\\Component\\Validator\\Constraints\\IsinValidator' => $vendorDir . '/symfony/validator/Constraints/IsinValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Issn' => $vendorDir . '/symfony/validator/Constraints/Issn.php', + 'Symfony\\Component\\Validator\\Constraints\\IssnValidator' => $vendorDir . '/symfony/validator/Constraints/IssnValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Json' => $vendorDir . '/symfony/validator/Constraints/Json.php', + 'Symfony\\Component\\Validator\\Constraints\\JsonValidator' => $vendorDir . '/symfony/validator/Constraints/JsonValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Language' => $vendorDir . '/symfony/validator/Constraints/Language.php', + 'Symfony\\Component\\Validator\\Constraints\\LanguageValidator' => $vendorDir . '/symfony/validator/Constraints/LanguageValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Length' => $vendorDir . '/symfony/validator/Constraints/Length.php', + 'Symfony\\Component\\Validator\\Constraints\\LengthValidator' => $vendorDir . '/symfony/validator/Constraints/LengthValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\LessThan' => $vendorDir . '/symfony/validator/Constraints/LessThan.php', + 'Symfony\\Component\\Validator\\Constraints\\LessThanOrEqual' => $vendorDir . '/symfony/validator/Constraints/LessThanOrEqual.php', + 'Symfony\\Component\\Validator\\Constraints\\LessThanOrEqualValidator' => $vendorDir . '/symfony/validator/Constraints/LessThanOrEqualValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\LessThanValidator' => $vendorDir . '/symfony/validator/Constraints/LessThanValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Locale' => $vendorDir . '/symfony/validator/Constraints/Locale.php', + 'Symfony\\Component\\Validator\\Constraints\\LocaleValidator' => $vendorDir . '/symfony/validator/Constraints/LocaleValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Luhn' => $vendorDir . '/symfony/validator/Constraints/Luhn.php', + 'Symfony\\Component\\Validator\\Constraints\\LuhnValidator' => $vendorDir . '/symfony/validator/Constraints/LuhnValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Negative' => $vendorDir . '/symfony/validator/Constraints/Negative.php', + 'Symfony\\Component\\Validator\\Constraints\\NegativeOrZero' => $vendorDir . '/symfony/validator/Constraints/NegativeOrZero.php', + 'Symfony\\Component\\Validator\\Constraints\\NoSuspiciousCharacters' => $vendorDir . '/symfony/validator/Constraints/NoSuspiciousCharacters.php', + 'Symfony\\Component\\Validator\\Constraints\\NoSuspiciousCharactersValidator' => $vendorDir . '/symfony/validator/Constraints/NoSuspiciousCharactersValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\NotBlank' => $vendorDir . '/symfony/validator/Constraints/NotBlank.php', + 'Symfony\\Component\\Validator\\Constraints\\NotBlankValidator' => $vendorDir . '/symfony/validator/Constraints/NotBlankValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\NotCompromisedPassword' => $vendorDir . '/symfony/validator/Constraints/NotCompromisedPassword.php', + 'Symfony\\Component\\Validator\\Constraints\\NotCompromisedPasswordValidator' => $vendorDir . '/symfony/validator/Constraints/NotCompromisedPasswordValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\NotEqualTo' => $vendorDir . '/symfony/validator/Constraints/NotEqualTo.php', + 'Symfony\\Component\\Validator\\Constraints\\NotEqualToValidator' => $vendorDir . '/symfony/validator/Constraints/NotEqualToValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\NotIdenticalTo' => $vendorDir . '/symfony/validator/Constraints/NotIdenticalTo.php', + 'Symfony\\Component\\Validator\\Constraints\\NotIdenticalToValidator' => $vendorDir . '/symfony/validator/Constraints/NotIdenticalToValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\NotNull' => $vendorDir . '/symfony/validator/Constraints/NotNull.php', + 'Symfony\\Component\\Validator\\Constraints\\NotNullValidator' => $vendorDir . '/symfony/validator/Constraints/NotNullValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Optional' => $vendorDir . '/symfony/validator/Constraints/Optional.php', + 'Symfony\\Component\\Validator\\Constraints\\PasswordStrength' => $vendorDir . '/symfony/validator/Constraints/PasswordStrength.php', + 'Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator' => $vendorDir . '/symfony/validator/Constraints/PasswordStrengthValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Positive' => $vendorDir . '/symfony/validator/Constraints/Positive.php', + 'Symfony\\Component\\Validator\\Constraints\\PositiveOrZero' => $vendorDir . '/symfony/validator/Constraints/PositiveOrZero.php', + 'Symfony\\Component\\Validator\\Constraints\\Range' => $vendorDir . '/symfony/validator/Constraints/Range.php', + 'Symfony\\Component\\Validator\\Constraints\\RangeValidator' => $vendorDir . '/symfony/validator/Constraints/RangeValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Regex' => $vendorDir . '/symfony/validator/Constraints/Regex.php', + 'Symfony\\Component\\Validator\\Constraints\\RegexValidator' => $vendorDir . '/symfony/validator/Constraints/RegexValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Required' => $vendorDir . '/symfony/validator/Constraints/Required.php', + 'Symfony\\Component\\Validator\\Constraints\\Sequentially' => $vendorDir . '/symfony/validator/Constraints/Sequentially.php', + 'Symfony\\Component\\Validator\\Constraints\\SequentiallyValidator' => $vendorDir . '/symfony/validator/Constraints/SequentiallyValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Time' => $vendorDir . '/symfony/validator/Constraints/Time.php', + 'Symfony\\Component\\Validator\\Constraints\\TimeValidator' => $vendorDir . '/symfony/validator/Constraints/TimeValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Timezone' => $vendorDir . '/symfony/validator/Constraints/Timezone.php', + 'Symfony\\Component\\Validator\\Constraints\\TimezoneValidator' => $vendorDir . '/symfony/validator/Constraints/TimezoneValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Traverse' => $vendorDir . '/symfony/validator/Constraints/Traverse.php', + 'Symfony\\Component\\Validator\\Constraints\\Type' => $vendorDir . '/symfony/validator/Constraints/Type.php', + 'Symfony\\Component\\Validator\\Constraints\\TypeValidator' => $vendorDir . '/symfony/validator/Constraints/TypeValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Ulid' => $vendorDir . '/symfony/validator/Constraints/Ulid.php', + 'Symfony\\Component\\Validator\\Constraints\\UlidValidator' => $vendorDir . '/symfony/validator/Constraints/UlidValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Unique' => $vendorDir . '/symfony/validator/Constraints/Unique.php', + 'Symfony\\Component\\Validator\\Constraints\\UniqueValidator' => $vendorDir . '/symfony/validator/Constraints/UniqueValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Url' => $vendorDir . '/symfony/validator/Constraints/Url.php', + 'Symfony\\Component\\Validator\\Constraints\\UrlValidator' => $vendorDir . '/symfony/validator/Constraints/UrlValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Uuid' => $vendorDir . '/symfony/validator/Constraints/Uuid.php', + 'Symfony\\Component\\Validator\\Constraints\\UuidValidator' => $vendorDir . '/symfony/validator/Constraints/UuidValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Valid' => $vendorDir . '/symfony/validator/Constraints/Valid.php', + 'Symfony\\Component\\Validator\\Constraints\\ValidValidator' => $vendorDir . '/symfony/validator/Constraints/ValidValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\When' => $vendorDir . '/symfony/validator/Constraints/When.php', + 'Symfony\\Component\\Validator\\Constraints\\WhenValidator' => $vendorDir . '/symfony/validator/Constraints/WhenValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\ZeroComparisonConstraintTrait' => $vendorDir . '/symfony/validator/Constraints/ZeroComparisonConstraintTrait.php', + 'Symfony\\Component\\Validator\\ContainerConstraintValidatorFactory' => $vendorDir . '/symfony/validator/ContainerConstraintValidatorFactory.php', + 'Symfony\\Component\\Validator\\Context\\ExecutionContext' => $vendorDir . '/symfony/validator/Context/ExecutionContext.php', + 'Symfony\\Component\\Validator\\Context\\ExecutionContextFactory' => $vendorDir . '/symfony/validator/Context/ExecutionContextFactory.php', + 'Symfony\\Component\\Validator\\Context\\ExecutionContextFactoryInterface' => $vendorDir . '/symfony/validator/Context/ExecutionContextFactoryInterface.php', + 'Symfony\\Component\\Validator\\Context\\ExecutionContextInterface' => $vendorDir . '/symfony/validator/Context/ExecutionContextInterface.php', + 'Symfony\\Component\\Validator\\DataCollector\\ValidatorDataCollector' => $vendorDir . '/symfony/validator/DataCollector/ValidatorDataCollector.php', + 'Symfony\\Component\\Validator\\DependencyInjection\\AddAutoMappingConfigurationPass' => $vendorDir . '/symfony/validator/DependencyInjection/AddAutoMappingConfigurationPass.php', + 'Symfony\\Component\\Validator\\DependencyInjection\\AddConstraintValidatorsPass' => $vendorDir . '/symfony/validator/DependencyInjection/AddConstraintValidatorsPass.php', + 'Symfony\\Component\\Validator\\DependencyInjection\\AddValidatorInitializersPass' => $vendorDir . '/symfony/validator/DependencyInjection/AddValidatorInitializersPass.php', + 'Symfony\\Component\\Validator\\Exception\\BadMethodCallException' => $vendorDir . '/symfony/validator/Exception/BadMethodCallException.php', + 'Symfony\\Component\\Validator\\Exception\\ConstraintDefinitionException' => $vendorDir . '/symfony/validator/Exception/ConstraintDefinitionException.php', + 'Symfony\\Component\\Validator\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/validator/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Validator\\Exception\\GroupDefinitionException' => $vendorDir . '/symfony/validator/Exception/GroupDefinitionException.php', + 'Symfony\\Component\\Validator\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/validator/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\Validator\\Exception\\InvalidOptionsException' => $vendorDir . '/symfony/validator/Exception/InvalidOptionsException.php', + 'Symfony\\Component\\Validator\\Exception\\LogicException' => $vendorDir . '/symfony/validator/Exception/LogicException.php', + 'Symfony\\Component\\Validator\\Exception\\MappingException' => $vendorDir . '/symfony/validator/Exception/MappingException.php', + 'Symfony\\Component\\Validator\\Exception\\MissingOptionsException' => $vendorDir . '/symfony/validator/Exception/MissingOptionsException.php', + 'Symfony\\Component\\Validator\\Exception\\NoSuchMetadataException' => $vendorDir . '/symfony/validator/Exception/NoSuchMetadataException.php', + 'Symfony\\Component\\Validator\\Exception\\OutOfBoundsException' => $vendorDir . '/symfony/validator/Exception/OutOfBoundsException.php', + 'Symfony\\Component\\Validator\\Exception\\RuntimeException' => $vendorDir . '/symfony/validator/Exception/RuntimeException.php', + 'Symfony\\Component\\Validator\\Exception\\UnexpectedTypeException' => $vendorDir . '/symfony/validator/Exception/UnexpectedTypeException.php', + 'Symfony\\Component\\Validator\\Exception\\UnexpectedValueException' => $vendorDir . '/symfony/validator/Exception/UnexpectedValueException.php', + 'Symfony\\Component\\Validator\\Exception\\UnsupportedMetadataException' => $vendorDir . '/symfony/validator/Exception/UnsupportedMetadataException.php', + 'Symfony\\Component\\Validator\\Exception\\ValidationFailedException' => $vendorDir . '/symfony/validator/Exception/ValidationFailedException.php', + 'Symfony\\Component\\Validator\\Exception\\ValidatorException' => $vendorDir . '/symfony/validator/Exception/ValidatorException.php', + 'Symfony\\Component\\Validator\\GroupProviderInterface' => $vendorDir . '/symfony/validator/GroupProviderInterface.php', + 'Symfony\\Component\\Validator\\GroupSequenceProviderInterface' => $vendorDir . '/symfony/validator/GroupSequenceProviderInterface.php', + 'Symfony\\Component\\Validator\\Mapping\\AutoMappingStrategy' => $vendorDir . '/symfony/validator/Mapping/AutoMappingStrategy.php', + 'Symfony\\Component\\Validator\\Mapping\\CascadingStrategy' => $vendorDir . '/symfony/validator/Mapping/CascadingStrategy.php', + 'Symfony\\Component\\Validator\\Mapping\\ClassMetadata' => $vendorDir . '/symfony/validator/Mapping/ClassMetadata.php', + 'Symfony\\Component\\Validator\\Mapping\\ClassMetadataInterface' => $vendorDir . '/symfony/validator/Mapping/ClassMetadataInterface.php', + 'Symfony\\Component\\Validator\\Mapping\\Factory\\BlackHoleMetadataFactory' => $vendorDir . '/symfony/validator/Mapping/Factory/BlackHoleMetadataFactory.php', + 'Symfony\\Component\\Validator\\Mapping\\Factory\\LazyLoadingMetadataFactory' => $vendorDir . '/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php', + 'Symfony\\Component\\Validator\\Mapping\\Factory\\MetadataFactoryInterface' => $vendorDir . '/symfony/validator/Mapping/Factory/MetadataFactoryInterface.php', + 'Symfony\\Component\\Validator\\Mapping\\GenericMetadata' => $vendorDir . '/symfony/validator/Mapping/GenericMetadata.php', + 'Symfony\\Component\\Validator\\Mapping\\GetterMetadata' => $vendorDir . '/symfony/validator/Mapping/GetterMetadata.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\AbstractLoader' => $vendorDir . '/symfony/validator/Mapping/Loader/AbstractLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\AnnotationLoader' => $vendorDir . '/symfony/validator/Mapping/Loader/AnnotationLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\AttributeLoader' => $vendorDir . '/symfony/validator/Mapping/Loader/AttributeLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\AutoMappingTrait' => $vendorDir . '/symfony/validator/Mapping/Loader/AutoMappingTrait.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\FileLoader' => $vendorDir . '/symfony/validator/Mapping/Loader/FileLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\FilesLoader' => $vendorDir . '/symfony/validator/Mapping/Loader/FilesLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\LoaderChain' => $vendorDir . '/symfony/validator/Mapping/Loader/LoaderChain.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\LoaderInterface' => $vendorDir . '/symfony/validator/Mapping/Loader/LoaderInterface.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\PropertyInfoLoader' => $vendorDir . '/symfony/validator/Mapping/Loader/PropertyInfoLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\StaticMethodLoader' => $vendorDir . '/symfony/validator/Mapping/Loader/StaticMethodLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\XmlFileLoader' => $vendorDir . '/symfony/validator/Mapping/Loader/XmlFileLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\XmlFilesLoader' => $vendorDir . '/symfony/validator/Mapping/Loader/XmlFilesLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\YamlFileLoader' => $vendorDir . '/symfony/validator/Mapping/Loader/YamlFileLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\YamlFilesLoader' => $vendorDir . '/symfony/validator/Mapping/Loader/YamlFilesLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\MemberMetadata' => $vendorDir . '/symfony/validator/Mapping/MemberMetadata.php', + 'Symfony\\Component\\Validator\\Mapping\\MetadataInterface' => $vendorDir . '/symfony/validator/Mapping/MetadataInterface.php', + 'Symfony\\Component\\Validator\\Mapping\\PropertyMetadata' => $vendorDir . '/symfony/validator/Mapping/PropertyMetadata.php', + 'Symfony\\Component\\Validator\\Mapping\\PropertyMetadataInterface' => $vendorDir . '/symfony/validator/Mapping/PropertyMetadataInterface.php', + 'Symfony\\Component\\Validator\\Mapping\\TraversalStrategy' => $vendorDir . '/symfony/validator/Mapping/TraversalStrategy.php', + 'Symfony\\Component\\Validator\\ObjectInitializerInterface' => $vendorDir . '/symfony/validator/ObjectInitializerInterface.php', + 'Symfony\\Component\\Validator\\Util\\PropertyPath' => $vendorDir . '/symfony/validator/Util/PropertyPath.php', + 'Symfony\\Component\\Validator\\Validation' => $vendorDir . '/symfony/validator/Validation.php', + 'Symfony\\Component\\Validator\\ValidatorBuilder' => $vendorDir . '/symfony/validator/ValidatorBuilder.php', + 'Symfony\\Component\\Validator\\Validator\\ContextualValidatorInterface' => $vendorDir . '/symfony/validator/Validator/ContextualValidatorInterface.php', + 'Symfony\\Component\\Validator\\Validator\\LazyProperty' => $vendorDir . '/symfony/validator/Validator/LazyProperty.php', + 'Symfony\\Component\\Validator\\Validator\\RecursiveContextualValidator' => $vendorDir . '/symfony/validator/Validator/RecursiveContextualValidator.php', + 'Symfony\\Component\\Validator\\Validator\\RecursiveValidator' => $vendorDir . '/symfony/validator/Validator/RecursiveValidator.php', + 'Symfony\\Component\\Validator\\Validator\\TraceableValidator' => $vendorDir . '/symfony/validator/Validator/TraceableValidator.php', + 'Symfony\\Component\\Validator\\Validator\\ValidatorInterface' => $vendorDir . '/symfony/validator/Validator/ValidatorInterface.php', + 'Symfony\\Component\\Validator\\Violation\\ConstraintViolationBuilder' => $vendorDir . '/symfony/validator/Violation/ConstraintViolationBuilder.php', + 'Symfony\\Component\\Validator\\Violation\\ConstraintViolationBuilderInterface' => $vendorDir . '/symfony/validator/Violation/ConstraintViolationBuilderInterface.php', 'Symfony\\Component\\VarDumper\\Caster\\AmqpCaster' => $vendorDir . '/symfony/var-dumper/Caster/AmqpCaster.php', 'Symfony\\Component\\VarDumper\\Caster\\ArgsStub' => $vendorDir . '/symfony/var-dumper/Caster/ArgsStub.php', 'Symfony\\Component\\VarDumper\\Caster\\Caster' => $vendorDir . '/symfony/var-dumper/Caster/Caster.php', diff --git a/lib/composer/autoload_psr4.php b/lib/composer/autoload_psr4.php index 602597214b..15036b1a53 100644 --- a/lib/composer/autoload_psr4.php +++ b/lib/composer/autoload_psr4.php @@ -22,6 +22,7 @@ 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'), 'Symfony\\Component\\VarExporter\\' => array($vendorDir . '/symfony/var-exporter'), 'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'), + 'Symfony\\Component\\Validator\\' => array($vendorDir . '/symfony/validator'), 'Symfony\\Component\\String\\' => array($vendorDir . '/symfony/string'), 'Symfony\\Component\\Stopwatch\\' => array($vendorDir . '/symfony/stopwatch'), 'Symfony\\Component\\Security\\Csrf\\' => array($vendorDir . '/symfony/security-csrf'), diff --git a/lib/composer/autoload_static.php b/lib/composer/autoload_static.php index 7c85ebdb58..ab4134cc7a 100644 --- a/lib/composer/autoload_static.php +++ b/lib/composer/autoload_static.php @@ -49,6 +49,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Symfony\\Component\\Yaml\\' => 23, 'Symfony\\Component\\VarExporter\\' => 30, 'Symfony\\Component\\VarDumper\\' => 28, + 'Symfony\\Component\\Validator\\' => 28, 'Symfony\\Component\\String\\' => 25, 'Symfony\\Component\\Stopwatch\\' => 28, 'Symfony\\Component\\Security\\Csrf\\' => 32, @@ -181,6 +182,10 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f array ( 0 => __DIR__ . '/..' . '/symfony/var-dumper', ), + 'Symfony\\Component\\Validator\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/validator', + ), 'Symfony\\Component\\String\\' => array ( 0 => __DIR__ . '/..' . '/symfony/string', @@ -625,6 +630,10 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Toolbar\\ToolbarSpacer\\ToolbarSpacer' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Toolbar/ToolbarSpacer/ToolbarSpacer.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Toolbar\\ToolbarSpacer\\ToolbarSpacerUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Toolbar/ToolbarSpacer/ToolbarSpacerUIBlockFactory.php', 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Toolbar\\ToolbarUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Toolbar/ToolbarUIBlockFactory.php', + 'Combodo\\iTop\\Application\\UI\\Base\\Component\\TurboForm\\TurboForm' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/TurboForm/TurboForm.php', + 'Combodo\\iTop\\Application\\UI\\Base\\Component\\TurboForm\\TurboFormUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/TurboForm/TurboFormUIBlockFactory.php', + 'Combodo\\iTop\\Application\\UI\\Base\\Component\\TurboUpdate\\TurboStream' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/TurboStream/TurboStream.php', + 'Combodo\\iTop\\Application\\UI\\Base\\Component\\TurboUpdate\\TurboStreamUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/TurboStream/TurboStreamUIBlockFactory.php', 'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityEntry\\ActivityEntry' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityEntry/ActivityEntry.php', 'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityEntry\\ActivityEntryFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityEntry/ActivityEntryFactory.php', 'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\ActivityEntry\\CMDBChangeOp\\CMDBChangeOpAttachmentAddedFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/ActivityEntry/CMDBChangeOp/CMDBChangeOpAttachmentAddedFactory.php', @@ -722,6 +731,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Combodo\\iTop\\Controller\\AjaxRenderController' => __DIR__ . '/../..' . '/sources/Controller/AjaxRenderController.php', 'Combodo\\iTop\\Controller\\Base\\Layout\\ActivityPanelController' => __DIR__ . '/../..' . '/sources/Controller/Base/Layout/ActivityPanelController.php', 'Combodo\\iTop\\Controller\\Base\\Layout\\ObjectController' => __DIR__ . '/../..' . '/sources/Controller/Base/Layout/ObjectController.php', + 'Combodo\\iTop\\Controller\\Base\\Layout\\OqlController' => __DIR__ . '/../..' . '/sources/Controller/Base/Layout/OqlController.php', 'Combodo\\iTop\\Controller\\Links\\LinkSetController' => __DIR__ . '/../..' . '/sources/Controller/Links/LinkSetController.php', 'Combodo\\iTop\\Controller\\Newsroom\\iTopNewsroomController' => __DIR__ . '/../..' . '/sources/Controller/Newsroom/iTopNewsroomController.php', 'Combodo\\iTop\\Controller\\Notifications\\ActionController' => __DIR__ . '/../..' . '/sources/Controller/Notifications/ActionController.php', @@ -854,8 +864,103 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Combodo\\iTop\\Form\\Validator\\MultipleChoicesValidator' => __DIR__ . '/../..' . '/sources/Form/Validator/MultipleChoicesValidator.php', 'Combodo\\iTop\\Form\\Validator\\NotEmptyExtKeyValidator' => __DIR__ . '/../..' . '/sources/Form/Validator/NotEmptyExtKeyValidator.php', 'Combodo\\iTop\\Form\\Validator\\SelectObjectValidator' => __DIR__ . '/../..' . '/sources/Form/Validator/SelectObjectValidator.php', + 'Combodo\\iTop\\Forms\\Block\\AbstractFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/AbstractFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\AbstractTypeFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/AbstractTypeFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\CheckboxFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/CheckboxFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/ChoiceFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFromInputsBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/ChoiceFromInputsBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\CollectionBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/CollectionBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\DateFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/DateFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\DateTimeFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/DateTimeFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\FormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/FormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\HiddenFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/HiddenFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\IntegerFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/IntegerFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\NumberFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/NumberFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\TextAreaFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/TextAreaFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/TextFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeTypeChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeTypeChoiceFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeValueChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\Dashlet\\AggregateFunctionFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/Dashlet/AggregateFunctionFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\Dashlet\\ClassAttributeGroupByFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/Dashlet/ClassAttributeGroupByFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\LabelFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/LabelFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/OqlFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Expression\\AbstractExpressionFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Expression/AbstractExpressionFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Expression\\BooleanExpressionFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Expression/BooleanExpressionFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Expression\\NumberExpressionFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Expression/NumberExpressionFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\Expression\\StringExpressionFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Expression/StringExpressionFormBlock.php', + 'Combodo\\iTop\\Forms\\Block\\FormBlockException' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockException.php', + 'Combodo\\iTop\\Forms\\Block\\FormBlockHelper' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockHelper.php', + 'Combodo\\iTop\\Forms\\Block\\FormBlockService' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockService.php', + 'Combodo\\iTop\\Forms\\Block\\IFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/IFormBlock.php', + 'Combodo\\iTop\\Forms\\Compiler\\FormsCompiler' => __DIR__ . '/../..' . '/sources/Forms/Compiler/FormsCompiler.php', + 'Combodo\\iTop\\Forms\\Compiler\\FormsCompilerException' => __DIR__ . '/../..' . '/sources/Forms/Compiler/FormsCompilerException.php', + 'Combodo\\iTop\\Forms\\Controller\\FormsController' => __DIR__ . '/../..' . '/sources/Forms/Controller/FormsController.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\DependencyHandler' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/DependencyHandler.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\DependencyMap' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/DependencyMap.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\FormBuilder' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/FormBuilder.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\FormBuilderException' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/FormBuilderException.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\FormHelper' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/FormHelper.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\FormTypeExtension' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/FormTypeExtension.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\ResolvedFormType' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/ResolvedFormType.php', + 'Combodo\\iTop\\Forms\\FormBuilder\\ResolvedFormTypeFactory' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/ResolvedFormTypeFactory.php', + 'Combodo\\iTop\\Forms\\FormType\\Base\\ChoiceFormType' => __DIR__ . '/../..' . '/sources/Forms/FormType/Base/ChoiceFormType.php', + 'Combodo\\iTop\\Forms\\FormType\\Base\\CollectionFormType' => __DIR__ . '/../..' . '/sources/Forms/FormType/Base/CollectionFormType.php', + 'Combodo\\iTop\\Forms\\FormType\\Base\\FormType' => __DIR__ . '/../..' . '/sources/Forms/FormType/Base/FormType.php', + 'Combodo\\iTop\\Forms\\FormType\\DataModel\\OqlFormType' => __DIR__ . '/../..' . '/sources/Forms/FormType/DataModel/OqlFormType.php', + 'Combodo\\iTop\\Forms\\FormType\\FormTypeHelper' => __DIR__ . '/../..' . '/sources/Forms/FormType/FormTypeHelper.php', + 'Combodo\\iTop\\Forms\\Forms' => __DIR__ . '/../..' . '/sources/Forms/Forms.php', + 'Combodo\\iTop\\Forms\\FormsException' => __DIR__ . '/../..' . '/sources/Forms/FormsException.php', + 'Combodo\\iTop\\Forms\\IO\\AbstractFormIO' => __DIR__ . '/../..' . '/sources/Forms/IO/AbstractFormIO.php', + 'Combodo\\iTop\\Forms\\IO\\Converter\\AbstractConverter' => __DIR__ . '/../..' . '/sources/Forms/IO/Converter/AbstractConverter.php', + 'Combodo\\iTop\\Forms\\IO\\Converter\\ChoiceValueToLabelConverter' => __DIR__ . '/../..' . '/sources/Forms/IO/Converter/ChoiceValueToLabelConverter.php', + 'Combodo\\iTop\\Forms\\IO\\Converter\\CollectionToCountConverter' => __DIR__ . '/../..' . '/sources/Forms/IO/Converter/CollectionToCountConverter.php', + 'Combodo\\iTop\\Forms\\IO\\Converter\\OqlToClassConverter' => __DIR__ . '/../..' . '/sources/Forms/IO/Converter/OqlToClassConverter.php', + 'Combodo\\iTop\\Forms\\IO\\FormBinding' => __DIR__ . '/../..' . '/sources/Forms/IO/FormBinding.php', + 'Combodo\\iTop\\Forms\\IO\\FormBlockIOException' => __DIR__ . '/../..' . '/sources/Forms/IO/FormBlockIOException.php', + 'Combodo\\iTop\\Forms\\IO\\FormInput' => __DIR__ . '/../..' . '/sources/Forms/IO/FormInput.php', + 'Combodo\\iTop\\Forms\\IO\\FormOutput' => __DIR__ . '/../..' . '/sources/Forms/IO/FormOutput.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\AbstractIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/AbstractIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\AttributeIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/AttributeIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\AttributeTypeArrayIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/AttributeTypeArrayIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\AttributeTypeIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/AttributeTypeIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\BooleanIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/BooleanIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\ClassIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/ClassIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\IntegerIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/IntegerIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\NumberIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/NumberIOFormat.php', + 'Combodo\\iTop\\Forms\\IO\\Format\\StringIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/StringIOFormat.php', + 'Combodo\\iTop\\Forms\\Register\\IORegister' => __DIR__ . '/../..' . '/sources/Forms/Register/IORegister.php', + 'Combodo\\iTop\\Forms\\Register\\Option' => __DIR__ . '/../..' . '/sources/Forms/Register/Option.php', + 'Combodo\\iTop\\Forms\\Register\\OptionsRegister' => __DIR__ . '/../..' . '/sources/Forms/Register/OptionsRegister.php', + 'Combodo\\iTop\\Forms\\Register\\RegisterException' => __DIR__ . '/../..' . '/sources/Forms/Register/RegisterException.php', 'Combodo\\iTop\\Forms\\Twig\\Extension\\FormCompatibilityExtension' => __DIR__ . '/../..' . '/sources/Forms/Twig/Extension/FormCompatibilityExtension.php', + 'Combodo\\iTop\\Forms\\Validator\\AttributeExist' => __DIR__ . '/../..' . '/sources/Forms/Validator/AttributeExist.php', + 'Combodo\\iTop\\Forms\\Validator\\AttributeExistValidator' => __DIR__ . '/../..' . '/sources/Forms/Validator/AttributeExistValidator.php', 'Combodo\\iTop\\PhpParser\\Evaluation\\PhpExpressionEvaluator' => __DIR__ . '/../..' . '/sources/PhpParser/Evaluation/PhpExpressionEvaluator.php', + 'Combodo\\iTop\\PropertyTree\\AbstractProperty' => __DIR__ . '/../..' . '/sources/PropertyTree/AbstractProperty.php', + 'Combodo\\iTop\\PropertyTree\\Property' => __DIR__ . '/../..' . '/sources/PropertyTree/Property.php', + 'Combodo\\iTop\\PropertyTree\\PropertyTree' => __DIR__ . '/../..' . '/sources/PropertyTree/PropertyTree.php', + 'Combodo\\iTop\\PropertyTree\\PropertyTreeDesign' => __DIR__ . '/../..' . '/sources/PropertyTree/PropertyTreeDesign.php', + 'Combodo\\iTop\\PropertyTree\\PropertyTreeException' => __DIR__ . '/../..' . '/sources/PropertyTree/PropertyTreeException.php', + 'Combodo\\iTop\\PropertyTree\\PropertyTreeFactory' => __DIR__ . '/../..' . '/sources/PropertyTree/PropertyTreeFactory.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\AbstractValueType' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/AbstractValueType.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeAggregateFunction' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeAggregateFunction.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeBoolean' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeBoolean.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeChoice' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeChoice.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeChoiceFromInput' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeChoiceFromInput.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClass' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeClass.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClassAttribute' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeClassAttribute.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClassAttributeGroupBy' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeClassAttributeGroupBy.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeClassAttributeValue' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeClassAttributeValue.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeCollection' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeCollection.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeFactory' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeFactory.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeIcon' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeIcon.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeInteger' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeInteger.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeLabel' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeLabel.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeOQL' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeOQL.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeProfileName' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeProfileName.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeString' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeString.php', + 'Combodo\\iTop\\PropertyTree\\ValueType\\ValueTypeText' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/ValueTypeText.php', 'Combodo\\iTop\\Renderer\\BlockRenderer' => __DIR__ . '/../..' . '/sources/Renderer/BlockRenderer.php', 'Combodo\\iTop\\Renderer\\Bootstrap\\BsFieldRendererMappings' => __DIR__ . '/../..' . '/sources/Renderer/Bootstrap/BsFieldRendererMappings.php', 'Combodo\\iTop\\Renderer\\Bootstrap\\BsFormRenderer' => __DIR__ . '/../..' . '/sources/Renderer/Bootstrap/BsFormRenderer.php', @@ -878,6 +983,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Combodo\\iTop\\Service\\Base\\ObjectRepository' => __DIR__ . '/../..' . '/sources/Service/Base/ObjectRepository.php', 'Combodo\\iTop\\Service\\Base\\iDataPostProcessor' => __DIR__ . '/../..' . '/sources/Service/Base/iDataPostProcessor.php', 'Combodo\\iTop\\Service\\Cache\\DataModelDependantCache' => __DIR__ . '/../..' . '/sources/Service/Cache/DataModelDependantCache.php', + 'Combodo\\iTop\\Service\\DependencyInjection\\DIException' => __DIR__ . '/../..' . '/sources/Service/DependencyInjection/DIException.php', + 'Combodo\\iTop\\Service\\DependencyInjection\\DIService' => __DIR__ . '/../..' . '/sources/Service/DependencyInjection/DIService.php', 'Combodo\\iTop\\Service\\Events\\Description\\EventDataDescription' => __DIR__ . '/../..' . '/sources/Service/Events/Description/EventDataDescription.php', 'Combodo\\iTop\\Service\\Events\\Description\\EventDescription' => __DIR__ . '/../..' . '/sources/Service/Events/Description/EventDescription.php', 'Combodo\\iTop\\Service\\Events\\EventData' => __DIR__ . '/../..' . '/sources/Service/Events/EventData.php', @@ -3452,6 +3559,227 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Symfony\\Component\\String\\Slugger\\AsciiSlugger' => __DIR__ . '/..' . '/symfony/string/Slugger/AsciiSlugger.php', 'Symfony\\Component\\String\\Slugger\\SluggerInterface' => __DIR__ . '/..' . '/symfony/string/Slugger/SluggerInterface.php', 'Symfony\\Component\\String\\UnicodeString' => __DIR__ . '/..' . '/symfony/string/UnicodeString.php', + 'Symfony\\Component\\Validator\\Attribute\\HasNamedArguments' => __DIR__ . '/..' . '/symfony/validator/Attribute/HasNamedArguments.php', + 'Symfony\\Component\\Validator\\Command\\DebugCommand' => __DIR__ . '/..' . '/symfony/validator/Command/DebugCommand.php', + 'Symfony\\Component\\Validator\\Constraint' => __DIR__ . '/..' . '/symfony/validator/Constraint.php', + 'Symfony\\Component\\Validator\\ConstraintValidator' => __DIR__ . '/..' . '/symfony/validator/ConstraintValidator.php', + 'Symfony\\Component\\Validator\\ConstraintValidatorFactory' => __DIR__ . '/..' . '/symfony/validator/ConstraintValidatorFactory.php', + 'Symfony\\Component\\Validator\\ConstraintValidatorFactoryInterface' => __DIR__ . '/..' . '/symfony/validator/ConstraintValidatorFactoryInterface.php', + 'Symfony\\Component\\Validator\\ConstraintValidatorInterface' => __DIR__ . '/..' . '/symfony/validator/ConstraintValidatorInterface.php', + 'Symfony\\Component\\Validator\\ConstraintViolation' => __DIR__ . '/..' . '/symfony/validator/ConstraintViolation.php', + 'Symfony\\Component\\Validator\\ConstraintViolationInterface' => __DIR__ . '/..' . '/symfony/validator/ConstraintViolationInterface.php', + 'Symfony\\Component\\Validator\\ConstraintViolationList' => __DIR__ . '/..' . '/symfony/validator/ConstraintViolationList.php', + 'Symfony\\Component\\Validator\\ConstraintViolationListInterface' => __DIR__ . '/..' . '/symfony/validator/ConstraintViolationListInterface.php', + 'Symfony\\Component\\Validator\\Constraints\\AbstractComparison' => __DIR__ . '/..' . '/symfony/validator/Constraints/AbstractComparison.php', + 'Symfony\\Component\\Validator\\Constraints\\AbstractComparisonValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/AbstractComparisonValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\All' => __DIR__ . '/..' . '/symfony/validator/Constraints/All.php', + 'Symfony\\Component\\Validator\\Constraints\\AllValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/AllValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\AtLeastOneOf' => __DIR__ . '/..' . '/symfony/validator/Constraints/AtLeastOneOf.php', + 'Symfony\\Component\\Validator\\Constraints\\AtLeastOneOfValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/AtLeastOneOfValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Bic' => __DIR__ . '/..' . '/symfony/validator/Constraints/Bic.php', + 'Symfony\\Component\\Validator\\Constraints\\BicValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/BicValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Blank' => __DIR__ . '/..' . '/symfony/validator/Constraints/Blank.php', + 'Symfony\\Component\\Validator\\Constraints\\BlankValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/BlankValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Callback' => __DIR__ . '/..' . '/symfony/validator/Constraints/Callback.php', + 'Symfony\\Component\\Validator\\Constraints\\CallbackValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/CallbackValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\CardScheme' => __DIR__ . '/..' . '/symfony/validator/Constraints/CardScheme.php', + 'Symfony\\Component\\Validator\\Constraints\\CardSchemeValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/CardSchemeValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Cascade' => __DIR__ . '/..' . '/symfony/validator/Constraints/Cascade.php', + 'Symfony\\Component\\Validator\\Constraints\\Choice' => __DIR__ . '/..' . '/symfony/validator/Constraints/Choice.php', + 'Symfony\\Component\\Validator\\Constraints\\ChoiceValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/ChoiceValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Cidr' => __DIR__ . '/..' . '/symfony/validator/Constraints/Cidr.php', + 'Symfony\\Component\\Validator\\Constraints\\CidrValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/CidrValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Collection' => __DIR__ . '/..' . '/symfony/validator/Constraints/Collection.php', + 'Symfony\\Component\\Validator\\Constraints\\CollectionValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/CollectionValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Composite' => __DIR__ . '/..' . '/symfony/validator/Constraints/Composite.php', + 'Symfony\\Component\\Validator\\Constraints\\Compound' => __DIR__ . '/..' . '/symfony/validator/Constraints/Compound.php', + 'Symfony\\Component\\Validator\\Constraints\\CompoundValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/CompoundValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Count' => __DIR__ . '/..' . '/symfony/validator/Constraints/Count.php', + 'Symfony\\Component\\Validator\\Constraints\\CountValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/CountValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Country' => __DIR__ . '/..' . '/symfony/validator/Constraints/Country.php', + 'Symfony\\Component\\Validator\\Constraints\\CountryValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/CountryValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\CssColor' => __DIR__ . '/..' . '/symfony/validator/Constraints/CssColor.php', + 'Symfony\\Component\\Validator\\Constraints\\CssColorValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/CssColorValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Currency' => __DIR__ . '/..' . '/symfony/validator/Constraints/Currency.php', + 'Symfony\\Component\\Validator\\Constraints\\CurrencyValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/CurrencyValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Date' => __DIR__ . '/..' . '/symfony/validator/Constraints/Date.php', + 'Symfony\\Component\\Validator\\Constraints\\DateTime' => __DIR__ . '/..' . '/symfony/validator/Constraints/DateTime.php', + 'Symfony\\Component\\Validator\\Constraints\\DateTimeValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/DateTimeValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\DateValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/DateValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\DisableAutoMapping' => __DIR__ . '/..' . '/symfony/validator/Constraints/DisableAutoMapping.php', + 'Symfony\\Component\\Validator\\Constraints\\DivisibleBy' => __DIR__ . '/..' . '/symfony/validator/Constraints/DivisibleBy.php', + 'Symfony\\Component\\Validator\\Constraints\\DivisibleByValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/DivisibleByValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Email' => __DIR__ . '/..' . '/symfony/validator/Constraints/Email.php', + 'Symfony\\Component\\Validator\\Constraints\\EmailValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/EmailValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\EnableAutoMapping' => __DIR__ . '/..' . '/symfony/validator/Constraints/EnableAutoMapping.php', + 'Symfony\\Component\\Validator\\Constraints\\EqualTo' => __DIR__ . '/..' . '/symfony/validator/Constraints/EqualTo.php', + 'Symfony\\Component\\Validator\\Constraints\\EqualToValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/EqualToValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Existence' => __DIR__ . '/..' . '/symfony/validator/Constraints/Existence.php', + 'Symfony\\Component\\Validator\\Constraints\\Expression' => __DIR__ . '/..' . '/symfony/validator/Constraints/Expression.php', + 'Symfony\\Component\\Validator\\Constraints\\ExpressionLanguageProvider' => __DIR__ . '/..' . '/symfony/validator/Constraints/ExpressionLanguageProvider.php', + 'Symfony\\Component\\Validator\\Constraints\\ExpressionLanguageSyntax' => __DIR__ . '/..' . '/symfony/validator/Constraints/ExpressionLanguageSyntax.php', + 'Symfony\\Component\\Validator\\Constraints\\ExpressionLanguageSyntaxValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/ExpressionLanguageSyntaxValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\ExpressionSyntax' => __DIR__ . '/..' . '/symfony/validator/Constraints/ExpressionSyntax.php', + 'Symfony\\Component\\Validator\\Constraints\\ExpressionSyntaxValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/ExpressionSyntaxValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\ExpressionValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/ExpressionValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\File' => __DIR__ . '/..' . '/symfony/validator/Constraints/File.php', + 'Symfony\\Component\\Validator\\Constraints\\FileValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/FileValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\GreaterThan' => __DIR__ . '/..' . '/symfony/validator/Constraints/GreaterThan.php', + 'Symfony\\Component\\Validator\\Constraints\\GreaterThanOrEqual' => __DIR__ . '/..' . '/symfony/validator/Constraints/GreaterThanOrEqual.php', + 'Symfony\\Component\\Validator\\Constraints\\GreaterThanOrEqualValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/GreaterThanOrEqualValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\GreaterThanValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/GreaterThanValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\GroupSequence' => __DIR__ . '/..' . '/symfony/validator/Constraints/GroupSequence.php', + 'Symfony\\Component\\Validator\\Constraints\\GroupSequenceProvider' => __DIR__ . '/..' . '/symfony/validator/Constraints/GroupSequenceProvider.php', + 'Symfony\\Component\\Validator\\Constraints\\Hostname' => __DIR__ . '/..' . '/symfony/validator/Constraints/Hostname.php', + 'Symfony\\Component\\Validator\\Constraints\\HostnameValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/HostnameValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Iban' => __DIR__ . '/..' . '/symfony/validator/Constraints/Iban.php', + 'Symfony\\Component\\Validator\\Constraints\\IbanValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/IbanValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\IdenticalTo' => __DIR__ . '/..' . '/symfony/validator/Constraints/IdenticalTo.php', + 'Symfony\\Component\\Validator\\Constraints\\IdenticalToValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/IdenticalToValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Image' => __DIR__ . '/..' . '/symfony/validator/Constraints/Image.php', + 'Symfony\\Component\\Validator\\Constraints\\ImageValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/ImageValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Ip' => __DIR__ . '/..' . '/symfony/validator/Constraints/Ip.php', + 'Symfony\\Component\\Validator\\Constraints\\IpValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/IpValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\IsFalse' => __DIR__ . '/..' . '/symfony/validator/Constraints/IsFalse.php', + 'Symfony\\Component\\Validator\\Constraints\\IsFalseValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/IsFalseValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\IsNull' => __DIR__ . '/..' . '/symfony/validator/Constraints/IsNull.php', + 'Symfony\\Component\\Validator\\Constraints\\IsNullValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/IsNullValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\IsTrue' => __DIR__ . '/..' . '/symfony/validator/Constraints/IsTrue.php', + 'Symfony\\Component\\Validator\\Constraints\\IsTrueValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/IsTrueValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Isbn' => __DIR__ . '/..' . '/symfony/validator/Constraints/Isbn.php', + 'Symfony\\Component\\Validator\\Constraints\\IsbnValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/IsbnValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Isin' => __DIR__ . '/..' . '/symfony/validator/Constraints/Isin.php', + 'Symfony\\Component\\Validator\\Constraints\\IsinValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/IsinValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Issn' => __DIR__ . '/..' . '/symfony/validator/Constraints/Issn.php', + 'Symfony\\Component\\Validator\\Constraints\\IssnValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/IssnValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Json' => __DIR__ . '/..' . '/symfony/validator/Constraints/Json.php', + 'Symfony\\Component\\Validator\\Constraints\\JsonValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/JsonValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Language' => __DIR__ . '/..' . '/symfony/validator/Constraints/Language.php', + 'Symfony\\Component\\Validator\\Constraints\\LanguageValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/LanguageValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Length' => __DIR__ . '/..' . '/symfony/validator/Constraints/Length.php', + 'Symfony\\Component\\Validator\\Constraints\\LengthValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/LengthValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\LessThan' => __DIR__ . '/..' . '/symfony/validator/Constraints/LessThan.php', + 'Symfony\\Component\\Validator\\Constraints\\LessThanOrEqual' => __DIR__ . '/..' . '/symfony/validator/Constraints/LessThanOrEqual.php', + 'Symfony\\Component\\Validator\\Constraints\\LessThanOrEqualValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/LessThanOrEqualValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\LessThanValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/LessThanValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Locale' => __DIR__ . '/..' . '/symfony/validator/Constraints/Locale.php', + 'Symfony\\Component\\Validator\\Constraints\\LocaleValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/LocaleValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Luhn' => __DIR__ . '/..' . '/symfony/validator/Constraints/Luhn.php', + 'Symfony\\Component\\Validator\\Constraints\\LuhnValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/LuhnValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Negative' => __DIR__ . '/..' . '/symfony/validator/Constraints/Negative.php', + 'Symfony\\Component\\Validator\\Constraints\\NegativeOrZero' => __DIR__ . '/..' . '/symfony/validator/Constraints/NegativeOrZero.php', + 'Symfony\\Component\\Validator\\Constraints\\NoSuspiciousCharacters' => __DIR__ . '/..' . '/symfony/validator/Constraints/NoSuspiciousCharacters.php', + 'Symfony\\Component\\Validator\\Constraints\\NoSuspiciousCharactersValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/NoSuspiciousCharactersValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\NotBlank' => __DIR__ . '/..' . '/symfony/validator/Constraints/NotBlank.php', + 'Symfony\\Component\\Validator\\Constraints\\NotBlankValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/NotBlankValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\NotCompromisedPassword' => __DIR__ . '/..' . '/symfony/validator/Constraints/NotCompromisedPassword.php', + 'Symfony\\Component\\Validator\\Constraints\\NotCompromisedPasswordValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/NotCompromisedPasswordValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\NotEqualTo' => __DIR__ . '/..' . '/symfony/validator/Constraints/NotEqualTo.php', + 'Symfony\\Component\\Validator\\Constraints\\NotEqualToValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/NotEqualToValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\NotIdenticalTo' => __DIR__ . '/..' . '/symfony/validator/Constraints/NotIdenticalTo.php', + 'Symfony\\Component\\Validator\\Constraints\\NotIdenticalToValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/NotIdenticalToValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\NotNull' => __DIR__ . '/..' . '/symfony/validator/Constraints/NotNull.php', + 'Symfony\\Component\\Validator\\Constraints\\NotNullValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/NotNullValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Optional' => __DIR__ . '/..' . '/symfony/validator/Constraints/Optional.php', + 'Symfony\\Component\\Validator\\Constraints\\PasswordStrength' => __DIR__ . '/..' . '/symfony/validator/Constraints/PasswordStrength.php', + 'Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/PasswordStrengthValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Positive' => __DIR__ . '/..' . '/symfony/validator/Constraints/Positive.php', + 'Symfony\\Component\\Validator\\Constraints\\PositiveOrZero' => __DIR__ . '/..' . '/symfony/validator/Constraints/PositiveOrZero.php', + 'Symfony\\Component\\Validator\\Constraints\\Range' => __DIR__ . '/..' . '/symfony/validator/Constraints/Range.php', + 'Symfony\\Component\\Validator\\Constraints\\RangeValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/RangeValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Regex' => __DIR__ . '/..' . '/symfony/validator/Constraints/Regex.php', + 'Symfony\\Component\\Validator\\Constraints\\RegexValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/RegexValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Required' => __DIR__ . '/..' . '/symfony/validator/Constraints/Required.php', + 'Symfony\\Component\\Validator\\Constraints\\Sequentially' => __DIR__ . '/..' . '/symfony/validator/Constraints/Sequentially.php', + 'Symfony\\Component\\Validator\\Constraints\\SequentiallyValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/SequentiallyValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Time' => __DIR__ . '/..' . '/symfony/validator/Constraints/Time.php', + 'Symfony\\Component\\Validator\\Constraints\\TimeValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/TimeValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Timezone' => __DIR__ . '/..' . '/symfony/validator/Constraints/Timezone.php', + 'Symfony\\Component\\Validator\\Constraints\\TimezoneValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/TimezoneValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Traverse' => __DIR__ . '/..' . '/symfony/validator/Constraints/Traverse.php', + 'Symfony\\Component\\Validator\\Constraints\\Type' => __DIR__ . '/..' . '/symfony/validator/Constraints/Type.php', + 'Symfony\\Component\\Validator\\Constraints\\TypeValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/TypeValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Ulid' => __DIR__ . '/..' . '/symfony/validator/Constraints/Ulid.php', + 'Symfony\\Component\\Validator\\Constraints\\UlidValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/UlidValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Unique' => __DIR__ . '/..' . '/symfony/validator/Constraints/Unique.php', + 'Symfony\\Component\\Validator\\Constraints\\UniqueValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/UniqueValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Url' => __DIR__ . '/..' . '/symfony/validator/Constraints/Url.php', + 'Symfony\\Component\\Validator\\Constraints\\UrlValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/UrlValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Uuid' => __DIR__ . '/..' . '/symfony/validator/Constraints/Uuid.php', + 'Symfony\\Component\\Validator\\Constraints\\UuidValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/UuidValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\Valid' => __DIR__ . '/..' . '/symfony/validator/Constraints/Valid.php', + 'Symfony\\Component\\Validator\\Constraints\\ValidValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/ValidValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\When' => __DIR__ . '/..' . '/symfony/validator/Constraints/When.php', + 'Symfony\\Component\\Validator\\Constraints\\WhenValidator' => __DIR__ . '/..' . '/symfony/validator/Constraints/WhenValidator.php', + 'Symfony\\Component\\Validator\\Constraints\\ZeroComparisonConstraintTrait' => __DIR__ . '/..' . '/symfony/validator/Constraints/ZeroComparisonConstraintTrait.php', + 'Symfony\\Component\\Validator\\ContainerConstraintValidatorFactory' => __DIR__ . '/..' . '/symfony/validator/ContainerConstraintValidatorFactory.php', + 'Symfony\\Component\\Validator\\Context\\ExecutionContext' => __DIR__ . '/..' . '/symfony/validator/Context/ExecutionContext.php', + 'Symfony\\Component\\Validator\\Context\\ExecutionContextFactory' => __DIR__ . '/..' . '/symfony/validator/Context/ExecutionContextFactory.php', + 'Symfony\\Component\\Validator\\Context\\ExecutionContextFactoryInterface' => __DIR__ . '/..' . '/symfony/validator/Context/ExecutionContextFactoryInterface.php', + 'Symfony\\Component\\Validator\\Context\\ExecutionContextInterface' => __DIR__ . '/..' . '/symfony/validator/Context/ExecutionContextInterface.php', + 'Symfony\\Component\\Validator\\DataCollector\\ValidatorDataCollector' => __DIR__ . '/..' . '/symfony/validator/DataCollector/ValidatorDataCollector.php', + 'Symfony\\Component\\Validator\\DependencyInjection\\AddAutoMappingConfigurationPass' => __DIR__ . '/..' . '/symfony/validator/DependencyInjection/AddAutoMappingConfigurationPass.php', + 'Symfony\\Component\\Validator\\DependencyInjection\\AddConstraintValidatorsPass' => __DIR__ . '/..' . '/symfony/validator/DependencyInjection/AddConstraintValidatorsPass.php', + 'Symfony\\Component\\Validator\\DependencyInjection\\AddValidatorInitializersPass' => __DIR__ . '/..' . '/symfony/validator/DependencyInjection/AddValidatorInitializersPass.php', + 'Symfony\\Component\\Validator\\Exception\\BadMethodCallException' => __DIR__ . '/..' . '/symfony/validator/Exception/BadMethodCallException.php', + 'Symfony\\Component\\Validator\\Exception\\ConstraintDefinitionException' => __DIR__ . '/..' . '/symfony/validator/Exception/ConstraintDefinitionException.php', + 'Symfony\\Component\\Validator\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/validator/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Validator\\Exception\\GroupDefinitionException' => __DIR__ . '/..' . '/symfony/validator/Exception/GroupDefinitionException.php', + 'Symfony\\Component\\Validator\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/validator/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\Validator\\Exception\\InvalidOptionsException' => __DIR__ . '/..' . '/symfony/validator/Exception/InvalidOptionsException.php', + 'Symfony\\Component\\Validator\\Exception\\LogicException' => __DIR__ . '/..' . '/symfony/validator/Exception/LogicException.php', + 'Symfony\\Component\\Validator\\Exception\\MappingException' => __DIR__ . '/..' . '/symfony/validator/Exception/MappingException.php', + 'Symfony\\Component\\Validator\\Exception\\MissingOptionsException' => __DIR__ . '/..' . '/symfony/validator/Exception/MissingOptionsException.php', + 'Symfony\\Component\\Validator\\Exception\\NoSuchMetadataException' => __DIR__ . '/..' . '/symfony/validator/Exception/NoSuchMetadataException.php', + 'Symfony\\Component\\Validator\\Exception\\OutOfBoundsException' => __DIR__ . '/..' . '/symfony/validator/Exception/OutOfBoundsException.php', + 'Symfony\\Component\\Validator\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/validator/Exception/RuntimeException.php', + 'Symfony\\Component\\Validator\\Exception\\UnexpectedTypeException' => __DIR__ . '/..' . '/symfony/validator/Exception/UnexpectedTypeException.php', + 'Symfony\\Component\\Validator\\Exception\\UnexpectedValueException' => __DIR__ . '/..' . '/symfony/validator/Exception/UnexpectedValueException.php', + 'Symfony\\Component\\Validator\\Exception\\UnsupportedMetadataException' => __DIR__ . '/..' . '/symfony/validator/Exception/UnsupportedMetadataException.php', + 'Symfony\\Component\\Validator\\Exception\\ValidationFailedException' => __DIR__ . '/..' . '/symfony/validator/Exception/ValidationFailedException.php', + 'Symfony\\Component\\Validator\\Exception\\ValidatorException' => __DIR__ . '/..' . '/symfony/validator/Exception/ValidatorException.php', + 'Symfony\\Component\\Validator\\GroupProviderInterface' => __DIR__ . '/..' . '/symfony/validator/GroupProviderInterface.php', + 'Symfony\\Component\\Validator\\GroupSequenceProviderInterface' => __DIR__ . '/..' . '/symfony/validator/GroupSequenceProviderInterface.php', + 'Symfony\\Component\\Validator\\Mapping\\AutoMappingStrategy' => __DIR__ . '/..' . '/symfony/validator/Mapping/AutoMappingStrategy.php', + 'Symfony\\Component\\Validator\\Mapping\\CascadingStrategy' => __DIR__ . '/..' . '/symfony/validator/Mapping/CascadingStrategy.php', + 'Symfony\\Component\\Validator\\Mapping\\ClassMetadata' => __DIR__ . '/..' . '/symfony/validator/Mapping/ClassMetadata.php', + 'Symfony\\Component\\Validator\\Mapping\\ClassMetadataInterface' => __DIR__ . '/..' . '/symfony/validator/Mapping/ClassMetadataInterface.php', + 'Symfony\\Component\\Validator\\Mapping\\Factory\\BlackHoleMetadataFactory' => __DIR__ . '/..' . '/symfony/validator/Mapping/Factory/BlackHoleMetadataFactory.php', + 'Symfony\\Component\\Validator\\Mapping\\Factory\\LazyLoadingMetadataFactory' => __DIR__ . '/..' . '/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php', + 'Symfony\\Component\\Validator\\Mapping\\Factory\\MetadataFactoryInterface' => __DIR__ . '/..' . '/symfony/validator/Mapping/Factory/MetadataFactoryInterface.php', + 'Symfony\\Component\\Validator\\Mapping\\GenericMetadata' => __DIR__ . '/..' . '/symfony/validator/Mapping/GenericMetadata.php', + 'Symfony\\Component\\Validator\\Mapping\\GetterMetadata' => __DIR__ . '/..' . '/symfony/validator/Mapping/GetterMetadata.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\AbstractLoader' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/AbstractLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\AnnotationLoader' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/AnnotationLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\AttributeLoader' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/AttributeLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\AutoMappingTrait' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/AutoMappingTrait.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\FileLoader' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/FileLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\FilesLoader' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/FilesLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\LoaderChain' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/LoaderChain.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\LoaderInterface' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/LoaderInterface.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\PropertyInfoLoader' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/PropertyInfoLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\StaticMethodLoader' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/StaticMethodLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\XmlFileLoader' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/XmlFileLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\XmlFilesLoader' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/XmlFilesLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\YamlFileLoader' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/YamlFileLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\Loader\\YamlFilesLoader' => __DIR__ . '/..' . '/symfony/validator/Mapping/Loader/YamlFilesLoader.php', + 'Symfony\\Component\\Validator\\Mapping\\MemberMetadata' => __DIR__ . '/..' . '/symfony/validator/Mapping/MemberMetadata.php', + 'Symfony\\Component\\Validator\\Mapping\\MetadataInterface' => __DIR__ . '/..' . '/symfony/validator/Mapping/MetadataInterface.php', + 'Symfony\\Component\\Validator\\Mapping\\PropertyMetadata' => __DIR__ . '/..' . '/symfony/validator/Mapping/PropertyMetadata.php', + 'Symfony\\Component\\Validator\\Mapping\\PropertyMetadataInterface' => __DIR__ . '/..' . '/symfony/validator/Mapping/PropertyMetadataInterface.php', + 'Symfony\\Component\\Validator\\Mapping\\TraversalStrategy' => __DIR__ . '/..' . '/symfony/validator/Mapping/TraversalStrategy.php', + 'Symfony\\Component\\Validator\\ObjectInitializerInterface' => __DIR__ . '/..' . '/symfony/validator/ObjectInitializerInterface.php', + 'Symfony\\Component\\Validator\\Util\\PropertyPath' => __DIR__ . '/..' . '/symfony/validator/Util/PropertyPath.php', + 'Symfony\\Component\\Validator\\Validation' => __DIR__ . '/..' . '/symfony/validator/Validation.php', + 'Symfony\\Component\\Validator\\ValidatorBuilder' => __DIR__ . '/..' . '/symfony/validator/ValidatorBuilder.php', + 'Symfony\\Component\\Validator\\Validator\\ContextualValidatorInterface' => __DIR__ . '/..' . '/symfony/validator/Validator/ContextualValidatorInterface.php', + 'Symfony\\Component\\Validator\\Validator\\LazyProperty' => __DIR__ . '/..' . '/symfony/validator/Validator/LazyProperty.php', + 'Symfony\\Component\\Validator\\Validator\\RecursiveContextualValidator' => __DIR__ . '/..' . '/symfony/validator/Validator/RecursiveContextualValidator.php', + 'Symfony\\Component\\Validator\\Validator\\RecursiveValidator' => __DIR__ . '/..' . '/symfony/validator/Validator/RecursiveValidator.php', + 'Symfony\\Component\\Validator\\Validator\\TraceableValidator' => __DIR__ . '/..' . '/symfony/validator/Validator/TraceableValidator.php', + 'Symfony\\Component\\Validator\\Validator\\ValidatorInterface' => __DIR__ . '/..' . '/symfony/validator/Validator/ValidatorInterface.php', + 'Symfony\\Component\\Validator\\Violation\\ConstraintViolationBuilder' => __DIR__ . '/..' . '/symfony/validator/Violation/ConstraintViolationBuilder.php', + 'Symfony\\Component\\Validator\\Violation\\ConstraintViolationBuilderInterface' => __DIR__ . '/..' . '/symfony/validator/Violation/ConstraintViolationBuilderInterface.php', 'Symfony\\Component\\VarDumper\\Caster\\AmqpCaster' => __DIR__ . '/..' . '/symfony/var-dumper/Caster/AmqpCaster.php', 'Symfony\\Component\\VarDumper\\Caster\\ArgsStub' => __DIR__ . '/..' . '/symfony/var-dumper/Caster/ArgsStub.php', 'Symfony\\Component\\VarDumper\\Caster\\Caster' => __DIR__ . '/..' . '/symfony/var-dumper/Caster/Caster.php', diff --git a/lib/composer/installed.json b/lib/composer/installed.json index 5ef18f98a8..f8383b72fe 100644 --- a/lib/composer/installed.json +++ b/lib/composer/installed.json @@ -5238,6 +5238,110 @@ ], "install-path": "../symfony/twig-bundle" }, + { + "name": "symfony/validator", + "version": "v6.4.29", + "version_normalized": "6.4.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/validator.git", + "reference": "99df8a769e64e399f510166141ea74f450e8dd1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/validator/zipball/99df8a769e64e399f510166141ea74f450e8dd1d", + "reference": "99df8a769e64e399f510166141ea74f450e8dd1d", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php83": "^1.27", + "symfony/translation-contracts": "^2.5|^3" + }, + "conflict": { + "doctrine/annotations": "<1.13", + "doctrine/lexer": "<1.1", + "symfony/dependency-injection": "<5.4", + "symfony/expression-language": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/intl": "<5.4", + "symfony/property-info": "<5.4", + "symfony/translation": "<5.4.35|>=6.0,<6.3.12|>=6.4,<6.4.3|>=7.0,<7.0.3", + "symfony/yaml": "<5.4" + }, + "require-dev": { + "doctrine/annotations": "^1.13|^2", + "egulias/email-validator": "^2.1.10|^3|^4", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4.35|~6.3.12|^6.4.3|^7.0.3", + "symfony/yaml": "^5.4|^6.0|^7.0" + }, + "time": "2025-11-06T20:26:06+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Validator\\": "" + }, + "exclude-from-classmap": [ + "/Tests/", + "/Resources/bin/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to validate values", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/validator/tree/v6.4.29" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/validator" + }, { "name": "symfony/var-dumper", "version": "v6.4.26", diff --git a/lib/composer/installed.php b/lib/composer/installed.php index 33b2f7d8a7..ff4da6e4b6 100644 --- a/lib/composer/installed.php +++ b/lib/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'combodo/itop', 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', - 'reference' => '19d062aa830b6d6c7d17ac4046fc9ee2c5e3fab1', + 'reference' => '06e5c8078690380fb8690371a69eb3c68469c1ed', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -22,7 +22,7 @@ 'combodo/itop' => array( 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', - 'reference' => '19d062aa830b6d6c7d17ac4046fc9ee2c5e3fab1', + 'reference' => '06e5c8078690380fb8690371a69eb3c68469c1ed', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -678,6 +678,15 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'symfony/validator' => array( + 'pretty_version' => 'v6.4.29', + 'version' => '6.4.29.0', + 'reference' => '99df8a769e64e399f510166141ea74f450e8dd1d', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/validator', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'symfony/var-dumper' => array( 'pretty_version' => 'v6.4.26', 'version' => '6.4.26.0', diff --git a/lib/soundasleep/html2text/phpstan.neon.dist b/lib/soundasleep/html2text/phpstan.neon.dist new file mode 100644 index 0000000000..b05dc95119 --- /dev/null +++ b/lib/soundasleep/html2text/phpstan.neon.dist @@ -0,0 +1,7 @@ +parameters: + level: 6 + errorFormat: raw + editorUrl: '%%file%% %%line%% %%column%%: %%error%%' + paths: + - src + - tests diff --git a/lib/symfony/form/FormBuilder.php b/lib/symfony/form/FormBuilder.php index 3c0f4e2179..beabdd03c8 100644 --- a/lib/symfony/form/FormBuilder.php +++ b/lib/symfony/form/FormBuilder.php @@ -26,192 +26,192 @@ */ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormBuilderInterface { - /** - * The children of the form builder. - * - * @var FormBuilderInterface[] - */ - private array $children = []; + /** + * The children of the form builder. + * + * @var FormBuilderInterface[] + */ + private array $children = []; - /** - * The data of children who haven't been converted to form builders yet. - */ - private array $unresolvedChildren = []; - - public function __construct(?string $name, ?string $dataClass, EventDispatcherInterface $dispatcher, FormFactoryInterface $factory, array $options = []) - { - parent::__construct($name, $dataClass, $dispatcher, $options); - - $this->setFormFactory($factory); - } + /** + * The data of children who haven't been converted to form builders yet. + */ + private array $unresolvedChildren = []; + + public function __construct(?string $name, ?string $dataClass, EventDispatcherInterface $dispatcher, FormFactoryInterface $factory, array $options = []) + { + parent::__construct($name, $dataClass, $dispatcher, $options); + + $this->setFormFactory($factory); + } - public function add(FormBuilderInterface|string $child, ?string $type = null, array $options = []): static - { - if ($this->locked) { - throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); - } - - if ($child instanceof FormBuilderInterface) { - $this->children[$child->getName()] = $child; - - // In case an unresolved child with the same name exists - unset($this->unresolvedChildren[$child->getName()]); + public function add(FormBuilderInterface|string $child, ?string $type = null, array $options = []): static + { + if ($this->locked) { + throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); + } + + if ($child instanceof FormBuilderInterface) { + $this->children[$child->getName()] = $child; + + // In case an unresolved child with the same name exists + unset($this->unresolvedChildren[$child->getName()]); - return $this; - } - - if (!\is_string($child) && !\is_int($child)) { - throw new UnexpectedTypeException($child, 'string or Symfony\Component\Form\FormBuilderInterface'); - } + return $this; + } + + if (!\is_string($child) && !\is_int($child)) { + throw new UnexpectedTypeException($child, 'string or Symfony\Component\Form\FormBuilderInterface'); + } - // Add to "children" to maintain order - $this->children[$child] = null; - $this->unresolvedChildren[$child] = [$type, $options]; + // Add to "children" to maintain order + $this->children[$child] = null; + $this->unresolvedChildren[$child] = [$type, $options]; - return $this; - } + return $this; + } - public function create(string $name, ?string $type = null, array $options = []): FormBuilderInterface - { - if ($this->locked) { - throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); - } + public function create(string $name, ?string $type = null, array $options = []): FormBuilderInterface + { + if ($this->locked) { + throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); + } - if (null === $type && null === $this->getDataClass()) { - $type = TextType::class; - } + if (null === $type && null === $this->getDataClass()) { + $type = TextType::class; + } - if (null !== $type) { - return $this->getFormFactory()->createNamedBuilder($name, $type, null, $options); - } - - return $this->getFormFactory()->createBuilderForProperty($this->getDataClass(), $name, null, $options); - } - - public function get(string $name): FormBuilderInterface - { - if ($this->locked) { - throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); - } - - if (isset($this->unresolvedChildren[$name])) { - return $this->resolveChild($name); - } - - if (isset($this->children[$name])) { - return $this->children[$name]; - } - - throw new InvalidArgumentException(\sprintf('The child with the name "%s" does not exist.', $name)); - } - - public function remove(string $name): static - { - if ($this->locked) { - throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); - } - - unset($this->unresolvedChildren[$name], $this->children[$name]); - - return $this; - } - - public function has(string $name): bool - { - if ($this->locked) { - throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); - } - - return isset($this->unresolvedChildren[$name]) || isset($this->children[$name]); - } - - public function all(): array - { - if ($this->locked) { - throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); - } - - $this->resolveChildren(); - - return $this->children; - } - - public function count(): int - { - if ($this->locked) { - throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); - } - - return \count($this->children); - } - - public function getFormConfig(): FormConfigInterface - { - /** @var self $config */ - $config = parent::getFormConfig(); - - $config->children = []; - $config->unresolvedChildren = []; - - return $config; - } - - public function getForm(): FormInterface - { - if ($this->locked) { - throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); - } - - $this->resolveChildren(); - - $form = new Form($this->getFormConfig()); - - foreach ($this->children as $child) { - // Automatic initialization is only supported on root forms - $form->add($child->setAutoInitialize(false)->getForm()); - } - - if ($this->getAutoInitialize()) { - // Automatically initialize the form if it is configured so - $form->initialize(); - } - - return $form; - } - - /** - * @return \Traversable - */ - public function getIterator(): \Traversable - { - if ($this->locked) { - throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); - } - - return new \ArrayIterator($this->all()); - } - - /** - * Converts an unresolved child into a {@link FormBuilderInterface} instance. - */ - private function resolveChild(string $name): FormBuilderInterface - { - [$type, $options] = $this->unresolvedChildren[$name]; - - unset($this->unresolvedChildren[$name]); - - return $this->children[$name] = $this->create($name, $type, $options); - } - - /** - * Converts all unresolved children into {@link FormBuilder} instances. - */ - private function resolveChildren(): void - { - foreach ($this->unresolvedChildren as $name => $info) { - $this->children[$name] = $this->create($name, $info[0], $info[1]); - } - - $this->unresolvedChildren = []; - } + if (null !== $type) { + return $this->getFormFactory()->createNamedBuilder($name, $type, null, $options); + } + + return $this->getFormFactory()->createBuilderForProperty($this->getDataClass(), $name, null, $options); + } + + public function get(string $name): FormBuilderInterface + { + if ($this->locked) { + throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); + } + + if (isset($this->unresolvedChildren[$name])) { + return $this->resolveChild($name); + } + + if (isset($this->children[$name])) { + return $this->children[$name]; + } + + throw new InvalidArgumentException(\sprintf('The child with the name "%s" does not exist.', $name)); + } + + public function remove(string $name): static + { + if ($this->locked) { + throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); + } + + unset($this->unresolvedChildren[$name], $this->children[$name]); + + return $this; + } + + public function has(string $name): bool + { + if ($this->locked) { + throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); + } + + return isset($this->unresolvedChildren[$name]) || isset($this->children[$name]); + } + + public function all(): array + { + if ($this->locked) { + throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); + } + + $this->resolveChildren(); + + return $this->children; + } + + public function count(): int + { + if ($this->locked) { + throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); + } + + return \count($this->children); + } + + public function getFormConfig(): FormConfigInterface + { + /** @var self $config */ + $config = parent::getFormConfig(); + + $config->children = []; + $config->unresolvedChildren = []; + + return $config; + } + + public function getForm(): FormInterface + { + if ($this->locked) { + throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); + } + + $this->resolveChildren(); + + $form = new Form($this->getFormConfig()); + + foreach ($this->children as $child) { + // Automatic initialization is only supported on root forms + $form->add($child->setAutoInitialize(false)->getForm()); + } + + if ($this->getAutoInitialize()) { + // Automatically initialize the form if it is configured so + $form->initialize(); + } + + return $form; + } + + /** + * @return \Traversable + */ + public function getIterator(): \Traversable + { + if ($this->locked) { + throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.'); + } + + return new \ArrayIterator($this->all()); + } + + /** + * Converts an unresolved child into a {@link FormBuilderInterface} instance. + */ + private function resolveChild(string $name): FormBuilderInterface + { + [$type, $options] = $this->unresolvedChildren[$name]; + + unset($this->unresolvedChildren[$name]); + + return $this->children[$name] = $this->create($name, $type, $options); + } + + /** + * Converts all unresolved children into {@link FormBuilder} instances. + */ + private function resolveChildren(): void + { + foreach ($this->unresolvedChildren as $name => $info) { + $this->children[$name] = $this->create($name, $info[0], $info[1]); + } + + $this->unresolvedChildren = []; + } } diff --git a/lib/symfony/mime/LICENSE b/lib/symfony/mime/LICENSE new file mode 100644 index 0000000000..4dd83ce0f1 --- /dev/null +++ b/lib/symfony/mime/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/symfony/validator/Attribute/HasNamedArguments.php b/lib/symfony/validator/Attribute/HasNamedArguments.php new file mode 100644 index 0000000000..cc16629436 --- /dev/null +++ b/lib/symfony/validator/Attribute/HasNamedArguments.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Attribute; + +#[\Attribute(\Attribute::TARGET_METHOD)] +final class HasNamedArguments +{ +} diff --git a/lib/symfony/validator/CHANGELOG.md b/lib/symfony/validator/CHANGELOG.md new file mode 100644 index 0000000000..5660c2f4e4 --- /dev/null +++ b/lib/symfony/validator/CHANGELOG.md @@ -0,0 +1,415 @@ +CHANGELOG +========= + +6.4 +--- + + * Add `is_valid` function to the `Expression` constraint, its behavior is the same as `ValidatorInterface::validate` + * Allow single integer for the `versions` option of the `Uuid` constraint + * Allow single constraint to be passed to the `constraints` option of the `When` constraint + * Deprecate Doctrine annotations support in favor of native attributes + * Deprecate `ValidatorBuilder::setDoctrineAnnotationReader()` + * Deprecate `ValidatorBuilder::addDefaultDoctrineAnnotationReader()` + * Add `number`, `finite-number` and `finite-float` types to `Type` constraint + * Add the `withSeconds` option to the `Time` constraint that allows to pass time without seconds + * Deprecate `ValidatorBuilder::enableAnnotationMapping()`, use `ValidatorBuilder::enableAttributeMapping()` instead + * Deprecate `ValidatorBuilder::disableAnnotationMapping()`, use `ValidatorBuilder::disableAttributeMapping()` instead + * Deprecate `AnnotationLoader`, use `AttributeLoader` instead + * Add `GroupProviderInterface` to implement validation group providers outside the underlying class + +6.3 +--- + + * Add method `getConstraint()` to `ConstraintViolationInterface` + * Add `Uuid::TIME_BASED_VERSIONS` to match that a UUID being validated embeds a timestamp + * Add the `pattern` parameter in violations of the `Regex` constraint + * Add a `NoSuspiciousCharacters` constraint to validate a string is not a spoofing attempt + * Add a `PasswordStrength` constraint to check the strength of a password + * Add the `countUnit` option to the `Length` constraint to allow counting the string length either by code points (like before, now the default setting `Length::COUNT_CODEPOINTS`), bytes (`Length::COUNT_BYTES`) or graphemes (`Length::COUNT_GRAPHEMES`) + * Add the `filenameMaxLength` option to the `File` constraint + * Add the `exclude` option to the `Cascade` constraint + * Add the `value_length` parameter to `Length` constraint + * Allow to disable the translation domain for `ConstraintViolationInterface` messages + +6.2 +--- + + * Add option `Email::VALIDATION_MODE_HTML5_ALLOW_NO_TLD` with "html5-allow-no-tld" e-mail validation mode, to match with the W3C official specification + * Add method `getCause()` to `ConstraintViolationInterface` + * Add the `When` constraint and validator + * Deprecate the "loose" e-mail validation mode, use "html5" instead + * Add the `negate` option to the `Expression` constraint, to inverse the logic of the violation's creation + * Add the `extensions` option to the `File` constraint as an alternative to `mimeTypes` which checks the mime type of the file, its extension, and the consistency between them + * Add padding for enhanced privacy to the `NotCompromisedPasswordValidator` + +6.1 +--- + + * Add the `fields` option to the `Unique` constraint, to define which collection keys should be checked for uniqueness + * Deprecate `Constraint::$errorNames`, use `Constraint::ERROR_NAMES` instead + * Deprecate constraint `ExpressionLanguageSyntax`, use `ExpressionSyntax` instead + * Add method `__toString()` to `ConstraintViolationInterface` & `ConstraintViolationListInterface` + * Allow creating constraints with required arguments + * Add the `match` option to the `Choice` constraint + +6.0 +--- + + * Remove the `allowEmptyString` option from the `Length` constraint + * Remove the `NumberConstraintTrait` trait + * `ValidatorBuilder::enableAnnotationMapping()` does not accept a Doctrine annotation reader anymore + * `ValidatorBuilder::enableAnnotationMapping()` won't automatically setup a Doctrine annotation reader anymore + +5.4 +--- + + * Add a `Cidr` constraint to validate CIDR notations + * Add a `CssColor` constraint to validate CSS colors + * Add support for `ConstraintViolationList::createFromMessage()` + * Add error's uid to `Count` and `Length` constraints with "exactly" option enabled + +5.3 +--- + + * Add the `normalizer` option to the `Unique` constraint + * Add `Validation::createIsValidCallable()` that returns true/false instead of throwing exceptions + +5.2.0 +----- + + * added a `Cascade` constraint to ease validating nested typed object properties + * deprecated the `allowEmptyString` option of the `Length` constraint + + Before: + + ```php + use Symfony\Component\Validator\Constraints as Assert; + + /** + * @Assert\Length(min=5, allowEmptyString=true) + */ + ``` + + After: + + ```php + use Symfony\Component\Validator\Constraints as Assert; + + /** + * @Assert\AtLeastOneOf({ + * @Assert\Blank(), + * @Assert\Length(min=5) + * }) + */ + ``` + * added the `Isin` constraint and validator + * added the `ULID` constraint and validator + * added support for UUIDv6 in `Uuid` constraint + * enabled the validator to load constraints from PHP attributes + * deprecated the `NumberConstraintTrait` trait + * deprecated setting or creating a Doctrine annotation reader via `ValidatorBuilder::enableAnnotationMapping()`, pass `true` as first parameter and additionally call `setDoctrineAnnotationReader()` or `addDefaultDoctrineAnnotationReader()` to set up the annotation reader + +5.1.0 +----- + + * Add `AtLeastOneOf` constraint that is considered to be valid if at least one of the nested constraints is valid + * added the `Hostname` constraint and validator + * added the `alpha3` option to the `Country` and `Language` constraints + * allow to define a reusable set of constraints by extending the `Compound` constraint + * added `Sequentially` constraint, to sequentially validate a set of constraints (any violation raised will prevent further validation of the nested constraints) + * added the `divisibleBy` option to the `Count` constraint + * added the `ExpressionLanguageSyntax` constraint + +5.0.0 +----- + + * an `ExpressionLanguage` instance or null must be passed as the first argument of `ExpressionValidator::__construct()` + * removed the `checkDNS` and `dnsMessage` options of the `Url` constraint + * removed the `checkMX`, `checkHost` and `strict` options of the `Email` constraint + * removed support for validating instances of `\DateTimeInterface` in `DateTimeValidator`, `DateValidator` and `TimeValidator` + * removed support for using the `Bic`, `Country`, `Currency`, `Language` and `Locale` constraints without `symfony/intl` + * removed support for using the `Email` constraint without `egulias/email-validator` + * removed support for using the `Expression` constraint without `symfony/expression-language` + * changed default value of `canonicalize` option of `Locale` constraint to `true` + * removed `ValidatorBuilderInterface` + * passing a null message when instantiating a `ConstraintViolation` is not allowed + * changed the default value of `Length::$allowEmptyString` to `false` and made it optional + * removed `Symfony\Component\Validator\Mapping\Cache\CacheInterface` in favor of PSR-6. + * removed `ValidatorBuilder::setMetadataCache`, use `ValidatorBuilder::setMappingCache` instead. + +4.4.0 +----- + + * [BC BREAK] using null as `$classValidatorRegexp` value in `PropertyInfoLoader::__construct` will not enable auto-mapping for all classes anymore, use `'{.*}'` instead. + * added `EnableAutoMapping` and `DisableAutoMapping` constraints to enable or disable auto mapping for class or a property + * using anything else than a `string` as the code of a `ConstraintViolation` is deprecated, a `string` type-hint will + be added to the constructor of the `ConstraintViolation` class and to the `ConstraintViolationBuilder::setCode()` + method in 5.0 + * deprecated passing an `ExpressionLanguage` instance as the second argument of `ExpressionValidator::__construct()`. Pass it as the first argument instead. + * added the `compared_value_path` parameter in violations when using any + comparison constraint with the `propertyPath` option. + * added support for checking an array of types in `TypeValidator` + * added a new `allowEmptyString` option to the `Length` constraint to allow rejecting empty strings when `min` is set, by setting it to `false`. + * Added new `minPropertyPath` and `maxPropertyPath` options + to `Range` constraint in order to get the value to compare + from an array or object + * added the `min_limit_path` and `max_limit_path` parameters in violations when using + `Range` constraint with respectively the `minPropertyPath` and + `maxPropertyPath` options + * added a new `notInRangeMessage` option to the `Range` constraint that will + be used in the violation builder when both `min` and `max` are not null + * added ability to use stringable objects as violation messages + * Overriding the methods `ConstraintValidatorTestCase::setUp()` and `ConstraintValidatorTestCase::tearDown()` without the `void` return-type is deprecated. + * deprecated `Symfony\Component\Validator\Mapping\Cache\CacheInterface` in favor of PSR-6. + * deprecated `ValidatorBuilder::setMetadataCache`, use `ValidatorBuilder::setMappingCache` instead. + * Marked the `ValidatorDataCollector` class as `@final`. + +4.3.0 +----- + + * added `Timezone` constraint + * added `NotCompromisedPassword` constraint + * added options `iban` and `ibanPropertyPath` to Bic constraint + * added UATP cards support to `CardSchemeValidator` + * added option `allowNull` to NotBlank constraint + * added `Json` constraint + * added `Unique` constraint + * added a new `normalizer` option to the string constraints and to the `NotBlank` constraint + * added `Positive` constraint + * added `PositiveOrZero` constraint + * added `Negative` constraint + * added `NegativeOrZero` constraint + +4.2.0 +----- + + * added a new `UnexpectedValueException` that can be thrown by constraint validators, these exceptions are caught by + the validator and are converted into constraint violations + * added `DivisibleBy` constraint + * decoupled from `symfony/translation` by using `Symfony\Contracts\Translation\TranslatorInterface` + * deprecated `ValidatorBuilderInterface` + * made `ValidatorBuilder::setTranslator()` final + * marked `format` the default option in `DateTime` constraint + * deprecated validating instances of `\DateTimeInterface` in `DateTimeValidator`, `DateValidator` and `TimeValidator`. + * deprecated using the `Bic`, `Country`, `Currency`, `Language` and `Locale` constraints without `symfony/intl` + * deprecated using the `Email` constraint without `egulias/email-validator` + * deprecated using the `Expression` constraint without `symfony/expression-language` + +4.1.0 +----- + + * Deprecated the `checkDNS` and `dnsMessage` options of the `Url` constraint. + * added a `values` option to the `Expression` constraint + * Deprecated use of `Locale` constraint without setting `true` at "canonicalize" option, which will be the default value in 5.0 + +4.0.0 +----- + + * Setting the `strict` option of the `Choice` constraint to anything but `true` + is not supported anymore. + * removed the `DateTimeValidator::PATTERN` constant + * removed the `AbstractConstraintValidatorTest` class + * removed support for setting the `checkDNS` option of the `Url` constraint to `true` + +3.4.0 +----- + + * added support for validation groups to the `Valid` constraint + * not setting the `strict` option of the `Choice` constraint to `true` is + deprecated and will throw an exception in Symfony 4.0 + * setting the `checkDNS` option of the `Url` constraint to `true` is deprecated in favor of + the `Url::CHECK_DNS_TYPE_*` constants values and will throw an exception in Symfony 4.0 + * added min/max amount of pixels check to `Image` constraint via `minPixels` and `maxPixels` + * added a new "propertyPath" option to comparison constraints in order to get the value to compare from an array or object + +3.3.0 +----- + + * added `AddValidatorInitializersPass` + * added `AddConstraintValidatorsPass` + * added `ContainerConstraintValidatorFactory` + +3.2.0 +----- + + * deprecated `Tests\Constraints\AbstractConstraintValidatorTest` in favor of `Test\ConstraintValidatorTestCase` + * added support for PHP constants in YAML configuration files + +3.1.0 +----- + + * deprecated `DateTimeValidator::PATTERN` constant + * added a `format` option to the `DateTime` constraint + +2.8.0 +----- + + * added the BIC (SWIFT-Code) validator + +2.7.0 +----- + + * deprecated `DefaultTranslator` in favor of `Symfony\Component\Translation\IdentityTranslator` + * deprecated PHP7-incompatible constraints (Null, True, False) and related validators (NullValidator, TrueValidator, FalseValidator) in favor of their `Is`-prefixed equivalent + +2.6.0 +----- + + * [BC BREAK] `FileValidator` disallow empty files + * [BC BREAK] `UserPasswordValidator` source message change + * [BC BREAK] added internal `ExecutionContextInterface::setConstraint()` + * added `ConstraintViolation::getConstraint()` + * [BC BREAK] The `ExpressionValidator` will now evaluate the Expression even when the property value is null or an empty string + * deprecated `ClassMetadata::hasMemberMetadatas()` + * deprecated `ClassMetadata::getMemberMetadatas()` + * deprecated `ClassMetadata::addMemberMetadata()` + * [BC BREAK] added `Mapping\MetadataInterface::getConstraints()` + * added generic "payload" option to all constraints for attaching domain-specific data + * [BC BREAK] added `ConstraintViolationBuilderInterface::setCause()` + +2.5.0 +----- + + * deprecated `ApcCache` in favor of `DoctrineCache` + * added `DoctrineCache` to adapt any Doctrine cache + * `GroupSequence` now implements `ArrayAccess`, `Countable` and `Traversable` + * [BC BREAK] changed `ClassMetadata::getGroupSequence()` to return a `GroupSequence` instance instead of an array + * `Callback` can now be put onto properties (useful when you pass a closure to the constraint) + * deprecated `ClassBasedInterface` + * deprecated `MetadataInterface` + * deprecated `PropertyMetadataInterface` + * deprecated `PropertyMetadataContainerInterface` + * deprecated `Mapping\ElementMetadata` + * added `Mapping\MetadataInterface` + * added `Mapping\ClassMetadataInterface` + * added `Mapping\PropertyMetadataInterface` + * added `Mapping\GenericMetadata` + * added `Mapping\CascadingStrategy` + * added `Mapping\TraversalStrategy` + * deprecated `Mapping\ClassMetadata::accept()` + * deprecated `Mapping\MemberMetadata::accept()` + * removed array type hint of `Mapping\ClassMetadata::setGroupSequence()` + * deprecated `MetadataFactoryInterface` + * deprecated `Mapping\BlackholeMetadataFactory` + * deprecated `Mapping\ClassMetadataFactory` + * added `Mapping\Factory\MetadataFactoryInterface` + * added `Mapping\Factory\BlackHoleMetadataFactory` + * added `Mapping\Factory\LazyLoadingMetadataFactory` + * deprecated `ExecutionContextInterface` + * deprecated `ExecutionContext` + * deprecated `GlobalExecutionContextInterface` + * added `Context\ExecutionContextInterface` + * added `Context\ExecutionContext` + * added `Context\ExecutionContextFactoryInterface` + * added `Context\ExecutionContextFactory` + * deprecated `ValidatorInterface` + * deprecated `Validator` + * deprecated `ValidationVisitorInterface` + * deprecated `ValidationVisitor` + * added `Validator\ValidatorInterface` + * added `Validator\RecursiveValidator` + * added `Validator\ContextualValidatorInterface` + * added `Validator\RecursiveContextualValidator` + * added `Violation\ConstraintViolationBuilderInterface` + * added `Violation\ConstraintViolationBuilder` + * added `ConstraintViolation::getParameters()` + * added `ConstraintViolation::getPlural()` + * added `Constraints\Traverse` + * deprecated `$deep` property in `Constraints\Valid` + * added `ValidatorBuilderInterface::setApiVersion()` + * added `Validation::API_VERSION_2_4` + * added `Validation::API_VERSION_2_5` + * added `Exception\OutOfBoundsException` + * added `Exception\UnsupportedMetadataException` + * made `Exception\ValidatorException` extend `Exception\RuntimeException` + * added `Util\PropertyPath` + * made the PropertyAccess component an optional dependency + * deprecated `ValidatorBuilder::setPropertyAccessor()` + * deprecated `validate` and `validateValue` on `Validator\Context\ExecutionContext` use `getValidator()` together with `inContext()` instead + +2.4.0 +----- + + * added a constraint the uses the expression language + * added `minRatio`, `maxRatio`, `allowSquare`, `allowLandscape`, and `allowPortrait` to Image validator + +2.3.29 +------ + + * fixed compatibility with PHP7 and up by introducing new constraints (IsNull, IsTrue, IsFalse) and related validators (IsNullValidator, IsTrueValidator, IsFalseValidator) + +2.3.0 +----- + + * added the ISBN, ISSN, and IBAN validators + * copied the constraints `Optional` and `Required` to the + `Symfony\Component\Validator\Constraints\` namespace and deprecated the original + classes. + * added comparison validators (EqualTo, NotEqualTo, LessThan, LessThanOrEqualTo, GreaterThan, GreaterThanOrEqualTo, IdenticalTo, NotIdenticalTo) + +2.2.0 +----- + + * added a CardScheme validator + * added a Luhn validator + * moved @api-tags from `Validator` to `ValidatorInterface` + * moved @api-tags from `ConstraintViolation` to the new `ConstraintViolationInterface` + * moved @api-tags from `ConstraintViolationList` to the new `ConstraintViolationListInterface` + * moved @api-tags from `ExecutionContext` to the new `ExecutionContextInterface` + * [BC BREAK] `ConstraintValidatorInterface::initialize` is now type hinted against `ExecutionContextInterface` instead of `ExecutionContext` + * [BC BREAK] changed the visibility of the properties in `Validator` from protected to private + * deprecated `ClassMetadataFactoryInterface` in favor of the new `MetadataFactoryInterface` + * deprecated `ClassMetadataFactory::getClassMetadata` in favor of `getMetadataFor` + * created `MetadataInterface`, `PropertyMetadataInterface`, `ClassBasedInterface` and `PropertyMetadataContainerInterface` + * deprecated `GraphWalker` in favor of the new `ValidationVisitorInterface` + * deprecated `ExecutionContext::addViolationAtPath` + * deprecated `ExecutionContext::addViolationAtSubPath` in favor of `ExecutionContextInterface::addViolationAt` + * deprecated `ExecutionContext::getCurrentClass` in favor of `ExecutionContextInterface::getClassName` + * deprecated `ExecutionContext::getCurrentProperty` in favor of `ExecutionContextInterface::getPropertyName` + * deprecated `ExecutionContext::getCurrentValue` in favor of `ExecutionContextInterface::getValue` + * deprecated `ExecutionContext::getGraphWalker` in favor of `ExecutionContextInterface::validate` and `ExecutionContextInterface::validateValue` + * improved `ValidatorInterface::validateValue` to accept arrays of constraints + * changed `ValidatorInterface::getMetadataFactory` to return a `MetadataFactoryInterface` instead of a `ClassMetadataFactoryInterface` + * removed `ClassMetadataFactoryInterface` type hint from `ValidatorBuilderInterface::setMetadataFactory`. + As of Symfony 2.3, this method will be typed against `MetadataFactoryInterface` instead. + * [BC BREAK] the switches `traverse` and `deep` in the `Valid` constraint and in `GraphWalker::walkReference` + are ignored for arrays now. Arrays are always traversed recursively. + * added dependency to Translation component + * violation messages are now translated with a TranslatorInterface implementation + * [BC BREAK] inserted argument `$message` in the constructor of `ConstraintViolation` + * [BC BREAK] inserted arguments `$translator` and `$translationDomain` in the constructor of `ExecutionContext` + * [BC BREAK] inserted arguments `$translator` and `$translationDomain` in the constructor of `GraphWalker` + * [BC BREAK] inserted arguments `$translator` and `$translationDomain` in the constructor of `ValidationVisitor` + * [BC BREAK] inserted arguments `$translator` and `$translationDomain` in the constructor of `Validator` + * [BC BREAK] added `setTranslator()` and `setTranslationDomain()` to `ValidatorBuilderInterface` + * improved the Validator to support pluralized messages by default + * [BC BREAK] changed the source of all pluralized messages in the translation files to the pluralized version + * added ExceptionInterface, BadMethodCallException and InvalidArgumentException + +2.1.0 +----- + + * added support for `ctype_*` assertions in `TypeValidator` + * improved the ImageValidator with min width, max width, min height, and max height constraints + * added support for MIME with wildcard in FileValidator + * changed Collection validator to add "missing" and "extra" errors to + individual fields + * changed default value for `extraFieldsMessage` and `missingFieldsMessage` + in Collection constraint + * made ExecutionContext immutable + * deprecated Constraint methods `setMessage`, `getMessageTemplate` and + `getMessageParameters` + * added support for dynamic group sequences with the GroupSequenceProvider pattern + * [BC BREAK] ConstraintValidatorInterface method `isValid` has been renamed to + `validate`, its return value was dropped. ConstraintValidator still contains + `isValid` for BC + * [BC BREAK] collections in fields annotated with `Valid` are not traversed + recursively anymore by default. `Valid` contains a new property `deep` + which enables the BC behavior. + * added Count constraint + * added Length constraint + * added Range constraint + * deprecated the Min and Max constraints + * deprecated the MinLength and MaxLength constraints + * added Validation and ValidatorBuilderInterface + * deprecated ValidatorContext, ValidatorContextInterface and ValidatorFactory diff --git a/lib/symfony/validator/Command/DebugCommand.php b/lib/symfony/validator/Command/DebugCommand.php new file mode 100644 index 0000000000..c2adfc0284 --- /dev/null +++ b/lib/symfony/validator/Command/DebugCommand.php @@ -0,0 +1,253 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Command; + +use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\Dumper; +use Symfony\Component\Console\Helper\Table; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Finder\Exception\DirectoryNotFoundException; +use Symfony\Component\Finder\Finder; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Mapping\AutoMappingStrategy; +use Symfony\Component\Validator\Mapping\CascadingStrategy; +use Symfony\Component\Validator\Mapping\ClassMetadataInterface; +use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; +use Symfony\Component\Validator\Mapping\GenericMetadata; +use Symfony\Component\Validator\Mapping\TraversalStrategy; + +/** + * A console command to debug Validators information. + * + * @author Loïc Frémont + */ +#[AsCommand(name: 'debug:validator', description: 'Display validation constraints for classes')] +class DebugCommand extends Command +{ + private MetadataFactoryInterface $validator; + + public function __construct(MetadataFactoryInterface $validator) + { + parent::__construct(); + + $this->validator = $validator; + } + + /** + * @return void + */ + protected function configure() + { + $this + ->addArgument('class', InputArgument::REQUIRED, 'A fully qualified class name or a path') + ->addOption('show-all', null, InputOption::VALUE_NONE, 'Show all classes even if they have no validation constraints') + ->setHelp(<<<'EOF' +The %command.name% 'App\Entity\Dummy' command dumps the validators for the dummy class. + +The %command.name% src/ command dumps the validators for the `src` directory. +EOF + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $class = $input->getArgument('class'); + + if (class_exists($class)) { + $this->dumpValidatorsForClass($input, $output, $class); + + return 0; + } + + try { + foreach ($this->getResourcesByPath($class) as $class) { + $this->dumpValidatorsForClass($input, $output, $class); + } + } catch (DirectoryNotFoundException) { + $io = new SymfonyStyle($input, $output); + $io->error(\sprintf('Neither class nor path were found with "%s" argument.', $input->getArgument('class'))); + + return 1; + } + + return 0; + } + + private function dumpValidatorsForClass(InputInterface $input, OutputInterface $output, string $class): void + { + $io = new SymfonyStyle($input, $output); + $title = \sprintf('%s', $class); + $rows = []; + $dump = new Dumper($output); + + /** @var ClassMetadataInterface $classMetadata */ + $classMetadata = $this->validator->getMetadataFor($class); + + foreach ($this->getClassConstraintsData($classMetadata) as $data) { + $rows[] = [ + '-', + $data['class'], + implode(', ', $data['groups']), + $dump($data['options']), + ]; + } + + foreach ($this->getConstrainedPropertiesData($classMetadata) as $propertyName => $constraintsData) { + foreach ($constraintsData as $data) { + $rows[] = [ + $propertyName, + $data['class'], + implode(', ', $data['groups']), + $dump($data['options']), + ]; + } + } + + if (!$rows) { + if (false === $input->getOption('show-all')) { + return; + } + + $io->section($title); + $io->text('No validators were found for this class.'); + + return; + } + + $io->section($title); + + $table = new Table($output); + $table->setHeaders(['Property', 'Name', 'Groups', 'Options']); + $table->setRows($rows); + $table->setColumnMaxWidth(3, 80); + $table->render(); + } + + private function getClassConstraintsData(ClassMetadataInterface $classMetadata): iterable + { + foreach ($classMetadata->getConstraints() as $constraint) { + yield [ + 'class' => $constraint::class, + 'groups' => $constraint->groups, + 'options' => $this->getConstraintOptions($constraint), + ]; + } + } + + private function getConstrainedPropertiesData(ClassMetadataInterface $classMetadata): array + { + $data = []; + + foreach ($classMetadata->getConstrainedProperties() as $constrainedProperty) { + $data[$constrainedProperty] = $this->getPropertyData($classMetadata, $constrainedProperty); + } + + return $data; + } + + private function getPropertyData(ClassMetadataInterface $classMetadata, string $constrainedProperty): array + { + $data = []; + + $propertyMetadata = $classMetadata->getPropertyMetadata($constrainedProperty); + foreach ($propertyMetadata as $metadata) { + $autoMapingStrategy = 'Not supported'; + if ($metadata instanceof GenericMetadata) { + $autoMapingStrategy = match ($metadata->getAutoMappingStrategy()) { + AutoMappingStrategy::ENABLED => 'Enabled', + AutoMappingStrategy::DISABLED => 'Disabled', + AutoMappingStrategy::NONE => 'None', + }; + } + $traversalStrategy = 'None'; + if (TraversalStrategy::TRAVERSE === $metadata->getTraversalStrategy()) { + $traversalStrategy = 'Traverse'; + } + if (TraversalStrategy::IMPLICIT === $metadata->getTraversalStrategy()) { + $traversalStrategy = 'Implicit'; + } + + $data[] = [ + 'class' => 'property options', + 'groups' => [], + 'options' => [ + 'cascadeStrategy' => CascadingStrategy::CASCADE === $metadata->getCascadingStrategy() ? 'Cascade' : 'None', + 'autoMappingStrategy' => $autoMapingStrategy, + 'traversalStrategy' => $traversalStrategy, + ], + ]; + foreach ($metadata->getConstraints() as $constraint) { + $data[] = [ + 'class' => $constraint::class, + 'groups' => $constraint->groups, + 'options' => $this->getConstraintOptions($constraint), + ]; + } + } + + return $data; + } + + private function getConstraintOptions(Constraint $constraint): array + { + $options = []; + + foreach (array_keys(get_object_vars($constraint)) as $propertyName) { + // Groups are dumped on a specific column. + if ('groups' === $propertyName) { + continue; + } + + $options[$propertyName] = $constraint->$propertyName; + } + + ksort($options); + + return $options; + } + + private function getResourcesByPath(string $path): array + { + $finder = new Finder(); + $finder->files()->in($path)->name('*.php')->sortByName(true); + $classes = []; + + foreach ($finder as $file) { + $fileContent = file_get_contents($file->getRealPath()); + + preg_match('/namespace (.+);/', $fileContent, $matches); + + $namespace = $matches[1] ?? null; + + if (!preg_match('/class +([^{ ]+)/', $fileContent, $matches)) { + // no class found + continue; + } + + $className = trim($matches[1]); + + if (null !== $namespace) { + $classes[] = $namespace.'\\'.$className; + } else { + $classes[] = $className; + } + } + + return $classes; + } +} diff --git a/lib/symfony/validator/Constraint.php b/lib/symfony/validator/Constraint.php new file mode 100644 index 0000000000..2a01a1d7c9 --- /dev/null +++ b/lib/symfony/validator/Constraint.php @@ -0,0 +1,321 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\InvalidArgumentException; +use Symfony\Component\Validator\Exception\InvalidOptionsException; +use Symfony\Component\Validator\Exception\MissingOptionsException; + +/** + * Contains the properties of a constraint definition. + * + * A constraint can be defined on a class, a property or a getter method. + * The Constraint class encapsulates all the configuration required for + * validating this class, property or getter result successfully. + * + * Constraint instances are immutable and serializable. + * + * @author Bernhard Schussek + */ +abstract class Constraint +{ + /** + * The name of the group given to all constraints with no explicit group. + */ + public const DEFAULT_GROUP = 'Default'; + + /** + * Marks a constraint that can be put onto classes. + */ + public const CLASS_CONSTRAINT = 'class'; + + /** + * Marks a constraint that can be put onto properties. + */ + public const PROPERTY_CONSTRAINT = 'property'; + + /** + * Maps error codes to the names of their constants. + * + * @var array + */ + protected const ERROR_NAMES = []; + + /** + * @deprecated since Symfony 6.1, use protected const ERROR_NAMES instead + */ + protected static $errorNames = []; + + /** + * Domain-specific data attached to a constraint. + * + * @var mixed + */ + public $payload; + + /** + * The groups that the constraint belongs to. + * + * @var string[] + */ + public $groups; + + /** + * Returns the name of the given error code. + * + * @throws InvalidArgumentException If the error code does not exist + */ + public static function getErrorName(string $errorCode): string + { + if (isset(static::ERROR_NAMES[$errorCode])) { + return static::ERROR_NAMES[$errorCode]; + } + + if (!isset(static::$errorNames[$errorCode])) { + throw new InvalidArgumentException(\sprintf('The error code "%s" does not exist for constraint of type "%s".', $errorCode, static::class)); + } + + trigger_deprecation('symfony/validator', '6.1', 'The "%s::$errorNames" property is deprecated, use protected const ERROR_NAMES instead.', static::class); + + return static::$errorNames[$errorCode]; + } + + /** + * Initializes the constraint with options. + * + * You should pass an associative array. The keys should be the names of + * existing properties in this class. The values should be the value for these + * properties. + * + * Alternatively you can override the method getDefaultOption() to return the + * name of an existing property. If no associative array is passed, this + * property is set instead. + * + * You can force that certain options are set by overriding + * getRequiredOptions() to return the names of these options. If any + * option is not set here, an exception is thrown. + * + * @param mixed $options The options (as associative array) + * or the value for the default + * option (any other type) + * @param string[] $groups An array of validation groups + * @param mixed $payload Domain-specific data attached to a constraint + * + * @throws InvalidOptionsException When you pass the names of non-existing + * options + * @throws MissingOptionsException When you don't pass any of the options + * returned by getRequiredOptions() + * @throws ConstraintDefinitionException When you don't pass an associative + * array, but getDefaultOption() returns + * null + */ + public function __construct(mixed $options = null, ?array $groups = null, mixed $payload = null) + { + unset($this->groups); // enable lazy initialization + + $options = $this->normalizeOptions($options); + if (null !== $groups) { + $options['groups'] = $groups; + } + $options['payload'] = $payload ?? $options['payload'] ?? null; + + foreach ($options as $name => $value) { + $this->$name = $value; + } + } + + protected function normalizeOptions(mixed $options): array + { + $normalizedOptions = []; + $defaultOption = $this->getDefaultOption(); + $invalidOptions = []; + $missingOptions = array_flip((array) $this->getRequiredOptions()); + $knownOptions = get_class_vars(static::class); + + if (\is_array($options) && isset($options['value']) && !property_exists($this, 'value')) { + if (null === $defaultOption) { + throw new ConstraintDefinitionException(\sprintf('No default option is configured for constraint "%s".', static::class)); + } + + $options[$defaultOption] = $options['value']; + unset($options['value']); + } + + if (\is_array($options)) { + reset($options); + } + if ($options && \is_array($options) && \is_string(key($options))) { + foreach ($options as $option => $value) { + if (\array_key_exists($option, $knownOptions)) { + $normalizedOptions[$option] = $value; + unset($missingOptions[$option]); + } else { + $invalidOptions[] = $option; + } + } + } elseif (null !== $options && !(\is_array($options) && 0 === \count($options))) { + if (null === $defaultOption) { + throw new ConstraintDefinitionException(\sprintf('No default option is configured for constraint "%s".', static::class)); + } + + if (\array_key_exists($defaultOption, $knownOptions)) { + $normalizedOptions[$defaultOption] = $options; + unset($missingOptions[$defaultOption]); + } else { + $invalidOptions[] = $defaultOption; + } + } + + if (\count($invalidOptions) > 0) { + throw new InvalidOptionsException(\sprintf('The options "%s" do not exist in constraint "%s".', implode('", "', $invalidOptions), static::class), $invalidOptions); + } + + if (\count($missingOptions) > 0) { + throw new MissingOptionsException(\sprintf('The options "%s" must be set for constraint "%s".', implode('", "', array_keys($missingOptions)), static::class), array_keys($missingOptions)); + } + + return $normalizedOptions; + } + + /** + * Sets the value of a lazily initialized option. + * + * Corresponding properties are added to the object on first access. Hence + * this method will be called at most once per constraint instance and + * option name. + * + * @return void + * + * @throws InvalidOptionsException If an invalid option name is given + */ + public function __set(string $option, mixed $value) + { + if ('groups' === $option) { + $this->groups = (array) $value; + + return; + } + + throw new InvalidOptionsException(\sprintf('The option "%s" does not exist in constraint "%s".', $option, static::class), [$option]); + } + + /** + * Returns the value of a lazily initialized option. + * + * Corresponding properties are added to the object on first access. Hence + * this method will be called at most once per constraint instance and + * option name. + * + * @throws InvalidOptionsException If an invalid option name is given + */ + public function __get(string $option): mixed + { + if ('groups' === $option) { + $this->groups = [self::DEFAULT_GROUP]; + + return $this->groups; + } + + throw new InvalidOptionsException(\sprintf('The option "%s" does not exist in constraint "%s".', $option, static::class), [$option]); + } + + public function __isset(string $option): bool + { + return 'groups' === $option; + } + + /** + * Adds the given group if this constraint is in the Default group. + * + * @return void + */ + public function addImplicitGroupName(string $group) + { + if (null === $this->groups && \array_key_exists('groups', (array) $this)) { + throw new \LogicException(\sprintf('"%s::$groups" is set to null. Did you forget to call "%s::__construct()"?', static::class, self::class)); + } + + if (\in_array(self::DEFAULT_GROUP, $this->groups) && !\in_array($group, $this->groups)) { + $this->groups[] = $group; + } + } + + /** + * Returns the name of the default option. + * + * Override this method to define a default option. + * + * @return string|null + * + * @see __construct() + */ + public function getDefaultOption() + { + return null; + } + + /** + * Returns the name of the required options. + * + * Override this method if you want to define required options. + * + * @return string[] + * + * @see __construct() + */ + public function getRequiredOptions() + { + return []; + } + + /** + * Returns the name of the class that validates this constraint. + * + * By default, this is the fully qualified name of the constraint class + * suffixed with "Validator". You can override this method to change that + * behavior. + * + * @return string + */ + public function validatedBy() + { + return static::class.'Validator'; + } + + /** + * Returns whether the constraint can be put onto classes, properties or + * both. + * + * This method should return one or more of the constants + * Constraint::CLASS_CONSTRAINT and Constraint::PROPERTY_CONSTRAINT. + * + * @return string|string[] One or more constant values + */ + public function getTargets() + { + return self::PROPERTY_CONSTRAINT; + } + + /** + * Optimizes the serialized value to minimize storage space. + * + * @internal + */ + public function __sleep(): array + { + // Initialize "groups" option if it is not set + $this->groups; + + return array_keys(get_object_vars($this)); + } +} diff --git a/lib/symfony/validator/ConstraintValidator.php b/lib/symfony/validator/ConstraintValidator.php new file mode 100644 index 0000000000..60808258c3 --- /dev/null +++ b/lib/symfony/validator/ConstraintValidator.php @@ -0,0 +1,157 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Symfony\Component\Validator\Context\ExecutionContextInterface; + +/** + * Base class for constraint validators. + * + * @author Bernhard Schussek + */ +abstract class ConstraintValidator implements ConstraintValidatorInterface +{ + /** + * Whether to format {@link \DateTime} objects, either with the {@link \IntlDateFormatter} + * (if it is available) or as RFC-3339 dates ("Y-m-d H:i:s"). + */ + public const PRETTY_DATE = 1; + + /** + * Whether to cast objects with a "__toString()" method to strings. + */ + public const OBJECT_TO_STRING = 2; + + /** + * @var ExecutionContextInterface + */ + protected $context; + + /** + * @return void + */ + public function initialize(ExecutionContextInterface $context) + { + $this->context = $context; + } + + /** + * Returns a string representation of the type of the value. + * + * This method should be used if you pass the type of a value as + * message parameter to a constraint violation. Note that such + * parameters should usually not be included in messages aimed at + * non-technical people. + */ + protected function formatTypeOf(mixed $value): string + { + return get_debug_type($value); + } + + /** + * Returns a string representation of the value. + * + * This method returns the equivalent PHP tokens for most scalar types + * (i.e. "false" for false, "1" for 1 etc.). Strings are always wrapped + * in double quotes ("). Objects, arrays and resources are formatted as + * "object", "array" and "resource". If the $format bitmask contains + * the PRETTY_DATE bit, then {@link \DateTime} objects will be formatted + * with the {@link \IntlDateFormatter}. If it is not available, they will be + * formatted as RFC-3339 dates ("Y-m-d H:i:s"). + * + * Be careful when passing message parameters to a constraint violation + * that (may) contain objects, arrays or resources. These parameters + * should only be displayed for technical users. Non-technical users + * won't know what an "object", "array" or "resource" is and will be + * confused by the violation message. + * + * @param int $format A bitwise combination of the format constants in this class + */ + protected function formatValue(mixed $value, int $format = 0): string + { + if (($format & self::PRETTY_DATE) && $value instanceof \DateTimeInterface) { + if (class_exists(\IntlDateFormatter::class)) { + $formatter = new \IntlDateFormatter(\Locale::getDefault(), \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT, 'UTC'); + + return $formatter->format(new \DateTimeImmutable( + $value->format('Y-m-d H:i:s.u'), + new \DateTimeZone('UTC') + )); + } + + return $value->format('Y-m-d H:i:s'); + } + + if ($value instanceof \UnitEnum) { + return $value->name; + } + + if (\is_object($value)) { + if (($format & self::OBJECT_TO_STRING) && $value instanceof \Stringable) { + return $value->__toString(); + } + + return 'object'; + } + + if (\is_array($value)) { + return 'array'; + } + + if (\is_string($value)) { + return '"'.$value.'"'; + } + + if (\is_resource($value)) { + return 'resource'; + } + + if (null === $value) { + return 'null'; + } + + if (false === $value) { + return 'false'; + } + + if (true === $value) { + return 'true'; + } + + if (is_nan($value)) { + return 'NAN'; + } + + return (string) $value; + } + + /** + * Returns a string representation of a list of values. + * + * Each of the values is converted to a string using + * {@link formatValue()}. The values are then concatenated with commas. + * + * @param array $values A list of values + * @param int $format A bitwise combination of the format + * constants in this class + * + * @see formatValue() + */ + protected function formatValues(array $values, int $format = 0): string + { + foreach ($values as $key => $value) { + $values[$key] = $this->formatValue($value, $format); + } + + return implode(', ', $values); + } +} diff --git a/lib/symfony/validator/ConstraintValidatorFactory.php b/lib/symfony/validator/ConstraintValidatorFactory.php new file mode 100644 index 0000000000..778e202a84 --- /dev/null +++ b/lib/symfony/validator/ConstraintValidatorFactory.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Symfony\Component\Validator\Constraints\ExpressionValidator; + +/** + * Default implementation of the ConstraintValidatorFactoryInterface. + * + * This enforces the convention that the validatedBy() method on any + * Constraint will return the class name of the ConstraintValidator that + * should validate the Constraint. + * + * @author Bernhard Schussek + */ +class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface +{ + protected $validators = []; + + public function __construct(array $validators = []) + { + $this->validators = $validators; + } + + public function getInstance(Constraint $constraint): ConstraintValidatorInterface + { + if ('validator.expression' === $name = $class = $constraint->validatedBy()) { + $class = ExpressionValidator::class; + } + + return $this->validators[$name] ??= new $class(); + } +} diff --git a/lib/symfony/validator/ConstraintValidatorFactoryInterface.php b/lib/symfony/validator/ConstraintValidatorFactoryInterface.php new file mode 100644 index 0000000000..f0abd27191 --- /dev/null +++ b/lib/symfony/validator/ConstraintValidatorFactoryInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +/** + * Specifies an object able to return the correct ConstraintValidatorInterface + * instance given a Constraint object. + */ +interface ConstraintValidatorFactoryInterface +{ + /** + * Given a Constraint, this returns the ConstraintValidatorInterface + * object that should be used to verify its validity. + */ + public function getInstance(Constraint $constraint): ConstraintValidatorInterface; +} diff --git a/lib/symfony/validator/ConstraintValidatorInterface.php b/lib/symfony/validator/ConstraintValidatorInterface.php new file mode 100644 index 0000000000..fe7da2e8f7 --- /dev/null +++ b/lib/symfony/validator/ConstraintValidatorInterface.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Symfony\Component\Validator\Context\ExecutionContextInterface; + +/** + * @author Bernhard Schussek + */ +interface ConstraintValidatorInterface +{ + /** + * Initializes the constraint validator. + * + * @return void + */ + public function initialize(ExecutionContextInterface $context); + + /** + * Checks if the passed value is valid. + * + * @return void + */ + public function validate(mixed $value, Constraint $constraint); +} diff --git a/lib/symfony/validator/ConstraintViolation.php b/lib/symfony/validator/ConstraintViolation.php new file mode 100644 index 0000000000..5129ccf952 --- /dev/null +++ b/lib/symfony/validator/ConstraintViolation.php @@ -0,0 +1,144 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +/** + * Default implementation of {@ConstraintViolationInterface}. + * + * @author Bernhard Schussek + */ +class ConstraintViolation implements ConstraintViolationInterface +{ + private string|\Stringable $message; + private ?string $messageTemplate; + private array $parameters; + private ?int $plural; + private mixed $root; + private ?string $propertyPath; + private mixed $invalidValue; + private ?Constraint $constraint; + private ?string $code; + private mixed $cause; + + /** + * Creates a new constraint violation. + * + * @param string|\Stringable $message The violation message as a string or a stringable object + * @param string|null $messageTemplate The raw violation message + * @param array $parameters The parameters to substitute in the + * raw violation message + * @param mixed $root The value originally passed to the + * validator + * @param string|null $propertyPath The property path from the root + * value to the invalid value + * @param mixed $invalidValue The invalid value that caused this + * violation + * @param int|null $plural The number for determining the plural + * form when translating the message + * @param string|null $code The error code of the violation + * @param Constraint|null $constraint The constraint whose validation + * caused the violation + * @param mixed $cause The cause of the violation + */ + public function __construct(string|\Stringable $message, ?string $messageTemplate, array $parameters, mixed $root, ?string $propertyPath, mixed $invalidValue, ?int $plural = null, ?string $code = null, ?Constraint $constraint = null, mixed $cause = null) + { + $this->message = $message; + $this->messageTemplate = $messageTemplate; + $this->parameters = $parameters; + $this->plural = $plural; + $this->root = $root; + $this->propertyPath = $propertyPath; + $this->invalidValue = $invalidValue; + $this->constraint = $constraint; + $this->code = $code; + $this->cause = $cause; + } + + public function __toString(): string + { + if (\is_object($this->root)) { + $class = 'Object('.$this->root::class.')'; + } elseif (\is_array($this->root)) { + $class = 'Array'; + } else { + $class = (string) $this->root; + } + + $propertyPath = (string) $this->propertyPath; + + if ('' !== $propertyPath && '[' !== $propertyPath[0] && '' !== $class) { + $class .= '.'; + } + + if (null !== ($code = $this->code) && '' !== $code) { + $code = ' (code '.$code.')'; + } + + return $class.$propertyPath.":\n ".$this->getMessage().$code; + } + + public function getMessageTemplate(): string + { + return (string) $this->messageTemplate; + } + + public function getParameters(): array + { + return $this->parameters; + } + + public function getPlural(): ?int + { + return $this->plural; + } + + public function getMessage(): string|\Stringable + { + return $this->message; + } + + public function getRoot(): mixed + { + return $this->root; + } + + public function getPropertyPath(): string + { + return (string) $this->propertyPath; + } + + public function getInvalidValue(): mixed + { + return $this->invalidValue; + } + + /** + * Returns the constraint whose validation caused the violation. + */ + public function getConstraint(): ?Constraint + { + return $this->constraint; + } + + /** + * Returns the cause of the violation. + */ + public function getCause(): mixed + { + return $this->cause; + } + + public function getCode(): ?string + { + return $this->code; + } +} diff --git a/lib/symfony/validator/ConstraintViolationInterface.php b/lib/symfony/validator/ConstraintViolationInterface.php new file mode 100644 index 0000000000..6eb2797406 --- /dev/null +++ b/lib/symfony/validator/ConstraintViolationInterface.php @@ -0,0 +1,116 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +/** + * A violation of a constraint that happened during validation. + * + * For each constraint that fails during validation one or more violations are + * created. The violations store the violation message, the path to the failing + * element in the validation graph and the root element that was originally + * passed to the validator. For example, take the following graph: + * + * (Person)---(firstName: string) + * \ + * (address: Address)---(street: string) + * + * If the Person object is validated and validation fails for the + * "firstName" property, the generated violation has the Person + * instance as root and the property path "firstName". If validation fails + * for the "street" property of the related Address instance, the root + * element is still the person, but the property path is "address.street". + * + * @author Bernhard Schussek + * + * @method Constraint|null getConstraint() Returns the constraint whose validation caused the violation. Not implementing it is deprecated since Symfony 6.3. + * @method mixed getCause() Returns the cause of the violation. Not implementing it is deprecated since Symfony 6.2. + * @method string __toString() Converts the violation into a string for debugging purposes. Not implementing it is deprecated since Symfony 6.1. + */ +interface ConstraintViolationInterface +{ + /** + * Returns the violation message. + */ + public function getMessage(): string|\Stringable; + + /** + * Returns the raw violation message. + * + * The raw violation message contains placeholders for the parameters + * returned by {@link getParameters}. Typically you'll pass the + * message template and parameters to a translation engine. + */ + public function getMessageTemplate(): string; + + /** + * Returns the parameters to be inserted into the raw violation message. + * + * @return array a possibly empty list of parameters indexed by the names + * that appear in the message template + * + * @see getMessageTemplate() + */ + public function getParameters(): array; + + /** + * Returns a number for pluralizing the violation message. + * + * For example, the message template could have different translation based + * on a parameter "choices": + * + *
    + *
  • Please select exactly one entry. (choices=1)
  • + *
  • Please select two entries. (choices=2)
  • + *
+ * + * This method returns the value of the parameter for choosing the right + * pluralization form (in this case "choices"). + */ + public function getPlural(): ?int; + + /** + * Returns the root element of the validation. + * + * @return mixed The value that was passed originally to the validator when + * the validation was started. Because the validator traverses + * the object graph, the value at which the violation occurs + * is not necessarily the value that was originally validated. + */ + public function getRoot(): mixed; + + /** + * Returns the property path from the root element to the violation. + * + * @return string The property path indicates how the validator reached + * the invalid value from the root element. If the root + * element is a Person instance with a property + * "address" that contains an Address instance + * with an invalid property "street", the generated property + * path is "address.street". Property access is denoted by + * dots, while array access is denoted by square brackets, + * for example "addresses[1].street". + */ + public function getPropertyPath(): string; + + /** + * Returns the value that caused the violation. + * + * @return mixed the invalid value that caused the validated constraint to + * fail + */ + public function getInvalidValue(): mixed; + + /** + * Returns a machine-digestible error code for the violation. + */ + public function getCode(): ?string; +} diff --git a/lib/symfony/validator/ConstraintViolationList.php b/lib/symfony/validator/ConstraintViolationList.php new file mode 100644 index 0000000000..dc2a6df437 --- /dev/null +++ b/lib/symfony/validator/ConstraintViolationList.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Symfony\Component\Validator\Exception\OutOfBoundsException; + +/** + * Default implementation of {@ConstraintViolationListInterface}. + * + * @author Bernhard Schussek + * + * @implements \IteratorAggregate + */ +class ConstraintViolationList implements \IteratorAggregate, ConstraintViolationListInterface +{ + /** + * @var list + */ + private array $violations = []; + + /** + * Creates a new constraint violation list. + * + * @param iterable $violations The constraint violations to add to the list + */ + public function __construct(iterable $violations = []) + { + foreach ($violations as $violation) { + $this->add($violation); + } + } + + public static function createFromMessage(string $message): self + { + $self = new self(); + $self->add(new ConstraintViolation($message, '', [], null, '', null)); + + return $self; + } + + public function __toString(): string + { + $string = ''; + + foreach ($this->violations as $violation) { + $string .= $violation."\n"; + } + + return $string; + } + + /** + * @return void + */ + public function add(ConstraintViolationInterface $violation) + { + $this->violations[] = $violation; + } + + /** + * @return void + */ + public function addAll(ConstraintViolationListInterface $otherList) + { + foreach ($otherList as $violation) { + $this->violations[] = $violation; + } + } + + public function get(int $offset): ConstraintViolationInterface + { + if (!isset($this->violations[$offset])) { + throw new OutOfBoundsException(\sprintf('The offset "%s" does not exist.', $offset)); + } + + return $this->violations[$offset]; + } + + public function has(int $offset): bool + { + return isset($this->violations[$offset]); + } + + /** + * @return void + */ + public function set(int $offset, ConstraintViolationInterface $violation) + { + $this->violations[$offset] = $violation; + } + + /** + * @return void + */ + public function remove(int $offset) + { + unset($this->violations[$offset]); + } + + /** + * @return \ArrayIterator + */ + public function getIterator(): \ArrayIterator + { + return new \ArrayIterator($this->violations); + } + + public function count(): int + { + return \count($this->violations); + } + + public function offsetExists(mixed $offset): bool + { + return $this->has($offset); + } + + public function offsetGet(mixed $offset): ConstraintViolationInterface + { + return $this->get($offset); + } + + public function offsetSet(mixed $offset, mixed $violation): void + { + if (null === $offset) { + $this->add($violation); + } else { + $this->set($offset, $violation); + } + } + + public function offsetUnset(mixed $offset): void + { + $this->remove($offset); + } + + /** + * Creates iterator for errors with specific codes. + * + * @param string|string[] $codes The codes to find + */ + public function findByCodes(string|array $codes): static + { + $codes = (array) $codes; + $violations = []; + foreach ($this as $violation) { + if (\in_array($violation->getCode(), $codes, true)) { + $violations[] = $violation; + } + } + + return new static($violations); + } +} diff --git a/lib/symfony/validator/ConstraintViolationListInterface.php b/lib/symfony/validator/ConstraintViolationListInterface.php new file mode 100644 index 0000000000..1fdbf0bc3f --- /dev/null +++ b/lib/symfony/validator/ConstraintViolationListInterface.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Symfony\Component\Validator\Exception\OutOfBoundsException; + +/** + * A list of constraint violations. + * + * @author Bernhard Schussek + * + * @extends \ArrayAccess + * @extends \Traversable + * + * @method string __toString() Converts the violation into a string for debugging purposes. Not implementing it is deprecated since Symfony 6.1. + */ +interface ConstraintViolationListInterface extends \Traversable, \Countable, \ArrayAccess +{ + /** + * Adds a constraint violation to this list. + * + * @return void + */ + public function add(ConstraintViolationInterface $violation); + + /** + * Merges an existing violation list into this list. + * + * @return void + */ + public function addAll(self $otherList); + + /** + * Returns the violation at a given offset. + * + * @param int $offset The offset of the violation + * + * @throws OutOfBoundsException if the offset does not exist + */ + public function get(int $offset): ConstraintViolationInterface; + + /** + * Returns whether the given offset exists. + * + * @param int $offset The violation offset + */ + public function has(int $offset): bool; + + /** + * Sets a violation at a given offset. + * + * @param int $offset The violation offset + * + * @return void + */ + public function set(int $offset, ConstraintViolationInterface $violation); + + /** + * Removes a violation at a given offset. + * + * @param int $offset The offset to remove + * + * @return void + */ + public function remove(int $offset); +} diff --git a/lib/symfony/validator/Constraints/AbstractComparison.php b/lib/symfony/validator/Constraints/AbstractComparison.php new file mode 100644 index 0000000000..ffba055116 --- /dev/null +++ b/lib/symfony/validator/Constraints/AbstractComparison.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\LogicException; + +/** + * Used for the comparison of values. + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +abstract class AbstractComparison extends Constraint +{ + public $message; + public $value; + public $propertyPath; + + public function __construct(mixed $value = null, ?string $propertyPath = null, ?string $message = null, ?array $groups = null, mixed $payload = null, array $options = []) + { + if (\is_array($value)) { + $options = array_merge($value, $options); + } elseif (null !== $value) { + $options['value'] = $value; + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->propertyPath = $propertyPath ?? $this->propertyPath; + + if (null === $this->value && null === $this->propertyPath) { + throw new ConstraintDefinitionException(\sprintf('The "%s" constraint requires either the "value" or "propertyPath" option to be set.', static::class)); + } + + if (null !== $this->value && null !== $this->propertyPath) { + throw new ConstraintDefinitionException(\sprintf('The "%s" constraint requires only one of the "value" or "propertyPath" options to be set, not both.', static::class)); + } + + if (null !== $this->propertyPath && !class_exists(PropertyAccess::class)) { + throw new LogicException(\sprintf('The "%s" constraint requires the Symfony PropertyAccess component to use the "propertyPath" option. Try running "composer require symfony/property-access".', static::class)); + } + } + + public function getDefaultOption(): ?string + { + return 'value'; + } +} diff --git a/lib/symfony/validator/Constraints/AbstractComparisonValidator.php b/lib/symfony/validator/Constraints/AbstractComparisonValidator.php new file mode 100644 index 0000000000..b7284fdb9e --- /dev/null +++ b/lib/symfony/validator/Constraints/AbstractComparisonValidator.php @@ -0,0 +1,110 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException; +use Symfony\Component\PropertyAccess\Exception\UninitializedPropertyException; +use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\PropertyAccess\PropertyAccessorInterface; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * Provides a base class for the validation of property comparisons. + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +abstract class AbstractComparisonValidator extends ConstraintValidator +{ + private ?PropertyAccessorInterface $propertyAccessor; + + public function __construct(?PropertyAccessorInterface $propertyAccessor = null) + { + $this->propertyAccessor = $propertyAccessor; + } + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof AbstractComparison) { + throw new UnexpectedTypeException($constraint, AbstractComparison::class); + } + + if (null === $value) { + return; + } + + if ($path = $constraint->propertyPath) { + if (null === $object = $this->context->getObject()) { + return; + } + + try { + $comparedValue = $this->getPropertyAccessor()->getValue($object, $path); + } catch (NoSuchPropertyException $e) { + throw new ConstraintDefinitionException(\sprintf('Invalid property path "%s" provided to "%s" constraint: ', $path, get_debug_type($constraint)).$e->getMessage(), 0, $e); + } catch (UninitializedPropertyException) { + $comparedValue = null; + } + } else { + $comparedValue = $constraint->value; + } + + // Convert strings to date-time objects if comparing to another date-time object + // This allows to compare with any date/time value supported by date-time constructors: + // https://php.net/datetime.formats + if (\is_string($comparedValue) && $value instanceof \DateTimeInterface) { + try { + $comparedValue = new $value($comparedValue); + } catch (\Exception) { + throw new ConstraintDefinitionException(\sprintf('The compared value "%s" could not be converted to a "%s" instance in the "%s" constraint.', $comparedValue, get_debug_type($value), get_debug_type($constraint))); + } + } + + if (!$this->compareValues($value, $comparedValue)) { + $violationBuilder = $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value, self::OBJECT_TO_STRING | self::PRETTY_DATE)) + ->setParameter('{{ compared_value }}', $this->formatValue($comparedValue, self::OBJECT_TO_STRING | self::PRETTY_DATE)) + ->setParameter('{{ compared_value_type }}', $this->formatTypeOf($comparedValue)) + ->setCode($this->getErrorCode()); + + if (null !== $path) { + $violationBuilder->setParameter('{{ compared_value_path }}', $path); + } + + $violationBuilder->addViolation(); + } + } + + private function getPropertyAccessor(): PropertyAccessorInterface + { + return $this->propertyAccessor ??= PropertyAccess::createPropertyAccessor(); + } + + /** + * Compares the two given values to find if their relationship is valid. + */ + abstract protected function compareValues(mixed $value1, mixed $value2): bool; + + /** + * Returns the error code used if the comparison fails. + */ + protected function getErrorCode(): ?string + { + return null; + } +} diff --git a/lib/symfony/validator/Constraints/All.php b/lib/symfony/validator/Constraints/All.php new file mode 100644 index 0000000000..0888084d77 --- /dev/null +++ b/lib/symfony/validator/Constraints/All.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class All extends Composite +{ + public $constraints = []; + + public function __construct(mixed $constraints = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($constraints ?? [], $groups, $payload); + } + + public function getDefaultOption(): ?string + { + return 'constraints'; + } + + public function getRequiredOptions(): array + { + return ['constraints']; + } + + protected function getCompositeOption(): string + { + return 'constraints'; + } +} diff --git a/lib/symfony/validator/Constraints/AllValidator.php b/lib/symfony/validator/Constraints/AllValidator.php new file mode 100644 index 0000000000..15896f29da --- /dev/null +++ b/lib/symfony/validator/Constraints/AllValidator.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * @author Bernhard Schussek + */ +class AllValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof All) { + throw new UnexpectedTypeException($constraint, All::class); + } + + if (null === $value) { + return; + } + + if (!\is_array($value) && !$value instanceof \Traversable) { + throw new UnexpectedValueException($value, 'iterable'); + } + + $context = $this->context; + + $validator = $context->getValidator()->inContext($context); + + foreach ($value as $key => $element) { + $validator->atPath('['.$key.']')->validate($element, $constraint->constraints); + } + } +} diff --git a/lib/symfony/validator/Constraints/AtLeastOneOf.php b/lib/symfony/validator/Constraints/AtLeastOneOf.php new file mode 100644 index 0000000000..4e86473974 --- /dev/null +++ b/lib/symfony/validator/Constraints/AtLeastOneOf.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Przemysław Bogusz + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class AtLeastOneOf extends Composite +{ + public const AT_LEAST_ONE_OF_ERROR = 'f27e6d6c-261a-4056-b391-6673a623531c'; + + protected const ERROR_NAMES = [ + self::AT_LEAST_ONE_OF_ERROR => 'AT_LEAST_ONE_OF_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $constraints = []; + public $message = 'This value should satisfy at least one of the following constraints:'; + public $messageCollection = 'Each element of this collection should satisfy its own set of constraints.'; + public $includeInternalMessages = true; + + public function __construct(mixed $constraints = null, ?array $groups = null, mixed $payload = null, ?string $message = null, ?string $messageCollection = null, ?bool $includeInternalMessages = null) + { + parent::__construct($constraints ?? [], $groups, $payload); + + $this->message = $message ?? $this->message; + $this->messageCollection = $messageCollection ?? $this->messageCollection; + $this->includeInternalMessages = $includeInternalMessages ?? $this->includeInternalMessages; + } + + public function getDefaultOption(): ?string + { + return 'constraints'; + } + + public function getRequiredOptions(): array + { + return ['constraints']; + } + + protected function getCompositeOption(): string + { + return 'constraints'; + } +} diff --git a/lib/symfony/validator/Constraints/AtLeastOneOfValidator.php b/lib/symfony/validator/Constraints/AtLeastOneOfValidator.php new file mode 100644 index 0000000000..5348527c70 --- /dev/null +++ b/lib/symfony/validator/Constraints/AtLeastOneOfValidator.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Przemysław Bogusz + */ +class AtLeastOneOfValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof AtLeastOneOf) { + throw new UnexpectedTypeException($constraint, AtLeastOneOf::class); + } + + $validator = $this->context->getValidator(); + + // Build a first violation to have the base message of the constraint translated + $baseMessageContext = clone $this->context; + $baseMessageContext->buildViolation($constraint->message)->addViolation(); + $baseViolations = $baseMessageContext->getViolations(); + $messages = [(string) $baseViolations->get(\count($baseViolations) - 1)->getMessage()]; + + foreach ($constraint->constraints as $key => $item) { + if (!\in_array($this->context->getGroup(), $item->groups, true)) { + continue; + } + + $context = $this->context; + $executionContext = clone $this->context; + $executionContext->setNode($value, $this->context->getObject(), $this->context->getMetadata(), $this->context->getPropertyPath()); + $violations = $validator->inContext($executionContext)->validate($value, $item, $this->context->getGroup())->getViolations(); + $this->context = $context; + + if (\count($this->context->getViolations()) === \count($violations)) { + return; + } + + if ($constraint->includeInternalMessages) { + $message = ' ['.($key + 1).'] '; + + if ($item instanceof All || $item instanceof Collection) { + $message .= $constraint->messageCollection; + } else { + $message .= $violations->get(\count($violations) - 1)->getMessage(); + } + + $messages[] = $message; + } + } + + $this->context->buildViolation(implode('', $messages)) + ->setCode(AtLeastOneOf::AT_LEAST_ONE_OF_ERROR) + ->addViolation() + ; + } +} diff --git a/lib/symfony/validator/Constraints/Bic.php b/lib/symfony/validator/Constraints/Bic.php new file mode 100644 index 0000000000..dfd54f7a2d --- /dev/null +++ b/lib/symfony/validator/Constraints/Bic.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Intl\Countries; +use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\LogicException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Michael Hirschler + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Bic extends Constraint +{ + public const INVALID_LENGTH_ERROR = '66dad313-af0b-4214-8566-6c799be9789c'; + public const INVALID_CHARACTERS_ERROR = 'f424c529-7add-4417-8f2d-4b656e4833e2'; + public const INVALID_BANK_CODE_ERROR = '00559357-6170-4f29-aebd-d19330aa19cf'; + public const INVALID_COUNTRY_CODE_ERROR = '1ce76f8d-3c1f-451c-9e62-fe9c3ed486ae'; + public const INVALID_CASE_ERROR = '11884038-3312-4ae5-9d04-699f782130c7'; + public const INVALID_IBAN_COUNTRY_CODE_ERROR = '29a2c3bb-587b-4996-b6f5-53081364cea5'; + + protected const ERROR_NAMES = [ + self::INVALID_LENGTH_ERROR => 'INVALID_LENGTH_ERROR', + self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR', + self::INVALID_BANK_CODE_ERROR => 'INVALID_BANK_CODE_ERROR', + self::INVALID_COUNTRY_CODE_ERROR => 'INVALID_COUNTRY_CODE_ERROR', + self::INVALID_CASE_ERROR => 'INVALID_CASE_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This is not a valid Business Identifier Code (BIC).'; + public $ibanMessage = 'This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.'; + public $iban; + public $ibanPropertyPath; + + public function __construct(?array $options = null, ?string $message = null, ?string $iban = null, ?string $ibanPropertyPath = null, ?string $ibanMessage = null, ?array $groups = null, mixed $payload = null) + { + if (!class_exists(Countries::class)) { + throw new LogicException('The Intl component is required to use the Bic constraint. Try running "composer require symfony/intl".'); + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->ibanMessage = $ibanMessage ?? $this->ibanMessage; + $this->iban = $iban ?? $this->iban; + $this->ibanPropertyPath = $ibanPropertyPath ?? $this->ibanPropertyPath; + + if (null !== $this->iban && null !== $this->ibanPropertyPath) { + throw new ConstraintDefinitionException('The "iban" and "ibanPropertyPath" options of the Iban constraint cannot be used at the same time.'); + } + + if (null !== $this->ibanPropertyPath && !class_exists(PropertyAccess::class)) { + throw new LogicException(\sprintf('The "symfony/property-access" component is required to use the "%s" constraint with the "ibanPropertyPath" option. Try running "composer require symfony/property-access".', self::class)); + } + } +} diff --git a/lib/symfony/validator/Constraints/BicValidator.php b/lib/symfony/validator/Constraints/BicValidator.php new file mode 100644 index 0000000000..d038b8cb82 --- /dev/null +++ b/lib/symfony/validator/Constraints/BicValidator.php @@ -0,0 +1,167 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Intl\Countries; +use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException; +use Symfony\Component\PropertyAccess\Exception\UninitializedPropertyException; +use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\PropertyAccess\PropertyAccessor; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\LogicException; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +/** + * @author Michael Hirschler + * + * @see https://en.wikipedia.org/wiki/ISO_9362#Structure + */ +class BicValidator extends ConstraintValidator +{ + // Reference: https://www.iban.com/structure + private const BIC_COUNTRY_TO_IBAN_COUNTRY_MAP = [ + // FR includes: + 'GF' => 'FR', // French Guiana + 'PF' => 'FR', // French Polynesia + 'TF' => 'FR', // French Southern Territories + 'GP' => 'FR', // Guadeloupe + 'MQ' => 'FR', // Martinique + 'YT' => 'FR', // Mayotte + 'NC' => 'FR', // New Caledonia + 'RE' => 'FR', // Reunion + 'BL' => 'FR', // Saint Barthelemy + 'MF' => 'FR', // Saint Martin (French part) + 'PM' => 'FR', // Saint Pierre and Miquelon + 'WF' => 'FR', // Wallis and Futuna Islands + // GB includes: + 'JE' => 'GB', // Jersey + 'IM' => 'GB', // Isle of Man + 'GG' => 'GB', // Guernsey + 'VG' => 'GB', // British Virgin Islands + // FI includes: + 'AX' => 'FI', // Aland Islands + // ES includes: + 'IC' => 'ES', // Canary Islands + 'EA' => 'ES', // Ceuta and Melilla + ]; + + private ?PropertyAccessor $propertyAccessor; + + public function __construct(?PropertyAccessor $propertyAccessor = null) + { + $this->propertyAccessor = $propertyAccessor; + } + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Bic) { + throw new UnexpectedTypeException($constraint, Bic::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $canonicalize = str_replace(' ', '', $value); + + // the bic must be either 8 or 11 characters long + if (!\in_array(\strlen($canonicalize), [8, 11])) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Bic::INVALID_LENGTH_ERROR) + ->addViolation(); + + return; + } + + // must contain alphanumeric values only + if (!ctype_alnum($canonicalize)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Bic::INVALID_CHARACTERS_ERROR) + ->addViolation(); + + return; + } + + $bicCountryCode = substr($canonicalize, 4, 2); + if (!isset(self::BIC_COUNTRY_TO_IBAN_COUNTRY_MAP[$bicCountryCode]) && !Countries::exists($bicCountryCode)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Bic::INVALID_COUNTRY_CODE_ERROR) + ->addViolation(); + + return; + } + + // should contain uppercase characters only + if (strtoupper($canonicalize) !== $canonicalize) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Bic::INVALID_CASE_ERROR) + ->addViolation(); + + return; + } + + // check against an IBAN + $iban = $constraint->iban; + $path = $constraint->ibanPropertyPath; + if ($path && null !== $object = $this->context->getObject()) { + try { + $iban = $this->getPropertyAccessor()->getValue($object, $path); + } catch (NoSuchPropertyException $e) { + throw new ConstraintDefinitionException(\sprintf('Invalid property path "%s" provided to "%s" constraint: ', $path, get_debug_type($constraint)).$e->getMessage(), 0, $e); + } catch (UninitializedPropertyException) { + $iban = null; + } + } + if (!$iban) { + return; + } + $ibanCountryCode = substr($iban, 0, 2); + if (ctype_alpha($ibanCountryCode) && !$this->bicAndIbanCountriesMatch($bicCountryCode, $ibanCountryCode)) { + $this->context->buildViolation($constraint->ibanMessage) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setParameter('{{ iban }}', $iban) + ->setCode(Bic::INVALID_IBAN_COUNTRY_CODE_ERROR) + ->addViolation(); + } + } + + private function getPropertyAccessor(): PropertyAccessor + { + if (null === $this->propertyAccessor) { + if (!class_exists(PropertyAccess::class)) { + throw new LogicException('Unable to use property path as the Symfony PropertyAccess component is not installed. Try running "composer require symfony/property-access".'); + } + $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); + } + + return $this->propertyAccessor; + } + + private function bicAndIbanCountriesMatch(string $bicCountryCode, string $ibanCountryCode): bool + { + return $ibanCountryCode === $bicCountryCode || $ibanCountryCode === (self::BIC_COUNTRY_TO_IBAN_COUNTRY_MAP[$bicCountryCode] ?? null); + } +} diff --git a/lib/symfony/validator/Constraints/Blank.php b/lib/symfony/validator/Constraints/Blank.php new file mode 100644 index 0000000000..00a4e65d97 --- /dev/null +++ b/lib/symfony/validator/Constraints/Blank.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Blank extends Constraint +{ + public const NOT_BLANK_ERROR = '183ad2de-533d-4796-a439-6d3c3852b549'; + + protected const ERROR_NAMES = [ + self::NOT_BLANK_ERROR => 'NOT_BLANK_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be blank.'; + + public function __construct(?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options ?? [], $groups, $payload); + + $this->message = $message ?? $this->message; + } +} diff --git a/lib/symfony/validator/Constraints/BlankValidator.php b/lib/symfony/validator/Constraints/BlankValidator.php new file mode 100644 index 0000000000..2551d5e244 --- /dev/null +++ b/lib/symfony/validator/Constraints/BlankValidator.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Bernhard Schussek + */ +class BlankValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Blank) { + throw new UnexpectedTypeException($constraint, Blank::class); + } + + if ('' !== $value && null !== $value) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Blank::NOT_BLANK_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Callback.php b/lib/symfony/validator/Constraints/Callback.php new file mode 100644 index 0000000000..5cff153d6b --- /dev/null +++ b/lib/symfony/validator/Constraints/Callback.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"CLASS", "PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Callback extends Constraint +{ + /** + * @var string|callable + */ + public $callback; + + public function __construct(array|string|callable|null $callback = null, ?array $groups = null, mixed $payload = null, array $options = []) + { + // Invocation through annotations with an array parameter only + if (\is_array($callback) && 1 === \count($callback) && isset($callback['value'])) { + $callback = $callback['value']; + } + + if (!\is_array($callback) || (!isset($callback['callback']) && !isset($callback['groups']) && !isset($callback['payload']))) { + $options['callback'] = $callback; + } else { + $options = array_merge($callback, $options); + } + + parent::__construct($options, $groups, $payload); + } + + public function getDefaultOption(): ?string + { + return 'callback'; + } + + public function getTargets(): string|array + { + return [self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT]; + } +} diff --git a/lib/symfony/validator/Constraints/CallbackValidator.php b/lib/symfony/validator/Constraints/CallbackValidator.php new file mode 100644 index 0000000000..e1936ad966 --- /dev/null +++ b/lib/symfony/validator/Constraints/CallbackValidator.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * Validator for Callback constraint. + * + * @author Bernhard Schussek + */ +class CallbackValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $object, Constraint $constraint) + { + if (!$constraint instanceof Callback) { + throw new UnexpectedTypeException($constraint, Callback::class); + } + + $method = $constraint->callback; + if ($method instanceof \Closure) { + $method($object, $this->context, $constraint->payload); + } elseif (\is_array($method)) { + if (!\is_callable($method)) { + if (isset($method[0]) && \is_object($method[0])) { + $method[0] = $method[0]::class; + } + throw new ConstraintDefinitionException(json_encode($method).' targeted by Callback constraint is not a valid callable.'); + } + + $method($object, $this->context, $constraint->payload); + } elseif (null !== $object) { + if (!method_exists($object, $method)) { + throw new ConstraintDefinitionException(\sprintf('Method "%s" targeted by Callback constraint does not exist in class "%s".', $method, get_debug_type($object))); + } + + $reflMethod = new \ReflectionMethod($object, $method); + + if ($reflMethod->isStatic()) { + $reflMethod->invoke(null, $object, $this->context, $constraint->payload); + } else { + $reflMethod->invoke($object, $this->context, $constraint->payload); + } + } + } +} diff --git a/lib/symfony/validator/Constraints/CardScheme.php b/lib/symfony/validator/Constraints/CardScheme.php new file mode 100644 index 0000000000..39eb1cd59b --- /dev/null +++ b/lib/symfony/validator/Constraints/CardScheme.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * Metadata for the CardSchemeValidator. + * + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Tim Nagel + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class CardScheme extends Constraint +{ + public const AMEX = 'AMEX'; + public const CHINA_UNIONPAY = 'CHINA_UNIONPAY'; + public const DINERS = 'DINERS'; + public const DISCOVER = 'DISCOVER'; + public const INSTAPAYMENT = 'INSTAPAYMENT'; + public const JCB = 'JCB'; + public const LASER = 'LASER'; + public const MAESTRO = 'MAESTRO'; + public const MASTERCARD = 'MASTERCARD'; + public const MIR = 'MIR'; + public const UATP = 'UATP'; + public const VISA = 'VISA'; + + public const NOT_NUMERIC_ERROR = 'a2ad9231-e827-485f-8a1e-ef4d9a6d5c2e'; + public const INVALID_FORMAT_ERROR = 'a8faedbf-1c2f-4695-8d22-55783be8efed'; + + protected const ERROR_NAMES = [ + self::NOT_NUMERIC_ERROR => 'NOT_NUMERIC_ERROR', + self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'Unsupported card type or invalid card number.'; + public $schemes; + + public function __construct(array|string|null $schemes, ?string $message = null, ?array $groups = null, mixed $payload = null, array $options = []) + { + if (\is_array($schemes) && \is_string(key($schemes))) { + $options = array_merge($schemes, $options); + } elseif (null !== $schemes) { + $options['value'] = $schemes; + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + } + + public function getDefaultOption(): ?string + { + return 'schemes'; + } + + public function getRequiredOptions(): array + { + return ['schemes']; + } +} diff --git a/lib/symfony/validator/Constraints/CardSchemeValidator.php b/lib/symfony/validator/Constraints/CardSchemeValidator.php new file mode 100644 index 0000000000..22de0d8db7 --- /dev/null +++ b/lib/symfony/validator/Constraints/CardSchemeValidator.php @@ -0,0 +1,134 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * Validates that a card number belongs to a specified scheme. + * + * @author Tim Nagel + * @author Bernhard Schussek + * + * @see https://en.wikipedia.org/wiki/Payment_card_number + * @see https://www.regular-expressions.info/creditcard.html + */ +class CardSchemeValidator extends ConstraintValidator +{ + protected $schemes = [ + // American Express card numbers start with 34 or 37 and have 15 digits. + CardScheme::AMEX => [ + '/^3[47][0-9]{13}$/D', + ], + // China UnionPay cards start with 62 and have between 16 and 19 digits. + // Please note that these cards do not follow Luhn Algorithm as a checksum. + CardScheme::CHINA_UNIONPAY => [ + '/^62[0-9]{14,17}$/D', + ], + // Diners Club card numbers begin with 300 through 305, 36 or 38. All have 14 digits. + // There are Diners Club cards that begin with 5 and have 16 digits. + // These are a joint venture between Diners Club and MasterCard, and should be processed like a MasterCard. + CardScheme::DINERS => [ + '/^3(?:0[0-5]|[68][0-9])[0-9]{11}$/D', + ], + // Discover card numbers begin with 6011, 622126 through 622925, 644 through 649 or 65. + // All have 16 digits. + CardScheme::DISCOVER => [ + '/^6011[0-9]{12}$/D', + '/^64[4-9][0-9]{13}$/D', + '/^65[0-9]{14}$/D', + '/^622(12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|91[0-9]|92[0-5])[0-9]{10}$/D', + ], + // InstaPayment cards begin with 637 through 639 and have 16 digits. + CardScheme::INSTAPAYMENT => [ + '/^63[7-9][0-9]{13}$/D', + ], + // JCB cards beginning with 2131 or 1800 have 15 digits. + // JCB cards beginning with 35 have 16 digits. + CardScheme::JCB => [ + '/^(?:2131|1800|35[0-9]{3})[0-9]{11}$/D', + ], + // Laser cards begin with either 6304, 6706, 6709 or 6771 and have between 16 and 19 digits. + CardScheme::LASER => [ + '/^(6304|670[69]|6771)[0-9]{12,15}$/D', + ], + // Maestro international cards begin with 675900..675999 and have between 12 and 19 digits. + // Maestro UK cards begin with either 500000..509999 or 560000..699999 and have between 12 and 19 digits. + CardScheme::MAESTRO => [ + '/^(6759[0-9]{2})[0-9]{6,13}$/D', + '/^(50[0-9]{4})[0-9]{6,13}$/D', + '/^5[6-9][0-9]{10,17}$/D', + '/^6[0-9]{11,18}$/D', + ], + // All MasterCard numbers start with the numbers 51 through 55. All have 16 digits. + // October 2016 MasterCard numbers can also start with 222100 through 272099. + CardScheme::MASTERCARD => [ + '/^5[1-5][0-9]{14}$/D', + '/^2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12})$/D', + ], + // Payment system MIR numbers start with 220, then 1 digit from 0 to 4, then between 12 and 15 digits + CardScheme::MIR => [ + '/^220[0-4][0-9]{12,15}$/D', + ], + // All UATP card numbers start with a 1 and have a length of 15 digits. + CardScheme::UATP => [ + '/^1[0-9]{14}$/D', + ], + // All Visa card numbers start with a 4 and have a length of 13, 16, or 19 digits. + CardScheme::VISA => [ + '/^4([0-9]{12}|[0-9]{15}|[0-9]{18})$/D', + ], + ]; + + /** + * Validates a creditcard belongs to a specified scheme. + * + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof CardScheme) { + throw new UnexpectedTypeException($constraint, CardScheme::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!is_numeric($value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(CardScheme::NOT_NUMERIC_ERROR) + ->addViolation(); + + return; + } + + $schemes = array_flip((array) $constraint->schemes); + $schemeRegexes = array_intersect_key($this->schemes, $schemes); + + foreach ($schemeRegexes as $regexes) { + foreach ($regexes as $regex) { + if (preg_match($regex, $value)) { + return; + } + } + } + + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(CardScheme::INVALID_FORMAT_ERROR) + ->addViolation(); + } +} diff --git a/lib/symfony/validator/Constraints/Cascade.php b/lib/symfony/validator/Constraints/Cascade.php new file mode 100644 index 0000000000..5a0fce110a --- /dev/null +++ b/lib/symfony/validator/Constraints/Cascade.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * @Annotation + * @Target({"CLASS"}) + * + * @author Jules Pietri + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +class Cascade extends Constraint +{ + public array $exclude = []; + + public function __construct(array|string|null $exclude = null, ?array $options = null) + { + if (\is_array($exclude) && !array_is_list($exclude)) { + $options = array_merge($exclude, $options ?? []); + $options['exclude'] = array_flip((array) ($options['exclude'] ?? [])); + } else { + $this->exclude = array_flip((array) $exclude); + } + + if (\is_array($options) && \array_key_exists('groups', $options)) { + throw new ConstraintDefinitionException(\sprintf('The option "groups" is not supported by the constraint "%s".', __CLASS__)); + } + + parent::__construct($options); + } + + public function getTargets(): string|array + { + return self::CLASS_CONSTRAINT; + } +} diff --git a/lib/symfony/validator/Constraints/Choice.php b/lib/symfony/validator/Constraints/Choice.php new file mode 100644 index 0000000000..7345e26403 --- /dev/null +++ b/lib/symfony/validator/Constraints/Choice.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Choice extends Constraint +{ + public const NO_SUCH_CHOICE_ERROR = '8e179f1b-97aa-4560-a02f-2a8b42e49df7'; + public const TOO_FEW_ERROR = '11edd7eb-5872-4b6e-9f12-89923999fd0e'; + public const TOO_MANY_ERROR = '9bd98e49-211c-433f-8630-fd1c2d0f08c3'; + + protected const ERROR_NAMES = [ + self::NO_SUCH_CHOICE_ERROR => 'NO_SUCH_CHOICE_ERROR', + self::TOO_FEW_ERROR => 'TOO_FEW_ERROR', + self::TOO_MANY_ERROR => 'TOO_MANY_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $choices; + /** @var callable|string|null */ + public $callback; + public $multiple = false; + public $strict = true; + public $min; + public $max; + public $message = 'The value you selected is not a valid choice.'; + public $multipleMessage = 'One or more of the given values is invalid.'; + public $minMessage = 'You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.'; + public $maxMessage = 'You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.'; + public bool $match = true; + + public function getDefaultOption(): ?string + { + return 'choices'; + } + + public function __construct( + string|array $options = [], + ?array $choices = null, + callable|string|null $callback = null, + ?bool $multiple = null, + ?bool $strict = null, + ?int $min = null, + ?int $max = null, + ?string $message = null, + ?string $multipleMessage = null, + ?string $minMessage = null, + ?string $maxMessage = null, + ?array $groups = null, + mixed $payload = null, + ?bool $match = null, + ) { + if (\is_array($options) && $options && array_is_list($options)) { + $choices ??= $options; + $options = []; + } + if (null !== $choices) { + $options['value'] = $choices; + } + + parent::__construct($options, $groups, $payload); + + $this->callback = $callback ?? $this->callback; + $this->multiple = $multiple ?? $this->multiple; + $this->strict = $strict ?? $this->strict; + $this->min = $min ?? $this->min; + $this->max = $max ?? $this->max; + $this->message = $message ?? $this->message; + $this->multipleMessage = $multipleMessage ?? $this->multipleMessage; + $this->minMessage = $minMessage ?? $this->minMessage; + $this->maxMessage = $maxMessage ?? $this->maxMessage; + $this->match = $match ?? $this->match; + } +} diff --git a/lib/symfony/validator/Constraints/ChoiceValidator.php b/lib/symfony/validator/Constraints/ChoiceValidator.php new file mode 100644 index 0000000000..d5c2b8c2b8 --- /dev/null +++ b/lib/symfony/validator/Constraints/ChoiceValidator.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\RuntimeException; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +/** + * ChoiceValidator validates that the value is one of the expected values. + * + * @author Fabien Potencier + * @author Florian Eckerstorfer + * @author Bernhard Schussek + */ +class ChoiceValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Choice) { + throw new UnexpectedTypeException($constraint, Choice::class); + } + + if (!\is_array($constraint->choices) && !$constraint->callback) { + throw new ConstraintDefinitionException('Either "choices" or "callback" must be specified on constraint Choice.'); + } + + if (null === $value) { + return; + } + + if ($constraint->multiple && !\is_array($value)) { + throw new UnexpectedValueException($value, 'array'); + } + + if ($constraint->callback) { + if (!\is_callable($choices = [$this->context->getObject(), $constraint->callback]) + && !\is_callable($choices = [$this->context->getClassName(), $constraint->callback]) + && !\is_callable($choices = $constraint->callback) + ) { + throw new ConstraintDefinitionException('The Choice constraint expects a valid callback.'); + } + $choices = $choices(); + if (!\is_array($choices)) { + throw new ConstraintDefinitionException(\sprintf('The Choice constraint callback "%s" is expected to return an array, but returned "%s".', trim($this->formatValue($constraint->callback), '"'), get_debug_type($choices))); + } + } else { + $choices = $constraint->choices; + } + + if (true !== $constraint->strict) { + throw new RuntimeException('The "strict" option of the Choice constraint should not be used.'); + } + + if ($constraint->multiple) { + foreach ($value as $_value) { + if ($constraint->match xor \in_array($_value, $choices, true)) { + $this->context->buildViolation($constraint->multipleMessage) + ->setParameter('{{ value }}', $this->formatValue($_value)) + ->setParameter('{{ choices }}', $this->formatValues($choices)) + ->setCode(Choice::NO_SUCH_CHOICE_ERROR) + ->setInvalidValue($_value) + ->addViolation(); + + return; + } + } + + $count = \count($value); + + if (null !== $constraint->min && $count < $constraint->min) { + $this->context->buildViolation($constraint->minMessage) + ->setParameter('{{ limit }}', $constraint->min) + ->setPlural((int) $constraint->min) + ->setCode(Choice::TOO_FEW_ERROR) + ->addViolation(); + + return; + } + + if (null !== $constraint->max && $count > $constraint->max) { + $this->context->buildViolation($constraint->maxMessage) + ->setParameter('{{ limit }}', $constraint->max) + ->setPlural((int) $constraint->max) + ->setCode(Choice::TOO_MANY_ERROR) + ->addViolation(); + + return; + } + } elseif ($constraint->match xor \in_array($value, $choices, true)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setParameter('{{ choices }}', $this->formatValues($choices)) + ->setCode(Choice::NO_SUCH_CHOICE_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Cidr.php b/lib/symfony/validator/Constraints/Cidr.php new file mode 100644 index 0000000000..92563d84d4 --- /dev/null +++ b/lib/symfony/validator/Constraints/Cidr.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * Validates that a value is a valid CIDR notation. + * + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Sorin Pop + * @author Calin Bolea + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Cidr extends Constraint +{ + public const INVALID_CIDR_ERROR = '5649e53a-5afb-47c5-a360-ffbab3be8567'; + public const OUT_OF_RANGE_ERROR = 'b9f14a51-acbd-401a-a078-8c6b204ab32f'; + + protected const ERROR_NAMES = [ + self::INVALID_CIDR_ERROR => 'INVALID_CIDR_ERROR', + self::OUT_OF_RANGE_ERROR => 'OUT_OF_RANGE_VIOLATION', + ]; + + private const NET_MAXES = [ + Ip::ALL => 128, + Ip::V4 => 32, + Ip::V6 => 128, + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $version = Ip::ALL; + + public $message = 'This value is not a valid CIDR notation.'; + + public $netmaskRangeViolationMessage = 'The value of the netmask should be between {{ min }} and {{ max }}.'; + + public $netmaskMin = 0; + + public $netmaskMax; + + public function __construct( + ?array $options = null, + ?string $version = null, + ?int $netmaskMin = null, + ?int $netmaskMax = null, + ?string $message = null, + ?array $groups = null, + $payload = null, + ) { + $this->version = $version ?? $options['version'] ?? $this->version; + + if (!\array_key_exists($this->version, self::NET_MAXES)) { + throw new ConstraintDefinitionException(\sprintf('The option "version" must be one of "%s".', implode('", "', array_keys(self::NET_MAXES)))); + } + + $this->netmaskMin = $netmaskMin ?? $options['netmaskMin'] ?? $this->netmaskMin; + $this->netmaskMax = $netmaskMax ?? $options['netmaskMax'] ?? self::NET_MAXES[$this->version]; + $this->message = $message ?? $this->message; + + unset($options['netmaskMin'], $options['netmaskMax'], $options['version']); + + if ($this->netmaskMin < 0 || $this->netmaskMax > self::NET_MAXES[$this->version] || $this->netmaskMin > $this->netmaskMax) { + throw new ConstraintDefinitionException(\sprintf('The netmask range must be between 0 and %d.', self::NET_MAXES[$this->version])); + } + + parent::__construct($options, $groups, $payload); + } +} diff --git a/lib/symfony/validator/Constraints/CidrValidator.php b/lib/symfony/validator/Constraints/CidrValidator.php new file mode 100644 index 0000000000..c90ebcfae3 --- /dev/null +++ b/lib/symfony/validator/Constraints/CidrValidator.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +class CidrValidator extends ConstraintValidator +{ + public function validate($value, Constraint $constraint): void + { + if (!$constraint instanceof Cidr) { + throw new UnexpectedTypeException($constraint, Cidr::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_string($value)) { + throw new UnexpectedValueException($value, 'string'); + } + + $cidrParts = explode('/', $value, 2); + + if (!isset($cidrParts[1]) + || !ctype_digit($cidrParts[1]) + || '' === $cidrParts[0] + ) { + $this->context + ->buildViolation($constraint->message) + ->setCode(Cidr::INVALID_CIDR_ERROR) + ->addViolation(); + + return; + } + + $ipAddress = $cidrParts[0]; + $netmask = (int) $cidrParts[1]; + + $validV4 = Ip::V6 !== $constraint->version + && filter_var($ipAddress, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4) + && $netmask <= 32; + + $validV6 = Ip::V4 !== $constraint->version + && filter_var($ipAddress, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6); + + if (!$validV4 && !$validV6) { + $this->context + ->buildViolation($constraint->message) + ->setCode(Cidr::INVALID_CIDR_ERROR) + ->addViolation(); + + return; + } + + if ($netmask < $constraint->netmaskMin || $netmask > $constraint->netmaskMax) { + $this->context + ->buildViolation($constraint->netmaskRangeViolationMessage) + ->setParameter('{{ min }}', $constraint->netmaskMin) + ->setParameter('{{ max }}', $constraint->netmaskMax) + ->setCode(Cidr::OUT_OF_RANGE_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Collection.php b/lib/symfony/validator/Constraints/Collection.php new file mode 100644 index 0000000000..edad4fa0b1 --- /dev/null +++ b/lib/symfony/validator/Constraints/Collection.php @@ -0,0 +1,119 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Collection extends Composite +{ + public const MISSING_FIELD_ERROR = '2fa2158c-2a7f-484b-98aa-975522539ff8'; + public const NO_SUCH_FIELD_ERROR = '7703c766-b5d5-4cef-ace7-ae0dd82304e9'; + + protected const ERROR_NAMES = [ + self::MISSING_FIELD_ERROR => 'MISSING_FIELD_ERROR', + self::NO_SUCH_FIELD_ERROR => 'NO_SUCH_FIELD_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $fields = []; + public $allowExtraFields = false; + public $allowMissingFields = false; + public $extraFieldsMessage = 'This field was not expected.'; + public $missingFieldsMessage = 'This field is missing.'; + + public function __construct(mixed $fields = null, ?array $groups = null, mixed $payload = null, ?bool $allowExtraFields = null, ?bool $allowMissingFields = null, ?string $extraFieldsMessage = null, ?string $missingFieldsMessage = null) + { + if (self::isFieldsOption($fields)) { + $fields = ['fields' => $fields]; + } + + parent::__construct($fields, $groups, $payload); + + $this->allowExtraFields = $allowExtraFields ?? $this->allowExtraFields; + $this->allowMissingFields = $allowMissingFields ?? $this->allowMissingFields; + $this->extraFieldsMessage = $extraFieldsMessage ?? $this->extraFieldsMessage; + $this->missingFieldsMessage = $missingFieldsMessage ?? $this->missingFieldsMessage; + } + + /** + * @return void + */ + protected function initializeNestedConstraints() + { + parent::initializeNestedConstraints(); + + if (!\is_array($this->fields)) { + throw new ConstraintDefinitionException(\sprintf('The option "fields" is expected to be an array in constraint "%s".', __CLASS__)); + } + + foreach ($this->fields as $fieldName => $field) { + // the XmlFileLoader and YamlFileLoader pass the field Optional + // and Required constraint as an array with exactly one element + if (\is_array($field) && 1 == \count($field)) { + $this->fields[$fieldName] = $field = $field[0]; + } + + if (!$field instanceof Optional && !$field instanceof Required) { + $this->fields[$fieldName] = new Required($field); + } + } + } + + public function getRequiredOptions(): array + { + return ['fields']; + } + + protected function getCompositeOption(): string + { + return 'fields'; + } + + private static function isFieldsOption($options): bool + { + if (!\is_array($options)) { + return false; + } + + foreach ($options as $optionOrField) { + if ($optionOrField instanceof Constraint) { + return true; + } + + if (null === $optionOrField) { + continue; + } + + if (!\is_array($optionOrField)) { + return false; + } + + if ($optionOrField && !($optionOrField[0] ?? null) instanceof Constraint) { + return false; + } + } + + return true; + } +} diff --git a/lib/symfony/validator/Constraints/CollectionValidator.php b/lib/symfony/validator/Constraints/CollectionValidator.php new file mode 100644 index 0000000000..141b50fb32 --- /dev/null +++ b/lib/symfony/validator/Constraints/CollectionValidator.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * @author Bernhard Schussek + */ +class CollectionValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Collection) { + throw new UnexpectedTypeException($constraint, Collection::class); + } + + if (null === $value) { + return; + } + + if (!\is_array($value) && !($value instanceof \Traversable && $value instanceof \ArrayAccess)) { + throw new UnexpectedValueException($value, 'array|(Traversable&ArrayAccess)'); + } + + // We need to keep the initialized context when CollectionValidator + // calls itself recursively (Collection constraints can be nested). + // Since the context of the validator is overwritten when initialize() + // is called for the nested constraint, the outer validator is + // acting on the wrong context when the nested validation terminates. + // + // A better solution - which should be approached in Symfony 3.0 - is to + // remove the initialize() method and pass the context as last argument + // to validate() instead. + $context = $this->context; + + foreach ($constraint->fields as $field => $fieldConstraint) { + $existsInArray = \is_array($value) && \array_key_exists($field, $value); + $existsInArrayAccess = $value instanceof \ArrayAccess && $value->offsetExists($field); + + if ($existsInArray || $existsInArrayAccess) { + if (\count($fieldConstraint->constraints) > 0) { + $context->getValidator() + ->inContext($context) + ->atPath('['.$field.']') + ->validate($value[$field], $fieldConstraint->constraints); + } + } elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) { + $context->buildViolation($constraint->missingFieldsMessage) + ->atPath('['.$field.']') + ->setParameter('{{ field }}', $this->formatValue($field)) + ->setInvalidValue(null) + ->setCode(Collection::MISSING_FIELD_ERROR) + ->addViolation(); + } + } + + if (!$constraint->allowExtraFields) { + foreach ($value as $field => $fieldValue) { + if (!isset($constraint->fields[$field])) { + $context->buildViolation($constraint->extraFieldsMessage) + ->atPath('['.$field.']') + ->setParameter('{{ field }}', $this->formatValue($field)) + ->setInvalidValue($fieldValue) + ->setCode(Collection::NO_SUCH_FIELD_ERROR) + ->addViolation(); + } + } + } + } +} diff --git a/lib/symfony/validator/Constraints/Composite.php b/lib/symfony/validator/Constraints/Composite.php new file mode 100644 index 0000000000..824c3a1743 --- /dev/null +++ b/lib/symfony/validator/Constraints/Composite.php @@ -0,0 +1,157 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * A constraint that is composed of other constraints. + * + * You should never use the nested constraint instances anywhere else, because + * their groups are adapted when passed to the constructor of this class. + * + * If you want to create your own composite constraint, extend this class and + * let {@link getCompositeOption()} return the name of the property which + * contains the nested constraints. + * + * @author Bernhard Schussek + */ +abstract class Composite extends Constraint +{ + /** + * The groups of the composite and its nested constraints are made + * consistent using the following strategy: + * + * - If groups are passed explicitly to the composite constraint, but + * not to the nested constraints, the options of the composite + * constraint are copied to the nested constraints; + * + * - If groups are passed explicitly to the nested constraints, but not + * to the composite constraint, the groups of all nested constraints + * are merged and used as groups for the composite constraint; + * + * - If groups are passed explicitly to both the composite and its nested + * constraints, the groups of the nested constraints must be a subset + * of the groups of the composite constraint. If not, a + * {@link ConstraintDefinitionException} is thrown. + * + * All this is done in the constructor, because constraints can then be + * cached. When constraints are loaded from the cache, no more group + * checks need to be done. + */ + public function __construct(mixed $options = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options, $groups, $payload); + + $this->initializeNestedConstraints(); + + /** @var Constraint[] $nestedConstraints */ + $compositeOption = $this->getCompositeOption(); + $nestedConstraints = $this->$compositeOption; + + if (!\is_array($nestedConstraints)) { + $nestedConstraints = [$nestedConstraints]; + } + + foreach ($nestedConstraints as $constraint) { + if (!$constraint instanceof Constraint) { + if (\is_object($constraint)) { + $constraint = $constraint::class; + } + + throw new ConstraintDefinitionException(\sprintf('The value "%s" is not an instance of Constraint in constraint "%s".', $constraint, static::class)); + } + + if ($constraint instanceof Valid) { + throw new ConstraintDefinitionException(\sprintf('The constraint Valid cannot be nested inside constraint "%s". You can only declare the Valid constraint directly on a field or method.', static::class)); + } + } + + if (!isset(((array) $this)['groups'])) { + $mergedGroups = []; + + foreach ($nestedConstraints as $constraint) { + foreach ($constraint->groups as $group) { + $mergedGroups[$group] = true; + } + } + + // prevent empty composite constraint to have empty groups + $this->groups = array_keys($mergedGroups) ?: [self::DEFAULT_GROUP]; + $this->$compositeOption = $nestedConstraints; + + return; + } + + foreach ($nestedConstraints as $constraint) { + if (isset(((array) $constraint)['groups'])) { + $excessGroups = array_diff($constraint->groups, $this->groups); + + if (\count($excessGroups) > 0) { + throw new ConstraintDefinitionException(\sprintf('The group(s) "%s" passed to the constraint "%s" should also be passed to its containing constraint "%s".', implode('", "', $excessGroups), get_debug_type($constraint), static::class)); + } + } else { + $constraint->groups = $this->groups; + } + } + + $this->$compositeOption = $nestedConstraints; + } + + /** + * Implicit group names are forwarded to nested constraints. + * + * @return void + */ + public function addImplicitGroupName(string $group) + { + parent::addImplicitGroupName($group); + + /** @var Constraint[] $nestedConstraints */ + $nestedConstraints = $this->{$this->getCompositeOption()}; + + foreach ($nestedConstraints as $constraint) { + $constraint->addImplicitGroupName($group); + } + } + + /** + * Returns the name of the property that contains the nested constraints. + */ + abstract protected function getCompositeOption(): string; + + /** + * @internal Used by metadata + * + * @return Constraint[] + */ + public function getNestedConstraints(): array + { + /** @var Constraint[] $nestedConstraints */ + return $this->{$this->getCompositeOption()}; + } + + /** + * Initializes the nested constraints. + * + * This method can be overwritten in subclasses to clean up the nested + * constraints passed to the constructor. + * + * @see Collection::initializeNestedConstraints() + * + * @return void + */ + protected function initializeNestedConstraints() + { + } +} diff --git a/lib/symfony/validator/Constraints/Compound.php b/lib/symfony/validator/Constraints/Compound.php new file mode 100644 index 0000000000..aa48dbe5ea --- /dev/null +++ b/lib/symfony/validator/Constraints/Compound.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * Extend this class to create a reusable set of constraints. + * + * @author Maxime Steinhausser + */ +abstract class Compound extends Composite +{ + /** @var Constraint[] */ + public $constraints = []; + + public function __construct(mixed $options = null) + { + if (isset($options[$this->getCompositeOption()])) { + throw new ConstraintDefinitionException(\sprintf('You can\'t redefine the "%s" option. Use the "%s::getConstraints()" method instead.', $this->getCompositeOption(), __CLASS__)); + } + + $this->constraints = $this->getConstraints($this->normalizeOptions($options)); + + parent::__construct($options); + } + + final protected function getCompositeOption(): string + { + return 'constraints'; + } + + final public function validatedBy(): string + { + return CompoundValidator::class; + } + + /** + * @return Constraint[] + */ + abstract protected function getConstraints(array $options): array; +} diff --git a/lib/symfony/validator/Constraints/CompoundValidator.php b/lib/symfony/validator/Constraints/CompoundValidator.php new file mode 100644 index 0000000000..8f9c713c79 --- /dev/null +++ b/lib/symfony/validator/Constraints/CompoundValidator.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Maxime Steinhausser + */ +class CompoundValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Compound) { + throw new UnexpectedTypeException($constraint, Compound::class); + } + + $context = $this->context; + + $validator = $context->getValidator()->inContext($context); + + $validator->validate($value, $constraint->constraints); + } +} diff --git a/lib/symfony/validator/Constraints/Count.php b/lib/symfony/validator/Constraints/Count.php new file mode 100644 index 0000000000..42cf6c196b --- /dev/null +++ b/lib/symfony/validator/Constraints/Count.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\MissingOptionsException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Count extends Constraint +{ + public const TOO_FEW_ERROR = 'bef8e338-6ae5-4caf-b8e2-50e7b0579e69'; + public const TOO_MANY_ERROR = '756b1212-697c-468d-a9ad-50dd783bb169'; + public const NOT_EQUAL_COUNT_ERROR = '9fe5d43f-3784-4ece-a0e1-473fc02dadbc'; + public const NOT_DIVISIBLE_BY_ERROR = DivisibleBy::NOT_DIVISIBLE_BY; + + protected const ERROR_NAMES = [ + self::TOO_FEW_ERROR => 'TOO_FEW_ERROR', + self::TOO_MANY_ERROR => 'TOO_MANY_ERROR', + self::NOT_EQUAL_COUNT_ERROR => 'NOT_EQUAL_COUNT_ERROR', + self::NOT_DIVISIBLE_BY_ERROR => 'NOT_DIVISIBLE_BY_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $minMessage = 'This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.'; + public $maxMessage = 'This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.'; + public $exactMessage = 'This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.'; + public $divisibleByMessage = 'The number of elements in this collection should be a multiple of {{ compared_value }}.'; + public $min; + public $max; + public $divisibleBy; + + public function __construct( + int|array|null $exactly = null, + ?int $min = null, + ?int $max = null, + ?int $divisibleBy = null, + ?string $exactMessage = null, + ?string $minMessage = null, + ?string $maxMessage = null, + ?string $divisibleByMessage = null, + ?array $groups = null, + mixed $payload = null, + array $options = [], + ) { + if (\is_array($exactly)) { + $options = array_merge($exactly, $options); + $exactly = $options['value'] ?? null; + } + + $min ??= $options['min'] ?? null; + $max ??= $options['max'] ?? null; + + unset($options['value'], $options['min'], $options['max']); + + if (null !== $exactly && null === $min && null === $max) { + $min = $max = $exactly; + } + + parent::__construct($options, $groups, $payload); + + $this->min = $min; + $this->max = $max; + $this->divisibleBy = $divisibleBy ?? $this->divisibleBy; + $this->exactMessage = $exactMessage ?? $this->exactMessage; + $this->minMessage = $minMessage ?? $this->minMessage; + $this->maxMessage = $maxMessage ?? $this->maxMessage; + $this->divisibleByMessage = $divisibleByMessage ?? $this->divisibleByMessage; + + if (null === $this->min && null === $this->max && null === $this->divisibleBy) { + throw new MissingOptionsException(\sprintf('Either option "min", "max" or "divisibleBy" must be given for constraint "%s".', __CLASS__), ['min', 'max', 'divisibleBy']); + } + } +} diff --git a/lib/symfony/validator/Constraints/CountValidator.php b/lib/symfony/validator/Constraints/CountValidator.php new file mode 100644 index 0000000000..3c56023538 --- /dev/null +++ b/lib/symfony/validator/Constraints/CountValidator.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * @author Bernhard Schussek + */ +class CountValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Count) { + throw new UnexpectedTypeException($constraint, Count::class); + } + + if (null === $value) { + return; + } + + if (!\is_array($value) && !$value instanceof \Countable) { + throw new UnexpectedValueException($value, 'array|\Countable'); + } + + $count = \count($value); + + if (null !== $constraint->max && $count > $constraint->max) { + $exactlyOptionEnabled = $constraint->min == $constraint->max; + + $this->context->buildViolation($exactlyOptionEnabled ? $constraint->exactMessage : $constraint->maxMessage) + ->setParameter('{{ count }}', $count) + ->setParameter('{{ limit }}', $constraint->max) + ->setInvalidValue($value) + ->setPlural((int) $constraint->max) + ->setCode($exactlyOptionEnabled ? Count::NOT_EQUAL_COUNT_ERROR : Count::TOO_MANY_ERROR) + ->addViolation(); + + return; + } + + if (null !== $constraint->min && $count < $constraint->min) { + $exactlyOptionEnabled = $constraint->min == $constraint->max; + + $this->context->buildViolation($exactlyOptionEnabled ? $constraint->exactMessage : $constraint->minMessage) + ->setParameter('{{ count }}', $count) + ->setParameter('{{ limit }}', $constraint->min) + ->setInvalidValue($value) + ->setPlural((int) $constraint->min) + ->setCode($exactlyOptionEnabled ? Count::NOT_EQUAL_COUNT_ERROR : Count::TOO_FEW_ERROR) + ->addViolation(); + + return; + } + + if (null !== $constraint->divisibleBy) { + $this->context + ->getValidator() + ->inContext($this->context) + ->validate($count, [ + new DivisibleBy([ + 'value' => $constraint->divisibleBy, + 'message' => $constraint->divisibleByMessage, + ]), + ], $this->context->getGroup()); + } + } +} diff --git a/lib/symfony/validator/Constraints/Country.php b/lib/symfony/validator/Constraints/Country.php new file mode 100644 index 0000000000..4ab5d67a89 --- /dev/null +++ b/lib/symfony/validator/Constraints/Country.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Intl\Countries; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\LogicException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Country extends Constraint +{ + public const NO_SUCH_COUNTRY_ERROR = '8f900c12-61bd-455d-9398-996cd040f7f0'; + + protected const ERROR_NAMES = [ + self::NO_SUCH_COUNTRY_ERROR => 'NO_SUCH_COUNTRY_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value is not a valid country.'; + public $alpha3 = false; + + public function __construct( + ?array $options = null, + ?string $message = null, + ?bool $alpha3 = null, + ?array $groups = null, + mixed $payload = null, + ) { + if (!class_exists(Countries::class)) { + throw new LogicException('The Intl component is required to use the Country constraint. Try running "composer require symfony/intl".'); + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->alpha3 = $alpha3 ?? $this->alpha3; + } +} diff --git a/lib/symfony/validator/Constraints/CountryValidator.php b/lib/symfony/validator/Constraints/CountryValidator.php new file mode 100644 index 0000000000..54c8da0f9e --- /dev/null +++ b/lib/symfony/validator/Constraints/CountryValidator.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Intl\Countries; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +/** + * Validates whether a value is a valid country code. + * + * @author Bernhard Schussek + */ +class CountryValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Country) { + throw new UnexpectedTypeException($constraint, Country::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + if ($constraint->alpha3 ? !Countries::alpha3CodeExists($value) : !Countries::exists($value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Country::NO_SUCH_COUNTRY_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/CssColor.php b/lib/symfony/validator/Constraints/CssColor.php new file mode 100644 index 0000000000..e8f0aaefd1 --- /dev/null +++ b/lib/symfony/validator/Constraints/CssColor.php @@ -0,0 +1,111 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\InvalidArgumentException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Mathieu Santostefano + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class CssColor extends Constraint +{ + public const HEX_LONG = 'hex_long'; + public const HEX_LONG_WITH_ALPHA = 'hex_long_with_alpha'; + public const HEX_SHORT = 'hex_short'; + public const HEX_SHORT_WITH_ALPHA = 'hex_short_with_alpha'; + public const BASIC_NAMED_COLORS = 'basic_named_colors'; + public const EXTENDED_NAMED_COLORS = 'extended_named_colors'; + public const SYSTEM_COLORS = 'system_colors'; + public const KEYWORDS = 'keywords'; + public const RGB = 'rgb'; + public const RGBA = 'rgba'; + public const HSL = 'hsl'; + public const HSLA = 'hsla'; + public const INVALID_FORMAT_ERROR = '454ab47b-aacf-4059-8f26-184b2dc9d48d'; + + protected const ERROR_NAMES = [ + self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + /** + * @var string[] + */ + private static array $validationModes = [ + self::HEX_LONG, + self::HEX_LONG_WITH_ALPHA, + self::HEX_SHORT, + self::HEX_SHORT_WITH_ALPHA, + self::BASIC_NAMED_COLORS, + self::EXTENDED_NAMED_COLORS, + self::SYSTEM_COLORS, + self::KEYWORDS, + self::RGB, + self::RGBA, + self::HSL, + self::HSLA, + ]; + + public $message = 'This value is not a valid CSS color.'; + public $formats; + + /** + * @param array|string $formats The types of CSS colors allowed (e.g. hexadecimal only, RGB and HSL only, etc.). + */ + public function __construct($formats = [], ?string $message = null, ?array $groups = null, $payload = null, ?array $options = null) + { + $validationModesAsString = implode(', ', self::$validationModes); + + if (!$formats) { + $options['value'] = self::$validationModes; + } elseif (\is_array($formats) && \is_string(key($formats))) { + $options = array_merge($formats, $options ?? []); + } elseif (\is_array($formats)) { + if ([] === array_intersect(self::$validationModes, $formats)) { + throw new InvalidArgumentException(\sprintf('The "formats" parameter value is not valid. It must contain one or more of the following values: "%s".', $validationModesAsString)); + } + + $options['value'] = $formats; + } elseif (\is_string($formats)) { + if (!\in_array($formats, self::$validationModes)) { + throw new InvalidArgumentException(\sprintf('The "formats" parameter value is not valid. It must contain one or more of the following values: "%s".', $validationModesAsString)); + } + + $options['value'] = [$formats]; + } else { + throw new InvalidArgumentException('The "formats" parameter type is not valid. It should be a string or an array.'); + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + } + + public function getDefaultOption(): string + { + return 'formats'; + } + + public function getRequiredOptions(): array + { + return ['formats']; + } +} diff --git a/lib/symfony/validator/Constraints/CssColorValidator.php b/lib/symfony/validator/Constraints/CssColorValidator.php new file mode 100644 index 0000000000..78563a92c3 --- /dev/null +++ b/lib/symfony/validator/Constraints/CssColorValidator.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * @author Mathieu Santostefano + */ +class CssColorValidator extends ConstraintValidator +{ + private const PATTERN_HEX_LONG = '/^#[0-9a-f]{6}$/iD'; + private const PATTERN_HEX_LONG_WITH_ALPHA = '/^#[0-9a-f]{8}$/iD'; + private const PATTERN_HEX_SHORT = '/^#[0-9a-f]{3}$/iD'; + private const PATTERN_HEX_SHORT_WITH_ALPHA = '/^#[0-9a-f]{4}$/iD'; + // List comes from https://www.w3.org/wiki/CSS/Properties/color/keywords#Basic_Colors + private const PATTERN_BASIC_NAMED_COLORS = '/^(black|silver|gray|white|maroon|red|purple|fuchsia|green|lime|olive|yellow|navy|blue|teal|aqua)$/iD'; + // List comes from https://www.w3.org/wiki/CSS/Properties/color/keywords#Extended_colors + private const PATTERN_EXTENDED_NAMED_COLORS = '/^(aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen)$/iD'; + // List comes from https://drafts.csswg.org/css-color/#css-system-colors + private const PATTERN_SYSTEM_COLORS = '/^(Canvas|CanvasText|LinkText|VisitedText|ActiveText|ButtonFace|ButtonText|ButtonBorder|Field|FieldText|Highlight|HighlightText|SelectedItem|SelectedItemText|Mark|MarkText|GrayText)$/iD'; + private const PATTERN_KEYWORDS = '/^(transparent|currentColor)$/iD'; + private const PATTERN_RGB = '/^rgb\(\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d)\s*\)$/iD'; + private const PATTERN_RGBA = '/^rgba\(\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|0?\.\d+|1(\.0)?)\s*\)$/iD'; + private const PATTERN_HSL = '/^hsl\(\s*(0|360|35\d|3[0-4]\d|[12]\d\d|0?\d?\d),\s*(0|100|\d{1,2})%,\s*(0|100|\d{1,2})%\s*\)$/iD'; + private const PATTERN_HSLA = '/^hsla\(\s*(0|360|35\d|3[0-4]\d|[12]\d\d|0?\d?\d),\s*(0|100|\d{1,2})%,\s*(0|100|\d{1,2})%,\s*(0|0?\.\d+|1(\.0)?)\s*\)$/iD'; + + private const COLOR_PATTERNS = [ + CssColor::HEX_LONG => self::PATTERN_HEX_LONG, + CssColor::HEX_LONG_WITH_ALPHA => self::PATTERN_HEX_LONG_WITH_ALPHA, + CssColor::HEX_SHORT => self::PATTERN_HEX_SHORT, + CssColor::HEX_SHORT_WITH_ALPHA => self::PATTERN_HEX_SHORT_WITH_ALPHA, + CssColor::BASIC_NAMED_COLORS => self::PATTERN_BASIC_NAMED_COLORS, + CssColor::EXTENDED_NAMED_COLORS => self::PATTERN_EXTENDED_NAMED_COLORS, + CssColor::SYSTEM_COLORS => self::PATTERN_SYSTEM_COLORS, + CssColor::KEYWORDS => self::PATTERN_KEYWORDS, + CssColor::RGB => self::PATTERN_RGB, + CssColor::RGBA => self::PATTERN_RGBA, + CssColor::HSL => self::PATTERN_HSL, + CssColor::HSLA => self::PATTERN_HSLA, + ]; + + public function validate($value, Constraint $constraint): void + { + if (!$constraint instanceof CssColor) { + throw new UnexpectedTypeException($constraint, CssColor::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_string($value)) { + throw new UnexpectedValueException($value, 'string'); + } + + $formats = array_flip((array) $constraint->formats); + $formatRegexes = array_intersect_key(self::COLOR_PATTERNS, $formats); + + foreach ($formatRegexes as $regex) { + if (preg_match($regex, (string) $value)) { + return; + } + } + + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(CssColor::INVALID_FORMAT_ERROR) + ->addViolation(); + } +} diff --git a/lib/symfony/validator/Constraints/Currency.php b/lib/symfony/validator/Constraints/Currency.php new file mode 100644 index 0000000000..facf111007 --- /dev/null +++ b/lib/symfony/validator/Constraints/Currency.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Intl\Currencies; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\LogicException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Miha Vrhovnik + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Currency extends Constraint +{ + public const NO_SUCH_CURRENCY_ERROR = '69945ac1-2db4-405f-bec7-d2772f73df52'; + + protected const ERROR_NAMES = [ + self::NO_SUCH_CURRENCY_ERROR => 'NO_SUCH_CURRENCY_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value is not a valid currency.'; + + public function __construct(?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null) + { + if (!class_exists(Currencies::class)) { + throw new LogicException('The Intl component is required to use the Currency constraint. Try running "composer require symfony/intl".'); + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + } +} diff --git a/lib/symfony/validator/Constraints/CurrencyValidator.php b/lib/symfony/validator/Constraints/CurrencyValidator.php new file mode 100644 index 0000000000..a50ea62ab6 --- /dev/null +++ b/lib/symfony/validator/Constraints/CurrencyValidator.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Intl\Currencies; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +/** + * Validates whether a value is a valid currency. + * + * @author Miha Vrhovnik + * @author Bernhard Schussek + */ +class CurrencyValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Currency) { + throw new UnexpectedTypeException($constraint, Currency::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + if (!Currencies::exists($value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Currency::NO_SUCH_CURRENCY_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Date.php b/lib/symfony/validator/Constraints/Date.php new file mode 100644 index 0000000000..bccb59ee6b --- /dev/null +++ b/lib/symfony/validator/Constraints/Date.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Date extends Constraint +{ + public const INVALID_FORMAT_ERROR = '69819696-02ac-4a99-9ff0-14e127c4d1bc'; + public const INVALID_DATE_ERROR = '3c184ce5-b31d-4de7-8b76-326da7b2be93'; + + protected const ERROR_NAMES = [ + self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR', + self::INVALID_DATE_ERROR => 'INVALID_DATE_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value is not a valid date.'; + + public function __construct(?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + } +} diff --git a/lib/symfony/validator/Constraints/DateTime.php b/lib/symfony/validator/Constraints/DateTime.php new file mode 100644 index 0000000000..45648f0baf --- /dev/null +++ b/lib/symfony/validator/Constraints/DateTime.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class DateTime extends Constraint +{ + public const INVALID_FORMAT_ERROR = '1a9da513-2640-4f84-9b6a-4d99dcddc628'; + public const INVALID_DATE_ERROR = 'd52afa47-620d-4d99-9f08-f4d85b36e33c'; + public const INVALID_TIME_ERROR = '5e797c9d-74f7-4098-baa3-94390c447b27'; + + protected const ERROR_NAMES = [ + self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR', + self::INVALID_DATE_ERROR => 'INVALID_DATE_ERROR', + self::INVALID_TIME_ERROR => 'INVALID_TIME_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $format = 'Y-m-d H:i:s'; + public $message = 'This value is not a valid datetime.'; + + public function __construct(string|array|null $format = null, ?string $message = null, ?array $groups = null, mixed $payload = null, array $options = []) + { + if (\is_array($format)) { + $options = array_merge($format, $options); + } elseif (null !== $format) { + $options['value'] = $format; + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + } + + public function getDefaultOption(): ?string + { + return 'format'; + } +} diff --git a/lib/symfony/validator/Constraints/DateTimeValidator.php b/lib/symfony/validator/Constraints/DateTimeValidator.php new file mode 100644 index 0000000000..c88732d4d8 --- /dev/null +++ b/lib/symfony/validator/Constraints/DateTimeValidator.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +/** + * @author Bernhard Schussek + * @author Diego Saint Esteben + */ +class DateTimeValidator extends DateValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof DateTime) { + throw new UnexpectedTypeException($constraint, DateTime::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + \DateTimeImmutable::createFromFormat($constraint->format, $value); + + $errors = \DateTimeImmutable::getLastErrors() ?: ['error_count' => 0, 'warnings' => []]; + + if (0 < $errors['error_count']) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(DateTime::INVALID_FORMAT_ERROR) + ->addViolation(); + + return; + } + + if (str_ends_with($constraint->format, '+')) { + $errors['warnings'] = array_filter($errors['warnings'], fn ($warning) => 'Trailing data' !== $warning); + } + + foreach ($errors['warnings'] as $warning) { + if ('The parsed date was invalid' === $warning) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(DateTime::INVALID_DATE_ERROR) + ->addViolation(); + } elseif ('The parsed time was invalid' === $warning) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(DateTime::INVALID_TIME_ERROR) + ->addViolation(); + } else { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(DateTime::INVALID_FORMAT_ERROR) + ->addViolation(); + } + } + } +} diff --git a/lib/symfony/validator/Constraints/DateValidator.php b/lib/symfony/validator/Constraints/DateValidator.php new file mode 100644 index 0000000000..65dc9648ac --- /dev/null +++ b/lib/symfony/validator/Constraints/DateValidator.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * @author Bernhard Schussek + */ +class DateValidator extends ConstraintValidator +{ + public const PATTERN = '/^(?\d{4})-(?\d{2})-(?\d{2})$/D'; + + /** + * Checks whether a date is valid. + * + * @internal + */ + public static function checkDate(int $year, int $month, int $day): bool + { + return checkdate($month, $day, $year); + } + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Date) { + throw new UnexpectedTypeException($constraint, Date::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + if (!preg_match(static::PATTERN, $value, $matches)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Date::INVALID_FORMAT_ERROR) + ->addViolation(); + + return; + } + + if (!self::checkDate( + $matches['year'] ?? $matches[1], + $matches['month'] ?? $matches[2], + $matches['day'] ?? $matches[3] + )) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Date::INVALID_DATE_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/DisableAutoMapping.php b/lib/symfony/validator/Constraints/DisableAutoMapping.php new file mode 100644 index 0000000000..636801ac97 --- /dev/null +++ b/lib/symfony/validator/Constraints/DisableAutoMapping.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * Disables auto mapping. + * + * Using the annotations on a property has higher precedence than using it on a class, + * which has higher precedence than any configuration that might be defined outside the class. + * + * @Annotation + * + * @author Kévin Dunglas + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)] +class DisableAutoMapping extends Constraint +{ + public function __construct(?array $options = null) + { + if (\is_array($options) && \array_key_exists('groups', $options)) { + throw new ConstraintDefinitionException(\sprintf('The option "groups" is not supported by the constraint "%s".', __CLASS__)); + } + + parent::__construct($options); + } + + public function getTargets(): string|array + { + return [self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT]; + } +} diff --git a/lib/symfony/validator/Constraints/DivisibleBy.php b/lib/symfony/validator/Constraints/DivisibleBy.php new file mode 100644 index 0000000000..90164aab28 --- /dev/null +++ b/lib/symfony/validator/Constraints/DivisibleBy.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Colin O'Dell + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class DivisibleBy extends AbstractComparison +{ + public const NOT_DIVISIBLE_BY = '6d99d6c3-1464-4ccf-bdc7-14d083cf455c'; + + protected const ERROR_NAMES = [ + self::NOT_DIVISIBLE_BY => 'NOT_DIVISIBLE_BY', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be a multiple of {{ compared_value }}.'; +} diff --git a/lib/symfony/validator/Constraints/DivisibleByValidator.php b/lib/symfony/validator/Constraints/DivisibleByValidator.php new file mode 100644 index 0000000000..d868758840 --- /dev/null +++ b/lib/symfony/validator/Constraints/DivisibleByValidator.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +/** + * Validates that values are a multiple of the given number. + * + * @author Colin O'Dell + */ +class DivisibleByValidator extends AbstractComparisonValidator +{ + protected function compareValues(mixed $value1, mixed $value2): bool + { + if (!is_numeric($value1)) { + throw new UnexpectedValueException($value1, 'numeric'); + } + + if (!is_numeric($value2)) { + throw new UnexpectedValueException($value2, 'numeric'); + } + + if (!$value2 = abs($value2)) { + return false; + } + if (\is_int($value1 = abs($value1)) && \is_int($value2)) { + return 0 === ($value1 % $value2); + } + if (!$remainder = fmod($value1, $value2)) { + return true; + } + if (\is_float($value2) && \INF !== $value2) { + $quotient = $value1 / $value2; + $rounded = round($quotient); + + return \sprintf('%.12e', $quotient) === \sprintf('%.12e', $rounded); + } + + return \sprintf('%.12e', $value2) === \sprintf('%.12e', $remainder); + } + + protected function getErrorCode(): ?string + { + return DivisibleBy::NOT_DIVISIBLE_BY; + } +} diff --git a/lib/symfony/validator/Constraints/Email.php b/lib/symfony/validator/Constraints/Email.php new file mode 100644 index 0000000000..995713c400 --- /dev/null +++ b/lib/symfony/validator/Constraints/Email.php @@ -0,0 +1,93 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Egulias\EmailValidator\EmailValidator as StrictEmailValidator; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\InvalidArgumentException; +use Symfony\Component\Validator\Exception\LogicException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Email extends Constraint +{ + public const VALIDATION_MODE_HTML5_ALLOW_NO_TLD = 'html5-allow-no-tld'; + public const VALIDATION_MODE_HTML5 = 'html5'; + public const VALIDATION_MODE_STRICT = 'strict'; + /** + * @deprecated since Symfony 6.2, use VALIDATION_MODE_HTML5 instead + */ + public const VALIDATION_MODE_LOOSE = 'loose'; + + public const INVALID_FORMAT_ERROR = 'bd79c0ab-ddba-46cc-a703-a7a4b08de310'; + + public const VALIDATION_MODES = [ + self::VALIDATION_MODE_HTML5_ALLOW_NO_TLD, + self::VALIDATION_MODE_HTML5, + self::VALIDATION_MODE_STRICT, + self::VALIDATION_MODE_LOOSE, + ]; + + protected const ERROR_NAMES = [ + self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value is not a valid email address.'; + public $mode; + /** @var callable|null */ + public $normalizer; + + public function __construct( + ?array $options = null, + ?string $message = null, + ?string $mode = null, + ?callable $normalizer = null, + ?array $groups = null, + mixed $payload = null, + ) { + if (\is_array($options) && \array_key_exists('mode', $options) && !\in_array($options['mode'], self::VALIDATION_MODES, true)) { + throw new InvalidArgumentException('The "mode" parameter value is not valid.'); + } + + if (null !== $mode && !\in_array($mode, self::VALIDATION_MODES, true)) { + throw new InvalidArgumentException('The "mode" parameter value is not valid.'); + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->mode = $mode ?? $this->mode; + $this->normalizer = $normalizer ?? $this->normalizer; + + if (self::VALIDATION_MODE_LOOSE === $this->mode) { + trigger_deprecation('symfony/validator', '6.2', 'The "%s" mode is deprecated. It will be removed in 7.0 and the default mode will be changed to "%s".', self::VALIDATION_MODE_LOOSE, self::VALIDATION_MODE_HTML5); + } + + if (self::VALIDATION_MODE_STRICT === $this->mode && !class_exists(StrictEmailValidator::class)) { + throw new LogicException(\sprintf('The "egulias/email-validator" component is required to use the "%s" constraint in strict mode. Try running "composer require egulias/email-validator".', __CLASS__)); + } + + if (null !== $this->normalizer && !\is_callable($this->normalizer)) { + throw new InvalidArgumentException(\sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer))); + } + } +} diff --git a/lib/symfony/validator/Constraints/EmailValidator.php b/lib/symfony/validator/Constraints/EmailValidator.php new file mode 100644 index 0000000000..2883d0d555 --- /dev/null +++ b/lib/symfony/validator/Constraints/EmailValidator.php @@ -0,0 +1,119 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Egulias\EmailValidator\EmailValidator as EguliasEmailValidator; +use Egulias\EmailValidator\Validation\EmailValidation; +use Egulias\EmailValidator\Validation\NoRFCWarningsValidation; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\InvalidArgumentException; +use Symfony\Component\Validator\Exception\LogicException; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +/** + * @author Bernhard Schussek + */ +class EmailValidator extends ConstraintValidator +{ + private const PATTERN_HTML5_ALLOW_NO_TLD = '/^[a-zA-Z0-9.!#$%&\'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/D'; + private const PATTERN_HTML5 = '/^[a-zA-Z0-9.!#$%&\'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/D'; + private const PATTERN_LOOSE = '/^.+\@\S+\.\S+$/D'; + + private const EMAIL_PATTERNS = [ + Email::VALIDATION_MODE_LOOSE => self::PATTERN_LOOSE, + Email::VALIDATION_MODE_HTML5 => self::PATTERN_HTML5, + Email::VALIDATION_MODE_HTML5_ALLOW_NO_TLD => self::PATTERN_HTML5_ALLOW_NO_TLD, + ]; + + private string $defaultMode; + + public function __construct(string $defaultMode = Email::VALIDATION_MODE_LOOSE) + { + if (!\in_array($defaultMode, Email::VALIDATION_MODES, true)) { + throw new InvalidArgumentException('The "defaultMode" parameter value is not valid.'); + } + + if (Email::VALIDATION_MODE_LOOSE === $defaultMode) { + trigger_deprecation('symfony/validator', '6.2', 'The "%s" mode is deprecated. It will be removed in 7.0 and the default mode will be changed to "%s".', Email::VALIDATION_MODE_LOOSE, Email::VALIDATION_MODE_HTML5); + } + + $this->defaultMode = $defaultMode; + } + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Email) { + throw new UnexpectedTypeException($constraint, Email::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + if ('' === $value) { + return; + } + + if (null !== $constraint->normalizer) { + $value = ($constraint->normalizer)($value); + } + + if (null === $constraint->mode) { + if (Email::VALIDATION_MODE_STRICT === $this->defaultMode && !class_exists(EguliasEmailValidator::class)) { + throw new LogicException(\sprintf('The "egulias/email-validator" component is required to make the "%s" constraint default to strict mode. Try running "composer require egulias/email-validator".', Email::class)); + } + + $constraint->mode = $this->defaultMode; + } + + if (!\in_array($constraint->mode, Email::VALIDATION_MODES, true)) { + throw new InvalidArgumentException(\sprintf('The "%s::$mode" parameter value is not valid.', get_debug_type($constraint))); + } + + if (Email::VALIDATION_MODE_STRICT === $constraint->mode) { + $strictValidator = new EguliasEmailValidator(); + + if (interface_exists(EmailValidation::class) && !$strictValidator->isValid($value, new NoRFCWarningsValidation())) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Email::INVALID_FORMAT_ERROR) + ->addViolation(); + + return; + } elseif (!interface_exists(EmailValidation::class) && !$strictValidator->isValid($value, false, true)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Email::INVALID_FORMAT_ERROR) + ->addViolation(); + + return; + } + } elseif (!preg_match(self::EMAIL_PATTERNS[$constraint->mode], $value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Email::INVALID_FORMAT_ERROR) + ->addViolation(); + + return; + } + } +} diff --git a/lib/symfony/validator/Constraints/EnableAutoMapping.php b/lib/symfony/validator/Constraints/EnableAutoMapping.php new file mode 100644 index 0000000000..c0ece7547d --- /dev/null +++ b/lib/symfony/validator/Constraints/EnableAutoMapping.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * Enables auto mapping. + * + * Using the annotations on a property has higher precedence than using it on a class, + * which has higher precedence than any configuration that might be defined outside the class. + * + * @Annotation + * + * @author Kévin Dunglas + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)] +class EnableAutoMapping extends Constraint +{ + public function __construct(?array $options = null) + { + if (\is_array($options) && \array_key_exists('groups', $options)) { + throw new ConstraintDefinitionException(\sprintf('The option "groups" is not supported by the constraint "%s".', __CLASS__)); + } + + parent::__construct($options); + } + + public function getTargets(): string|array + { + return [self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT]; + } +} diff --git a/lib/symfony/validator/Constraints/EqualTo.php b/lib/symfony/validator/Constraints/EqualTo.php new file mode 100644 index 0000000000..03769ce8a8 --- /dev/null +++ b/lib/symfony/validator/Constraints/EqualTo.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class EqualTo extends AbstractComparison +{ + public const NOT_EQUAL_ERROR = '478618a7-95ba-473d-9101-cabd45e49115'; + + protected const ERROR_NAMES = [ + self::NOT_EQUAL_ERROR => 'NOT_EQUAL_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be equal to {{ compared_value }}.'; +} diff --git a/lib/symfony/validator/Constraints/EqualToValidator.php b/lib/symfony/validator/Constraints/EqualToValidator.php new file mode 100644 index 0000000000..a8b5bad9da --- /dev/null +++ b/lib/symfony/validator/Constraints/EqualToValidator.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * Validates values are equal (==). + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +class EqualToValidator extends AbstractComparisonValidator +{ + protected function compareValues(mixed $value1, mixed $value2): bool + { + return $value1 == $value2; + } + + protected function getErrorCode(): ?string + { + return EqualTo::NOT_EQUAL_ERROR; + } +} diff --git a/lib/symfony/validator/Constraints/Existence.php b/lib/symfony/validator/Constraints/Existence.php new file mode 100644 index 0000000000..a0d6ebd606 --- /dev/null +++ b/lib/symfony/validator/Constraints/Existence.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @author Bernhard Schussek + */ +abstract class Existence extends Composite +{ + public $constraints = []; + + public function getDefaultOption(): ?string + { + return 'constraints'; + } + + protected function getCompositeOption(): string + { + return 'constraints'; + } +} diff --git a/lib/symfony/validator/Constraints/Expression.php b/lib/symfony/validator/Constraints/Expression.php new file mode 100644 index 0000000000..e784ce9e87 --- /dev/null +++ b/lib/symfony/validator/Constraints/Expression.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\ExpressionLanguage\Expression as ExpressionObject; +use Symfony\Component\ExpressionLanguage\ExpressionLanguage; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\LogicException; + +/** + * @Annotation + * @Target({"CLASS", "PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Fabien Potencier + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)] +class Expression extends Constraint +{ + public const EXPRESSION_FAILED_ERROR = '6b3befbc-2f01-4ddf-be21-b57898905284'; + + protected const ERROR_NAMES = [ + self::EXPRESSION_FAILED_ERROR => 'EXPRESSION_FAILED_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value is not valid.'; + public $expression; + public $values = []; + public bool $negate = true; + + public function __construct( + string|ExpressionObject|array|null $expression, + ?string $message = null, + ?array $values = null, + ?array $groups = null, + mixed $payload = null, + array $options = [], + ?bool $negate = null, + ) { + if (!class_exists(ExpressionLanguage::class)) { + throw new LogicException(\sprintf('The "symfony/expression-language" component is required to use the "%s" constraint. Try running "composer require symfony/expression-language".', __CLASS__)); + } + + if (\is_array($expression)) { + $options = array_merge($expression, $options); + } elseif (null !== $expression) { + $options['value'] = $expression; + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->values = $values ?? $this->values; + $this->negate = $negate ?? $this->negate; + } + + public function getDefaultOption(): ?string + { + return 'expression'; + } + + public function getRequiredOptions(): array + { + return ['expression']; + } + + public function getTargets(): string|array + { + return [self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT]; + } + + public function validatedBy(): string + { + return 'validator.expression'; + } +} diff --git a/lib/symfony/validator/Constraints/ExpressionLanguageProvider.php b/lib/symfony/validator/Constraints/ExpressionLanguageProvider.php new file mode 100644 index 0000000000..0a3727503e --- /dev/null +++ b/lib/symfony/validator/Constraints/ExpressionLanguageProvider.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\ExpressionLanguage\ExpressionFunction; +use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; + +class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface +{ + public function getFunctions(): array + { + return [ + new ExpressionFunction('is_valid', function (...$arguments) { + return \sprintf( + '0 === $context->getValidator()->inContext($context)->validate(%s)->getViolations()->count()', + implode(', ', $arguments) + ); + }, function (array $variables, ...$arguments): bool { + return 0 === $variables['context']->getValidator()->inContext($variables['context'])->validate(...$arguments)->getViolations()->count(); + }), + ]; + } +} diff --git a/lib/symfony/validator/Constraints/ExpressionLanguageSyntax.php b/lib/symfony/validator/Constraints/ExpressionLanguageSyntax.php new file mode 100644 index 0000000000..4f9bbe256d --- /dev/null +++ b/lib/symfony/validator/Constraints/ExpressionLanguageSyntax.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +trigger_deprecation('symfony/validator', '6.1', 'The "%s" constraint is deprecated since symfony 6.1, use "ExpressionSyntax" instead.', ExpressionLanguageSyntax::class); + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Andrey Sevastianov + * + * @deprecated since symfony 6.1, use ExpressionSyntax instead + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class ExpressionLanguageSyntax extends Constraint +{ + public const EXPRESSION_LANGUAGE_SYNTAX_ERROR = '1766a3f3-ff03-40eb-b053-ab7aa23d988a'; + + protected const ERROR_NAMES = [ + self::EXPRESSION_LANGUAGE_SYNTAX_ERROR => 'EXPRESSION_LANGUAGE_SYNTAX_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be a valid expression.'; + public $service; + public $allowedVariables; + + public function __construct(?array $options = null, ?string $message = null, ?string $service = null, ?array $allowedVariables = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->service = $service ?? $this->service; + $this->allowedVariables = $allowedVariables ?? $this->allowedVariables; + } + + public function validatedBy(): string + { + return $this->service ?? static::class.'Validator'; + } +} diff --git a/lib/symfony/validator/Constraints/ExpressionLanguageSyntaxValidator.php b/lib/symfony/validator/Constraints/ExpressionLanguageSyntaxValidator.php new file mode 100644 index 0000000000..3290e1c05e --- /dev/null +++ b/lib/symfony/validator/Constraints/ExpressionLanguageSyntaxValidator.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\ExpressionLanguage\ExpressionLanguage; +use Symfony\Component\ExpressionLanguage\SyntaxError; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +trigger_deprecation('symfony/validator', '6.1', 'The "%s" constraint is deprecated since symfony 6.1, use "ExpressionSyntaxValidator" instead.', ExpressionLanguageSyntaxValidator::class); + +/** + * @author Andrey Sevastianov + * + * @deprecated since symfony 6.1, use ExpressionSyntaxValidator instead + */ +class ExpressionLanguageSyntaxValidator extends ConstraintValidator +{ + private ?ExpressionLanguage $expressionLanguage; + + public function __construct(?ExpressionLanguage $expressionLanguage = null) + { + if (!class_exists(ExpressionLanguage::class)) { + throw new \LogicException(\sprintf('The "%s" class requires the "ExpressionLanguage" component. Try running "composer require symfony/expression-language".', self::class)); + } + + $this->expressionLanguage = $expressionLanguage; + } + + public function validate(mixed $expression, Constraint $constraint): void + { + if (!$constraint instanceof ExpressionLanguageSyntax) { + throw new UnexpectedTypeException($constraint, ExpressionLanguageSyntax::class); + } + + if (!\is_string($expression)) { + throw new UnexpectedValueException($expression, 'string'); + } + + $this->expressionLanguage ??= new ExpressionLanguage(); + + try { + $this->expressionLanguage->lint($expression, $constraint->allowedVariables); + } catch (SyntaxError $exception) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ syntax_error }}', $this->formatValue($exception->getMessage())) + ->setInvalidValue((string) $expression) + ->setCode(ExpressionLanguageSyntax::EXPRESSION_LANGUAGE_SYNTAX_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/ExpressionSyntax.php b/lib/symfony/validator/Constraints/ExpressionSyntax.php new file mode 100644 index 0000000000..2d2eb18a1f --- /dev/null +++ b/lib/symfony/validator/Constraints/ExpressionSyntax.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Andrey Sevastianov + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class ExpressionSyntax extends Constraint +{ + public const EXPRESSION_SYNTAX_ERROR = 'e219aa22-8b11-48ec-81a0-fc07cdb0e13f'; + + protected const ERROR_NAMES = [ + self::EXPRESSION_SYNTAX_ERROR => 'EXPRESSION_SYNTAX_ERROR', + ]; + + public $message = 'This value should be a valid expression.'; + public $service; + public $allowedVariables; + + public function __construct(?array $options = null, ?string $message = null, ?string $service = null, ?array $allowedVariables = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->service = $service ?? $this->service; + $this->allowedVariables = $allowedVariables ?? $this->allowedVariables; + } + + public function validatedBy(): string + { + return $this->service ?? static::class.'Validator'; + } +} diff --git a/lib/symfony/validator/Constraints/ExpressionSyntaxValidator.php b/lib/symfony/validator/Constraints/ExpressionSyntaxValidator.php new file mode 100644 index 0000000000..36db35c63b --- /dev/null +++ b/lib/symfony/validator/Constraints/ExpressionSyntaxValidator.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\ExpressionLanguage\ExpressionLanguage; +use Symfony\Component\ExpressionLanguage\SyntaxError; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +/** + * @author Andrey Sevastianov + */ +class ExpressionSyntaxValidator extends ConstraintValidator +{ + private ?ExpressionLanguage $expressionLanguage; + + public function __construct(?ExpressionLanguage $expressionLanguage = null) + { + $this->expressionLanguage = $expressionLanguage; + } + + public function validate(mixed $expression, Constraint $constraint): void + { + if (!$constraint instanceof ExpressionSyntax) { + throw new UnexpectedTypeException($constraint, ExpressionSyntax::class); + } + + if (null === $expression || '' === $expression) { + return; + } + + if (!\is_string($expression)) { + throw new UnexpectedValueException($expression, 'string'); + } + + $this->expressionLanguage ??= new ExpressionLanguage(); + + try { + $this->expressionLanguage->lint($expression, $constraint->allowedVariables); + } catch (SyntaxError $exception) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ syntax_error }}', $this->formatValue($exception->getMessage())) + ->setInvalidValue((string) $expression) + ->setCode(ExpressionSyntax::EXPRESSION_SYNTAX_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/ExpressionValidator.php b/lib/symfony/validator/Constraints/ExpressionValidator.php new file mode 100644 index 0000000000..9eddbc4397 --- /dev/null +++ b/lib/symfony/validator/Constraints/ExpressionValidator.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\ExpressionLanguage\ExpressionLanguage; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Fabien Potencier + * @author Bernhard Schussek + */ +class ExpressionValidator extends ConstraintValidator +{ + private ExpressionLanguage $expressionLanguage; + + public function __construct(?ExpressionLanguage $expressionLanguage = null) + { + if ($expressionLanguage) { + $this->expressionLanguage = $expressionLanguage; + } + } + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Expression) { + throw new UnexpectedTypeException($constraint, Expression::class); + } + + $variables = $constraint->values; + $variables['value'] = $value; + $variables['this'] = $this->context->getObject(); + $variables['context'] = $this->context; + + if ($constraint->negate xor $this->getExpressionLanguage()->evaluate($constraint->expression, $variables)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value, self::OBJECT_TO_STRING)) + ->setCode(Expression::EXPRESSION_FAILED_ERROR) + ->addViolation(); + } + } + + private function getExpressionLanguage(): ExpressionLanguage + { + if (!isset($this->expressionLanguage)) { + $this->expressionLanguage = new ExpressionLanguage(); + $this->expressionLanguage->registerProvider(new ExpressionLanguageProvider()); + } + + return $this->expressionLanguage; + } +} diff --git a/lib/symfony/validator/Constraints/File.php b/lib/symfony/validator/Constraints/File.php new file mode 100644 index 0000000000..88712a7a2d --- /dev/null +++ b/lib/symfony/validator/Constraints/File.php @@ -0,0 +1,186 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @property int $maxSize + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class File extends Constraint +{ + // Check the Image constraint for clashes if adding new constants here + + public const NOT_FOUND_ERROR = 'd2a3fb6e-7ddc-4210-8fbf-2ab345ce1998'; + public const NOT_READABLE_ERROR = 'c20c92a4-5bfa-4202-9477-28e800e0f6ff'; + public const EMPTY_ERROR = '5d743385-9775-4aa5-8ff5-495fb1e60137'; + public const TOO_LARGE_ERROR = 'df8637af-d466-48c6-a59d-e7126250a654'; + public const INVALID_MIME_TYPE_ERROR = '744f00bc-4389-4c74-92de-9a43cde55534'; + public const INVALID_EXTENSION_ERROR = 'c8c7315c-6186-4719-8b71-5659e16bdcb7'; + public const FILENAME_TOO_LONG = 'e5706483-91a8-49d8-9a59-5e81a3c634a8'; + + protected const ERROR_NAMES = [ + self::NOT_FOUND_ERROR => 'NOT_FOUND_ERROR', + self::NOT_READABLE_ERROR => 'NOT_READABLE_ERROR', + self::EMPTY_ERROR => 'EMPTY_ERROR', + self::TOO_LARGE_ERROR => 'TOO_LARGE_ERROR', + self::INVALID_MIME_TYPE_ERROR => 'INVALID_MIME_TYPE_ERROR', + self::INVALID_EXTENSION_ERROR => 'INVALID_EXTENSION_ERROR', + self::FILENAME_TOO_LONG => 'FILENAME_TOO_LONG', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $binaryFormat; + public $mimeTypes = []; + public ?int $filenameMaxLength = null; + public array|string|null $extensions = []; + public $notFoundMessage = 'The file could not be found.'; + public $notReadableMessage = 'The file is not readable.'; + public $maxSizeMessage = 'The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.'; + public $mimeTypesMessage = 'The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.'; + public string $extensionsMessage = 'The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}.'; + public $disallowEmptyMessage = 'An empty file is not allowed.'; + public $filenameTooLongMessage = 'The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less.'; + + public $uploadIniSizeErrorMessage = 'The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.'; + public $uploadFormSizeErrorMessage = 'The file is too large.'; + public $uploadPartialErrorMessage = 'The file was only partially uploaded.'; + public $uploadNoFileErrorMessage = 'No file was uploaded.'; + public $uploadNoTmpDirErrorMessage = 'No temporary folder was configured in php.ini.'; + public $uploadCantWriteErrorMessage = 'Cannot write temporary file to disk.'; + public $uploadExtensionErrorMessage = 'A PHP extension caused the upload to fail.'; + public $uploadErrorMessage = 'The file could not be uploaded.'; + + protected $maxSize; + + /** + * @param array|string $extensions + */ + public function __construct( + ?array $options = null, + int|string|null $maxSize = null, + ?bool $binaryFormat = null, + array|string|null $mimeTypes = null, + ?int $filenameMaxLength = null, + ?string $notFoundMessage = null, + ?string $notReadableMessage = null, + ?string $maxSizeMessage = null, + ?string $mimeTypesMessage = null, + ?string $disallowEmptyMessage = null, + ?string $filenameTooLongMessage = null, + + ?string $uploadIniSizeErrorMessage = null, + ?string $uploadFormSizeErrorMessage = null, + ?string $uploadPartialErrorMessage = null, + ?string $uploadNoFileErrorMessage = null, + ?string $uploadNoTmpDirErrorMessage = null, + ?string $uploadCantWriteErrorMessage = null, + ?string $uploadExtensionErrorMessage = null, + ?string $uploadErrorMessage = null, + ?array $groups = null, + mixed $payload = null, + + array|string|null $extensions = null, + ?string $extensionsMessage = null, + ) { + parent::__construct($options, $groups, $payload); + + $this->maxSize = $maxSize ?? $this->maxSize; + $this->binaryFormat = $binaryFormat ?? $this->binaryFormat; + $this->mimeTypes = $mimeTypes ?? $this->mimeTypes; + $this->filenameMaxLength = $filenameMaxLength ?? $this->filenameMaxLength; + $this->extensions = $extensions ?? $this->extensions; + $this->notFoundMessage = $notFoundMessage ?? $this->notFoundMessage; + $this->notReadableMessage = $notReadableMessage ?? $this->notReadableMessage; + $this->maxSizeMessage = $maxSizeMessage ?? $this->maxSizeMessage; + $this->mimeTypesMessage = $mimeTypesMessage ?? $this->mimeTypesMessage; + $this->extensionsMessage = $extensionsMessage ?? $this->extensionsMessage; + $this->disallowEmptyMessage = $disallowEmptyMessage ?? $this->disallowEmptyMessage; + $this->filenameTooLongMessage = $filenameTooLongMessage ?? $this->filenameTooLongMessage; + $this->uploadIniSizeErrorMessage = $uploadIniSizeErrorMessage ?? $this->uploadIniSizeErrorMessage; + $this->uploadFormSizeErrorMessage = $uploadFormSizeErrorMessage ?? $this->uploadFormSizeErrorMessage; + $this->uploadPartialErrorMessage = $uploadPartialErrorMessage ?? $this->uploadPartialErrorMessage; + $this->uploadNoFileErrorMessage = $uploadNoFileErrorMessage ?? $this->uploadNoFileErrorMessage; + $this->uploadNoTmpDirErrorMessage = $uploadNoTmpDirErrorMessage ?? $this->uploadNoTmpDirErrorMessage; + $this->uploadCantWriteErrorMessage = $uploadCantWriteErrorMessage ?? $this->uploadCantWriteErrorMessage; + $this->uploadExtensionErrorMessage = $uploadExtensionErrorMessage ?? $this->uploadExtensionErrorMessage; + $this->uploadErrorMessage = $uploadErrorMessage ?? $this->uploadErrorMessage; + + if (null !== $this->maxSize) { + $this->normalizeBinaryFormat($this->maxSize); + } + } + + /** + * @return void + */ + public function __set(string $option, mixed $value) + { + if ('maxSize' === $option) { + $this->normalizeBinaryFormat($value); + + return; + } + + parent::__set($option, $value); + } + + public function __get(string $option): mixed + { + if ('maxSize' === $option) { + return $this->maxSize; + } + + return parent::__get($option); + } + + public function __isset(string $option): bool + { + if ('maxSize' === $option) { + return true; + } + + return parent::__isset($option); + } + + private function normalizeBinaryFormat(int|string $maxSize): void + { + $factors = [ + 'k' => 1000, + 'ki' => 1 << 10, + 'm' => 1000 * 1000, + 'mi' => 1 << 20, + 'g' => 1000 * 1000 * 1000, + 'gi' => 1 << 30, + ]; + if (ctype_digit((string) $maxSize)) { + $this->maxSize = (int) $maxSize; + $this->binaryFormat ??= false; + } elseif (preg_match('/^(\d++)('.implode('|', array_keys($factors)).')$/i', $maxSize, $matches)) { + $this->maxSize = $matches[1] * $factors[$unit = strtolower($matches[2])]; + $this->binaryFormat ??= 2 === \strlen($unit); + } else { + throw new ConstraintDefinitionException(\sprintf('"%s" is not a valid maximum size.', $maxSize)); + } + } +} diff --git a/lib/symfony/validator/Constraints/FileValidator.php b/lib/symfony/validator/Constraints/FileValidator.php new file mode 100644 index 0000000000..6346ad098f --- /dev/null +++ b/lib/symfony/validator/Constraints/FileValidator.php @@ -0,0 +1,309 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\HttpFoundation\File\File as FileObject; +use Symfony\Component\HttpFoundation\File\UploadedFile; +use Symfony\Component\Mime\MimeTypes; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\LogicException; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +/** + * @author Bernhard Schussek + */ +class FileValidator extends ConstraintValidator +{ + public const KB_BYTES = 1000; + public const MB_BYTES = 1000000; + public const KIB_BYTES = 1024; + public const MIB_BYTES = 1048576; + + private const SUFFICES = [ + 1 => 'bytes', + self::KB_BYTES => 'kB', + self::MB_BYTES => 'MB', + self::KIB_BYTES => 'KiB', + self::MIB_BYTES => 'MiB', + ]; + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof File) { + throw new UnexpectedTypeException($constraint, File::class); + } + + if (null === $value || '' === $value) { + return; + } + + if ($value instanceof UploadedFile && !$value->isValid()) { + switch ($value->getError()) { + case \UPLOAD_ERR_INI_SIZE: + $iniLimitSize = UploadedFile::getMaxFilesize(); + if ($constraint->maxSize && $constraint->maxSize < $iniLimitSize) { + $limitInBytes = $constraint->maxSize; + $binaryFormat = $constraint->binaryFormat; + } else { + $limitInBytes = $iniLimitSize; + $binaryFormat = $constraint->binaryFormat ?? true; + } + + [, $limitAsString, $suffix] = $this->factorizeSizes(0, $limitInBytes, $binaryFormat); + $this->context->buildViolation($constraint->uploadIniSizeErrorMessage) + ->setParameter('{{ limit }}', $limitAsString) + ->setParameter('{{ suffix }}', $suffix) + ->setCode((string) \UPLOAD_ERR_INI_SIZE) + ->addViolation(); + + return; + case \UPLOAD_ERR_FORM_SIZE: + $this->context->buildViolation($constraint->uploadFormSizeErrorMessage) + ->setCode((string) \UPLOAD_ERR_FORM_SIZE) + ->addViolation(); + + return; + case \UPLOAD_ERR_PARTIAL: + $this->context->buildViolation($constraint->uploadPartialErrorMessage) + ->setCode((string) \UPLOAD_ERR_PARTIAL) + ->addViolation(); + + return; + case \UPLOAD_ERR_NO_FILE: + $this->context->buildViolation($constraint->uploadNoFileErrorMessage) + ->setCode((string) \UPLOAD_ERR_NO_FILE) + ->addViolation(); + + return; + case \UPLOAD_ERR_NO_TMP_DIR: + $this->context->buildViolation($constraint->uploadNoTmpDirErrorMessage) + ->setCode((string) \UPLOAD_ERR_NO_TMP_DIR) + ->addViolation(); + + return; + case \UPLOAD_ERR_CANT_WRITE: + $this->context->buildViolation($constraint->uploadCantWriteErrorMessage) + ->setCode((string) \UPLOAD_ERR_CANT_WRITE) + ->addViolation(); + + return; + case \UPLOAD_ERR_EXTENSION: + $this->context->buildViolation($constraint->uploadExtensionErrorMessage) + ->setCode((string) \UPLOAD_ERR_EXTENSION) + ->addViolation(); + + return; + default: + $this->context->buildViolation($constraint->uploadErrorMessage) + ->setCode((string) $value->getError()) + ->addViolation(); + + return; + } + } + + if (!\is_scalar($value) && !$value instanceof FileObject && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $path = $value instanceof FileObject ? $value->getPathname() : (string) $value; + + if (!is_file($path)) { + $this->context->buildViolation($constraint->notFoundMessage) + ->setParameter('{{ file }}', $this->formatValue($path)) + ->setCode(File::NOT_FOUND_ERROR) + ->addViolation(); + + return; + } + + if (!is_readable($path)) { + $this->context->buildViolation($constraint->notReadableMessage) + ->setParameter('{{ file }}', $this->formatValue($path)) + ->setCode(File::NOT_READABLE_ERROR) + ->addViolation(); + + return; + } + + $sizeInBytes = filesize($path); + $basename = $value instanceof UploadedFile ? $value->getClientOriginalName() : basename($path); + + if ($constraint->filenameMaxLength && $constraint->filenameMaxLength < $filenameLength = \strlen($basename)) { + $this->context->buildViolation($constraint->filenameTooLongMessage) + ->setParameter('{{ filename_max_length }}', $this->formatValue($constraint->filenameMaxLength)) + ->setCode(File::FILENAME_TOO_LONG) + ->setPlural($constraint->filenameMaxLength) + ->addViolation(); + + return; + } + + if (0 === $sizeInBytes) { + $this->context->buildViolation($constraint->disallowEmptyMessage) + ->setParameter('{{ file }}', $this->formatValue($path)) + ->setParameter('{{ name }}', $this->formatValue($basename)) + ->setCode(File::EMPTY_ERROR) + ->addViolation(); + + return; + } + + if ($constraint->maxSize) { + $limitInBytes = $constraint->maxSize; + + if ($sizeInBytes > $limitInBytes) { + [$sizeAsString, $limitAsString, $suffix] = $this->factorizeSizes($sizeInBytes, $limitInBytes, $constraint->binaryFormat); + $this->context->buildViolation($constraint->maxSizeMessage) + ->setParameter('{{ file }}', $this->formatValue($path)) + ->setParameter('{{ size }}', $sizeAsString) + ->setParameter('{{ limit }}', $limitAsString) + ->setParameter('{{ suffix }}', $suffix) + ->setParameter('{{ name }}', $this->formatValue($basename)) + ->setCode(File::TOO_LARGE_ERROR) + ->addViolation(); + + return; + } + } + + $mimeTypes = (array) $constraint->mimeTypes; + + if ($constraint->extensions) { + $fileExtension = strtolower(pathinfo($basename, \PATHINFO_EXTENSION)); + + $found = false; + $normalizedExtensions = []; + foreach ((array) $constraint->extensions as $k => $v) { + if (!\is_string($k)) { + $k = $v; + $v = null; + } + + $normalizedExtensions[] = $k; + + if ($fileExtension !== $k) { + continue; + } + + $found = true; + if (null === $v) { + if (!class_exists(MimeTypes::class)) { + throw new LogicException('You cannot validate the mime-type of files as the Mime component is not installed. Try running "composer require symfony/mime".'); + } + + $mimeTypesHelper = MimeTypes::getDefault(); + $v = $mimeTypesHelper->getMimeTypes($k); + } + + $mimeTypes = $mimeTypes ? array_intersect($v, $mimeTypes) : (array) $v; + break; + } + + if (!$found) { + $this->context->buildViolation($constraint->extensionsMessage) + ->setParameter('{{ file }}', $this->formatValue($path)) + ->setParameter('{{ extension }}', $this->formatValue($fileExtension)) + ->setParameter('{{ extensions }}', $this->formatValues($normalizedExtensions)) + ->setParameter('{{ name }}', $this->formatValue($basename)) + ->setCode(File::INVALID_EXTENSION_ERROR) + ->addViolation(); + } + } + + if ($mimeTypes) { + if ($value instanceof FileObject) { + $mime = $value->getMimeType(); + } elseif (isset($mimeTypesHelper) || class_exists(MimeTypes::class)) { + $mime = ($mimeTypesHelper ?? MimeTypes::getDefault())->guessMimeType($path); + } elseif (!class_exists(FileObject::class)) { + throw new LogicException('You cannot validate the mime-type of files as the Mime component is not installed. Try running "composer require symfony/mime".'); + } else { + $mime = (new FileObject($value))->getMimeType(); + } + + foreach ($mimeTypes as $mimeType) { + if ($mimeType === $mime) { + return; + } + + if ($discrete = strstr($mimeType, '/*', true)) { + if (strstr($mime, '/', true) === $discrete) { + return; + } + } + } + + $this->context->buildViolation($constraint->mimeTypesMessage) + ->setParameter('{{ file }}', $this->formatValue($path)) + ->setParameter('{{ type }}', $this->formatValue($mime)) + ->setParameter('{{ types }}', $this->formatValues($mimeTypes)) + ->setParameter('{{ name }}', $this->formatValue($basename)) + ->setCode(File::INVALID_MIME_TYPE_ERROR) + ->addViolation(); + } + } + + private static function moreDecimalsThan(string $double, int $numberOfDecimals): bool + { + return \strlen($double) > \strlen(round($double, $numberOfDecimals)); + } + + /** + * Convert the limit to the smallest possible number + * (i.e. try "MB", then "kB", then "bytes"). + */ + private function factorizeSizes(int $size, int|float $limit, bool $binaryFormat): array + { + if ($binaryFormat) { + $coef = self::MIB_BYTES; + $coefFactor = self::KIB_BYTES; + } else { + $coef = self::MB_BYTES; + $coefFactor = self::KB_BYTES; + } + + // If $limit < $coef, $limitAsString could be < 1 with less than 3 decimals. + // In this case, we would end up displaying an allowed size < 1 (eg: 0.1 MB). + // It looks better to keep on factorizing (to display 100 kB for example). + while ($limit < $coef) { + $coef /= $coefFactor; + } + + $limitAsString = (string) ($limit / $coef); + + // Restrict the limit to 2 decimals (without rounding! we + // need the precise value) + while (self::moreDecimalsThan($limitAsString, 2)) { + $coef /= $coefFactor; + $limitAsString = (string) ($limit / $coef); + } + + // Convert size to the same measure, but round to 2 decimals + $sizeAsString = (string) round($size / $coef, 2); + + // If the size and limit produce the same string output + // (due to rounding), reduce the coefficient + while ($sizeAsString === $limitAsString) { + $coef /= $coefFactor; + $limitAsString = (string) ($limit / $coef); + $sizeAsString = (string) round($size / $coef, 2); + } + + return [$sizeAsString, $limitAsString, self::SUFFICES[$coef]]; + } +} diff --git a/lib/symfony/validator/Constraints/GreaterThan.php b/lib/symfony/validator/Constraints/GreaterThan.php new file mode 100644 index 0000000000..ce56f1ac1c --- /dev/null +++ b/lib/symfony/validator/Constraints/GreaterThan.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class GreaterThan extends AbstractComparison +{ + public const TOO_LOW_ERROR = '778b7ae0-84d3-481a-9dec-35fdb64b1d78'; + + protected const ERROR_NAMES = [ + self::TOO_LOW_ERROR => 'TOO_LOW_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be greater than {{ compared_value }}.'; +} diff --git a/lib/symfony/validator/Constraints/GreaterThanOrEqual.php b/lib/symfony/validator/Constraints/GreaterThanOrEqual.php new file mode 100644 index 0000000000..c962f7964f --- /dev/null +++ b/lib/symfony/validator/Constraints/GreaterThanOrEqual.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class GreaterThanOrEqual extends AbstractComparison +{ + public const TOO_LOW_ERROR = 'ea4e51d1-3342-48bd-87f1-9e672cd90cad'; + + protected const ERROR_NAMES = [ + self::TOO_LOW_ERROR => 'TOO_LOW_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be greater than or equal to {{ compared_value }}.'; +} diff --git a/lib/symfony/validator/Constraints/GreaterThanOrEqualValidator.php b/lib/symfony/validator/Constraints/GreaterThanOrEqualValidator.php new file mode 100644 index 0000000000..bcf80a82d4 --- /dev/null +++ b/lib/symfony/validator/Constraints/GreaterThanOrEqualValidator.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * Validates values are greater than or equal to the previous (>=). + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +class GreaterThanOrEqualValidator extends AbstractComparisonValidator +{ + protected function compareValues(mixed $value1, mixed $value2): bool + { + return null === $value2 || $value1 >= $value2; + } + + protected function getErrorCode(): ?string + { + return GreaterThanOrEqual::TOO_LOW_ERROR; + } +} diff --git a/lib/symfony/validator/Constraints/GreaterThanValidator.php b/lib/symfony/validator/Constraints/GreaterThanValidator.php new file mode 100644 index 0000000000..1e8734fab3 --- /dev/null +++ b/lib/symfony/validator/Constraints/GreaterThanValidator.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * Validates values are greater than the previous (>). + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +class GreaterThanValidator extends AbstractComparisonValidator +{ + protected function compareValues(mixed $value1, mixed $value2): bool + { + return null === $value2 || $value1 > $value2; + } + + protected function getErrorCode(): ?string + { + return GreaterThan::TOO_LOW_ERROR; + } +} diff --git a/lib/symfony/validator/Constraints/GroupSequence.php b/lib/symfony/validator/Constraints/GroupSequence.php new file mode 100644 index 0000000000..8c91b4de2f --- /dev/null +++ b/lib/symfony/validator/Constraints/GroupSequence.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * A sequence of validation groups. + * + * When validating a group sequence, each group will only be validated if all + * of the previous groups in the sequence succeeded. For example: + * + * $validator->validate($address, null, new GroupSequence(['Basic', 'Strict'])); + * + * In the first step, all constraints that belong to the group "Basic" will be + * validated. If none of the constraints fail, the validator will then validate + * the constraints in group "Strict". This is useful, for example, if "Strict" + * contains expensive checks that require a lot of CPU or slow, external + * services. You usually don't want to run expensive checks if any of the cheap + * checks fail. + * + * When adding metadata to a class, you can override the "Default" group of + * that class with a group sequence: + * #[GroupSequence(['Address', 'Strict'])] + * class Address + * { + * // ... + * } + * + * Whenever you validate that object in the "Default" group, the group sequence + * will be validated: + * + * $validator->validate($address); + * + * If you want to execute the constraints of the "Default" group for a class + * with an overridden default group, pass the class name as group name instead: + * + * $validator->validate($address, null, "Address") + * + * @Annotation + * @Target({"CLASS", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +class GroupSequence +{ + /** + * The groups in the sequence. + * + * @var array + */ + public $groups; + + /** + * The group in which cascaded objects are validated when validating + * this sequence. + * + * By default, cascaded objects are validated in each of the groups of + * the sequence. + * + * If a class has a group sequence attached, that sequence replaces the + * "Default" group. When validating that class in the "Default" group, the + * group sequence is used instead, but still the "Default" group should be + * cascaded to other objects. + * + * @var string|GroupSequence + */ + public $cascadedGroup; + + /** + * Creates a new group sequence. + * + * @param array $groups The groups in the sequence + */ + public function __construct(array $groups) + { + $this->groups = $groups['value'] ?? $groups; + } +} diff --git a/lib/symfony/validator/Constraints/GroupSequenceProvider.php b/lib/symfony/validator/Constraints/GroupSequenceProvider.php new file mode 100644 index 0000000000..842bfd4684 --- /dev/null +++ b/lib/symfony/validator/Constraints/GroupSequenceProvider.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor; +use Symfony\Component\Validator\Attribute\HasNamedArguments; + +/** + * Attribute to define a group sequence provider. + * + * @Annotation + * @NamedArgumentConstructor + * @Target({"CLASS", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +class GroupSequenceProvider +{ + #[HasNamedArguments] + public function __construct(public ?string $provider = null) + { + } +} diff --git a/lib/symfony/validator/Constraints/Hostname.php b/lib/symfony/validator/Constraints/Hostname.php new file mode 100644 index 0000000000..79e1c87c27 --- /dev/null +++ b/lib/symfony/validator/Constraints/Hostname.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Dmitrii Poddubnyi + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Hostname extends Constraint +{ + public const INVALID_HOSTNAME_ERROR = '7057ffdb-0af4-4f7e-bd5e-e9acfa6d7a2d'; + + protected const ERROR_NAMES = [ + self::INVALID_HOSTNAME_ERROR => 'INVALID_HOSTNAME_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value is not a valid hostname.'; + public $requireTld = true; + + public function __construct( + ?array $options = null, + ?string $message = null, + ?bool $requireTld = null, + ?array $groups = null, + mixed $payload = null, + ) { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->requireTld = $requireTld ?? $this->requireTld; + } +} diff --git a/lib/symfony/validator/Constraints/HostnameValidator.php b/lib/symfony/validator/Constraints/HostnameValidator.php new file mode 100644 index 0000000000..8b0fa60e20 --- /dev/null +++ b/lib/symfony/validator/Constraints/HostnameValidator.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * @author Dmitrii Poddubnyi + */ +class HostnameValidator extends ConstraintValidator +{ + /** + * https://tools.ietf.org/html/rfc2606. + */ + private const RESERVED_TLDS = [ + 'example', + 'invalid', + 'localhost', + 'test', + ]; + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Hostname) { + throw new UnexpectedTypeException($constraint, Hostname::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + if ('' === $value) { + return; + } + if (!$this->isValid($value) || ($constraint->requireTld && !$this->hasValidTld($value))) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Hostname::INVALID_HOSTNAME_ERROR) + ->addViolation(); + } + } + + private function isValid(string $domain): bool + { + return false !== filter_var($domain, \FILTER_VALIDATE_DOMAIN, \FILTER_FLAG_HOSTNAME); + } + + private function hasValidTld(string $domain): bool + { + return str_contains($domain, '.') && !\in_array(substr($domain, strrpos($domain, '.') + 1), self::RESERVED_TLDS, true); + } +} diff --git a/lib/symfony/validator/Constraints/Iban.php b/lib/symfony/validator/Constraints/Iban.php new file mode 100644 index 0000000000..16f557f12e --- /dev/null +++ b/lib/symfony/validator/Constraints/Iban.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Manuel Reinhard + * @author Michael Schummel + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Iban extends Constraint +{ + public const INVALID_COUNTRY_CODE_ERROR = 'de78ee2c-bd50-44e2-aec8-3d8228aeadb9'; + public const INVALID_CHARACTERS_ERROR = '8d3d85e4-784f-4719-a5bc-d9e40d45a3a5'; + public const CHECKSUM_FAILED_ERROR = 'b9401321-f9bf-4dcb-83c1-f31094440795'; + public const INVALID_FORMAT_ERROR = 'c8d318f1-2ecc-41ba-b983-df70d225cf5a'; + public const NOT_SUPPORTED_COUNTRY_CODE_ERROR = 'e2c259f3-4b46-48e6-b72e-891658158ec8'; + + protected const ERROR_NAMES = [ + self::INVALID_COUNTRY_CODE_ERROR => 'INVALID_COUNTRY_CODE_ERROR', + self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR', + self::CHECKSUM_FAILED_ERROR => 'CHECKSUM_FAILED_ERROR', + self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR', + self::NOT_SUPPORTED_COUNTRY_CODE_ERROR => 'NOT_SUPPORTED_COUNTRY_CODE_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This is not a valid International Bank Account Number (IBAN).'; + + public function __construct(?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + } +} diff --git a/lib/symfony/validator/Constraints/IbanValidator.php b/lib/symfony/validator/Constraints/IbanValidator.php new file mode 100644 index 0000000000..13d91315b5 --- /dev/null +++ b/lib/symfony/validator/Constraints/IbanValidator.php @@ -0,0 +1,301 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * @author Manuel Reinhard + * @author Michael Schummel + * @author Bernhard Schussek + */ +class IbanValidator extends ConstraintValidator +{ + /** + * IBAN country specific formats. + * + * The first 2 characters from an IBAN format are the two-character ISO country code. + * The following 2 characters represent the check digits calculated from the rest of the IBAN characters. + * The rest are up to thirty alphanumeric characters for + * a BBAN (Basic Bank Account Number) which has a fixed length per country and, + * included within it, a bank identifier with a fixed position and a fixed length per country + * + * @see Resources/bin/sync-iban-formats.php + * @see https://www.swift.com/swift-resource/11971/download?language=en + * @see https://en.wikipedia.org/wiki/International_Bank_Account_Number + */ + private const FORMATS = [ + // auto-generated + 'AD' => 'AD\d{2}\d{4}\d{4}[\dA-Z]{12}', // Andorra + 'AE' => 'AE\d{2}\d{3}\d{16}', // United Arab Emirates (The) + 'AL' => 'AL\d{2}\d{8}[\dA-Z]{16}', // Albania + 'AO' => 'AO\d{2}\d{21}', // Angola + 'AT' => 'AT\d{2}\d{5}\d{11}', // Austria + 'AX' => 'FI\d{2}\d{3}\d{11}', // Finland + 'AZ' => 'AZ\d{2}[A-Z]{4}[\dA-Z]{20}', // Azerbaijan + 'BA' => 'BA\d{2}\d{3}\d{3}\d{8}\d{2}', // Bosnia and Herzegovina + 'BE' => 'BE\d{2}\d{3}\d{7}\d{2}', // Belgium + 'BF' => 'BF\d{2}[\dA-Z]{2}\d{22}', // Burkina Faso + 'BG' => 'BG\d{2}[A-Z]{4}\d{4}\d{2}[\dA-Z]{8}', // Bulgaria + 'BH' => 'BH\d{2}[A-Z]{4}[\dA-Z]{14}', // Bahrain + 'BI' => 'BI\d{2}\d{5}\d{5}\d{11}\d{2}', // Burundi + 'BJ' => 'BJ\d{2}[\dA-Z]{2}\d{22}', // Benin + 'BL' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France + 'BR' => 'BR\d{2}\d{8}\d{5}\d{10}[A-Z]{1}[\dA-Z]{1}', // Brazil + 'BY' => 'BY\d{2}[\dA-Z]{4}\d{4}[\dA-Z]{16}', // Republic of Belarus + 'CF' => 'CF\d{2}\d{23}', // Central African Republic + 'CG' => 'CG\d{2}\d{23}', // Congo, Republic of the + 'CH' => 'CH\d{2}\d{5}[\dA-Z]{12}', // Switzerland + 'CI' => 'CI\d{2}[A-Z]{1}\d{23}', // Côte d'Ivoire + 'CM' => 'CM\d{2}\d{23}', // Cameroon + 'CR' => 'CR\d{2}\d{4}\d{14}', // Costa Rica + 'CV' => 'CV\d{2}\d{21}', // Cabo Verde + 'CY' => 'CY\d{2}\d{3}\d{5}[\dA-Z]{16}', // Cyprus + 'CZ' => 'CZ\d{2}\d{4}\d{6}\d{10}', // Czechia + 'DE' => 'DE\d{2}\d{8}\d{10}', // Germany + 'DJ' => 'DJ\d{2}\d{5}\d{5}\d{11}\d{2}', // Djibouti + 'DK' => 'DK\d{2}\d{4}\d{9}\d{1}', // Denmark + 'DO' => 'DO\d{2}[\dA-Z]{4}\d{20}', // Dominican Republic + 'DZ' => 'DZ\d{2}\d{22}', // Algeria + 'EE' => 'EE\d{2}\d{2}\d{14}', // Estonia + 'EG' => 'EG\d{2}\d{4}\d{4}\d{17}', // Egypt + 'ES' => 'ES\d{2}\d{4}\d{4}\d{1}\d{1}\d{10}', // Spain + 'FI' => 'FI\d{2}\d{3}\d{11}', // Finland + 'FK' => 'FK\d{2}[A-Z]{2}\d{12}', // Falkland Islands + 'FO' => 'FO\d{2}\d{4}\d{9}\d{1}', // Faroe Islands + 'FR' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France + 'GA' => 'GA\d{2}\d{23}', // Gabon + 'GB' => 'GB\d{2}[A-Z]{4}\d{6}\d{8}', // United Kingdom + 'GE' => 'GE\d{2}[A-Z]{2}\d{16}', // Georgia + 'GF' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France + 'GG' => 'GB\d{2}[A-Z]{4}\d{6}\d{8}', // United Kingdom + 'GI' => 'GI\d{2}[A-Z]{4}[\dA-Z]{15}', // Gibraltar + 'GL' => 'GL\d{2}\d{4}\d{9}\d{1}', // Greenland + 'GP' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France + 'GQ' => 'GQ\d{2}\d{23}', // Equatorial Guinea + 'GR' => 'GR\d{2}\d{3}\d{4}[\dA-Z]{16}', // Greece + 'GT' => 'GT\d{2}[\dA-Z]{4}[\dA-Z]{20}', // Guatemala + 'GW' => 'GW\d{2}[\dA-Z]{2}\d{19}', // Guinea-Bissau + 'HN' => 'HN\d{2}[A-Z]{4}\d{20}', // Honduras + 'HR' => 'HR\d{2}\d{7}\d{10}', // Croatia + 'HU' => 'HU\d{2}\d{3}\d{4}\d{1}\d{15}\d{1}', // Hungary + 'IE' => 'IE\d{2}[A-Z]{4}\d{6}\d{8}', // Ireland + 'IL' => 'IL\d{2}\d{3}\d{3}\d{13}', // Israel + 'IM' => 'GB\d{2}[A-Z]{4}\d{6}\d{8}', // United Kingdom + 'IQ' => 'IQ\d{2}[A-Z]{4}\d{3}\d{12}', // Iraq + 'IR' => 'IR\d{2}\d{22}', // Iran + 'IS' => 'IS\d{2}\d{4}\d{2}\d{6}\d{10}', // Iceland + 'IT' => 'IT\d{2}[A-Z]{1}\d{5}\d{5}[\dA-Z]{12}', // Italy + 'JE' => 'GB\d{2}[A-Z]{4}\d{6}\d{8}', // United Kingdom + 'JO' => 'JO\d{2}[A-Z]{4}\d{4}[\dA-Z]{18}', // Jordan + 'KM' => 'KM\d{2}\d{23}', // Comoros + 'KW' => 'KW\d{2}[A-Z]{4}[\dA-Z]{22}', // Kuwait + 'KZ' => 'KZ\d{2}\d{3}[\dA-Z]{13}', // Kazakhstan + 'LB' => 'LB\d{2}\d{4}[\dA-Z]{20}', // Lebanon + 'LC' => 'LC\d{2}[A-Z]{4}[\dA-Z]{24}', // Saint Lucia + 'LI' => 'LI\d{2}\d{5}[\dA-Z]{12}', // Liechtenstein + 'LT' => 'LT\d{2}\d{5}\d{11}', // Lithuania + 'LU' => 'LU\d{2}\d{3}[\dA-Z]{13}', // Luxembourg + 'LV' => 'LV\d{2}[A-Z]{4}[\dA-Z]{13}', // Latvia + 'LY' => 'LY\d{2}\d{3}\d{3}\d{15}', // Libya + 'MA' => 'MA\d{2}\d{24}', // Morocco + 'MC' => 'MC\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // Monaco + 'MD' => 'MD\d{2}[\dA-Z]{2}[\dA-Z]{18}', // Moldova + 'ME' => 'ME\d{2}\d{3}\d{13}\d{2}', // Montenegro + 'MF' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France + 'MG' => 'MG\d{2}\d{23}', // Madagascar + 'MK' => 'MK\d{2}\d{3}[\dA-Z]{10}\d{2}', // Macedonia + 'ML' => 'ML\d{2}[\dA-Z]{2}\d{22}', // Mali + 'MN' => 'MN\d{2}\d{4}\d{12}', // Mongolia + 'MQ' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France + 'MR' => 'MR\d{2}\d{5}\d{5}\d{11}\d{2}', // Mauritania + 'MT' => 'MT\d{2}[A-Z]{4}\d{5}[\dA-Z]{18}', // Malta + 'MU' => 'MU\d{2}[A-Z]{4}\d{2}\d{2}\d{12}\d{3}[A-Z]{3}', // Mauritius + 'MZ' => 'MZ\d{2}\d{21}', // Mozambique + 'NC' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France + 'NE' => 'NE\d{2}[A-Z]{2}\d{22}', // Niger + 'NI' => 'NI\d{2}[A-Z]{4}\d{20}', // Nicaragua + 'NL' => 'NL\d{2}[A-Z]{4}\d{10}', // Netherlands (The) + 'NO' => 'NO\d{2}\d{4}\d{6}\d{1}', // Norway + 'OM' => 'OM\d{2}\d{3}[\dA-Z]{16}', // Oman + 'PF' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France + 'PK' => 'PK\d{2}[A-Z]{4}[\dA-Z]{16}', // Pakistan + 'PL' => 'PL\d{2}\d{8}\d{16}', // Poland + 'PM' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France + 'PS' => 'PS\d{2}[A-Z]{4}[\dA-Z]{21}', // Palestine, State of + 'PT' => 'PT\d{2}\d{4}\d{4}\d{11}\d{2}', // Portugal + 'QA' => 'QA\d{2}[A-Z]{4}[\dA-Z]{21}', // Qatar + 'RE' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France + 'RO' => 'RO\d{2}[A-Z]{4}[\dA-Z]{16}', // Romania + 'RS' => 'RS\d{2}\d{3}\d{13}\d{2}', // Serbia + 'RU' => 'RU\d{2}\d{9}\d{5}[\dA-Z]{15}', // Russia + 'SA' => 'SA\d{2}\d{2}[\dA-Z]{18}', // Saudi Arabia + 'SC' => 'SC\d{2}[A-Z]{4}\d{2}\d{2}\d{16}[A-Z]{3}', // Seychelles + 'SD' => 'SD\d{2}\d{2}\d{12}', // Sudan + 'SE' => 'SE\d{2}\d{3}\d{16}\d{1}', // Sweden + 'SI' => 'SI\d{2}\d{5}\d{8}\d{2}', // Slovenia + 'SK' => 'SK\d{2}\d{4}\d{6}\d{10}', // Slovakia + 'SM' => 'SM\d{2}[A-Z]{1}\d{5}\d{5}[\dA-Z]{12}', // San Marino + 'SN' => 'SN\d{2}[A-Z]{2}\d{22}', // Senegal + 'SO' => 'SO\d{2}\d{4}\d{3}\d{12}', // Somalia + 'ST' => 'ST\d{2}\d{8}\d{11}\d{2}', // Sao Tome and Principe + 'SV' => 'SV\d{2}[A-Z]{4}\d{20}', // El Salvador + 'TD' => 'TD\d{2}\d{23}', // Chad + 'TF' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France + 'TG' => 'TG\d{2}[A-Z]{2}\d{22}', // Togo + 'TL' => 'TL\d{2}\d{3}\d{14}\d{2}', // Timor-Leste + 'TN' => 'TN\d{2}\d{2}\d{3}\d{13}\d{2}', // Tunisia + 'TR' => 'TR\d{2}\d{5}\d{1}[\dA-Z]{16}', // Turkey + 'UA' => 'UA\d{2}\d{6}[\dA-Z]{19}', // Ukraine + 'VA' => 'VA\d{2}\d{3}\d{15}', // Vatican City State + 'VG' => 'VG\d{2}[A-Z]{4}\d{16}', // Virgin Islands + 'WF' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France + 'XK' => 'XK\d{2}\d{4}\d{10}\d{2}', // Kosovo + 'YE' => 'YE\d{2}[A-Z]{4}\d{4}[\dA-Z]{18}', // Yemen + 'YT' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France + ]; + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Iban) { + throw new UnexpectedTypeException($constraint, Iban::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + // Remove spaces and convert to uppercase + $canonicalized = str_replace(' ', '', strtoupper($value)); + + // The IBAN must contain only digits and characters... + if (!ctype_alnum($canonicalized)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Iban::INVALID_CHARACTERS_ERROR) + ->addViolation(); + + return; + } + + // ...start with a two-letter country code + $countryCode = substr($canonicalized, 0, 2); + + if (!ctype_alpha($countryCode)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Iban::INVALID_COUNTRY_CODE_ERROR) + ->addViolation(); + + return; + } + + // ...have a format available + if (!\array_key_exists($countryCode, self::FORMATS)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Iban::NOT_SUPPORTED_COUNTRY_CODE_ERROR) + ->addViolation(); + + return; + } + + // ...and have a valid format + if (!preg_match('/^'.self::FORMATS[$countryCode].'$/', $canonicalized) + ) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Iban::INVALID_FORMAT_ERROR) + ->addViolation(); + + return; + } + + // Check digits should always between 2 and 98 + // A ECBS document (https://www.ecbs.org/Download/EBS204_V3.PDF) replicates part of the ISO/IEC 7064:2003 standard as a method for generating check digits in the range 02 to 98. + $checkDigits = (int) substr($canonicalized, 2, 2); + if ($checkDigits < 2 || $checkDigits > 98) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Iban::CHECKSUM_FAILED_ERROR) + ->addViolation(); + + return; + } + + // Move the first four characters to the end + // e.g. CH93 0076 2011 6238 5295 7 + // -> 0076 2011 6238 5295 7 CH93 + $canonicalized = substr($canonicalized, 4).substr($canonicalized, 0, 4); + + // Convert all remaining letters to their ordinals + // The result is an integer, which is too large for PHP's int + // data type, so we store it in a string instead. + // e.g. 0076 2011 6238 5295 7 CH93 + // -> 0076 2011 6238 5295 7 121893 + $checkSum = self::toBigInt($canonicalized); + + // Do a modulo-97 operation on the large integer + // We cannot use PHP's modulo operator, so we calculate the + // modulo step-wisely instead + if (1 !== self::bigModulo97($checkSum)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Iban::CHECKSUM_FAILED_ERROR) + ->addViolation(); + } + } + + private static function toBigInt(string $string): string + { + $chars = str_split($string); + $bigInt = ''; + + foreach ($chars as $char) { + // Convert uppercase characters to ordinals, starting with 10 for "A" + if (ctype_upper($char)) { + $bigInt .= (\ord($char) - 55); + + continue; + } + + // Simply append digits + $bigInt .= $char; + } + + return $bigInt; + } + + private static function bigModulo97(string $bigInt): int + { + $parts = str_split($bigInt, 7); + $rest = 0; + + foreach ($parts as $part) { + $rest = ($rest.$part) % 97; + } + + return $rest; + } +} diff --git a/lib/symfony/validator/Constraints/IdenticalTo.php b/lib/symfony/validator/Constraints/IdenticalTo.php new file mode 100644 index 0000000000..50ec5e1297 --- /dev/null +++ b/lib/symfony/validator/Constraints/IdenticalTo.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class IdenticalTo extends AbstractComparison +{ + public const NOT_IDENTICAL_ERROR = '2a8cc50f-58a2-4536-875e-060a2ce69ed5'; + + protected const ERROR_NAMES = [ + self::NOT_IDENTICAL_ERROR => 'NOT_IDENTICAL_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be identical to {{ compared_value_type }} {{ compared_value }}.'; +} diff --git a/lib/symfony/validator/Constraints/IdenticalToValidator.php b/lib/symfony/validator/Constraints/IdenticalToValidator.php new file mode 100644 index 0000000000..0f5d506780 --- /dev/null +++ b/lib/symfony/validator/Constraints/IdenticalToValidator.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * Validates values are identical (===). + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +class IdenticalToValidator extends AbstractComparisonValidator +{ + protected function compareValues(mixed $value1, mixed $value2): bool + { + return $value1 === $value2; + } + + protected function getErrorCode(): ?string + { + return IdenticalTo::NOT_IDENTICAL_ERROR; + } +} diff --git a/lib/symfony/validator/Constraints/Image.php b/lib/symfony/validator/Constraints/Image.php new file mode 100644 index 0000000000..8fafa5044f --- /dev/null +++ b/lib/symfony/validator/Constraints/Image.php @@ -0,0 +1,207 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Benjamin Dulau + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Image extends File +{ + public const SIZE_NOT_DETECTED_ERROR = '6d55c3f4-e58e-4fe3-91ee-74b492199956'; + public const TOO_WIDE_ERROR = '7f87163d-878f-47f5-99ba-a8eb723a1ab2'; + public const TOO_NARROW_ERROR = '9afbd561-4f90-4a27-be62-1780fc43604a'; + public const TOO_HIGH_ERROR = '7efae81c-4877-47ba-aa65-d01ccb0d4645'; + public const TOO_LOW_ERROR = 'aef0cb6a-c07f-4894-bc08-1781420d7b4c'; + public const TOO_FEW_PIXEL_ERROR = '1b06b97d-ae48-474e-978f-038a74854c43'; + public const TOO_MANY_PIXEL_ERROR = 'ee0804e8-44db-4eac-9775-be91aaf72ce1'; + public const RATIO_TOO_BIG_ERROR = '70cafca6-168f-41c9-8c8c-4e47a52be643'; + public const RATIO_TOO_SMALL_ERROR = '59b8c6ef-bcf2-4ceb-afff-4642ed92f12e'; + public const SQUARE_NOT_ALLOWED_ERROR = '5d41425b-facb-47f7-a55a-de9fbe45cb46'; + public const LANDSCAPE_NOT_ALLOWED_ERROR = '6f895685-7cf2-4d65-b3da-9029c5581d88'; + public const PORTRAIT_NOT_ALLOWED_ERROR = '65608156-77da-4c79-a88c-02ef6d18c782'; + public const CORRUPTED_IMAGE_ERROR = '5d4163f3-648f-4e39-87fd-cc5ea7aad2d1'; + + // Include the mapping from the base class + + protected const ERROR_NAMES = [ + self::NOT_FOUND_ERROR => 'NOT_FOUND_ERROR', + self::NOT_READABLE_ERROR => 'NOT_READABLE_ERROR', + self::EMPTY_ERROR => 'EMPTY_ERROR', + self::TOO_LARGE_ERROR => 'TOO_LARGE_ERROR', + self::INVALID_MIME_TYPE_ERROR => 'INVALID_MIME_TYPE_ERROR', + self::FILENAME_TOO_LONG => 'FILENAME_TOO_LONG', + self::SIZE_NOT_DETECTED_ERROR => 'SIZE_NOT_DETECTED_ERROR', + self::TOO_WIDE_ERROR => 'TOO_WIDE_ERROR', + self::TOO_NARROW_ERROR => 'TOO_NARROW_ERROR', + self::TOO_HIGH_ERROR => 'TOO_HIGH_ERROR', + self::TOO_LOW_ERROR => 'TOO_LOW_ERROR', + self::TOO_FEW_PIXEL_ERROR => 'TOO_FEW_PIXEL_ERROR', + self::TOO_MANY_PIXEL_ERROR => 'TOO_MANY_PIXEL_ERROR', + self::RATIO_TOO_BIG_ERROR => 'RATIO_TOO_BIG_ERROR', + self::RATIO_TOO_SMALL_ERROR => 'RATIO_TOO_SMALL_ERROR', + self::SQUARE_NOT_ALLOWED_ERROR => 'SQUARE_NOT_ALLOWED_ERROR', + self::LANDSCAPE_NOT_ALLOWED_ERROR => 'LANDSCAPE_NOT_ALLOWED_ERROR', + self::PORTRAIT_NOT_ALLOWED_ERROR => 'PORTRAIT_NOT_ALLOWED_ERROR', + self::CORRUPTED_IMAGE_ERROR => 'CORRUPTED_IMAGE_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $mimeTypes; + public $minWidth; + public $maxWidth; + public $maxHeight; + public $minHeight; + public $maxRatio; + public $minRatio; + public $minPixels; + public $maxPixels; + public $allowSquare = true; + public $allowLandscape = true; + public $allowPortrait = true; + public $detectCorrupted = false; + + // The constant for a wrong MIME type is taken from the parent class. + public $mimeTypesMessage = 'This file is not a valid image.'; + public $sizeNotDetectedMessage = 'The size of the image could not be detected.'; + public $maxWidthMessage = 'The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.'; + public $minWidthMessage = 'The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.'; + public $maxHeightMessage = 'The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.'; + public $minHeightMessage = 'The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.'; + public $minPixelsMessage = 'The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels.'; + public $maxPixelsMessage = 'The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels.'; + public $maxRatioMessage = 'The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.'; + public $minRatioMessage = 'The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.'; + public $allowSquareMessage = 'The image is square ({{ width }}x{{ height }}px). Square images are not allowed.'; + public $allowLandscapeMessage = 'The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.'; + public $allowPortraitMessage = 'The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.'; + public $corruptedMessage = 'The image file is corrupted.'; + + public function __construct( + ?array $options = null, + int|string|null $maxSize = null, + ?bool $binaryFormat = null, + ?array $mimeTypes = null, + ?int $filenameMaxLength = null, + ?int $minWidth = null, + ?int $maxWidth = null, + ?int $maxHeight = null, + ?int $minHeight = null, + int|float|null $maxRatio = null, + int|float|null $minRatio = null, + int|float|null $minPixels = null, + int|float|null $maxPixels = null, + ?bool $allowSquare = null, + ?bool $allowLandscape = null, + ?bool $allowPortrait = null, + ?bool $detectCorrupted = null, + ?string $notFoundMessage = null, + ?string $notReadableMessage = null, + ?string $maxSizeMessage = null, + ?string $mimeTypesMessage = null, + ?string $disallowEmptyMessage = null, + ?string $filenameTooLongMessage = null, + ?string $uploadIniSizeErrorMessage = null, + ?string $uploadFormSizeErrorMessage = null, + ?string $uploadPartialErrorMessage = null, + ?string $uploadNoFileErrorMessage = null, + ?string $uploadNoTmpDirErrorMessage = null, + ?string $uploadCantWriteErrorMessage = null, + ?string $uploadExtensionErrorMessage = null, + ?string $uploadErrorMessage = null, + ?string $sizeNotDetectedMessage = null, + ?string $maxWidthMessage = null, + ?string $minWidthMessage = null, + ?string $maxHeightMessage = null, + ?string $minHeightMessage = null, + ?string $minPixelsMessage = null, + ?string $maxPixelsMessage = null, + ?string $maxRatioMessage = null, + ?string $minRatioMessage = null, + ?string $allowSquareMessage = null, + ?string $allowLandscapeMessage = null, + ?string $allowPortraitMessage = null, + ?string $corruptedMessage = null, + ?array $groups = null, + mixed $payload = null, + array|string|null $extensions = null, + ?string $extensionsMessage = null, + ) { + parent::__construct( + $options, + $maxSize, + $binaryFormat, + $mimeTypes, + $filenameMaxLength, + $notFoundMessage, + $notReadableMessage, + $maxSizeMessage, + $mimeTypesMessage, + $disallowEmptyMessage, + $filenameTooLongMessage, + $uploadIniSizeErrorMessage, + $uploadFormSizeErrorMessage, + $uploadPartialErrorMessage, + $uploadNoFileErrorMessage, + $uploadNoTmpDirErrorMessage, + $uploadCantWriteErrorMessage, + $uploadExtensionErrorMessage, + $uploadErrorMessage, + $groups, + $payload, + $extensions, + $extensionsMessage, + ); + + $this->minWidth = $minWidth ?? $this->minWidth; + $this->maxWidth = $maxWidth ?? $this->maxWidth; + $this->maxHeight = $maxHeight ?? $this->maxHeight; + $this->minHeight = $minHeight ?? $this->minHeight; + $this->maxRatio = $maxRatio ?? $this->maxRatio; + $this->minRatio = $minRatio ?? $this->minRatio; + $this->minPixels = $minPixels ?? $this->minPixels; + $this->maxPixels = $maxPixels ?? $this->maxPixels; + $this->allowSquare = $allowSquare ?? $this->allowSquare; + $this->allowLandscape = $allowLandscape ?? $this->allowLandscape; + $this->allowPortrait = $allowPortrait ?? $this->allowPortrait; + $this->detectCorrupted = $detectCorrupted ?? $this->detectCorrupted; + $this->sizeNotDetectedMessage = $sizeNotDetectedMessage ?? $this->sizeNotDetectedMessage; + $this->maxWidthMessage = $maxWidthMessage ?? $this->maxWidthMessage; + $this->minWidthMessage = $minWidthMessage ?? $this->minWidthMessage; + $this->maxHeightMessage = $maxHeightMessage ?? $this->maxHeightMessage; + $this->minHeightMessage = $minHeightMessage ?? $this->minHeightMessage; + $this->minPixelsMessage = $minPixelsMessage ?? $this->minPixelsMessage; + $this->maxPixelsMessage = $maxPixelsMessage ?? $this->maxPixelsMessage; + $this->maxRatioMessage = $maxRatioMessage ?? $this->maxRatioMessage; + $this->minRatioMessage = $minRatioMessage ?? $this->minRatioMessage; + $this->allowSquareMessage = $allowSquareMessage ?? $this->allowSquareMessage; + $this->allowLandscapeMessage = $allowLandscapeMessage ?? $this->allowLandscapeMessage; + $this->allowPortraitMessage = $allowPortraitMessage ?? $this->allowPortraitMessage; + $this->corruptedMessage = $corruptedMessage ?? $this->corruptedMessage; + + if (null === $this->mimeTypes && [] === $this->extensions) { + $this->mimeTypes = 'image/*'; + } + + if (!\in_array('image/*', (array) $this->mimeTypes, true) && !\array_key_exists('mimeTypesMessage', $options ?? []) && null === $mimeTypesMessage) { + $this->mimeTypesMessage = 'The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.'; + } + } +} diff --git a/lib/symfony/validator/Constraints/ImageValidator.php b/lib/symfony/validator/Constraints/ImageValidator.php new file mode 100644 index 0000000000..0c2fd318ab --- /dev/null +++ b/lib/symfony/validator/Constraints/ImageValidator.php @@ -0,0 +1,235 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\LogicException; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * Validates whether a value is a valid image file and is valid + * against minWidth, maxWidth, minHeight and maxHeight constraints. + * + * @author Benjamin Dulau + * @author Bernhard Schussek + */ +class ImageValidator extends FileValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Image) { + throw new UnexpectedTypeException($constraint, Image::class); + } + + $violations = \count($this->context->getViolations()); + + parent::validate($value, $constraint); + + $failed = \count($this->context->getViolations()) !== $violations; + + if ($failed || null === $value || '' === $value) { + return; + } + + if (null === $constraint->minWidth && null === $constraint->maxWidth + && null === $constraint->minHeight && null === $constraint->maxHeight + && null === $constraint->minPixels && null === $constraint->maxPixels + && null === $constraint->minRatio && null === $constraint->maxRatio + && $constraint->allowSquare && $constraint->allowLandscape && $constraint->allowPortrait + && !$constraint->detectCorrupted) { + return; + } + + $size = @getimagesize($value); + + if (empty($size) || (0 === $size[0]) || (0 === $size[1])) { + $this->context->buildViolation($constraint->sizeNotDetectedMessage) + ->setCode(Image::SIZE_NOT_DETECTED_ERROR) + ->addViolation(); + + return; + } + + $width = $size[0]; + $height = $size[1]; + + if ($constraint->minWidth) { + if (!ctype_digit((string) $constraint->minWidth)) { + throw new ConstraintDefinitionException(\sprintf('"%s" is not a valid minimum width.', $constraint->minWidth)); + } + + if ($width < $constraint->minWidth) { + $this->context->buildViolation($constraint->minWidthMessage) + ->setParameter('{{ width }}', $width) + ->setParameter('{{ min_width }}', $constraint->minWidth) + ->setCode(Image::TOO_NARROW_ERROR) + ->addViolation(); + + return; + } + } + + if ($constraint->maxWidth) { + if (!ctype_digit((string) $constraint->maxWidth)) { + throw new ConstraintDefinitionException(\sprintf('"%s" is not a valid maximum width.', $constraint->maxWidth)); + } + + if ($width > $constraint->maxWidth) { + $this->context->buildViolation($constraint->maxWidthMessage) + ->setParameter('{{ width }}', $width) + ->setParameter('{{ max_width }}', $constraint->maxWidth) + ->setCode(Image::TOO_WIDE_ERROR) + ->addViolation(); + + return; + } + } + + if ($constraint->minHeight) { + if (!ctype_digit((string) $constraint->minHeight)) { + throw new ConstraintDefinitionException(\sprintf('"%s" is not a valid minimum height.', $constraint->minHeight)); + } + + if ($height < $constraint->minHeight) { + $this->context->buildViolation($constraint->minHeightMessage) + ->setParameter('{{ height }}', $height) + ->setParameter('{{ min_height }}', $constraint->minHeight) + ->setCode(Image::TOO_LOW_ERROR) + ->addViolation(); + + return; + } + } + + if ($constraint->maxHeight) { + if (!ctype_digit((string) $constraint->maxHeight)) { + throw new ConstraintDefinitionException(\sprintf('"%s" is not a valid maximum height.', $constraint->maxHeight)); + } + + if ($height > $constraint->maxHeight) { + $this->context->buildViolation($constraint->maxHeightMessage) + ->setParameter('{{ height }}', $height) + ->setParameter('{{ max_height }}', $constraint->maxHeight) + ->setCode(Image::TOO_HIGH_ERROR) + ->addViolation(); + } + } + + $pixels = $width * $height; + + if (null !== $constraint->minPixels) { + if (!ctype_digit((string) $constraint->minPixels)) { + throw new ConstraintDefinitionException(\sprintf('"%s" is not a valid minimum amount of pixels.', $constraint->minPixels)); + } + + if ($pixels < $constraint->minPixels) { + $this->context->buildViolation($constraint->minPixelsMessage) + ->setParameter('{{ pixels }}', $pixels) + ->setParameter('{{ min_pixels }}', $constraint->minPixels) + ->setParameter('{{ height }}', $height) + ->setParameter('{{ width }}', $width) + ->setCode(Image::TOO_FEW_PIXEL_ERROR) + ->addViolation(); + } + } + + if (null !== $constraint->maxPixels) { + if (!ctype_digit((string) $constraint->maxPixels)) { + throw new ConstraintDefinitionException(\sprintf('"%s" is not a valid maximum amount of pixels.', $constraint->maxPixels)); + } + + if ($pixels > $constraint->maxPixels) { + $this->context->buildViolation($constraint->maxPixelsMessage) + ->setParameter('{{ pixels }}', $pixels) + ->setParameter('{{ max_pixels }}', $constraint->maxPixels) + ->setParameter('{{ height }}', $height) + ->setParameter('{{ width }}', $width) + ->setCode(Image::TOO_MANY_PIXEL_ERROR) + ->addViolation(); + } + } + + $ratio = round($width / $height, 2); + + if (null !== $constraint->minRatio) { + if (!is_numeric((string) $constraint->minRatio)) { + throw new ConstraintDefinitionException(\sprintf('"%s" is not a valid minimum ratio.', $constraint->minRatio)); + } + + if ($ratio < round($constraint->minRatio, 2)) { + $this->context->buildViolation($constraint->minRatioMessage) + ->setParameter('{{ ratio }}', $ratio) + ->setParameter('{{ min_ratio }}', round($constraint->minRatio, 2)) + ->setCode(Image::RATIO_TOO_SMALL_ERROR) + ->addViolation(); + } + } + + if (null !== $constraint->maxRatio) { + if (!is_numeric((string) $constraint->maxRatio)) { + throw new ConstraintDefinitionException(\sprintf('"%s" is not a valid maximum ratio.', $constraint->maxRatio)); + } + + if ($ratio > round($constraint->maxRatio, 2)) { + $this->context->buildViolation($constraint->maxRatioMessage) + ->setParameter('{{ ratio }}', $ratio) + ->setParameter('{{ max_ratio }}', round($constraint->maxRatio, 2)) + ->setCode(Image::RATIO_TOO_BIG_ERROR) + ->addViolation(); + } + } + + if (!$constraint->allowSquare && $width == $height) { + $this->context->buildViolation($constraint->allowSquareMessage) + ->setParameter('{{ width }}', $width) + ->setParameter('{{ height }}', $height) + ->setCode(Image::SQUARE_NOT_ALLOWED_ERROR) + ->addViolation(); + } + + if (!$constraint->allowLandscape && $width > $height) { + $this->context->buildViolation($constraint->allowLandscapeMessage) + ->setParameter('{{ width }}', $width) + ->setParameter('{{ height }}', $height) + ->setCode(Image::LANDSCAPE_NOT_ALLOWED_ERROR) + ->addViolation(); + } + + if (!$constraint->allowPortrait && $width < $height) { + $this->context->buildViolation($constraint->allowPortraitMessage) + ->setParameter('{{ width }}', $width) + ->setParameter('{{ height }}', $height) + ->setCode(Image::PORTRAIT_NOT_ALLOWED_ERROR) + ->addViolation(); + } + + if ($constraint->detectCorrupted) { + if (!\function_exists('imagecreatefromstring')) { + throw new LogicException('Corrupted images detection requires installed and enabled GD extension.'); + } + + $resource = @imagecreatefromstring(file_get_contents($value)); + + if (false === $resource) { + $this->context->buildViolation($constraint->corruptedMessage) + ->setCode(Image::CORRUPTED_IMAGE_ERROR) + ->addViolation(); + + return; + } + } + } +} diff --git a/lib/symfony/validator/Constraints/Ip.php b/lib/symfony/validator/Constraints/Ip.php new file mode 100644 index 0000000000..0ff522107b --- /dev/null +++ b/lib/symfony/validator/Constraints/Ip.php @@ -0,0 +1,112 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\InvalidArgumentException; + +/** + * Validates that a value is a valid IP address. + * + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + * @author Joseph Bielawski + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Ip extends Constraint +{ + public const V4 = '4'; + public const V6 = '6'; + public const ALL = 'all'; + + // adds FILTER_FLAG_NO_PRIV_RANGE flag (skip private ranges) + public const V4_NO_PRIV = '4_no_priv'; + public const V6_NO_PRIV = '6_no_priv'; + public const ALL_NO_PRIV = 'all_no_priv'; + + // adds FILTER_FLAG_NO_RES_RANGE flag (skip reserved ranges) + public const V4_NO_RES = '4_no_res'; + public const V6_NO_RES = '6_no_res'; + public const ALL_NO_RES = 'all_no_res'; + + // adds FILTER_FLAG_NO_PRIV_RANGE and FILTER_FLAG_NO_RES_RANGE flags (skip both) + public const V4_ONLY_PUBLIC = '4_public'; + public const V6_ONLY_PUBLIC = '6_public'; + public const ALL_ONLY_PUBLIC = 'all_public'; + + public const INVALID_IP_ERROR = 'b1b427ae-9f6f-41b0-aa9b-84511fbb3c5b'; + + protected const VERSIONS = [ + self::V4, + self::V6, + self::ALL, + + self::V4_NO_PRIV, + self::V6_NO_PRIV, + self::ALL_NO_PRIV, + + self::V4_NO_RES, + self::V6_NO_RES, + self::ALL_NO_RES, + + self::V4_ONLY_PUBLIC, + self::V6_ONLY_PUBLIC, + self::ALL_ONLY_PUBLIC, + ]; + + protected const ERROR_NAMES = [ + self::INVALID_IP_ERROR => 'INVALID_IP_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const VERSIONS instead + */ + protected static $versions = self::VERSIONS; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $version = self::V4; + + public $message = 'This is not a valid IP address.'; + + /** @var callable|null */ + public $normalizer; + + public function __construct( + ?array $options = null, + ?string $version = null, + ?string $message = null, + ?callable $normalizer = null, + ?array $groups = null, + mixed $payload = null, + ) { + parent::__construct($options, $groups, $payload); + + $this->version = $version ?? $this->version; + $this->message = $message ?? $this->message; + $this->normalizer = $normalizer ?? $this->normalizer; + + if (!\in_array($this->version, self::$versions)) { + throw new ConstraintDefinitionException(\sprintf('The option "version" must be one of "%s".', implode('", "', self::$versions))); + } + + if (null !== $this->normalizer && !\is_callable($this->normalizer)) { + throw new InvalidArgumentException(\sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer))); + } + } +} diff --git a/lib/symfony/validator/Constraints/IpValidator.php b/lib/symfony/validator/Constraints/IpValidator.php new file mode 100644 index 0000000000..2f71a88045 --- /dev/null +++ b/lib/symfony/validator/Constraints/IpValidator.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * Validates whether a value is a valid IP address. + * + * @author Bernhard Schussek + * @author Joseph Bielawski + */ +class IpValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Ip) { + throw new UnexpectedTypeException($constraint, Ip::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + if (null !== $constraint->normalizer) { + $value = ($constraint->normalizer)($value); + } + + $flag = match ($constraint->version) { + Ip::V4 => \FILTER_FLAG_IPV4, + Ip::V6 => \FILTER_FLAG_IPV6, + Ip::V4_NO_PRIV => \FILTER_FLAG_IPV4 | \FILTER_FLAG_NO_PRIV_RANGE, + Ip::V6_NO_PRIV => \FILTER_FLAG_IPV6 | \FILTER_FLAG_NO_PRIV_RANGE, + Ip::ALL_NO_PRIV => \FILTER_FLAG_NO_PRIV_RANGE, + Ip::V4_NO_RES => \FILTER_FLAG_IPV4 | \FILTER_FLAG_NO_RES_RANGE, + Ip::V6_NO_RES => \FILTER_FLAG_IPV6 | \FILTER_FLAG_NO_RES_RANGE, + Ip::ALL_NO_RES => \FILTER_FLAG_NO_RES_RANGE, + Ip::V4_ONLY_PUBLIC => \FILTER_FLAG_IPV4 | \FILTER_FLAG_NO_PRIV_RANGE | \FILTER_FLAG_NO_RES_RANGE, + Ip::V6_ONLY_PUBLIC => \FILTER_FLAG_IPV6 | \FILTER_FLAG_NO_PRIV_RANGE | \FILTER_FLAG_NO_RES_RANGE, + Ip::ALL_ONLY_PUBLIC => \FILTER_FLAG_NO_PRIV_RANGE | \FILTER_FLAG_NO_RES_RANGE, + default => 0, + }; + + if (!filter_var($value, \FILTER_VALIDATE_IP, $flag)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Ip::INVALID_IP_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/IsFalse.php b/lib/symfony/validator/Constraints/IsFalse.php new file mode 100644 index 0000000000..ad6f64f1da --- /dev/null +++ b/lib/symfony/validator/Constraints/IsFalse.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class IsFalse extends Constraint +{ + public const NOT_FALSE_ERROR = 'd53a91b0-def3-426a-83d7-269da7ab4200'; + + protected const ERROR_NAMES = [ + self::NOT_FALSE_ERROR => 'NOT_FALSE_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be false.'; + + public function __construct(?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options ?? [], $groups, $payload); + + $this->message = $message ?? $this->message; + } +} diff --git a/lib/symfony/validator/Constraints/IsFalseValidator.php b/lib/symfony/validator/Constraints/IsFalseValidator.php new file mode 100644 index 0000000000..76a24ad789 --- /dev/null +++ b/lib/symfony/validator/Constraints/IsFalseValidator.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Bernhard Schussek + */ +class IsFalseValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof IsFalse) { + throw new UnexpectedTypeException($constraint, IsFalse::class); + } + + if (null === $value || false === $value || 0 === $value || '0' === $value) { + return; + } + + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(IsFalse::NOT_FALSE_ERROR) + ->addViolation(); + } +} diff --git a/lib/symfony/validator/Constraints/IsNull.php b/lib/symfony/validator/Constraints/IsNull.php new file mode 100644 index 0000000000..11c05485e9 --- /dev/null +++ b/lib/symfony/validator/Constraints/IsNull.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class IsNull extends Constraint +{ + public const NOT_NULL_ERROR = '60d2f30b-8cfa-4372-b155-9656634de120'; + + protected const ERROR_NAMES = [ + self::NOT_NULL_ERROR => 'NOT_NULL_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be null.'; + + public function __construct(?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options ?? [], $groups, $payload); + + $this->message = $message ?? $this->message; + } +} diff --git a/lib/symfony/validator/Constraints/IsNullValidator.php b/lib/symfony/validator/Constraints/IsNullValidator.php new file mode 100644 index 0000000000..628aacf267 --- /dev/null +++ b/lib/symfony/validator/Constraints/IsNullValidator.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Bernhard Schussek + */ +class IsNullValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof IsNull) { + throw new UnexpectedTypeException($constraint, IsNull::class); + } + + if (null !== $value) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(IsNull::NOT_NULL_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/IsTrue.php b/lib/symfony/validator/Constraints/IsTrue.php new file mode 100644 index 0000000000..db2ac166f6 --- /dev/null +++ b/lib/symfony/validator/Constraints/IsTrue.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class IsTrue extends Constraint +{ + public const NOT_TRUE_ERROR = '2beabf1c-54c0-4882-a928-05249b26e23b'; + + protected const ERROR_NAMES = [ + self::NOT_TRUE_ERROR => 'NOT_TRUE_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be true.'; + + public function __construct(?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options ?? [], $groups, $payload); + + $this->message = $message ?? $this->message; + } +} diff --git a/lib/symfony/validator/Constraints/IsTrueValidator.php b/lib/symfony/validator/Constraints/IsTrueValidator.php new file mode 100644 index 0000000000..644bbf70cb --- /dev/null +++ b/lib/symfony/validator/Constraints/IsTrueValidator.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Bernhard Schussek + */ +class IsTrueValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof IsTrue) { + throw new UnexpectedTypeException($constraint, IsTrue::class); + } + + if (null === $value || true === $value || 1 === $value || '1' === $value) { + return; + } + + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(IsTrue::NOT_TRUE_ERROR) + ->addViolation(); + } +} diff --git a/lib/symfony/validator/Constraints/Isbn.php b/lib/symfony/validator/Constraints/Isbn.php new file mode 100644 index 0000000000..e27d6d9771 --- /dev/null +++ b/lib/symfony/validator/Constraints/Isbn.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author The Whole Life To Learn + * @author Manuel Reinhard + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Isbn extends Constraint +{ + public const ISBN_10 = 'isbn10'; + public const ISBN_13 = 'isbn13'; + + public const TOO_SHORT_ERROR = '949acbb0-8ef5-43ed-a0e9-032dfd08ae45'; + public const TOO_LONG_ERROR = '3171387d-f80a-47b3-bd6e-60598545316a'; + public const INVALID_CHARACTERS_ERROR = '23d21cea-da99-453d-98b1-a7d916fbb339'; + public const CHECKSUM_FAILED_ERROR = '2881c032-660f-46b6-8153-d352d9706640'; + public const TYPE_NOT_RECOGNIZED_ERROR = 'fa54a457-f042-441f-89c4-066ee5bdd3e1'; + + protected const ERROR_NAMES = [ + self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR', + self::TOO_LONG_ERROR => 'TOO_LONG_ERROR', + self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR', + self::CHECKSUM_FAILED_ERROR => 'CHECKSUM_FAILED_ERROR', + self::TYPE_NOT_RECOGNIZED_ERROR => 'TYPE_NOT_RECOGNIZED_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $isbn10Message = 'This value is not a valid ISBN-10.'; + public $isbn13Message = 'This value is not a valid ISBN-13.'; + public $bothIsbnMessage = 'This value is neither a valid ISBN-10 nor a valid ISBN-13.'; + public $type; + public $message; + + public function __construct( + string|array|null $type = null, + ?string $message = null, + ?string $isbn10Message = null, + ?string $isbn13Message = null, + ?string $bothIsbnMessage = null, + ?array $groups = null, + mixed $payload = null, + array $options = [], + ) { + if (\is_array($type)) { + $options = array_merge($type, $options); + } elseif (null !== $type) { + $options['value'] = $type; + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->isbn10Message = $isbn10Message ?? $this->isbn10Message; + $this->isbn13Message = $isbn13Message ?? $this->isbn13Message; + $this->bothIsbnMessage = $bothIsbnMessage ?? $this->bothIsbnMessage; + } + + public function getDefaultOption(): ?string + { + return 'type'; + } +} diff --git a/lib/symfony/validator/Constraints/IsbnValidator.php b/lib/symfony/validator/Constraints/IsbnValidator.php new file mode 100644 index 0000000000..26e9d4a211 --- /dev/null +++ b/lib/symfony/validator/Constraints/IsbnValidator.php @@ -0,0 +1,193 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * Validates whether the value is a valid ISBN-10 or ISBN-13. + * + * @author The Whole Life To Learn + * @author Manuel Reinhard + * @author Bernhard Schussek + * + * @see https://en.wikipedia.org/wiki/Isbn + */ +class IsbnValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Isbn) { + throw new UnexpectedTypeException($constraint, Isbn::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + $canonical = str_replace('-', '', $value); + + // Explicitly validate against ISBN-10 + if (Isbn::ISBN_10 === $constraint->type) { + if (true !== ($code = $this->validateIsbn10($canonical))) { + $this->context->buildViolation($this->getMessage($constraint, $constraint->type)) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode($code) + ->addViolation(); + } + + return; + } + + // Explicitly validate against ISBN-13 + if (Isbn::ISBN_13 === $constraint->type) { + if (true !== ($code = $this->validateIsbn13($canonical))) { + $this->context->buildViolation($this->getMessage($constraint, $constraint->type)) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode($code) + ->addViolation(); + } + + return; + } + + // Try both ISBNs + + // First, try ISBN-10 + $code = $this->validateIsbn10($canonical); + + // The ISBN can only be an ISBN-13 if the value was too long for ISBN-10 + if (Isbn::TOO_LONG_ERROR === $code) { + // Try ISBN-13 now + $code = $this->validateIsbn13($canonical); + + // If too short, this means we have 11 or 12 digits + if (Isbn::TOO_SHORT_ERROR === $code) { + $code = Isbn::TYPE_NOT_RECOGNIZED_ERROR; + } + } + + if (true !== $code) { + $this->context->buildViolation($this->getMessage($constraint)) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode($code) + ->addViolation(); + } + } + + /** + * @return string|bool + */ + protected function validateIsbn10(string $isbn) + { + // Choose an algorithm so that ERROR_INVALID_CHARACTERS is preferred + // over ERROR_TOO_SHORT/ERROR_TOO_LONG + // Otherwise "0-45122-5244" passes, but "0-45122_5244" reports + // "too long" + + // Error priority: + // 1. ERROR_INVALID_CHARACTERS + // 2. ERROR_TOO_SHORT/ERROR_TOO_LONG + // 3. ERROR_CHECKSUM_FAILED + + $checkSum = 0; + + for ($i = 0; $i < 10; ++$i) { + // If we test the length before the loop, we get an ERROR_TOO_SHORT + // when actually an ERROR_INVALID_CHARACTERS is wanted, e.g. for + // "0-45122_5244" (typo) + if (!isset($isbn[$i])) { + return Isbn::TOO_SHORT_ERROR; + } + + if ('X' === $isbn[$i]) { + $digit = 10; + } elseif (ctype_digit($isbn[$i])) { + $digit = $isbn[$i]; + } else { + return Isbn::INVALID_CHARACTERS_ERROR; + } + + $checkSum += $digit * (10 - $i); + } + + if (isset($isbn[$i])) { + return Isbn::TOO_LONG_ERROR; + } + + return 0 === $checkSum % 11 ? true : Isbn::CHECKSUM_FAILED_ERROR; + } + + /** + * @return string|bool + */ + protected function validateIsbn13(string $isbn) + { + // Error priority: + // 1. ERROR_INVALID_CHARACTERS + // 2. ERROR_TOO_SHORT/ERROR_TOO_LONG + // 3. ERROR_CHECKSUM_FAILED + + if (!ctype_digit($isbn)) { + return Isbn::INVALID_CHARACTERS_ERROR; + } + + $length = \strlen($isbn); + + if ($length < 13) { + return Isbn::TOO_SHORT_ERROR; + } + + if ($length > 13) { + return Isbn::TOO_LONG_ERROR; + } + + $checkSum = 0; + + for ($i = 0; $i < 13; $i += 2) { + $checkSum += $isbn[$i]; + } + + for ($i = 1; $i < 12; $i += 2) { + $checkSum += $isbn[$i] * 3; + } + + return 0 === $checkSum % 10 ? true : Isbn::CHECKSUM_FAILED_ERROR; + } + + /** + * @return string + */ + protected function getMessage(Isbn $constraint, ?string $type = null) + { + if (null !== $constraint->message) { + return $constraint->message; + } elseif (Isbn::ISBN_10 === $type) { + return $constraint->isbn10Message; + } elseif (Isbn::ISBN_13 === $type) { + return $constraint->isbn13Message; + } + + return $constraint->bothIsbnMessage; + } +} diff --git a/lib/symfony/validator/Constraints/Isin.php b/lib/symfony/validator/Constraints/Isin.php new file mode 100644 index 0000000000..19f964222e --- /dev/null +++ b/lib/symfony/validator/Constraints/Isin.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Laurent Masforné + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Isin extends Constraint +{ + public const VALIDATION_LENGTH = 12; + public const VALIDATION_PATTERN = '/[A-Z]{2}[A-Z0-9]{9}[0-9]{1}/'; + + public const INVALID_LENGTH_ERROR = '88738dfc-9ed5-ba1e-aebe-402a2a9bf58e'; + public const INVALID_PATTERN_ERROR = '3d08ce0-ded9-a93d-9216-17ac21265b65e'; + public const INVALID_CHECKSUM_ERROR = '32089b-0ee1-93ba-399e-aa232e62f2d29d'; + + protected const ERROR_NAMES = [ + self::INVALID_LENGTH_ERROR => 'INVALID_LENGTH_ERROR', + self::INVALID_PATTERN_ERROR => 'INVALID_PATTERN_ERROR', + self::INVALID_CHECKSUM_ERROR => 'INVALID_CHECKSUM_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value is not a valid International Securities Identification Number (ISIN).'; + + public function __construct(?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + } +} diff --git a/lib/symfony/validator/Constraints/IsinValidator.php b/lib/symfony/validator/Constraints/IsinValidator.php new file mode 100644 index 0000000000..21539cbcb7 --- /dev/null +++ b/lib/symfony/validator/Constraints/IsinValidator.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * @author Laurent Masforné + * + * @see https://en.wikipedia.org/wiki/International_Securities_Identification_Number + */ +class IsinValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Isin) { + throw new UnexpectedTypeException($constraint, Isin::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = strtoupper($value); + + if (Isin::VALIDATION_LENGTH !== \strlen($value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Isin::INVALID_LENGTH_ERROR) + ->addViolation(); + + return; + } + + if (!preg_match(Isin::VALIDATION_PATTERN, $value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Isin::INVALID_PATTERN_ERROR) + ->addViolation(); + + return; + } + + if (!$this->isCorrectChecksum($value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Isin::INVALID_CHECKSUM_ERROR) + ->addViolation(); + } + } + + private function isCorrectChecksum(string $input): bool + { + $characters = str_split($input); + foreach ($characters as $i => $char) { + $characters[$i] = \intval($char, 36); + } + $number = implode('', $characters); + + return 0 === $this->context->getValidator()->validate($number, new Luhn())->count(); + } +} diff --git a/lib/symfony/validator/Constraints/Issn.php b/lib/symfony/validator/Constraints/Issn.php new file mode 100644 index 0000000000..e2c45cb510 --- /dev/null +++ b/lib/symfony/validator/Constraints/Issn.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Antonio J. García Lagar + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Issn extends Constraint +{ + public const TOO_SHORT_ERROR = '6a20dd3d-f463-4460-8e7b-18a1b98abbfb'; + public const TOO_LONG_ERROR = '37cef893-5871-464e-8b12-7fb79324833c'; + public const MISSING_HYPHEN_ERROR = '2983286f-8134-4693-957a-1ec4ef887b15'; + public const INVALID_CHARACTERS_ERROR = 'a663d266-37c2-4ece-a914-ae891940c588'; + public const INVALID_CASE_ERROR = '7b6dd393-7523-4a6c-b84d-72b91bba5e1a'; + public const CHECKSUM_FAILED_ERROR = 'b0f92dbc-667c-48de-b526-ad9586d43e85'; + + protected const ERROR_NAMES = [ + self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR', + self::TOO_LONG_ERROR => 'TOO_LONG_ERROR', + self::MISSING_HYPHEN_ERROR => 'MISSING_HYPHEN_ERROR', + self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR', + self::INVALID_CASE_ERROR => 'INVALID_CASE_ERROR', + self::CHECKSUM_FAILED_ERROR => 'CHECKSUM_FAILED_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value is not a valid ISSN.'; + public $caseSensitive = false; + public $requireHyphen = false; + + public function __construct( + ?array $options = null, + ?string $message = null, + ?bool $caseSensitive = null, + ?bool $requireHyphen = null, + ?array $groups = null, + mixed $payload = null, + ) { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->caseSensitive = $caseSensitive ?? $this->caseSensitive; + $this->requireHyphen = $requireHyphen ?? $this->requireHyphen; + } +} diff --git a/lib/symfony/validator/Constraints/IssnValidator.php b/lib/symfony/validator/Constraints/IssnValidator.php new file mode 100644 index 0000000000..1962322b49 --- /dev/null +++ b/lib/symfony/validator/Constraints/IssnValidator.php @@ -0,0 +1,131 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * Validates whether the value is a valid ISSN. + * + * @author Antonio J. García Lagar + * @author Bernhard Schussek + * + * @see https://en.wikipedia.org/wiki/Issn + */ +class IssnValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Issn) { + throw new UnexpectedTypeException($constraint, Issn::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + $canonical = $value; + + // 1234-567X + // ^ + if (isset($canonical[4]) && '-' === $canonical[4]) { + // remove hyphen + $canonical = substr($canonical, 0, 4).substr($canonical, 5); + } elseif ($constraint->requireHyphen) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::MISSING_HYPHEN_ERROR) + ->addViolation(); + + return; + } + + $length = \strlen($canonical); + + if ($length < 8) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::TOO_SHORT_ERROR) + ->addViolation(); + + return; + } + + if ($length > 8) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::TOO_LONG_ERROR) + ->addViolation(); + + return; + } + + // 1234567X + // ^^^^^^^ digits only + if (!ctype_digit(substr($canonical, 0, 7))) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::INVALID_CHARACTERS_ERROR) + ->addViolation(); + + return; + } + + // 1234567X + // ^ digit, x or X + if (!ctype_digit($canonical[7]) && 'x' !== $canonical[7] && 'X' !== $canonical[7]) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::INVALID_CHARACTERS_ERROR) + ->addViolation(); + + return; + } + + // 1234567X + // ^ case-sensitive? + if ($constraint->caseSensitive && 'x' === $canonical[7]) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::INVALID_CASE_ERROR) + ->addViolation(); + + return; + } + + // Calculate a checksum. "X" equals 10. + $checkSum = 'X' === $canonical[7] || 'x' === $canonical[7] ? 10 : $canonical[7]; + + for ($i = 0; $i < 7; ++$i) { + // Multiply the first digit by 8, the second by 7, etc. + $checkSum += (8 - $i) * (int) $canonical[$i]; + } + + if (0 !== $checkSum % 11) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::CHECKSUM_FAILED_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Json.php b/lib/symfony/validator/Constraints/Json.php new file mode 100644 index 0000000000..05018e7a00 --- /dev/null +++ b/lib/symfony/validator/Constraints/Json.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Imad ZAIRIG + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Json extends Constraint +{ + public const INVALID_JSON_ERROR = '0789c8ad-2d2b-49a4-8356-e2ce63998504'; + + protected const ERROR_NAMES = [ + self::INVALID_JSON_ERROR => 'INVALID_JSON_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be valid JSON.'; + + public function __construct(?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + } +} diff --git a/lib/symfony/validator/Constraints/JsonValidator.php b/lib/symfony/validator/Constraints/JsonValidator.php new file mode 100644 index 0000000000..9134da9dd6 --- /dev/null +++ b/lib/symfony/validator/Constraints/JsonValidator.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * @author Imad ZAIRIG + */ +class JsonValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Json) { + throw new UnexpectedTypeException($constraint, Json::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + if (!json_validate($value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Json::INVALID_JSON_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Language.php b/lib/symfony/validator/Constraints/Language.php new file mode 100644 index 0000000000..b354144717 --- /dev/null +++ b/lib/symfony/validator/Constraints/Language.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Intl\Languages; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\LogicException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Language extends Constraint +{ + public const NO_SUCH_LANGUAGE_ERROR = 'ee65fec4-9a20-4202-9f39-ca558cd7bdf7'; + + protected const ERROR_NAMES = [ + self::NO_SUCH_LANGUAGE_ERROR => 'NO_SUCH_LANGUAGE_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value is not a valid language.'; + public $alpha3 = false; + + public function __construct( + ?array $options = null, + ?string $message = null, + ?bool $alpha3 = null, + ?array $groups = null, + mixed $payload = null, + ) { + if (!class_exists(Languages::class)) { + throw new LogicException('The Intl component is required to use the Language constraint. Try running "composer require symfony/intl".'); + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->alpha3 = $alpha3 ?? $this->alpha3; + } +} diff --git a/lib/symfony/validator/Constraints/LanguageValidator.php b/lib/symfony/validator/Constraints/LanguageValidator.php new file mode 100644 index 0000000000..4706c33569 --- /dev/null +++ b/lib/symfony/validator/Constraints/LanguageValidator.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Intl\Languages; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +/** + * Validates whether a value is a valid language code. + * + * @author Bernhard Schussek + */ +class LanguageValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Language) { + throw new UnexpectedTypeException($constraint, Language::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + if ($constraint->alpha3 ? !Languages::alpha3CodeExists($value) : !Languages::exists($value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Language::NO_SUCH_LANGUAGE_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Length.php b/lib/symfony/validator/Constraints/Length.php new file mode 100644 index 0000000000..93e797d302 --- /dev/null +++ b/lib/symfony/validator/Constraints/Length.php @@ -0,0 +1,122 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\InvalidArgumentException; +use Symfony\Component\Validator\Exception\MissingOptionsException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Length extends Constraint +{ + public const TOO_SHORT_ERROR = '9ff3fdc4-b214-49db-8718-39c315e33d45'; + public const TOO_LONG_ERROR = 'd94b19cc-114f-4f44-9cc4-4138e80a87b9'; + public const NOT_EQUAL_LENGTH_ERROR = '4b6f5c76-22b4-409d-af16-fbe823ba9332'; + public const INVALID_CHARACTERS_ERROR = '35e6a710-aa2e-4719-b58e-24b35749b767'; + + protected const ERROR_NAMES = [ + self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR', + self::TOO_LONG_ERROR => 'TOO_LONG_ERROR', + self::NOT_EQUAL_LENGTH_ERROR => 'NOT_EQUAL_LENGTH_ERROR', + self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR', + ]; + + public const COUNT_BYTES = 'bytes'; + public const COUNT_CODEPOINTS = 'codepoints'; + public const COUNT_GRAPHEMES = 'graphemes'; + + private const VALID_COUNT_UNITS = [ + self::COUNT_BYTES, + self::COUNT_CODEPOINTS, + self::COUNT_GRAPHEMES, + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $maxMessage = 'This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.'; + public $minMessage = 'This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.'; + public $exactMessage = 'This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.'; + public $charsetMessage = 'This value does not match the expected {{ charset }} charset.'; + public $max; + public $min; + public $charset = 'UTF-8'; + /** @var callable|null */ + public $normalizer; + /** @var self::COUNT_* */ + public string $countUnit = self::COUNT_CODEPOINTS; + + /** + * @param self::COUNT_*|null $countUnit + */ + public function __construct( + int|array|null $exactly = null, + ?int $min = null, + ?int $max = null, + ?string $charset = null, + ?callable $normalizer = null, + ?string $countUnit = null, + ?string $exactMessage = null, + ?string $minMessage = null, + ?string $maxMessage = null, + ?string $charsetMessage = null, + ?array $groups = null, + mixed $payload = null, + array $options = [], + ) { + if (\is_array($exactly)) { + $options = array_merge($exactly, $options); + $exactly = $options['value'] ?? null; + } + + $min ??= $options['min'] ?? null; + $max ??= $options['max'] ?? null; + + unset($options['value'], $options['min'], $options['max']); + + if (null !== $exactly && null === $min && null === $max) { + $min = $max = $exactly; + } + + parent::__construct($options, $groups, $payload); + + $this->min = $min; + $this->max = $max; + $this->charset = $charset ?? $this->charset; + $this->normalizer = $normalizer ?? $this->normalizer; + $this->countUnit = $countUnit ?? $this->countUnit; + $this->exactMessage = $exactMessage ?? $this->exactMessage; + $this->minMessage = $minMessage ?? $this->minMessage; + $this->maxMessage = $maxMessage ?? $this->maxMessage; + $this->charsetMessage = $charsetMessage ?? $this->charsetMessage; + + if (null === $this->min && null === $this->max) { + throw new MissingOptionsException(\sprintf('Either option "min" or "max" must be given for constraint "%s".', __CLASS__), ['min', 'max']); + } + + if (null !== $this->normalizer && !\is_callable($this->normalizer)) { + throw new InvalidArgumentException(\sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer))); + } + + if (!\in_array($this->countUnit, self::VALID_COUNT_UNITS)) { + throw new InvalidArgumentException(\sprintf('The "countUnit" option must be one of the "%s"::COUNT_* constants ("%s" given).', __CLASS__, $this->countUnit)); + } + } +} diff --git a/lib/symfony/validator/Constraints/LengthValidator.php b/lib/symfony/validator/Constraints/LengthValidator.php new file mode 100644 index 0000000000..c92fca0d59 --- /dev/null +++ b/lib/symfony/validator/Constraints/LengthValidator.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * @author Bernhard Schussek + */ +class LengthValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Length) { + throw new UnexpectedTypeException($constraint, Length::class); + } + + if (null === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $stringValue = (string) $value; + + if (null !== $constraint->normalizer) { + $stringValue = ($constraint->normalizer)($stringValue); + } + + try { + $invalidCharset = !@mb_check_encoding($stringValue, $constraint->charset); + } catch (\ValueError $e) { + if (!str_starts_with($e->getMessage(), 'mb_check_encoding(): Argument #2 ($encoding) must be a valid encoding')) { + throw $e; + } + + $invalidCharset = true; + } + + $length = $invalidCharset ? 0 : match ($constraint->countUnit) { + Length::COUNT_BYTES => \strlen($stringValue), + Length::COUNT_CODEPOINTS => mb_strlen($stringValue, $constraint->charset), + Length::COUNT_GRAPHEMES => grapheme_strlen($stringValue), + }; + + if ($invalidCharset || false === ($length ?? false)) { + $this->context->buildViolation($constraint->charsetMessage) + ->setParameter('{{ value }}', $this->formatValue($stringValue)) + ->setParameter('{{ charset }}', $constraint->charset) + ->setInvalidValue($value) + ->setCode(Length::INVALID_CHARACTERS_ERROR) + ->addViolation(); + + return; + } + + if (null !== $constraint->max && $length > $constraint->max) { + $exactlyOptionEnabled = $constraint->min == $constraint->max; + + $this->context->buildViolation($exactlyOptionEnabled ? $constraint->exactMessage : $constraint->maxMessage) + ->setParameter('{{ value }}', $this->formatValue($stringValue)) + ->setParameter('{{ limit }}', $constraint->max) + ->setParameter('{{ value_length }}', $length) + ->setInvalidValue($value) + ->setPlural((int) $constraint->max) + ->setCode($exactlyOptionEnabled ? Length::NOT_EQUAL_LENGTH_ERROR : Length::TOO_LONG_ERROR) + ->addViolation(); + + return; + } + + if (null !== $constraint->min && $length < $constraint->min) { + $exactlyOptionEnabled = $constraint->min == $constraint->max; + + $this->context->buildViolation($exactlyOptionEnabled ? $constraint->exactMessage : $constraint->minMessage) + ->setParameter('{{ value }}', $this->formatValue($stringValue)) + ->setParameter('{{ limit }}', $constraint->min) + ->setParameter('{{ value_length }}', $length) + ->setInvalidValue($value) + ->setPlural((int) $constraint->min) + ->setCode($exactlyOptionEnabled ? Length::NOT_EQUAL_LENGTH_ERROR : Length::TOO_SHORT_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/LessThan.php b/lib/symfony/validator/Constraints/LessThan.php new file mode 100644 index 0000000000..cf4144d6d2 --- /dev/null +++ b/lib/symfony/validator/Constraints/LessThan.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class LessThan extends AbstractComparison +{ + public const TOO_HIGH_ERROR = '079d7420-2d13-460c-8756-de810eeb37d2'; + + protected const ERROR_NAMES = [ + self::TOO_HIGH_ERROR => 'TOO_HIGH_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be less than {{ compared_value }}.'; +} diff --git a/lib/symfony/validator/Constraints/LessThanOrEqual.php b/lib/symfony/validator/Constraints/LessThanOrEqual.php new file mode 100644 index 0000000000..84e31abfc0 --- /dev/null +++ b/lib/symfony/validator/Constraints/LessThanOrEqual.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class LessThanOrEqual extends AbstractComparison +{ + public const TOO_HIGH_ERROR = '30fbb013-d015-4232-8b3b-8f3be97a7e14'; + + protected const ERROR_NAMES = [ + self::TOO_HIGH_ERROR => 'TOO_HIGH_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be less than or equal to {{ compared_value }}.'; +} diff --git a/lib/symfony/validator/Constraints/LessThanOrEqualValidator.php b/lib/symfony/validator/Constraints/LessThanOrEqualValidator.php new file mode 100644 index 0000000000..55b3b0a12b --- /dev/null +++ b/lib/symfony/validator/Constraints/LessThanOrEqualValidator.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * Validates values are less than or equal to the previous (<=). + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +class LessThanOrEqualValidator extends AbstractComparisonValidator +{ + protected function compareValues(mixed $value1, mixed $value2): bool + { + return null === $value2 || $value1 <= $value2; + } + + protected function getErrorCode(): ?string + { + return LessThanOrEqual::TOO_HIGH_ERROR; + } +} diff --git a/lib/symfony/validator/Constraints/LessThanValidator.php b/lib/symfony/validator/Constraints/LessThanValidator.php new file mode 100644 index 0000000000..b6cbae18bd --- /dev/null +++ b/lib/symfony/validator/Constraints/LessThanValidator.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * Validates values are less than the previous (<). + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +class LessThanValidator extends AbstractComparisonValidator +{ + protected function compareValues(mixed $value1, mixed $value2): bool + { + return null === $value2 || $value1 < $value2; + } + + protected function getErrorCode(): ?string + { + return LessThan::TOO_HIGH_ERROR; + } +} diff --git a/lib/symfony/validator/Constraints/Locale.php b/lib/symfony/validator/Constraints/Locale.php new file mode 100644 index 0000000000..9470f1ac8e --- /dev/null +++ b/lib/symfony/validator/Constraints/Locale.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Intl\Locales; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\LogicException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Locale extends Constraint +{ + public const NO_SUCH_LOCALE_ERROR = 'a0af4293-1f1a-4a1c-a328-979cba6182a2'; + + protected const ERROR_NAMES = [ + self::NO_SUCH_LOCALE_ERROR => 'NO_SUCH_LOCALE_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value is not a valid locale.'; + public $canonicalize = true; + + public function __construct( + ?array $options = null, + ?string $message = null, + ?bool $canonicalize = null, + ?array $groups = null, + mixed $payload = null, + ) { + if (!class_exists(Locales::class)) { + throw new LogicException('The Intl component is required to use the Locale constraint. Try running "composer require symfony/intl".'); + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->canonicalize = $canonicalize ?? $this->canonicalize; + } +} diff --git a/lib/symfony/validator/Constraints/LocaleValidator.php b/lib/symfony/validator/Constraints/LocaleValidator.php new file mode 100644 index 0000000000..11045ca95f --- /dev/null +++ b/lib/symfony/validator/Constraints/LocaleValidator.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Intl\Locales; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +/** + * Validates whether a value is a valid locale code. + * + * @author Bernhard Schussek + */ +class LocaleValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Locale) { + throw new UnexpectedTypeException($constraint, Locale::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $inputValue = (string) $value; + $value = $inputValue; + if ($constraint->canonicalize) { + $value = \Locale::canonicalize($value); + } + + if (null === $value || !Locales::exists($value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($inputValue)) + ->setCode(Locale::NO_SUCH_LOCALE_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Luhn.php b/lib/symfony/validator/Constraints/Luhn.php new file mode 100644 index 0000000000..3725c3bc52 --- /dev/null +++ b/lib/symfony/validator/Constraints/Luhn.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * Metadata for the LuhnValidator. + * + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Tim Nagel + * @author Greg Knapp http://gregk.me/2011/php-implementation-of-bank-card-luhn-algorithm/ + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Luhn extends Constraint +{ + public const INVALID_CHARACTERS_ERROR = 'dfad6d23-1b74-4374-929b-5cbb56fc0d9e'; + public const CHECKSUM_FAILED_ERROR = '4d760774-3f50-4cd5-a6d5-b10a3299d8d3'; + + protected const ERROR_NAMES = [ + self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR', + self::CHECKSUM_FAILED_ERROR => 'CHECKSUM_FAILED_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'Invalid card number.'; + + public function __construct( + ?array $options = null, + ?string $message = null, + ?array $groups = null, + mixed $payload = null, + ) { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + } +} diff --git a/lib/symfony/validator/Constraints/LuhnValidator.php b/lib/symfony/validator/Constraints/LuhnValidator.php new file mode 100644 index 0000000000..a3f871e339 --- /dev/null +++ b/lib/symfony/validator/Constraints/LuhnValidator.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * Validates a PAN using the LUHN Algorithm. + * + * For a list of example card numbers that are used to test this + * class, please see the LuhnValidatorTest class. + * + * @see http://en.wikipedia.org/wiki/Luhn_algorithm + * + * @author Tim Nagel + * @author Greg Knapp http://gregk.me/2011/php-implementation-of-bank-card-luhn-algorithm/ + * @author Bernhard Schussek + */ +class LuhnValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Luhn) { + throw new UnexpectedTypeException($constraint, Luhn::class); + } + + if (null === $value || '' === $value) { + return; + } + + // Work with strings only, because long numbers are represented as floats + // internally and don't work with strlen() + if (!\is_string($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + if (!ctype_digit($value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Luhn::INVALID_CHARACTERS_ERROR) + ->addViolation(); + + return; + } + + $checkSum = 0; + $length = \strlen($value); + + for ($i = $length - 1; $i >= 0; --$i) { + if (($i % 2) ^ ($length % 2)) { + // Starting with the last digit and walking left, add every second + // digit to the check sum + // e.g. 7 9 9 2 7 3 9 8 7 1 3 + // ^ ^ ^ ^ ^ ^ + // = 7 + 9 + 7 + 9 + 7 + 3 + $checkSum += (int) $value[$i]; + } else { + // Starting with the second last digit and walking left, double every + // second digit and add it to the check sum + // For doubles greater than 9, sum the individual digits + // e.g. 7 9 9 2 7 3 9 8 7 1 3 + // ^ ^ ^ ^ ^ + // = 1+8 + 4 + 6 + 1+6 + 2 + $checkSum += (((int) (2 * $value[$i] / 10)) + (2 * $value[$i]) % 10); + } + } + + if (0 === $checkSum || 0 !== $checkSum % 10) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Luhn::CHECKSUM_FAILED_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Negative.php b/lib/symfony/validator/Constraints/Negative.php new file mode 100644 index 0000000000..c13ebcb4a8 --- /dev/null +++ b/lib/symfony/validator/Constraints/Negative.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Jan Schädlich + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Negative extends LessThan +{ + use ZeroComparisonConstraintTrait; + + public $message = 'This value should be negative.'; +} diff --git a/lib/symfony/validator/Constraints/NegativeOrZero.php b/lib/symfony/validator/Constraints/NegativeOrZero.php new file mode 100644 index 0000000000..5be735c312 --- /dev/null +++ b/lib/symfony/validator/Constraints/NegativeOrZero.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Jan Schädlich + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class NegativeOrZero extends LessThanOrEqual +{ + use ZeroComparisonConstraintTrait; + + public $message = 'This value should be either negative or zero.'; +} diff --git a/lib/symfony/validator/Constraints/NoSuspiciousCharacters.php b/lib/symfony/validator/Constraints/NoSuspiciousCharacters.php new file mode 100644 index 0000000000..b64d26865b --- /dev/null +++ b/lib/symfony/validator/Constraints/NoSuspiciousCharacters.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\LogicException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Mathieu Lechat + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class NoSuspiciousCharacters extends Constraint +{ + public const RESTRICTION_LEVEL_ERROR = '1ece07dc-dca2-45f1-ba47-8d7dc3a12774'; + public const INVISIBLE_ERROR = '6ed60e6c-179b-4e93-8a6c-667d85c6de5e'; + public const MIXED_NUMBERS_ERROR = '9f01fc26-3bc4-44b1-a6b1-c08e2412053a'; + public const HIDDEN_OVERLAY_ERROR = '56380dc5-0476-4f04-bbaa-b68cd1c2d974'; + + protected const ERROR_NAMES = [ + self::RESTRICTION_LEVEL_ERROR => 'RESTRICTION_LEVEL_ERROR', + self::INVISIBLE_ERROR => 'INVISIBLE_ERROR', + self::MIXED_NUMBERS_ERROR => 'MIXED_NUMBERS_ERROR', + self::HIDDEN_OVERLAY_ERROR => 'INVALID_CASE_ERROR', + ]; + + /** + * Check a string for the presence of invisible characters such as zero-width spaces, + * or character sequences that are likely not to display such as multiple occurrences of the same non-spacing mark. + */ + public const CHECK_INVISIBLE = 32; + + /** + * Check that a string does not mix numbers from different numbering systems; + * for example “8” (Digit Eight) and “৪” (Bengali Digit Four). + */ + public const CHECK_MIXED_NUMBERS = 128; + + /** + * Check that a string does not have a combining character following a character in which it would be hidden; + * for example “i” (Latin Small Letter I) followed by a U+0307 (Combining Dot Above). + */ + public const CHECK_HIDDEN_OVERLAY = 256; + + /** @see https://unicode.org/reports/tr39/#ascii_only */ + public const RESTRICTION_LEVEL_ASCII = 268435456; + + /** @see https://unicode.org/reports/tr39/#single_script */ + public const RESTRICTION_LEVEL_SINGLE_SCRIPT = 536870912; + + /** @see https://unicode.org/reports/tr39/#highly_restrictive */ + public const RESTRICTION_LEVEL_HIGH = 805306368; + + /** @see https://unicode.org/reports/tr39/#moderately_restrictive */ + public const RESTRICTION_LEVEL_MODERATE = 1073741824; + + /** @see https://unicode.org/reports/tr39/#minimally_restrictive */ + public const RESTRICTION_LEVEL_MINIMAL = 1342177280; + + /** @see https://unicode.org/reports/tr39/#unrestricted */ + public const RESTRICTION_LEVEL_NONE = 1610612736; + + public string $restrictionLevelMessage = 'This value contains characters that are not allowed by the current restriction-level.'; + public string $invisibleMessage = 'Using invisible characters is not allowed.'; + public string $mixedNumbersMessage = 'Mixing numbers from different scripts is not allowed.'; + public string $hiddenOverlayMessage = 'Using hidden overlay characters is not allowed.'; + + public int $checks = self::CHECK_INVISIBLE | self::CHECK_MIXED_NUMBERS | self::CHECK_HIDDEN_OVERLAY; + public ?int $restrictionLevel = null; + public ?array $locales = null; + + /** + * @param int-mask-of|null $checks + * @param self::RESTRICTION_LEVEL_*|null $restrictionLevel + */ + public function __construct( + ?array $options = null, + ?string $restrictionLevelMessage = null, + ?string $invisibleMessage = null, + ?string $mixedNumbersMessage = null, + ?string $hiddenOverlayMessage = null, + ?int $checks = null, + ?int $restrictionLevel = null, + ?array $locales = null, + ?array $groups = null, + mixed $payload = null, + ) { + if (!class_exists(\Spoofchecker::class)) { + throw new LogicException('The intl extension is required to use the NoSuspiciousCharacters constraint.'); + } + + parent::__construct($options, $groups, $payload); + + $this->restrictionLevelMessage = $restrictionLevelMessage ?? $this->restrictionLevelMessage; + $this->invisibleMessage = $invisibleMessage ?? $this->invisibleMessage; + $this->mixedNumbersMessage = $mixedNumbersMessage ?? $this->mixedNumbersMessage; + $this->hiddenOverlayMessage = $hiddenOverlayMessage ?? $this->hiddenOverlayMessage; + $this->checks = $checks ?? $this->checks; + $this->restrictionLevel = $restrictionLevel ?? $this->restrictionLevel; + $this->locales = $locales ?? $this->locales; + } +} diff --git a/lib/symfony/validator/Constraints/NoSuspiciousCharactersValidator.php b/lib/symfony/validator/Constraints/NoSuspiciousCharactersValidator.php new file mode 100644 index 0000000000..659de93f9e --- /dev/null +++ b/lib/symfony/validator/Constraints/NoSuspiciousCharactersValidator.php @@ -0,0 +1,122 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\LogicException; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +/** + * @author Mathieu Lechat + */ +class NoSuspiciousCharactersValidator extends ConstraintValidator +{ + private const CHECK_RESTRICTION_LEVEL = 16; + private const CHECK_SINGLE_SCRIPT = 16; + private const CHECK_CHAR_LIMIT = 64; + + private const CHECK_ERROR = [ + self::CHECK_RESTRICTION_LEVEL => [ + 'code' => NoSuspiciousCharacters::RESTRICTION_LEVEL_ERROR, + 'messageProperty' => 'restrictionLevelMessage', + ], + NoSuspiciousCharacters::CHECK_INVISIBLE => [ + 'code' => NoSuspiciousCharacters::INVISIBLE_ERROR, + 'messageProperty' => 'invisibleMessage', + ], + self::CHECK_CHAR_LIMIT => [ + 'code' => NoSuspiciousCharacters::RESTRICTION_LEVEL_ERROR, + 'messageProperty' => 'restrictionLevelMessage', + ], + NoSuspiciousCharacters::CHECK_MIXED_NUMBERS => [ + 'code' => NoSuspiciousCharacters::MIXED_NUMBERS_ERROR, + 'messageProperty' => 'mixedNumbersMessage', + ], + NoSuspiciousCharacters::CHECK_HIDDEN_OVERLAY => [ + 'code' => NoSuspiciousCharacters::HIDDEN_OVERLAY_ERROR, + 'messageProperty' => 'hiddenOverlayMessage', + ], + ]; + + /** + * @param string[] $defaultLocales + */ + public function __construct(private readonly array $defaultLocales = []) + { + } + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof NoSuspiciousCharacters) { + throw new UnexpectedTypeException($constraint, NoSuspiciousCharacters::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + if ('' === $value = (string) $value) { + return; + } + + $checker = new \Spoofchecker(); + $checks = $constraint->checks; + + if (method_exists($checker, 'setRestrictionLevel')) { + $checks |= self::CHECK_RESTRICTION_LEVEL; + $checker->setRestrictionLevel($constraint->restrictionLevel ?? NoSuspiciousCharacters::RESTRICTION_LEVEL_MODERATE); + } elseif (NoSuspiciousCharacters::RESTRICTION_LEVEL_MINIMAL === $constraint->restrictionLevel) { + $checks |= self::CHECK_CHAR_LIMIT; + } elseif (NoSuspiciousCharacters::RESTRICTION_LEVEL_SINGLE_SCRIPT === $constraint->restrictionLevel) { + $checks |= self::CHECK_SINGLE_SCRIPT | self::CHECK_CHAR_LIMIT; + } elseif ($constraint->restrictionLevel) { + throw new LogicException('You can only use one of RESTRICTION_LEVEL_NONE, RESTRICTION_LEVEL_MINIMAL or RESTRICTION_LEVEL_SINGLE_SCRIPT with intl compiled against ICU < 58.'); + } else { + $checks |= self::CHECK_SINGLE_SCRIPT; + } + + $checker->setAllowedLocales(implode(',', $constraint->locales ?? $this->defaultLocales)); + + $checker->setChecks($checks); + + if (!$checker->isSuspicious($value)) { + return; + } + + foreach (self::CHECK_ERROR as $check => $error) { + if (!($checks & $check)) { + continue; + } + + $checker->setChecks($check); + + if (!$checker->isSuspicious($value)) { + continue; + } + + $this->context->buildViolation($constraint->{$error['messageProperty']}) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode($error['code']) + ->addViolation() + ; + } + } +} diff --git a/lib/symfony/validator/Constraints/NotBlank.php b/lib/symfony/validator/Constraints/NotBlank.php new file mode 100644 index 0000000000..17ada2770f --- /dev/null +++ b/lib/symfony/validator/Constraints/NotBlank.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\InvalidArgumentException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + * @author Kévin Dunglas + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class NotBlank extends Constraint +{ + public const IS_BLANK_ERROR = 'c1051bb4-d103-4f74-8988-acbcafc7fdc3'; + + protected const ERROR_NAMES = [ + self::IS_BLANK_ERROR => 'IS_BLANK_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should not be blank.'; + public $allowNull = false; + /** @var callable|null */ + public $normalizer; + + public function __construct(?array $options = null, ?string $message = null, ?bool $allowNull = null, ?callable $normalizer = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options ?? [], $groups, $payload); + + $this->message = $message ?? $this->message; + $this->allowNull = $allowNull ?? $this->allowNull; + $this->normalizer = $normalizer ?? $this->normalizer; + + if (null !== $this->normalizer && !\is_callable($this->normalizer)) { + throw new InvalidArgumentException(\sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer))); + } + } +} diff --git a/lib/symfony/validator/Constraints/NotBlankValidator.php b/lib/symfony/validator/Constraints/NotBlankValidator.php new file mode 100644 index 0000000000..fa6c794c02 --- /dev/null +++ b/lib/symfony/validator/Constraints/NotBlankValidator.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Bernhard Schussek + * @author Kévin Dunglas + */ +class NotBlankValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof NotBlank) { + throw new UnexpectedTypeException($constraint, NotBlank::class); + } + + if ($constraint->allowNull && null === $value) { + return; + } + + if (\is_string($value) && null !== $constraint->normalizer) { + $value = ($constraint->normalizer)($value); + } + + if (false === $value || (empty($value) && '0' != $value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(NotBlank::IS_BLANK_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/NotCompromisedPassword.php b/lib/symfony/validator/Constraints/NotCompromisedPassword.php new file mode 100644 index 0000000000..f5970a1787 --- /dev/null +++ b/lib/symfony/validator/Constraints/NotCompromisedPassword.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * Checks if a password has been leaked in a data breach. + * + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Kévin Dunglas + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class NotCompromisedPassword extends Constraint +{ + public const COMPROMISED_PASSWORD_ERROR = 'd9bcdbfe-a9d6-4bfa-a8ff-da5fd93e0f6d'; + + protected const ERROR_NAMES = [ + self::COMPROMISED_PASSWORD_ERROR => 'COMPROMISED_PASSWORD_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This password has been leaked in a data breach, it must not be used. Please use another password.'; + public $threshold = 1; + public $skipOnError = false; + + public function __construct( + ?array $options = null, + ?string $message = null, + ?int $threshold = null, + ?bool $skipOnError = null, + ?array $groups = null, + mixed $payload = null, + ) { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->threshold = $threshold ?? $this->threshold; + $this->skipOnError = $skipOnError ?? $this->skipOnError; + } +} diff --git a/lib/symfony/validator/Constraints/NotCompromisedPasswordValidator.php b/lib/symfony/validator/Constraints/NotCompromisedPasswordValidator.php new file mode 100644 index 0000000000..47a9942d83 --- /dev/null +++ b/lib/symfony/validator/Constraints/NotCompromisedPasswordValidator.php @@ -0,0 +1,110 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\HttpClient\HttpClient; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\LogicException; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; +use Symfony\Contracts\HttpClient\Exception\ExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * Checks if a password has been leaked in a data breach using haveibeenpwned.com's API. + * Use a k-anonymity model to protect the password being searched for. + * + * @see https://haveibeenpwned.com/API/v2#SearchingPwnedPasswordsByRange + * + * @author Kévin Dunglas + */ +class NotCompromisedPasswordValidator extends ConstraintValidator +{ + private const DEFAULT_API_ENDPOINT = 'https://api.pwnedpasswords.com/range/%s'; + + private HttpClientInterface $httpClient; + private string $charset; + private bool $enabled; + private string $endpoint; + + public function __construct(?HttpClientInterface $httpClient = null, string $charset = 'UTF-8', bool $enabled = true, ?string $endpoint = null) + { + if (null === $httpClient && !class_exists(HttpClient::class)) { + throw new LogicException(\sprintf('The "%s" class requires the "HttpClient" component. Try running "composer require symfony/http-client".', self::class)); + } + + $this->httpClient = $httpClient ?? HttpClient::create(); + $this->charset = $charset; + $this->enabled = $enabled; + $this->endpoint = $endpoint ?? self::DEFAULT_API_ENDPOINT; + } + + /** + * @return void + * + * @throws ExceptionInterface + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof NotCompromisedPassword) { + throw new UnexpectedTypeException($constraint, NotCompromisedPassword::class); + } + + if (!$this->enabled) { + return; + } + + if (null !== $value && !\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + if ('' === $value) { + return; + } + + if ('UTF-8' !== $this->charset) { + $value = mb_convert_encoding($value, 'UTF-8', $this->charset); + } + + $hash = strtoupper(sha1($value)); + $hashPrefix = substr($hash, 0, 5); + $url = \sprintf($this->endpoint, $hashPrefix); + + try { + $result = $this->httpClient->request('GET', $url, ['headers' => ['Add-Padding' => 'true']])->getContent(); + } catch (ExceptionInterface $e) { + if ($constraint->skipOnError) { + return; + } + + throw $e; + } + + foreach (explode("\r\n", $result) as $line) { + if (!str_contains($line, ':')) { + continue; + } + + [$hashSuffix, $count] = explode(':', $line); + + if ($hashPrefix.$hashSuffix === $hash && $constraint->threshold <= (int) $count) { + $this->context->buildViolation($constraint->message) + ->setCode(NotCompromisedPassword::COMPROMISED_PASSWORD_ERROR) + ->addViolation(); + + return; + } + } + } +} diff --git a/lib/symfony/validator/Constraints/NotEqualTo.php b/lib/symfony/validator/Constraints/NotEqualTo.php new file mode 100644 index 0000000000..9a5c07b21e --- /dev/null +++ b/lib/symfony/validator/Constraints/NotEqualTo.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class NotEqualTo extends AbstractComparison +{ + public const IS_EQUAL_ERROR = 'aa2e33da-25c8-4d76-8c6c-812f02ea89dd'; + + protected const ERROR_NAMES = [ + self::IS_EQUAL_ERROR => 'IS_EQUAL_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should not be equal to {{ compared_value }}.'; +} diff --git a/lib/symfony/validator/Constraints/NotEqualToValidator.php b/lib/symfony/validator/Constraints/NotEqualToValidator.php new file mode 100644 index 0000000000..9b5413a598 --- /dev/null +++ b/lib/symfony/validator/Constraints/NotEqualToValidator.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * Validates values are all unequal (!=). + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +class NotEqualToValidator extends AbstractComparisonValidator +{ + protected function compareValues(mixed $value1, mixed $value2): bool + { + return $value1 != $value2; + } + + protected function getErrorCode(): ?string + { + return NotEqualTo::IS_EQUAL_ERROR; + } +} diff --git a/lib/symfony/validator/Constraints/NotIdenticalTo.php b/lib/symfony/validator/Constraints/NotIdenticalTo.php new file mode 100644 index 0000000000..206c106137 --- /dev/null +++ b/lib/symfony/validator/Constraints/NotIdenticalTo.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class NotIdenticalTo extends AbstractComparison +{ + public const IS_IDENTICAL_ERROR = '4aaac518-0dda-4129-a6d9-e216b9b454a0'; + + protected const ERROR_NAMES = [ + self::IS_IDENTICAL_ERROR => 'IS_IDENTICAL_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should not be identical to {{ compared_value_type }} {{ compared_value }}.'; +} diff --git a/lib/symfony/validator/Constraints/NotIdenticalToValidator.php b/lib/symfony/validator/Constraints/NotIdenticalToValidator.php new file mode 100644 index 0000000000..ef7d2f43a5 --- /dev/null +++ b/lib/symfony/validator/Constraints/NotIdenticalToValidator.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * Validates values aren't identical (!==). + * + * @author Daniel Holmes + * @author Bernhard Schussek + */ +class NotIdenticalToValidator extends AbstractComparisonValidator +{ + protected function compareValues(mixed $value1, mixed $value2): bool + { + return $value1 !== $value2; + } + + protected function getErrorCode(): ?string + { + return NotIdenticalTo::IS_IDENTICAL_ERROR; + } +} diff --git a/lib/symfony/validator/Constraints/NotNull.php b/lib/symfony/validator/Constraints/NotNull.php new file mode 100644 index 0000000000..b8523466c7 --- /dev/null +++ b/lib/symfony/validator/Constraints/NotNull.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class NotNull extends Constraint +{ + public const IS_NULL_ERROR = 'ad32d13f-c3d4-423b-909a-857b961eb720'; + + protected const ERROR_NAMES = [ + self::IS_NULL_ERROR => 'IS_NULL_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should not be null.'; + + public function __construct(?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options ?? [], $groups, $payload); + + $this->message = $message ?? $this->message; + } +} diff --git a/lib/symfony/validator/Constraints/NotNullValidator.php b/lib/symfony/validator/Constraints/NotNullValidator.php new file mode 100644 index 0000000000..3f8f951280 --- /dev/null +++ b/lib/symfony/validator/Constraints/NotNullValidator.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Bernhard Schussek + */ +class NotNullValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof NotNull) { + throw new UnexpectedTypeException($constraint, NotNull::class); + } + + if (null === $value) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(NotNull::IS_NULL_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Optional.php b/lib/symfony/validator/Constraints/Optional.php new file mode 100644 index 0000000000..dab8b4371f --- /dev/null +++ b/lib/symfony/validator/Constraints/Optional.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"ANNOTATION"}) + * + * @author Bernhard Schussek + */ +class Optional extends Existence +{ +} diff --git a/lib/symfony/validator/Constraints/PasswordStrength.php b/lib/symfony/validator/Constraints/PasswordStrength.php new file mode 100644 index 0000000000..090d50d672 --- /dev/null +++ b/lib/symfony/validator/Constraints/PasswordStrength.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Florent Morselli + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +final class PasswordStrength extends Constraint +{ + public const STRENGTH_VERY_WEAK = 0; + public const STRENGTH_WEAK = 1; + public const STRENGTH_MEDIUM = 2; + public const STRENGTH_STRONG = 3; + public const STRENGTH_VERY_STRONG = 4; + + public const PASSWORD_STRENGTH_ERROR = '4234df00-45dd-49a4-b303-a75dbf8b10d8'; + + protected const ERROR_NAMES = [ + self::PASSWORD_STRENGTH_ERROR => 'PASSWORD_STRENGTH_ERROR', + ]; + + public string $message = 'The password strength is too low. Please use a stronger password.'; + + public int $minScore; + + public function __construct(?array $options = null, ?int $minScore = null, ?array $groups = null, mixed $payload = null, ?string $message = null) + { + $options['minScore'] ??= self::STRENGTH_MEDIUM; + + parent::__construct($options, $groups, $payload); + + $this->minScore = $minScore ?? $this->minScore; + $this->message = $message ?? $this->message; + + if ($this->minScore < 1 || 4 < $this->minScore) { + throw new ConstraintDefinitionException(\sprintf('The parameter "minScore" of the "%s" constraint must be an integer between 1 and 4.', self::class)); + } + } +} diff --git a/lib/symfony/validator/Constraints/PasswordStrengthValidator.php b/lib/symfony/validator/Constraints/PasswordStrengthValidator.php new file mode 100644 index 0000000000..c3d2b7d76a --- /dev/null +++ b/lib/symfony/validator/Constraints/PasswordStrengthValidator.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +final class PasswordStrengthValidator extends ConstraintValidator +{ + /** + * @param (\Closure(string):PasswordStrength::STRENGTH_*)|null $passwordStrengthEstimator + */ + public function __construct( + private readonly ?\Closure $passwordStrengthEstimator = null, + ) { + } + + public function validate(#[\SensitiveParameter] mixed $value, Constraint $constraint): void + { + if (!$constraint instanceof PasswordStrength) { + throw new UnexpectedTypeException($constraint, PasswordStrength::class); + } + + if (null === $value) { + return; + } + + if (!\is_string($value)) { + throw new UnexpectedValueException($value, 'string'); + } + $passwordStrengthEstimator = $this->passwordStrengthEstimator ?? self::estimateStrength(...); + $strength = $passwordStrengthEstimator($value); + + if ($strength < $constraint->minScore) { + $this->context->buildViolation($constraint->message) + ->setCode(PasswordStrength::PASSWORD_STRENGTH_ERROR) + ->addViolation(); + } + } + + /** + * Returns the estimated strength of a password. + * + * The higher the value, the stronger the password. + * + * @return PasswordStrength::STRENGTH_* + */ + private static function estimateStrength(#[\SensitiveParameter] string $password): int + { + if (!$length = \strlen($password)) { + return PasswordStrength::STRENGTH_VERY_WEAK; + } + $password = count_chars($password, 1); + $chars = \count($password); + + $control = $digit = $upper = $lower = $symbol = $other = 0; + foreach ($password as $chr => $count) { + match (true) { + $chr < 32 || 127 === $chr => $control = 33, + 48 <= $chr && $chr <= 57 => $digit = 10, + 65 <= $chr && $chr <= 90 => $upper = 26, + 97 <= $chr && $chr <= 122 => $lower = 26, + 128 <= $chr => $other = 128, + default => $symbol = 33, + }; + } + + $pool = $lower + $upper + $digit + $symbol + $control + $other; + $entropy = $chars * log($pool, 2) + ($length - $chars) * log($chars, 2); + + return match (true) { + $entropy >= 120 => PasswordStrength::STRENGTH_VERY_STRONG, + $entropy >= 100 => PasswordStrength::STRENGTH_STRONG, + $entropy >= 80 => PasswordStrength::STRENGTH_MEDIUM, + $entropy >= 60 => PasswordStrength::STRENGTH_WEAK, + default => PasswordStrength::STRENGTH_VERY_WEAK, + }; + } +} diff --git a/lib/symfony/validator/Constraints/Positive.php b/lib/symfony/validator/Constraints/Positive.php new file mode 100644 index 0000000000..951e944c9a --- /dev/null +++ b/lib/symfony/validator/Constraints/Positive.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Jan Schädlich + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Positive extends GreaterThan +{ + use ZeroComparisonConstraintTrait; + + public $message = 'This value should be positive.'; +} diff --git a/lib/symfony/validator/Constraints/PositiveOrZero.php b/lib/symfony/validator/Constraints/PositiveOrZero.php new file mode 100644 index 0000000000..a7669c6107 --- /dev/null +++ b/lib/symfony/validator/Constraints/PositiveOrZero.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Jan Schädlich + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class PositiveOrZero extends GreaterThanOrEqual +{ + use ZeroComparisonConstraintTrait; + + public $message = 'This value should be either positive or zero.'; +} diff --git a/lib/symfony/validator/Constraints/Range.php b/lib/symfony/validator/Constraints/Range.php new file mode 100644 index 0000000000..48dc39487f --- /dev/null +++ b/lib/symfony/validator/Constraints/Range.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\LogicException; +use Symfony\Component\Validator\Exception\MissingOptionsException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Range extends Constraint +{ + public const INVALID_CHARACTERS_ERROR = 'ad9a9798-7a99-4df7-8ce9-46e416a1e60b'; + public const NOT_IN_RANGE_ERROR = '04b91c99-a946-4221-afc5-e65ebac401eb'; + public const TOO_HIGH_ERROR = '2d28afcb-e32e-45fb-a815-01c431a86a69'; + public const TOO_LOW_ERROR = '76454e69-502c-46c5-9643-f447d837c4d5'; + + protected const ERROR_NAMES = [ + self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR', + self::NOT_IN_RANGE_ERROR => 'NOT_IN_RANGE_ERROR', + self::TOO_HIGH_ERROR => 'TOO_HIGH_ERROR', + self::TOO_LOW_ERROR => 'TOO_LOW_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $notInRangeMessage = 'This value should be between {{ min }} and {{ max }}.'; + public $minMessage = 'This value should be {{ limit }} or more.'; + public $maxMessage = 'This value should be {{ limit }} or less.'; + public $invalidMessage = 'This value should be a valid number.'; + public $invalidDateTimeMessage = 'This value is not a valid datetime.'; + public $min; + public $minPropertyPath; + public $max; + public $maxPropertyPath; + + public function __construct( + ?array $options = null, + ?string $notInRangeMessage = null, + ?string $minMessage = null, + ?string $maxMessage = null, + ?string $invalidMessage = null, + ?string $invalidDateTimeMessage = null, + mixed $min = null, + ?string $minPropertyPath = null, + mixed $max = null, + ?string $maxPropertyPath = null, + ?array $groups = null, + mixed $payload = null, + ) { + parent::__construct($options, $groups, $payload); + + $this->notInRangeMessage = $notInRangeMessage ?? $this->notInRangeMessage; + $this->minMessage = $minMessage ?? $this->minMessage; + $this->maxMessage = $maxMessage ?? $this->maxMessage; + $this->invalidMessage = $invalidMessage ?? $this->invalidMessage; + $this->invalidDateTimeMessage = $invalidDateTimeMessage ?? $this->invalidDateTimeMessage; + $this->min = $min ?? $this->min; + $this->minPropertyPath = $minPropertyPath ?? $this->minPropertyPath; + $this->max = $max ?? $this->max; + $this->maxPropertyPath = $maxPropertyPath ?? $this->maxPropertyPath; + + if (null === $this->min && null === $this->minPropertyPath && null === $this->max && null === $this->maxPropertyPath) { + throw new MissingOptionsException(\sprintf('Either option "min", "minPropertyPath", "max" or "maxPropertyPath" must be given for constraint "%s".', __CLASS__), ['min', 'minPropertyPath', 'max', 'maxPropertyPath']); + } + + if (null !== $this->min && null !== $this->minPropertyPath) { + throw new ConstraintDefinitionException(\sprintf('The "%s" constraint requires only one of the "min" or "minPropertyPath" options to be set, not both.', static::class)); + } + + if (null !== $this->max && null !== $this->maxPropertyPath) { + throw new ConstraintDefinitionException(\sprintf('The "%s" constraint requires only one of the "max" or "maxPropertyPath" options to be set, not both.', static::class)); + } + + if ((null !== $this->minPropertyPath || null !== $this->maxPropertyPath) && !class_exists(PropertyAccess::class)) { + throw new LogicException(\sprintf('The "%s" constraint requires the Symfony PropertyAccess component to use the "minPropertyPath" or "maxPropertyPath" option. Try running "composer require symfony/property-access".', static::class)); + } + + if (null !== $this->min && null !== $this->max && ($minMessage || $maxMessage || isset($options['minMessage']) || isset($options['maxMessage']))) { + throw new ConstraintDefinitionException(\sprintf('The "%s" constraint can not use "minMessage" and "maxMessage" when the "min" and "max" options are both set. Use "notInRangeMessage" instead.', static::class)); + } + } +} diff --git a/lib/symfony/validator/Constraints/RangeValidator.php b/lib/symfony/validator/Constraints/RangeValidator.php new file mode 100644 index 0000000000..cc1109c364 --- /dev/null +++ b/lib/symfony/validator/Constraints/RangeValidator.php @@ -0,0 +1,194 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException; +use Symfony\Component\PropertyAccess\Exception\UninitializedPropertyException; +use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\PropertyAccess\PropertyAccessorInterface; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Bernhard Schussek + */ +class RangeValidator extends ConstraintValidator +{ + private ?PropertyAccessorInterface $propertyAccessor; + + public function __construct(?PropertyAccessorInterface $propertyAccessor = null) + { + $this->propertyAccessor = $propertyAccessor; + } + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Range) { + throw new UnexpectedTypeException($constraint, Range::class); + } + + if (null === $value) { + return; + } + + $min = $this->getLimit($constraint->minPropertyPath, $constraint->min, $constraint); + $max = $this->getLimit($constraint->maxPropertyPath, $constraint->max, $constraint); + + if (!is_numeric($value) && !$value instanceof \DateTimeInterface) { + if ($this->isParsableDatetimeString($min) && $this->isParsableDatetimeString($max)) { + $this->context->buildViolation($constraint->invalidDateTimeMessage) + ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) + ->setCode(Range::INVALID_CHARACTERS_ERROR) + ->addViolation(); + } else { + $this->context->buildViolation($constraint->invalidMessage) + ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) + ->setCode(Range::INVALID_CHARACTERS_ERROR) + ->addViolation(); + } + + return; + } + + // Convert strings to DateTimes if comparing another DateTime + // This allows to compare with any date/time value supported by + // the DateTime constructor: + // https://php.net/datetime.formats + if ($value instanceof \DateTimeInterface) { + if (\is_string($min)) { + try { + $min = new $value($min); + } catch (\Exception) { + throw new ConstraintDefinitionException(\sprintf('The min value "%s" could not be converted to a "%s" instance in the "%s" constraint.', $min, get_debug_type($value), get_debug_type($constraint))); + } + } + + if (\is_string($max)) { + try { + $max = new $value($max); + } catch (\Exception) { + throw new ConstraintDefinitionException(\sprintf('The max value "%s" could not be converted to a "%s" instance in the "%s" constraint.', $max, get_debug_type($value), get_debug_type($constraint))); + } + } + } + + $hasLowerLimit = null !== $min; + $hasUpperLimit = null !== $max; + + if ($hasLowerLimit && $hasUpperLimit && ($value < $min || $value > $max)) { + $message = $constraint->notInRangeMessage; + $code = Range::NOT_IN_RANGE_ERROR; + + $violationBuilder = $this->context->buildViolation($message) + ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) + ->setParameter('{{ min }}', $this->formatValue($min, self::PRETTY_DATE)) + ->setParameter('{{ max }}', $this->formatValue($max, self::PRETTY_DATE)) + ->setCode($code); + + if (null !== $constraint->maxPropertyPath) { + $violationBuilder->setParameter('{{ max_limit_path }}', $constraint->maxPropertyPath); + } + + if (null !== $constraint->minPropertyPath) { + $violationBuilder->setParameter('{{ min_limit_path }}', $constraint->minPropertyPath); + } + + $violationBuilder->addViolation(); + + return; + } + + if ($hasUpperLimit && $value > $max) { + $violationBuilder = $this->context->buildViolation($constraint->maxMessage) + ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) + ->setParameter('{{ limit }}', $this->formatValue($max, self::PRETTY_DATE)) + ->setCode(Range::TOO_HIGH_ERROR); + + if (null !== $constraint->maxPropertyPath) { + $violationBuilder->setParameter('{{ max_limit_path }}', $constraint->maxPropertyPath); + } + + if (null !== $constraint->minPropertyPath) { + $violationBuilder->setParameter('{{ min_limit_path }}', $constraint->minPropertyPath); + } + + $violationBuilder->addViolation(); + + return; + } + + if ($hasLowerLimit && $value < $min) { + $violationBuilder = $this->context->buildViolation($constraint->minMessage) + ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) + ->setParameter('{{ limit }}', $this->formatValue($min, self::PRETTY_DATE)) + ->setCode(Range::TOO_LOW_ERROR); + + if (null !== $constraint->maxPropertyPath) { + $violationBuilder->setParameter('{{ max_limit_path }}', $constraint->maxPropertyPath); + } + + if (null !== $constraint->minPropertyPath) { + $violationBuilder->setParameter('{{ min_limit_path }}', $constraint->minPropertyPath); + } + + $violationBuilder->addViolation(); + } + } + + private function getLimit(?string $propertyPath, mixed $default, Constraint $constraint): mixed + { + if (null === $propertyPath) { + return $default; + } + + if (null === $object = $this->context->getObject()) { + return $default; + } + + try { + return $this->getPropertyAccessor()->getValue($object, $propertyPath); + } catch (NoSuchPropertyException $e) { + throw new ConstraintDefinitionException(\sprintf('Invalid property path "%s" provided to "%s" constraint: ', $propertyPath, get_debug_type($constraint)).$e->getMessage(), 0, $e); + } catch (UninitializedPropertyException) { + return null; + } + } + + private function getPropertyAccessor(): PropertyAccessorInterface + { + return $this->propertyAccessor ??= PropertyAccess::createPropertyAccessor(); + } + + private function isParsableDatetimeString(mixed $boundary): bool + { + if (null === $boundary) { + return true; + } + + if (!\is_string($boundary)) { + return false; + } + + try { + new \DateTimeImmutable($boundary); + } catch (\Exception) { + return false; + } + + return true; + } +} diff --git a/lib/symfony/validator/Constraints/Regex.php b/lib/symfony/validator/Constraints/Regex.php new file mode 100644 index 0000000000..006e5c5073 --- /dev/null +++ b/lib/symfony/validator/Constraints/Regex.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\InvalidArgumentException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Regex extends Constraint +{ + public const REGEX_FAILED_ERROR = 'de1e3db3-5ed4-4941-aae4-59f3667cc3a3'; + + protected const ERROR_NAMES = [ + self::REGEX_FAILED_ERROR => 'REGEX_FAILED_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value is not valid.'; + public $pattern; + public $htmlPattern; + public $match = true; + /** @var callable|null */ + public $normalizer; + + public function __construct( + string|array|null $pattern, + ?string $message = null, + ?string $htmlPattern = null, + ?bool $match = null, + ?callable $normalizer = null, + ?array $groups = null, + mixed $payload = null, + array $options = [], + ) { + if (\is_array($pattern)) { + $options = array_merge($pattern, $options); + } elseif (null !== $pattern) { + $options['value'] = $pattern; + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->htmlPattern = $htmlPattern ?? $this->htmlPattern; + $this->match = $match ?? $this->match; + $this->normalizer = $normalizer ?? $this->normalizer; + + if (null !== $this->normalizer && !\is_callable($this->normalizer)) { + throw new InvalidArgumentException(\sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer))); + } + } + + public function getDefaultOption(): ?string + { + return 'pattern'; + } + + public function getRequiredOptions(): array + { + return ['pattern']; + } + + /** + * Converts the htmlPattern to a suitable format for HTML5 pattern. + * Example: /^[a-z]+$/ would be converted to [a-z]+ + * However, if options are specified, it cannot be converted. + * + * @see http://dev.w3.org/html5/spec/single-page.html#the-pattern-attribute + */ + public function getHtmlPattern(): ?string + { + // If htmlPattern is specified, use it + if (null !== $this->htmlPattern) { + return empty($this->htmlPattern) + ? null + : $this->htmlPattern; + } + + // Quit if delimiters not at very beginning/end (e.g. when options are passed) + if ($this->pattern[0] !== $this->pattern[\strlen($this->pattern) - 1]) { + return null; + } + + $delimiter = $this->pattern[0]; + + // Unescape the delimiter + $pattern = str_replace('\\'.$delimiter, $delimiter, substr($this->pattern, 1, -1)); + + // If the pattern is inverted, we can wrap it in + // ((?!pattern).)* + if (!$this->match) { + return '((?!'.$pattern.').)*'; + } + + // If the pattern contains an or statement, wrap the pattern in + // .*(pattern).* and quit. Otherwise we'd need to parse the pattern + if (str_contains($pattern, '|')) { + return '.*('.$pattern.').*'; + } + + // Trim leading ^, otherwise prepend .* + $pattern = '^' === $pattern[0] ? substr($pattern, 1) : '.*'.$pattern; + + // Trim trailing $, otherwise append .* + $pattern = '$' === $pattern[\strlen($pattern) - 1] ? substr($pattern, 0, -1) : $pattern.'.*'; + + return $pattern; + } +} diff --git a/lib/symfony/validator/Constraints/RegexValidator.php b/lib/symfony/validator/Constraints/RegexValidator.php new file mode 100644 index 0000000000..4e9ae9039f --- /dev/null +++ b/lib/symfony/validator/Constraints/RegexValidator.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * Validates whether a value match or not given regexp pattern. + * + * @author Bernhard Schussek + * @author Joseph Bielawski + */ +class RegexValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Regex) { + throw new UnexpectedTypeException($constraint, Regex::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + if (null !== $constraint->normalizer) { + $value = ($constraint->normalizer)($value); + } + + if ($constraint->match xor preg_match($constraint->pattern, $value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setParameter('{{ pattern }}', $constraint->pattern) + ->setCode(Regex::REGEX_FAILED_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Required.php b/lib/symfony/validator/Constraints/Required.php new file mode 100644 index 0000000000..bd77a909f9 --- /dev/null +++ b/lib/symfony/validator/Constraints/Required.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * @Annotation + * @Target({"ANNOTATION"}) + * + * @author Bernhard Schussek + */ +class Required extends Existence +{ +} diff --git a/lib/symfony/validator/Constraints/Sequentially.php b/lib/symfony/validator/Constraints/Sequentially.php new file mode 100644 index 0000000000..79901f4806 --- /dev/null +++ b/lib/symfony/validator/Constraints/Sequentially.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +/** + * Use this constraint to sequentially validate nested constraints. + * Validation for the nested constraints collection will stop at first violation. + * + * @Annotation + * @Target({"CLASS", "PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Maxime Steinhausser + */ +#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Sequentially extends Composite +{ + public $constraints = []; + + public function __construct(mixed $constraints = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($constraints ?? [], $groups, $payload); + } + + public function getDefaultOption(): ?string + { + return 'constraints'; + } + + public function getRequiredOptions(): array + { + return ['constraints']; + } + + protected function getCompositeOption(): string + { + return 'constraints'; + } + + public function getTargets(): string|array + { + return [self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT]; + } +} diff --git a/lib/symfony/validator/Constraints/SequentiallyValidator.php b/lib/symfony/validator/Constraints/SequentiallyValidator.php new file mode 100644 index 0000000000..d076f3cfdd --- /dev/null +++ b/lib/symfony/validator/Constraints/SequentiallyValidator.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Maxime Steinhausser + */ +class SequentiallyValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Sequentially) { + throw new UnexpectedTypeException($constraint, Sequentially::class); + } + + $context = $this->context; + + $validator = $context->getValidator()->inContext($context); + + $originalCount = $validator->getViolations()->count(); + + foreach ($constraint->constraints as $c) { + if ($originalCount !== $validator->validate($value, $c)->getViolations()->count()) { + break; + } + } + } +} diff --git a/lib/symfony/validator/Constraints/Time.php b/lib/symfony/validator/Constraints/Time.php new file mode 100644 index 0000000000..b3adbfd9e4 --- /dev/null +++ b/lib/symfony/validator/Constraints/Time.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Time extends Constraint +{ + public const INVALID_FORMAT_ERROR = '9d27b2bb-f755-4fbf-b725-39b1edbdebdf'; + public const INVALID_TIME_ERROR = '8532f9e1-84b2-4d67-8989-0818bc38533b'; + + protected const ERROR_NAMES = [ + self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR', + self::INVALID_TIME_ERROR => 'INVALID_TIME_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $withSeconds = true; + public $message = 'This value is not a valid time.'; + + public function __construct( + ?array $options = null, + ?string $message = null, + ?array $groups = null, + mixed $payload = null, + ?bool $withSeconds = null, + ) { + parent::__construct($options, $groups, $payload); + + $this->withSeconds = $withSeconds ?? $this->withSeconds; + $this->message = $message ?? $this->message; + } +} diff --git a/lib/symfony/validator/Constraints/TimeValidator.php b/lib/symfony/validator/Constraints/TimeValidator.php new file mode 100644 index 0000000000..ef422cdf5a --- /dev/null +++ b/lib/symfony/validator/Constraints/TimeValidator.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * @author Bernhard Schussek + */ +class TimeValidator extends ConstraintValidator +{ + public const PATTERN = '/^(\d{2}):(\d{2}):(\d{2})$/D'; + public const PATTERN_WITHOUT_SECONDS = '/^(\d{2}):(\d{2})$/D'; + + /** + * Checks whether a time is valid. + * + * @internal + */ + public static function checkTime(int $hour, int $minute, float $second): bool + { + return $hour >= 0 && $hour < 24 && $minute >= 0 && $minute < 60 && $second >= 0 && $second < 60; + } + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Time) { + throw new UnexpectedTypeException($constraint, Time::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + if (!preg_match($constraint->withSeconds ? static::PATTERN : static::PATTERN_WITHOUT_SECONDS, $value, $matches)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Time::INVALID_FORMAT_ERROR) + ->addViolation(); + + return; + } + + if (!self::checkTime($matches[1], $matches[2], $constraint->withSeconds ? $matches[3] : 0)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Time::INVALID_TIME_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Timezone.php b/lib/symfony/validator/Constraints/Timezone.php new file mode 100644 index 0000000000..17d740a49e --- /dev/null +++ b/lib/symfony/validator/Constraints/Timezone.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Javier Spagnoletti + * @author Hugo Hamon + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Timezone extends Constraint +{ + public const TIMEZONE_IDENTIFIER_ERROR = '5ce113e6-5e64-4ea2-90fe-d2233956db13'; + public const TIMEZONE_IDENTIFIER_IN_ZONE_ERROR = 'b57767b1-36c0-40ac-a3d7-629420c775b8'; + public const TIMEZONE_IDENTIFIER_IN_COUNTRY_ERROR = 'c4a22222-dc92-4fc0-abb0-d95b268c7d0b'; + public const TIMEZONE_IDENTIFIER_INTL_ERROR = '45863c26-88dc-41ba-bf53-c73bd1f7e90d'; + + public $zone = \DateTimeZone::ALL; + public $countryCode; + public $intlCompatible = false; + public $message = 'This value is not a valid timezone.'; + + protected const ERROR_NAMES = [ + self::TIMEZONE_IDENTIFIER_ERROR => 'TIMEZONE_IDENTIFIER_ERROR', + self::TIMEZONE_IDENTIFIER_IN_ZONE_ERROR => 'TIMEZONE_IDENTIFIER_IN_ZONE_ERROR', + self::TIMEZONE_IDENTIFIER_IN_COUNTRY_ERROR => 'TIMEZONE_IDENTIFIER_IN_COUNTRY_ERROR', + self::TIMEZONE_IDENTIFIER_INTL_ERROR => 'TIMEZONE_IDENTIFIER_INTL_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public function __construct( + int|array|null $zone = null, + ?string $message = null, + ?string $countryCode = null, + ?bool $intlCompatible = null, + ?array $groups = null, + mixed $payload = null, + array $options = [], + ) { + if (\is_array($zone)) { + $options = array_merge($zone, $options); + } elseif (null !== $zone) { + $options['value'] = $zone; + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->countryCode = $countryCode ?? $this->countryCode; + $this->intlCompatible = $intlCompatible ?? $this->intlCompatible; + + if (null === $this->countryCode) { + if (0 >= $this->zone || \DateTimeZone::ALL_WITH_BC < $this->zone) { + throw new ConstraintDefinitionException('The option "zone" must be a valid range of "\DateTimeZone" constants.'); + } + } elseif (\DateTimeZone::PER_COUNTRY !== (\DateTimeZone::PER_COUNTRY & $this->zone)) { + throw new ConstraintDefinitionException('The option "countryCode" can only be used when the "zone" option is configured with "\DateTimeZone::PER_COUNTRY".'); + } + if ($this->intlCompatible && !class_exists(\IntlTimeZone::class)) { + throw new ConstraintDefinitionException('The option "intlCompatible" can only be used when the PHP intl extension is available.'); + } + } + + public function getDefaultOption(): ?string + { + return 'zone'; + } +} diff --git a/lib/symfony/validator/Constraints/TimezoneValidator.php b/lib/symfony/validator/Constraints/TimezoneValidator.php new file mode 100644 index 0000000000..409deec7cc --- /dev/null +++ b/lib/symfony/validator/Constraints/TimezoneValidator.php @@ -0,0 +1,122 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Intl\Exception\MissingResourceException; +use Symfony\Component\Intl\Timezones; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; + +/** + * Validates whether a value is a valid timezone identifier. + * + * @author Javier Spagnoletti + * @author Hugo Hamon + */ +class TimezoneValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Timezone) { + throw new UnexpectedTypeException($constraint, Timezone::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + if ($constraint->intlCompatible && 'Etc/Unknown' === \IntlTimeZone::createTimeZone($value)->getID()) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Timezone::TIMEZONE_IDENTIFIER_INTL_ERROR) + ->addViolation(); + + return; + } + + if ( + \in_array($value, self::getPhpTimezones($constraint->zone, $constraint->countryCode), true) + || \in_array($value, self::getIntlTimezones($constraint->zone, $constraint->countryCode), true) + ) { + return; + } + + if ($constraint->countryCode) { + $code = Timezone::TIMEZONE_IDENTIFIER_IN_COUNTRY_ERROR; + } elseif (\DateTimeZone::ALL !== $constraint->zone) { + $code = Timezone::TIMEZONE_IDENTIFIER_IN_ZONE_ERROR; + } else { + $code = Timezone::TIMEZONE_IDENTIFIER_ERROR; + } + + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode($code) + ->addViolation(); + } + + private static function getPhpTimezones(int $zone, ?string $countryCode = null): array + { + if (null !== $countryCode) { + try { + return @\DateTimeZone::listIdentifiers($zone, $countryCode) ?: []; + } catch (\ValueError) { + return []; + } + } + + return \DateTimeZone::listIdentifiers($zone); + } + + private static function getIntlTimezones(int $zone, ?string $countryCode = null): array + { + if (!class_exists(Timezones::class)) { + return []; + } + + if (null !== $countryCode) { + try { + return Timezones::forCountryCode($countryCode); + } catch (MissingResourceException) { + return []; + } + } + + $timezones = Timezones::getIds(); + + if (\DateTimeZone::ALL === (\DateTimeZone::ALL & $zone)) { + return $timezones; + } + + $filtered = []; + foreach ((new \ReflectionClass(\DateTimeZone::class))->getConstants() as $const => $flag) { + if ($flag !== ($flag & $zone)) { + continue; + } + + $filtered[] = array_filter($timezones, static fn ($id) => 0 === stripos($id, $const.'/')); + } + + return $filtered ? array_merge(...$filtered) : []; + } +} diff --git a/lib/symfony/validator/Constraints/Traverse.php b/lib/symfony/validator/Constraints/Traverse.php new file mode 100644 index 0000000000..f4754ff0ac --- /dev/null +++ b/lib/symfony/validator/Constraints/Traverse.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * @Annotation + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +class Traverse extends Constraint +{ + public $traverse = true; + + public function __construct(bool|array|null $traverse = null) + { + if (\is_array($traverse) && \array_key_exists('groups', $traverse)) { + throw new ConstraintDefinitionException(\sprintf('The option "groups" is not supported by the constraint "%s".', __CLASS__)); + } + + parent::__construct($traverse); + } + + public function getDefaultOption(): ?string + { + return 'traverse'; + } + + public function getTargets(): string|array + { + return self::CLASS_CONSTRAINT; + } +} diff --git a/lib/symfony/validator/Constraints/Type.php b/lib/symfony/validator/Constraints/Type.php new file mode 100644 index 0000000000..e6f479789f --- /dev/null +++ b/lib/symfony/validator/Constraints/Type.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Type extends Constraint +{ + public const INVALID_TYPE_ERROR = 'ba785a8c-82cb-4283-967c-3cf342181b40'; + + protected const ERROR_NAMES = [ + self::INVALID_TYPE_ERROR => 'INVALID_TYPE_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value should be of type {{ type }}.'; + public $type; + + public function __construct(string|array|null $type, ?string $message = null, ?array $groups = null, mixed $payload = null, array $options = []) + { + if (\is_array($type) && \is_string(key($type))) { + $options = array_merge($type, $options); + } elseif (null !== $type) { + $options['value'] = $type; + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + } + + public function getDefaultOption(): ?string + { + return 'type'; + } + + public function getRequiredOptions(): array + { + return ['type']; + } +} diff --git a/lib/symfony/validator/Constraints/TypeValidator.php b/lib/symfony/validator/Constraints/TypeValidator.php new file mode 100644 index 0000000000..0b4513ac03 --- /dev/null +++ b/lib/symfony/validator/Constraints/TypeValidator.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Bernhard Schussek + */ +class TypeValidator extends ConstraintValidator +{ + private const VALIDATION_FUNCTIONS = [ + 'bool' => 'is_bool', + 'boolean' => 'is_bool', + 'int' => 'is_int', + 'integer' => 'is_int', + 'long' => 'is_int', + 'float' => 'is_float', + 'double' => 'is_float', + 'real' => 'is_float', + 'number' => 'is_int || is_float && !is_nan', + 'finite-float' => 'is_float && is_finite', + 'finite-number' => 'is_int || is_float && is_finite', + 'numeric' => 'is_numeric', + 'string' => 'is_string', + 'scalar' => 'is_scalar', + 'array' => 'is_array', + 'iterable' => 'is_iterable', + 'countable' => 'is_countable', + 'callable' => 'is_callable', + 'object' => 'is_object', + 'resource' => 'is_resource', + 'null' => 'is_null', + 'alnum' => 'ctype_alnum', + 'alpha' => 'ctype_alpha', + 'cntrl' => 'ctype_cntrl', + 'digit' => 'ctype_digit', + 'graph' => 'ctype_graph', + 'lower' => 'ctype_lower', + 'print' => 'ctype_print', + 'punct' => 'ctype_punct', + 'space' => 'ctype_space', + 'upper' => 'ctype_upper', + 'xdigit' => 'ctype_xdigit', + ]; + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Type) { + throw new UnexpectedTypeException($constraint, Type::class); + } + + if (null === $value) { + return; + } + + $types = (array) $constraint->type; + + foreach ($types as $type) { + $type = strtolower($type); + if (isset(self::VALIDATION_FUNCTIONS[$type]) && match ($type) { + 'finite-float' => \is_float($value) && is_finite($value), + 'finite-number' => \is_int($value) || \is_float($value) && is_finite($value), + 'number' => \is_int($value) || \is_float($value) && !is_nan($value), + default => self::VALIDATION_FUNCTIONS[$type]($value), + }) { + return; + } + + if ($value instanceof $type) { + return; + } + } + + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setParameter('{{ type }}', implode('|', $types)) + ->setCode(Type::INVALID_TYPE_ERROR) + ->addViolation(); + } +} diff --git a/lib/symfony/validator/Constraints/Ulid.php b/lib/symfony/validator/Constraints/Ulid.php new file mode 100644 index 0000000000..5b2b825a74 --- /dev/null +++ b/lib/symfony/validator/Constraints/Ulid.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * + * @author Laurent Clouet + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Ulid extends Constraint +{ + public const TOO_SHORT_ERROR = '7b44804e-37d5-4df4-9bdd-b738d4a45bb4'; + public const TOO_LONG_ERROR = '9608249f-6da1-4d53-889e-9864b58c4d37'; + public const INVALID_CHARACTERS_ERROR = 'e4155739-5135-4258-9c81-ae7b44b5311e'; + public const TOO_LARGE_ERROR = 'df8cfb9a-ce6d-4a69-ae5a-eea7ab6f278b'; + + protected const ERROR_NAMES = [ + self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR', + self::TOO_LONG_ERROR => 'TOO_LONG_ERROR', + self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR', + self::TOO_LARGE_ERROR => 'TOO_LARGE_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This is not a valid ULID.'; + + public function __construct( + ?array $options = null, + ?string $message = null, + ?array $groups = null, + mixed $payload = null, + ) { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + } +} diff --git a/lib/symfony/validator/Constraints/UlidValidator.php b/lib/symfony/validator/Constraints/UlidValidator.php new file mode 100644 index 0000000000..ad47f66d4f --- /dev/null +++ b/lib/symfony/validator/Constraints/UlidValidator.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * Validates whether the value is a valid ULID (Universally Unique Lexicographically Sortable Identifier). + * Cf https://github.com/ulid/spec for ULID specifications. + * + * @author Laurent Clouet + */ +class UlidValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Ulid) { + throw new UnexpectedTypeException($constraint, Ulid::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + if (26 !== \strlen($value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(26 > \strlen($value) ? Ulid::TOO_SHORT_ERROR : Ulid::TOO_LONG_ERROR) + ->addViolation(); + + return; + } + + if (\strlen($value) !== strspn($value, '0123456789ABCDEFGHJKMNPQRSTVWXYZabcdefghjkmnpqrstvwxyz')) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Ulid::INVALID_CHARACTERS_ERROR) + ->addViolation(); + + return; + } + + // Largest valid ULID is '7ZZZZZZZZZZZZZZZZZZZZZZZZZ' + // Cf https://github.com/ulid/spec#overflow-errors-when-parsing-base32-strings + if ($value[0] > '7') { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Ulid::TOO_LARGE_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Unique.php b/lib/symfony/validator/Constraints/Unique.php new file mode 100644 index 0000000000..4f77d3a7fd --- /dev/null +++ b/lib/symfony/validator/Constraints/Unique.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\InvalidArgumentException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Yevgeniy Zholkevskiy + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Unique extends Constraint +{ + public const IS_NOT_UNIQUE = '7911c98d-b845-4da0-94b7-a8dac36bc55a'; + + public array|string $fields = []; + + protected const ERROR_NAMES = [ + self::IS_NOT_UNIQUE => 'IS_NOT_UNIQUE', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This collection should contain only unique elements.'; + /** @var callable|null */ + public $normalizer; + + /** + * @param array|string $fields the combination of fields that must contain unique values or a set of options + */ + public function __construct( + ?array $options = null, + ?string $message = null, + ?callable $normalizer = null, + ?array $groups = null, + mixed $payload = null, + array|string|null $fields = null, + ) { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->normalizer = $normalizer ?? $this->normalizer; + $this->fields = $fields ?? $this->fields; + + if (null !== $this->normalizer && !\is_callable($this->normalizer)) { + throw new InvalidArgumentException(\sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer))); + } + } +} diff --git a/lib/symfony/validator/Constraints/UniqueValidator.php b/lib/symfony/validator/Constraints/UniqueValidator.php new file mode 100644 index 0000000000..94d6a89658 --- /dev/null +++ b/lib/symfony/validator/Constraints/UniqueValidator.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * @author Yevgeniy Zholkevskiy + */ +class UniqueValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Unique) { + throw new UnexpectedTypeException($constraint, Unique::class); + } + + $fields = (array) $constraint->fields; + + if (null === $value) { + return; + } + + if (!\is_array($value) && !$value instanceof \IteratorAggregate) { + throw new UnexpectedValueException($value, 'array|IteratorAggregate'); + } + + $collectionElements = []; + $normalizer = $this->getNormalizer($constraint); + foreach ($value as $element) { + $element = $normalizer($element); + + if ($fields && !$element = $this->reduceElementKeys($fields, $element)) { + continue; + } + + if (\in_array($element, $collectionElements, true)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($element)) + ->setCode(Unique::IS_NOT_UNIQUE) + ->addViolation(); + + return; + } + $collectionElements[] = $element; + } + } + + private function getNormalizer(Unique $unique): callable + { + if (null === $unique->normalizer) { + return static fn ($value) => $value; + } + + return $unique->normalizer; + } + + private function reduceElementKeys(array $fields, array $element): array + { + $output = []; + foreach ($fields as $field) { + if (!\is_string($field)) { + throw new UnexpectedTypeException($field, 'string'); + } + if (\array_key_exists($field, $element)) { + $output[$field] = $element[$field]; + } + } + + return $output; + } +} diff --git a/lib/symfony/validator/Constraints/Url.php b/lib/symfony/validator/Constraints/Url.php new file mode 100644 index 0000000000..0986d8a175 --- /dev/null +++ b/lib/symfony/validator/Constraints/Url.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\InvalidArgumentException; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Url extends Constraint +{ + public const INVALID_URL_ERROR = '57c2f299-1154-4870-89bb-ef3b1f5ad229'; + + protected const ERROR_NAMES = [ + self::INVALID_URL_ERROR => 'INVALID_URL_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + public $message = 'This value is not a valid URL.'; + public $protocols = ['http', 'https']; + public $relativeProtocol = false; + /** @var callable|null */ + public $normalizer; + + public function __construct( + ?array $options = null, + ?string $message = null, + ?array $protocols = null, + ?bool $relativeProtocol = null, + ?callable $normalizer = null, + ?array $groups = null, + mixed $payload = null, + ) { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->protocols = $protocols ?? $this->protocols; + $this->relativeProtocol = $relativeProtocol ?? $this->relativeProtocol; + $this->normalizer = $normalizer ?? $this->normalizer; + + if (null !== $this->normalizer && !\is_callable($this->normalizer)) { + throw new InvalidArgumentException(\sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer))); + } + } +} diff --git a/lib/symfony/validator/Constraints/UrlValidator.php b/lib/symfony/validator/Constraints/UrlValidator.php new file mode 100644 index 0000000000..55a545e8ba --- /dev/null +++ b/lib/symfony/validator/Constraints/UrlValidator.php @@ -0,0 +1,93 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * @author Bernhard Schussek + */ +class UrlValidator extends ConstraintValidator +{ + public const PATTERN = <<<'REGEX' + {^ + (%s):// # protocol + ((?:[\pL\pN\-._~!$&'()*+,;=]|%%[0-9A-Fa-f]{2})++(?::(?:[:\pL\pN\-._~!$&'()*+,;=]|%%[0-9A-Fa-f]{2})*+)?@)? # basic auth + ( + (?: + (?: + (?:[\pL\pN\pS\pM\-\_]++\.)+ + (?: + (?:xn--[a-z0-9-]++) # punycode in tld + | + (?:[\pL\pN\pM]++) # no punycode in tld + ) + ) # a multi-level domain name + | + [a-z0-9\-\_]++ # a single-level domain name + )\.? + | # or + \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # an IP address + | # or + \[ + (?:(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-f]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,1}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,2}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,3}(?:(?:[0-9a-f]{1,4})))?::(?:(?:[0-9a-f]{1,4})):)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,4}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,5}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,6}(?:(?:[0-9a-f]{1,4})))?::)))) + \] # an IPv6 address + ) + (:[0-9]+)? # a port (optional) + (?:/ (?:[\pL\pN\pS\pM\-._~!$&'()*+,;=:@]|%%[0-9A-Fa-f]{2})* )* # a path + (?:\? (?:[\pL\pN\-._~!$&'()*+,;=:@/?[\]]|%%[0-9A-Fa-f]{2})* )? # a query (optional) + (?:\# (?:[\pL\pN\-._~!$&'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a fragment (optional) + $}ixuD + REGEX; + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Url) { + throw new UnexpectedTypeException($constraint, Url::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + if ('' === $value) { + return; + } + + if (null !== $constraint->normalizer) { + $value = ($constraint->normalizer)($value); + } + + $pattern = $constraint->relativeProtocol ? str_replace('(%s):', '(?:(%s):)?', static::PATTERN) : static::PATTERN; + $pattern = \sprintf($pattern, implode('|', $constraint->protocols)); + + if (!preg_match($pattern, $value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Url::INVALID_URL_ERROR) + ->addViolation(); + + return; + } + } +} diff --git a/lib/symfony/validator/Constraints/Uuid.php b/lib/symfony/validator/Constraints/Uuid.php new file mode 100644 index 0000000000..87fb9b3221 --- /dev/null +++ b/lib/symfony/validator/Constraints/Uuid.php @@ -0,0 +1,126 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\InvalidArgumentException; + +/** + * @Annotation + * + * @author Colin O'Dell + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Uuid extends Constraint +{ + public const TOO_SHORT_ERROR = 'aa314679-dac9-4f54-bf97-b2049df8f2a3'; + public const TOO_LONG_ERROR = '494897dd-36f8-4d31-8923-71a8d5f3000d'; + public const INVALID_CHARACTERS_ERROR = '51120b12-a2bc-41bf-aa53-cd73daf330d0'; + public const INVALID_HYPHEN_PLACEMENT_ERROR = '98469c83-0309-4f5d-bf95-a496dcaa869c'; + public const INVALID_VERSION_ERROR = '21ba13b4-b185-4882-ac6f-d147355987eb'; + public const INVALID_TIME_BASED_VERSION_ERROR = '484081ca-6fbd-11ed-ade8-a3bdfd0fcf2f'; + public const INVALID_VARIANT_ERROR = '164ef693-2b9d-46de-ad7f-836201f0c2db'; + + protected const ERROR_NAMES = [ + self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR', + self::TOO_LONG_ERROR => 'TOO_LONG_ERROR', + self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR', + self::INVALID_HYPHEN_PLACEMENT_ERROR => 'INVALID_HYPHEN_PLACEMENT_ERROR', + self::INVALID_VERSION_ERROR => 'INVALID_VERSION_ERROR', + self::INVALID_VARIANT_ERROR => 'INVALID_VARIANT_ERROR', + ]; + + /** + * @deprecated since Symfony 6.1, use const ERROR_NAMES instead + */ + protected static $errorNames = self::ERROR_NAMES; + + // Possible versions defined by RFC 9562/4122 + public const V1_MAC = 1; + public const V2_DCE = 2; + public const V3_MD5 = 3; + public const V4_RANDOM = 4; + public const V5_SHA1 = 5; + public const V6_SORTABLE = 6; + public const V7_MONOTONIC = 7; + public const V8_CUSTOM = 8; + + public const ALL_VERSIONS = [ + self::V1_MAC, + self::V2_DCE, + self::V3_MD5, + self::V4_RANDOM, + self::V5_SHA1, + self::V6_SORTABLE, + self::V7_MONOTONIC, + self::V8_CUSTOM, + ]; + + public const TIME_BASED_VERSIONS = [ + self::V1_MAC, + self::V6_SORTABLE, + self::V7_MONOTONIC, + ]; + + /** + * Message to display when validation fails. + * + * @var string + */ + public $message = 'This is not a valid UUID.'; + + /** + * Strict mode only allows UUIDs that meet the formal definition and formatting per RFC 9562/4122. + * + * Set this to `false` to allow legacy formats with different dash positioning or wrapping characters + * + * @var bool + */ + public $strict = true; + + /** + * Array of allowed versions (see version constants above). + * + * All UUID versions are allowed by default + * + * @var int[] + */ + public $versions = self::ALL_VERSIONS; + + /** @var callable|null */ + public $normalizer; + + /** + * @param int[]|int|null $versions + */ + public function __construct( + ?array $options = null, + ?string $message = null, + array|int|null $versions = null, + ?bool $strict = null, + ?callable $normalizer = null, + ?array $groups = null, + mixed $payload = null, + ) { + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->versions = (array) ($versions ?? $this->versions); + $this->strict = $strict ?? $this->strict; + $this->normalizer = $normalizer ?? $this->normalizer; + + if (null !== $this->normalizer && !\is_callable($this->normalizer)) { + throw new InvalidArgumentException(\sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer))); + } + } +} diff --git a/lib/symfony/validator/Constraints/UuidValidator.php b/lib/symfony/validator/Constraints/UuidValidator.php new file mode 100644 index 0000000000..120f8a426b --- /dev/null +++ b/lib/symfony/validator/Constraints/UuidValidator.php @@ -0,0 +1,260 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +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; + +/** + * Validates whether the value is a valid UUID (also known as GUID). + * + * Strict validation will allow a UUID as specified per RFC 9562/4122. + * Loose validation will allow any type of UUID. + * + * @author Colin O'Dell + * @author Bernhard Schussek + * + * @see https://datatracker.ietf.org/doc/html/rfc9562 + * @see https://en.wikipedia.org/wiki/Universally_unique_identifier + */ +class UuidValidator extends ConstraintValidator +{ + // The strict pattern matches UUIDs like this: + // xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx + + // Roughly speaking: + // x = any hexadecimal character + // M = any allowed version {1..8} + // N = any allowed variant {8, 9, a, b} + + public const STRICT_LENGTH = 36; + public const STRICT_FIRST_HYPHEN_POSITION = 8; + public const STRICT_LAST_HYPHEN_POSITION = 23; + public const STRICT_VERSION_POSITION = 14; + public const STRICT_VARIANT_POSITION = 19; + + // The loose pattern validates similar yet non-compliant UUIDs. + // Hyphens are completely optional. If present, they should only appear + // between every fourth character: + // xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx + // xxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxx-xxxx + // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + // The value can also be wrapped with characters like []{}: + // {xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx} + + // Neither the version nor the variant is validated by this pattern. + + public const LOOSE_MAX_LENGTH = 39; + public const LOOSE_FIRST_HYPHEN_POSITION = 4; + + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Uuid) { + throw new UnexpectedTypeException($constraint, Uuid::class); + } + + if (null === $value || '' === $value) { + return; + } + + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new UnexpectedValueException($value, 'string'); + } + + $value = (string) $value; + + if (null !== $constraint->normalizer) { + $value = ($constraint->normalizer)($value); + } + + if ($constraint->strict) { + $this->validateStrict($value, $constraint); + + return; + } + + $this->validateLoose($value, $constraint); + } + + private function validateLoose(string $value, Uuid $constraint): void + { + // Error priority: + // 1. ERROR_INVALID_CHARACTERS + // 2. ERROR_INVALID_HYPHEN_PLACEMENT + // 3. ERROR_TOO_SHORT/ERROR_TOO_LONG + + // Trim any wrapping characters like [] or {} used by some legacy systems + $trimmed = trim($value, '[]{}'); + + // Position of the next expected hyphen + $h = self::LOOSE_FIRST_HYPHEN_POSITION; + + // Expected length + $l = self::LOOSE_MAX_LENGTH; + + for ($i = 0; $i < $l; ++$i) { + // Check length + if (!isset($trimmed[$i])) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::TOO_SHORT_ERROR) + ->addViolation(); + + return; + } + + // Hyphens must occur every fifth position + // xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx + // ^ ^ ^ ^ ^ ^ ^ + if ('-' === $trimmed[$i]) { + if ($i !== $h) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::INVALID_HYPHEN_PLACEMENT_ERROR) + ->addViolation(); + + return; + } + + $h += 5; + + continue; + } + + // Missing hyphens are ignored + if ($i === $h) { + $h += 4; + --$l; + } + + // Check characters + if (!ctype_xdigit($trimmed[$i])) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::INVALID_CHARACTERS_ERROR) + ->addViolation(); + + return; + } + } + + // Check length again + if (isset($trimmed[$i])) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::TOO_LONG_ERROR) + ->addViolation(); + } + } + + private function validateStrict(string $value, Uuid $constraint): void + { + // Error priority: + // 1. ERROR_INVALID_CHARACTERS + // 2. ERROR_INVALID_HYPHEN_PLACEMENT + // 3. ERROR_TOO_SHORT/ERROR_TOO_LONG + // 4. ERROR_INVALID_VERSION + // 5. ERROR_INVALID_VARIANT + + // Position of the next expected hyphen + $h = self::STRICT_FIRST_HYPHEN_POSITION; + + for ($i = 0; $i < self::STRICT_LENGTH; ++$i) { + // Check length + if (!isset($value[$i])) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::TOO_SHORT_ERROR) + ->addViolation(); + + return; + } + + // Check hyphen placement + // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + // ^ ^ ^ ^ + if ('-' === $value[$i]) { + if ($i !== $h) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::INVALID_HYPHEN_PLACEMENT_ERROR) + ->addViolation(); + + return; + } + + // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + // ^ + if ($h < self::STRICT_LAST_HYPHEN_POSITION) { + $h += 5; + } + + continue; + } + + // Check characters + if (!ctype_xdigit($value[$i])) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::INVALID_CHARACTERS_ERROR) + ->addViolation(); + + return; + } + + // Missing hyphen + if ($i === $h) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::INVALID_HYPHEN_PLACEMENT_ERROR) + ->addViolation(); + + return; + } + } + + // Check length again + if (isset($value[$i])) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::TOO_LONG_ERROR) + ->addViolation(); + } + + // Check version + if (!\in_array($value[self::STRICT_VERSION_POSITION], $constraint->versions)) { + $code = Uuid::TIME_BASED_VERSIONS === $constraint->versions ? Uuid::INVALID_TIME_BASED_VERSION_ERROR : Uuid::INVALID_VERSION_ERROR; + + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode($code) + ->addViolation(); + } + + // Check variant - first two bits must equal "10" + // 0b10xx + // & 0b1100 (12) + // = 0b1000 (8) + if (8 !== (hexdec($value[self::STRICT_VARIANT_POSITION]) & 12)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::INVALID_VARIANT_ERROR) + ->addViolation(); + } + } +} diff --git a/lib/symfony/validator/Constraints/Valid.php b/lib/symfony/validator/Constraints/Valid.php new file mode 100644 index 0000000000..b58686e201 --- /dev/null +++ b/lib/symfony/validator/Constraints/Valid.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) + * + * @author Bernhard Schussek + */ +#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class Valid extends Constraint +{ + public $traverse = true; + + public function __construct(?array $options = null, ?array $groups = null, $payload = null, ?bool $traverse = null) + { + parent::__construct($options ?? [], $groups, $payload); + + $this->traverse = $traverse ?? $this->traverse; + } + + public function __get(string $option): mixed + { + if ('groups' === $option) { + // when this is reached, no groups have been configured + return null; + } + + return parent::__get($option); + } + + /** + * @return void + */ + public function addImplicitGroupName(string $group) + { + if (null !== $this->groups) { + parent::addImplicitGroupName($group); + } + } +} diff --git a/lib/symfony/validator/Constraints/ValidValidator.php b/lib/symfony/validator/Constraints/ValidValidator.php new file mode 100644 index 0000000000..7c960ffee1 --- /dev/null +++ b/lib/symfony/validator/Constraints/ValidValidator.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * @author Christian Flothmann + */ +class ValidValidator extends ConstraintValidator +{ + /** + * @return void + */ + public function validate(mixed $value, Constraint $constraint) + { + if (!$constraint instanceof Valid) { + throw new UnexpectedTypeException($constraint, Valid::class); + } + + if (null === $value) { + return; + } + + $this->context + ->getValidator() + ->inContext($this->context) + ->validate($value, null, $this->context->getGroup()); + } +} diff --git a/lib/symfony/validator/Constraints/When.php b/lib/symfony/validator/Constraints/When.php new file mode 100644 index 0000000000..3150284275 --- /dev/null +++ b/lib/symfony/validator/Constraints/When.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\ExpressionLanguage\Expression; +use Symfony\Component\ExpressionLanguage\ExpressionLanguage; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\LogicException; + +/** + * @Annotation + * @Target({"CLASS", "PROPERTY", "METHOD", "ANNOTATION"}) + */ +#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] +class When extends Composite +{ + public $expression; + public $constraints = []; + public $values = []; + + public function __construct(string|Expression|array $expression, array|Constraint|null $constraints = null, ?array $values = null, ?array $groups = null, $payload = null, array $options = []) + { + if (!class_exists(ExpressionLanguage::class)) { + throw new LogicException(\sprintf('The "symfony/expression-language" component is required to use the "%s" constraint. Try running "composer require symfony/expression-language".', __CLASS__)); + } + + if (\is_array($expression)) { + $options = array_merge($expression, $options); + } else { + $options['expression'] = $expression; + + if (null !== $constraints) { + $options['constraints'] = $constraints; + } + } + + if (isset($options['constraints']) && !\is_array($options['constraints'])) { + $options['constraints'] = [$options['constraints']]; + } + + if (null !== $groups) { + $options['groups'] = $groups; + } + + if (null !== $payload) { + $options['payload'] = $payload; + } + + parent::__construct($options); + + $this->values = $values ?? $this->values; + } + + public function getRequiredOptions(): array + { + return ['expression', 'constraints']; + } + + public function getTargets(): string|array + { + return [self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT]; + } + + protected function getCompositeOption(): string + { + return 'constraints'; + } +} diff --git a/lib/symfony/validator/Constraints/WhenValidator.php b/lib/symfony/validator/Constraints/WhenValidator.php new file mode 100644 index 0000000000..c02a450e8c --- /dev/null +++ b/lib/symfony/validator/Constraints/WhenValidator.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\ExpressionLanguage\ExpressionLanguage; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\LogicException; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +final class WhenValidator extends ConstraintValidator +{ + public function __construct(private ?ExpressionLanguage $expressionLanguage = null) + { + } + + public function validate(mixed $value, Constraint $constraint): void + { + if (!$constraint instanceof When) { + throw new UnexpectedTypeException($constraint, When::class); + } + + $context = $this->context; + $variables = $constraint->values; + $variables['value'] = $value; + $variables['this'] = $context->getObject(); + + if ($this->getExpressionLanguage()->evaluate($constraint->expression, $variables)) { + $context->getValidator()->inContext($context) + ->validate($value, $constraint->constraints); + } + } + + private function getExpressionLanguage(): ExpressionLanguage + { + if (!class_exists(ExpressionLanguage::class)) { + throw new LogicException(\sprintf('The "symfony/expression-language" component is required to use the "%s" validator. Try running "composer require symfony/expression-language".', __CLASS__)); + } + + return $this->expressionLanguage ??= new ExpressionLanguage(); + } +} diff --git a/lib/symfony/validator/Constraints/ZeroComparisonConstraintTrait.php b/lib/symfony/validator/Constraints/ZeroComparisonConstraintTrait.php new file mode 100644 index 0000000000..78fab1f54e --- /dev/null +++ b/lib/symfony/validator/Constraints/ZeroComparisonConstraintTrait.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * @internal + * + * @author Jan Schädlich + * @author Alexander M. Turek + */ +trait ZeroComparisonConstraintTrait +{ + public function __construct(?array $options = null, ?string $message = null, ?array $groups = null, mixed $payload = null) + { + $options ??= []; + + if (isset($options['propertyPath'])) { + throw new ConstraintDefinitionException(\sprintf('The "propertyPath" option of the "%s" constraint cannot be set.', static::class)); + } + + if (isset($options['value'])) { + throw new ConstraintDefinitionException(\sprintf('The "value" option of the "%s" constraint cannot be set.', static::class)); + } + + parent::__construct(0, null, $message, $groups, $payload, $options); + } + + public function validatedBy(): string + { + return parent::class.'Validator'; + } +} diff --git a/lib/symfony/validator/ContainerConstraintValidatorFactory.php b/lib/symfony/validator/ContainerConstraintValidatorFactory.php new file mode 100644 index 0000000000..89e2ce14e2 --- /dev/null +++ b/lib/symfony/validator/ContainerConstraintValidatorFactory.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Psr\Container\ContainerInterface; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\ValidatorException; + +/** + * Uses a service container to create constraint validators. + * + * @author Kris Wallsmith + */ +class ContainerConstraintValidatorFactory implements ConstraintValidatorFactoryInterface +{ + private ContainerInterface $container; + private array $validators; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + $this->validators = []; + } + + /** + * @throws ValidatorException When the validator class does not exist + * @throws UnexpectedTypeException When the validator is not an instance of ConstraintValidatorInterface + */ + public function getInstance(Constraint $constraint): ConstraintValidatorInterface + { + $name = $constraint->validatedBy(); + + if (!isset($this->validators[$name])) { + if ($this->container->has($name)) { + $this->validators[$name] = $this->container->get($name); + } else { + if (!class_exists($name)) { + throw new ValidatorException(\sprintf('Constraint validator "%s" does not exist or is not enabled. Check the "validatedBy" method in your constraint class "%s".', $name, get_debug_type($constraint))); + } + + $this->validators[$name] = new $name(); + } + } + + if (!$this->validators[$name] instanceof ConstraintValidatorInterface) { + throw new UnexpectedTypeException($this->validators[$name], ConstraintValidatorInterface::class); + } + + return $this->validators[$name]; + } +} diff --git a/lib/symfony/validator/Context/ExecutionContext.php b/lib/symfony/validator/Context/ExecutionContext.php new file mode 100644 index 0000000000..8ab1ec4d5c --- /dev/null +++ b/lib/symfony/validator/Context/ExecutionContext.php @@ -0,0 +1,281 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Context; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintViolation; +use Symfony\Component\Validator\ConstraintViolationList; +use Symfony\Component\Validator\ConstraintViolationListInterface; +use Symfony\Component\Validator\Mapping\ClassMetadataInterface; +use Symfony\Component\Validator\Mapping\MemberMetadata; +use Symfony\Component\Validator\Mapping\MetadataInterface; +use Symfony\Component\Validator\Mapping\PropertyMetadataInterface; +use Symfony\Component\Validator\Util\PropertyPath; +use Symfony\Component\Validator\Validator\LazyProperty; +use Symfony\Component\Validator\Validator\ValidatorInterface; +use Symfony\Component\Validator\Violation\ConstraintViolationBuilder; +use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface; +use Symfony\Contracts\Translation\TranslatorInterface; + +/** + * The context used and created by {@link ExecutionContextFactory}. + * + * @author Bernhard Schussek + * + * @see ExecutionContextInterface + * + * @internal since version 2.5. Code against ExecutionContextInterface instead. + */ +class ExecutionContext implements ExecutionContextInterface +{ + private ValidatorInterface $validator; + + /** + * The root value of the validated object graph. + */ + private mixed $root; + + private TranslatorInterface $translator; + private ?string $translationDomain; + + /** + * The violations generated in the current context. + */ + private ConstraintViolationList $violations; + + /** + * The currently validated value. + */ + private mixed $value = null; + + /** + * The currently validated object. + */ + private ?object $object = null; + + /** + * The property path leading to the current value. + */ + private string $propertyPath = ''; + + /** + * The current validation metadata. + */ + private ?MetadataInterface $metadata = null; + + /** + * The currently validated group. + */ + private ?string $group = null; + + /** + * The currently validated constraint. + */ + private ?Constraint $constraint = null; + + /** + * Stores which objects have been validated in which group. + * + * @var bool[][] + */ + private array $validatedObjects = []; + + /** + * Stores which class constraint has been validated for which object. + * + * @var bool[] + */ + private array $validatedConstraints = []; + + /** + * Stores which objects have been initialized. + * + * @var bool[] + */ + private array $initializedObjects = []; + + /** + * @var \SplObjectStorage + */ + private \SplObjectStorage $cachedObjectsRefs; + + /** + * @internal Called by {@link ExecutionContextFactory}. Should not be used in user code. + */ + public function __construct(ValidatorInterface $validator, mixed $root, TranslatorInterface $translator, ?string $translationDomain = null) + { + $this->validator = $validator; + $this->root = $root; + $this->translator = $translator; + $this->translationDomain = $translationDomain; + $this->violations = new ConstraintViolationList(); + $this->cachedObjectsRefs = new \SplObjectStorage(); + } + + public function setNode(mixed $value, ?object $object, ?MetadataInterface $metadata, string $propertyPath): void + { + $this->value = $value; + $this->object = $object; + $this->metadata = $metadata; + $this->propertyPath = $propertyPath; + } + + public function setGroup(?string $group): void + { + $this->group = $group; + } + + public function setConstraint(Constraint $constraint): void + { + $this->constraint = $constraint; + } + + public function addViolation(string|\Stringable $message, array $parameters = []): void + { + $this->violations->add(new ConstraintViolation( + $this->translator->trans($message, $parameters, $this->translationDomain), + $message, + $parameters, + $this->root, + $this->propertyPath, + $this->getValue(), + null, + null, + $this->constraint + )); + } + + public function buildViolation(string|\Stringable $message, array $parameters = []): ConstraintViolationBuilderInterface + { + return new ConstraintViolationBuilder( + $this->violations, + $this->constraint, + $message, + $parameters, + $this->root, + $this->propertyPath, + $this->getValue(), + $this->translator, + $this->translationDomain + ); + } + + public function getViolations(): ConstraintViolationListInterface + { + return $this->violations; + } + + public function getValidator(): ValidatorInterface + { + return $this->validator; + } + + public function getRoot(): mixed + { + return $this->root; + } + + public function getValue(): mixed + { + if ($this->value instanceof LazyProperty) { + return $this->value->getPropertyValue(); + } + + return $this->value; + } + + public function getObject(): ?object + { + return $this->object; + } + + public function getMetadata(): ?MetadataInterface + { + return $this->metadata; + } + + public function getGroup(): ?string + { + return $this->group; + } + + public function getConstraint(): ?Constraint + { + return $this->constraint; + } + + public function getClassName(): ?string + { + return $this->metadata instanceof MemberMetadata || $this->metadata instanceof ClassMetadataInterface ? $this->metadata->getClassName() : null; + } + + public function getPropertyName(): ?string + { + return $this->metadata instanceof PropertyMetadataInterface ? $this->metadata->getPropertyName() : null; + } + + public function getPropertyPath(string $subPath = ''): string + { + return PropertyPath::append($this->propertyPath, $subPath); + } + + public function markGroupAsValidated(string $cacheKey, string $groupHash): void + { + if (!isset($this->validatedObjects[$cacheKey])) { + $this->validatedObjects[$cacheKey] = []; + } + + $this->validatedObjects[$cacheKey][$groupHash] = true; + } + + public function isGroupValidated(string $cacheKey, string $groupHash): bool + { + return isset($this->validatedObjects[$cacheKey][$groupHash]); + } + + public function markConstraintAsValidated(string $cacheKey, string $constraintHash): void + { + $this->validatedConstraints[$cacheKey.':'.$constraintHash] = true; + } + + public function isConstraintValidated(string $cacheKey, string $constraintHash): bool + { + return isset($this->validatedConstraints[$cacheKey.':'.$constraintHash]); + } + + public function markObjectAsInitialized(string $cacheKey): void + { + $this->initializedObjects[$cacheKey] = true; + } + + public function isObjectInitialized(string $cacheKey): bool + { + return isset($this->initializedObjects[$cacheKey]); + } + + /** + * @internal + */ + public function generateCacheKey(object $object): string + { + if (!isset($this->cachedObjectsRefs[$object])) { + $this->cachedObjectsRefs[$object] = spl_object_hash($object); + } + + return $this->cachedObjectsRefs[$object]; + } + + public function __clone() + { + $this->violations = clone $this->violations; + } +} diff --git a/lib/symfony/validator/Context/ExecutionContextFactory.php b/lib/symfony/validator/Context/ExecutionContextFactory.php new file mode 100644 index 0000000000..9979059b6d --- /dev/null +++ b/lib/symfony/validator/Context/ExecutionContextFactory.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Context; + +use Symfony\Component\Validator\Validator\ValidatorInterface; +use Symfony\Contracts\Translation\TranslatorInterface; + +/** + * Creates new {@link ExecutionContext} instances. + * + * @author Bernhard Schussek + * + * @internal version 2.5. Code against ExecutionContextFactoryInterface instead. + */ +class ExecutionContextFactory implements ExecutionContextFactoryInterface +{ + private TranslatorInterface $translator; + private ?string $translationDomain; + + public function __construct(TranslatorInterface $translator, ?string $translationDomain = null) + { + $this->translator = $translator; + $this->translationDomain = $translationDomain; + } + + public function createContext(ValidatorInterface $validator, mixed $root): ExecutionContextInterface + { + return new ExecutionContext( + $validator, + $root, + $this->translator, + $this->translationDomain + ); + } +} diff --git a/lib/symfony/validator/Context/ExecutionContextFactoryInterface.php b/lib/symfony/validator/Context/ExecutionContextFactoryInterface.php new file mode 100644 index 0000000000..71d17ce3f2 --- /dev/null +++ b/lib/symfony/validator/Context/ExecutionContextFactoryInterface.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Context; + +use Symfony\Component\Validator\Validator\ValidatorInterface; + +/** + * Creates instances of {@link ExecutionContextInterface}. + * + * You can use a custom factory if you want to customize the execution context + * that is passed through the validation run. + * + * @author Bernhard Schussek + */ +interface ExecutionContextFactoryInterface +{ + /** + * Creates a new execution context. + * + * @param mixed $root The root value of the validated + * object graph + */ + public function createContext(ValidatorInterface $validator, mixed $root): ExecutionContextInterface; +} diff --git a/lib/symfony/validator/Context/ExecutionContextInterface.php b/lib/symfony/validator/Context/ExecutionContextInterface.php new file mode 100644 index 0000000000..fd72a149e9 --- /dev/null +++ b/lib/symfony/validator/Context/ExecutionContextInterface.php @@ -0,0 +1,297 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Context; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintViolationListInterface; +use Symfony\Component\Validator\Mapping; +use Symfony\Component\Validator\Mapping\MetadataInterface; +use Symfony\Component\Validator\Validator\ValidatorInterface; +use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface; + +/** + * The context of a validation run. + * + * The context collects all violations generated during the validation. By + * default, validators execute all validations in a new context: + * + * $violations = $validator->validate($object); + * + * When you make another call to the validator, while the validation is in + * progress, the violations will be isolated from each other: + * + * public function validate(mixed $value, Constraint $constraint): void + * { + * $validator = $this->context->getValidator(); + * + * // The violations are not added to $this->context + * $violations = $validator->validate($value); + * } + * + * However, if you want to add the violations to the current context, use the + * {@link ValidatorInterface::inContext()} method: + * + * public function validate(mixed $value, Constraint $constraint): void + * { + * $validator = $this->context->getValidator(); + * + * // The violations are added to $this->context + * $validator + * ->inContext($this->context) + * ->validate($value) + * ; + * } + * + * Additionally, the context provides information about the current state of + * the validator, such as the currently validated class, the name of the + * currently validated property and more. These values change over time, so you + * cannot store a context and expect that the methods still return the same + * results later on. + * + * @author Bernhard Schussek + */ +interface ExecutionContextInterface +{ + /** + * Adds a violation at the current node of the validation graph. + * + * @param string|\Stringable $message The error message as a string or a stringable object + * @param array $params The parameters substituted in the error message + * + * @return void + */ + public function addViolation(string $message, array $params = []); + + /** + * Returns a builder for adding a violation with extended information. + * + * Call {@link ConstraintViolationBuilderInterface::addViolation()} to + * add the violation when you're done with the configuration: + * + * $context->buildViolation('Please enter a number between %min% and %max%.') + * ->setParameter('%min%', '3') + * ->setParameter('%max%', '10') + * ->setTranslationDomain('number_validation') + * ->addViolation(); + * + * @param string|\Stringable $message The error message as a string or a stringable object + * @param array $parameters The parameters substituted in the error message + */ + public function buildViolation(string $message, array $parameters = []): ConstraintViolationBuilderInterface; + + /** + * Returns the validator. + * + * Useful if you want to validate additional constraints: + * + * public function validate(mixed $value, Constraint $constraint): void + * { + * $validator = $this->context->getValidator(); + * + * $violations = $validator->validate($value, new Length(['min' => 3])); + * + * if (count($violations) > 0) { + * // ... + * } + * } + */ + public function getValidator(): ValidatorInterface; + + /** + * Returns the currently validated object. + * + * If the validator is currently validating a class constraint, the + * object of that class is returned. If it is validating a property or + * getter constraint, the object that the property/getter belongs to is + * returned. + * + * In other cases, null is returned. + */ + public function getObject(): ?object; + + /** + * Warning: Should not be called by user code, to be used by the validator engine only. + * + * @param object|null $object The currently validated object + * @param string $propertyPath The property path to the current value + * + * @return void + */ + public function setNode(mixed $value, ?object $object, ?MetadataInterface $metadata, string $propertyPath); + + /** + * Warning: Should not be called by user code, to be used by the validator engine only. + * + * @param string|null $group The validated group + * + * @return void + */ + public function setGroup(?string $group); + + /** + * Warning: Should not be called by user code, to be used by the validator engine only. + * + * @return void + */ + public function setConstraint(Constraint $constraint); + + /** + * Warning: Should not be called by user code, to be used by the validator engine only. + * + * @param string $cacheKey The hash of the object + * @param string $groupHash The group's name or hash, if it is group + * sequence + * + * @return void + */ + public function markGroupAsValidated(string $cacheKey, string $groupHash); + + /** + * Warning: Should not be called by user code, to be used by the validator engine only. + * + * @param string $cacheKey The hash of the object + * @param string $groupHash The group's name or hash, if it is group + * sequence + */ + public function isGroupValidated(string $cacheKey, string $groupHash): bool; + + /** + * Warning: Should not be called by user code, to be used by the validator engine only. + * + * @param string $cacheKey The hash of the object + * @param string $constraintHash The hash of the constraint + * + * @return void + */ + public function markConstraintAsValidated(string $cacheKey, string $constraintHash); + + /** + * Warning: Should not be called by user code, to be used by the validator engine only. + * + * @param string $cacheKey The hash of the object + * @param string $constraintHash The hash of the constraint + */ + public function isConstraintValidated(string $cacheKey, string $constraintHash): bool; + + /** + * Warning: Should not be called by user code, to be used by the validator engine only. + * + * @param string $cacheKey The hash of the object + * + * @see ObjectInitializerInterface + */ + public function markObjectAsInitialized(string $cacheKey): void; + + /** + * Warning: Should not be called by user code, to be used by the validator engine only. + * + * @param string $cacheKey The hash of the object + * + * @see ObjectInitializerInterface + */ + public function isObjectInitialized(string $cacheKey): bool; + + /** + * Returns the violations generated by the validator so far. + */ + public function getViolations(): ConstraintViolationListInterface; + + /** + * Returns the value at which validation was started in the object graph. + * + * The validator, when given an object, traverses the properties and + * related objects and their properties. The root of the validation is the + * object from which the traversal started. + * + * The current value is returned by {@link getValue}. + */ + public function getRoot(): mixed; + + /** + * Returns the value that the validator is currently validating. + * + * If you want to retrieve the object that was originally passed to the + * validator, use {@link getRoot}. + */ + public function getValue(): mixed; + + /** + * Returns the metadata for the currently validated value. + * + * With the core implementation, this method returns a + * {@link Mapping\ClassMetadataInterface} instance if the current value is an object, + * a {@link Mapping\PropertyMetadata} instance if the current value is + * the value of a property and a {@link Mapping\GetterMetadata} instance if + * the validated value is the result of a getter method. + * + * If the validated value is neither of these, for example if the validator + * has been called with a plain value and constraint, this method returns + * null. + */ + public function getMetadata(): ?MetadataInterface; + + /** + * Returns the validation group that is currently being validated. + */ + public function getGroup(): ?string; + + /** + * Returns the class name of the current node. + * + * If the metadata of the current node does not implement + * {@link Mapping\ClassMetadataInterface} or if no metadata is available for the + * current node, this method returns null. + */ + public function getClassName(): ?string; + + /** + * Returns the property name of the current node. + * + * If the metadata of the current node does not implement + * {@link PropertyMetadataInterface} or if no metadata is available for the + * current node, this method returns null. + */ + public function getPropertyName(): ?string; + + /** + * Returns the property path to the value that the validator is currently + * validating. + * + * For example, take the following object graph: + * + *
+     * (Person)---($address: Address)---($street: string)
+     * 
+ * + * When the Person instance is passed to the validator, the + * property path is initially empty. When the $address property + * of that person is validated, the property path is "address". When + * the $street property of the related Address instance + * is validated, the property path is "address.street". + * + * Properties of objects are prefixed with a dot in the property path. + * Indices of arrays or objects implementing the {@link \ArrayAccess} + * interface are enclosed in brackets. For example, if the property in + * the previous example is $addresses and contains an array + * of Address instance, the property path generated for the + * $street property of one of these addresses is for example + * "addresses[0].street". + * + * @param string $subPath Optional. The suffix appended to the current + * property path. + * + * @return string The current property path. The result may be an empty + * string if the validator is currently validating the + * root value of the validation graph. + */ + public function getPropertyPath(string $subPath = ''): string; +} diff --git a/lib/symfony/validator/DataCollector/ValidatorDataCollector.php b/lib/symfony/validator/DataCollector/ValidatorDataCollector.php new file mode 100644 index 0000000000..a50b16687a --- /dev/null +++ b/lib/symfony/validator/DataCollector/ValidatorDataCollector.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\DataCollector; + +use Symfony\Component\Form\FormInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DataCollector; +use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface; +use Symfony\Component\Validator\Validator\TraceableValidator; +use Symfony\Component\VarDumper\Caster\Caster; +use Symfony\Component\VarDumper\Caster\ClassStub; +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * @author Maxime Steinhausser + * + * @final + */ +class ValidatorDataCollector extends DataCollector implements LateDataCollectorInterface +{ + private TraceableValidator $validator; + + public function __construct(TraceableValidator $validator) + { + $this->validator = $validator; + $this->reset(); + } + + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void + { + // Everything is collected once, on kernel terminate. + } + + public function reset(): void + { + $this->data = [ + 'calls' => $this->cloneVar([]), + 'violations_count' => 0, + ]; + } + + public function lateCollect(): void + { + $collected = $this->validator->getCollectedData(); + $this->data['calls'] = $this->cloneVar($collected); + $this->data['violations_count'] = array_reduce($collected, fn ($previous, $item) => $previous + \count($item['violations']), 0); + } + + public function getCalls(): Data + { + return $this->data['calls']; + } + + public function getViolationsCount(): int + { + return $this->data['violations_count']; + } + + public function getName(): string + { + return 'validator'; + } + + protected function getCasters(): array + { + return parent::getCasters() + [ + \Exception::class => function (\Exception $e, array $a, Stub $s) { + foreach (["\0Exception\0previous", "\0Exception\0trace"] as $k) { + if (isset($a[$k])) { + unset($a[$k]); + ++$s->cut; + } + } + + return $a; + }, + FormInterface::class => fn (FormInterface $f, array $a) => [ + Caster::PREFIX_VIRTUAL.'name' => $f->getName(), + Caster::PREFIX_VIRTUAL.'type_class' => new ClassStub($f->getConfig()->getType()->getInnerType()::class), + Caster::PREFIX_VIRTUAL.'data' => $f->getData(), + ], + ]; + } +} diff --git a/lib/symfony/validator/DependencyInjection/AddAutoMappingConfigurationPass.php b/lib/symfony/validator/DependencyInjection/AddAutoMappingConfigurationPass.php new file mode 100644 index 0000000000..3fcc84e7dc --- /dev/null +++ b/lib/symfony/validator/DependencyInjection/AddAutoMappingConfigurationPass.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Injects the automapping configuration as last argument of loaders tagged with the "validator.auto_mapper" tag. + * + * @author Kévin Dunglas + */ +class AddAutoMappingConfigurationPass implements CompilerPassInterface +{ + /** + * @return void + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasParameter('validator.auto_mapping') || !$container->hasDefinition('validator.builder')) { + return; + } + + $config = $container->getParameter('validator.auto_mapping'); + + $globalNamespaces = []; + $servicesToNamespaces = []; + foreach ($config as $namespace => $value) { + if ([] === $value['services']) { + $globalNamespaces[] = $namespace; + + continue; + } + + foreach ($value['services'] as $service) { + $servicesToNamespaces[$service][] = $namespace; + } + } + + $validatorBuilder = $container->getDefinition('validator.builder'); + foreach ($container->findTaggedServiceIds('validator.auto_mapper') as $id => $tags) { + $regexp = $this->getRegexp(array_merge($globalNamespaces, $servicesToNamespaces[$id] ?? [])); + $validatorBuilder->addMethodCall('addLoader', [new Reference($id)]); + $container->getDefinition($id)->setArgument('$classValidatorRegexp', $regexp); + } + + $container->getParameterBag()->remove('validator.auto_mapping'); + } + + /** + * Builds a regexp to check if a class is auto-mapped. + */ + private function getRegexp(array $patterns): ?string + { + if (!$patterns) { + return null; + } + + $regexps = []; + foreach ($patterns as $pattern) { + // Escape namespace + $regex = preg_quote(ltrim($pattern, '\\')); + + // Wildcards * and ** + $regex = strtr($regex, ['\\*\\*' => '.*?', '\\*' => '[^\\\\]*?']); + + // If this class does not end by a slash, anchor the end + if (!str_ends_with($regex, '\\')) { + $regex .= '$'; + } + + $regexps[] = '^'.$regex; + } + + return \sprintf('{%s}', implode('|', $regexps)); + } +} diff --git a/lib/symfony/validator/DependencyInjection/AddConstraintValidatorsPass.php b/lib/symfony/validator/DependencyInjection/AddConstraintValidatorsPass.php new file mode 100644 index 0000000000..4bcae00efa --- /dev/null +++ b/lib/symfony/validator/DependencyInjection/AddConstraintValidatorsPass.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * @author Johannes M. Schmitt + * @author Robin Chalas + */ +class AddConstraintValidatorsPass implements CompilerPassInterface +{ + /** + * @return void + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('validator.validator_factory')) { + return; + } + + $validators = []; + foreach ($container->findTaggedServiceIds('validator.constraint_validator', true) as $id => $attributes) { + $definition = $container->getDefinition($id); + + if (isset($attributes[0]['alias'])) { + $validators[$attributes[0]['alias']] = new Reference($id); + } + + $validators[$definition->getClass()] = new Reference($id); + } + + $container + ->getDefinition('validator.validator_factory') + ->replaceArgument(0, ServiceLocatorTagPass::register($container, $validators)) + ; + } +} diff --git a/lib/symfony/validator/DependencyInjection/AddValidatorInitializersPass.php b/lib/symfony/validator/DependencyInjection/AddValidatorInitializersPass.php new file mode 100644 index 0000000000..d53e3c85e7 --- /dev/null +++ b/lib/symfony/validator/DependencyInjection/AddValidatorInitializersPass.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * @author Fabien Potencier + * @author Robin Chalas + */ +class AddValidatorInitializersPass implements CompilerPassInterface +{ + /** + * @return void + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('validator.builder')) { + return; + } + + $initializers = []; + foreach ($container->findTaggedServiceIds('validator.initializer', true) as $id => $attributes) { + $initializers[] = new Reference($id); + } + + $container->getDefinition('validator.builder')->addMethodCall('addObjectInitializers', [$initializers]); + } +} diff --git a/lib/symfony/validator/Exception/BadMethodCallException.php b/lib/symfony/validator/Exception/BadMethodCallException.php new file mode 100644 index 0000000000..939161bff3 --- /dev/null +++ b/lib/symfony/validator/Exception/BadMethodCallException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * Base BadMethodCallException for the Validator component. + * + * @author Bernhard Schussek + */ +class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface +{ +} diff --git a/lib/symfony/validator/Exception/ConstraintDefinitionException.php b/lib/symfony/validator/Exception/ConstraintDefinitionException.php new file mode 100644 index 0000000000..b24fdd68d2 --- /dev/null +++ b/lib/symfony/validator/Exception/ConstraintDefinitionException.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +class ConstraintDefinitionException extends ValidatorException +{ +} diff --git a/lib/symfony/validator/Exception/ExceptionInterface.php b/lib/symfony/validator/Exception/ExceptionInterface.php new file mode 100644 index 0000000000..390e8c053f --- /dev/null +++ b/lib/symfony/validator/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * Base ExceptionInterface for the Validator component. + * + * @author Bernhard Schussek + */ +interface ExceptionInterface extends \Throwable +{ +} diff --git a/lib/symfony/validator/Exception/GroupDefinitionException.php b/lib/symfony/validator/Exception/GroupDefinitionException.php new file mode 100644 index 0000000000..ab7e91d9e6 --- /dev/null +++ b/lib/symfony/validator/Exception/GroupDefinitionException.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +class GroupDefinitionException extends ValidatorException +{ +} diff --git a/lib/symfony/validator/Exception/InvalidArgumentException.php b/lib/symfony/validator/Exception/InvalidArgumentException.php new file mode 100644 index 0000000000..22da39bb26 --- /dev/null +++ b/lib/symfony/validator/Exception/InvalidArgumentException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * Base InvalidArgumentException for the Validator component. + * + * @author Bernhard Schussek + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/lib/symfony/validator/Exception/InvalidOptionsException.php b/lib/symfony/validator/Exception/InvalidOptionsException.php new file mode 100644 index 0000000000..8a4fba25d0 --- /dev/null +++ b/lib/symfony/validator/Exception/InvalidOptionsException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +class InvalidOptionsException extends ValidatorException +{ + private array $options; + + public function __construct(string $message, array $options) + { + parent::__construct($message); + + $this->options = $options; + } + + /** + * @return array + */ + public function getOptions() + { + return $this->options; + } +} diff --git a/lib/symfony/validator/Exception/LogicException.php b/lib/symfony/validator/Exception/LogicException.php new file mode 100644 index 0000000000..41d0975c38 --- /dev/null +++ b/lib/symfony/validator/Exception/LogicException.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/lib/symfony/validator/Exception/MappingException.php b/lib/symfony/validator/Exception/MappingException.php new file mode 100644 index 0000000000..4c8c057b9f --- /dev/null +++ b/lib/symfony/validator/Exception/MappingException.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +class MappingException extends ValidatorException +{ +} diff --git a/lib/symfony/validator/Exception/MissingOptionsException.php b/lib/symfony/validator/Exception/MissingOptionsException.php new file mode 100644 index 0000000000..a7eda1457d --- /dev/null +++ b/lib/symfony/validator/Exception/MissingOptionsException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +class MissingOptionsException extends ValidatorException +{ + private array $options; + + public function __construct(string $message, array $options) + { + parent::__construct($message); + + $this->options = $options; + } + + /** + * @return array + */ + public function getOptions() + { + return $this->options; + } +} diff --git a/lib/symfony/validator/Exception/NoSuchMetadataException.php b/lib/symfony/validator/Exception/NoSuchMetadataException.php new file mode 100644 index 0000000000..4cac74cf30 --- /dev/null +++ b/lib/symfony/validator/Exception/NoSuchMetadataException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * @author Bernhard Schussek + */ +class NoSuchMetadataException extends ValidatorException +{ +} diff --git a/lib/symfony/validator/Exception/OutOfBoundsException.php b/lib/symfony/validator/Exception/OutOfBoundsException.php new file mode 100644 index 0000000000..30906e8a82 --- /dev/null +++ b/lib/symfony/validator/Exception/OutOfBoundsException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * Base OutOfBoundsException for the Validator component. + * + * @author Bernhard Schussek + */ +class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface +{ +} diff --git a/lib/symfony/validator/Exception/RuntimeException.php b/lib/symfony/validator/Exception/RuntimeException.php new file mode 100644 index 0000000000..df4a50c474 --- /dev/null +++ b/lib/symfony/validator/Exception/RuntimeException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * Base RuntimeException for the Validator component. + * + * @author Bernhard Schussek + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/lib/symfony/validator/Exception/UnexpectedTypeException.php b/lib/symfony/validator/Exception/UnexpectedTypeException.php new file mode 100644 index 0000000000..24ae4b3ac6 --- /dev/null +++ b/lib/symfony/validator/Exception/UnexpectedTypeException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +class UnexpectedTypeException extends ValidatorException +{ + public function __construct(mixed $value, string $expectedType) + { + parent::__construct(\sprintf('Expected argument of type "%s", "%s" given', $expectedType, get_debug_type($value))); + } +} diff --git a/lib/symfony/validator/Exception/UnexpectedValueException.php b/lib/symfony/validator/Exception/UnexpectedValueException.php new file mode 100644 index 0000000000..83a7e7a7d6 --- /dev/null +++ b/lib/symfony/validator/Exception/UnexpectedValueException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * @author Christian Flothmann + */ +class UnexpectedValueException extends UnexpectedTypeException +{ + private string $expectedType; + + public function __construct(mixed $value, string $expectedType) + { + parent::__construct($value, $expectedType); + + $this->expectedType = $expectedType; + } + + public function getExpectedType(): string + { + return $this->expectedType; + } +} diff --git a/lib/symfony/validator/Exception/UnsupportedMetadataException.php b/lib/symfony/validator/Exception/UnsupportedMetadataException.php new file mode 100644 index 0000000000..aff569b957 --- /dev/null +++ b/lib/symfony/validator/Exception/UnsupportedMetadataException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +/** + * @author Bernhard Schussek + */ +class UnsupportedMetadataException extends InvalidArgumentException +{ +} diff --git a/lib/symfony/validator/Exception/ValidationFailedException.php b/lib/symfony/validator/Exception/ValidationFailedException.php new file mode 100644 index 0000000000..2106e0a0ba --- /dev/null +++ b/lib/symfony/validator/Exception/ValidationFailedException.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +use Symfony\Component\Validator\ConstraintViolationListInterface; + +/** + * @author Jan Vernieuwe + */ +class ValidationFailedException extends RuntimeException +{ + private ConstraintViolationListInterface $violations; + private mixed $value; + + public function __construct(mixed $value, ConstraintViolationListInterface $violations) + { + $this->violations = $violations; + $this->value = $value; + parent::__construct($violations); + } + + /** + * @return mixed + */ + public function getValue() + { + return $this->value; + } + + public function getViolations(): ConstraintViolationListInterface + { + return $this->violations; + } +} diff --git a/lib/symfony/validator/Exception/ValidatorException.php b/lib/symfony/validator/Exception/ValidatorException.php new file mode 100644 index 0000000000..28bd4704e8 --- /dev/null +++ b/lib/symfony/validator/Exception/ValidatorException.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Exception; + +class ValidatorException extends RuntimeException +{ +} diff --git a/lib/symfony/validator/GroupProviderInterface.php b/lib/symfony/validator/GroupProviderInterface.php new file mode 100644 index 0000000000..7651ca2233 --- /dev/null +++ b/lib/symfony/validator/GroupProviderInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Symfony\Component\Validator\Constraints\GroupSequence; + +/** + * Defines the interface for a validation group provider. + * + * @author Yonel Ceruto + */ +interface GroupProviderInterface +{ + /** + * Returns which validation groups should be used for a certain state + * of the object. + * + * @return string[]|string[][]|GroupSequence + */ + public function getGroups(object $object): array|GroupSequence; +} diff --git a/lib/symfony/validator/GroupSequenceProviderInterface.php b/lib/symfony/validator/GroupSequenceProviderInterface.php new file mode 100644 index 0000000000..32fae2365c --- /dev/null +++ b/lib/symfony/validator/GroupSequenceProviderInterface.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Symfony\Component\Validator\Constraints\GroupSequence; + +/** + * Defines the interface for a group sequence provider. + */ +interface GroupSequenceProviderInterface +{ + /** + * Returns which validation groups should be used for a certain state + * of the object. + * + * @return string[]|string[][]|GroupSequence + */ + public function getGroupSequence(): array|GroupSequence; +} diff --git a/lib/symfony/validator/LICENSE b/lib/symfony/validator/LICENSE new file mode 100644 index 0000000000..0138f8f071 --- /dev/null +++ b/lib/symfony/validator/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/symfony/validator/Mapping/AutoMappingStrategy.php b/lib/symfony/validator/Mapping/AutoMappingStrategy.php new file mode 100644 index 0000000000..4012ddcff9 --- /dev/null +++ b/lib/symfony/validator/Mapping/AutoMappingStrategy.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping; + +/** + * Specifies how the auto-mapping feature should behave. + * + * @author Maxime Steinhausser + */ +final class AutoMappingStrategy +{ + /** + * Nothing explicitly set, rely on auto-mapping configured regex. + */ + public const NONE = 0; + + /** + * Explicitly enabled. + */ + public const ENABLED = 1; + + /** + * Explicitly disabled. + */ + public const DISABLED = 2; + + /** + * Not instantiable. + */ + private function __construct() + { + } +} diff --git a/lib/symfony/validator/Mapping/CascadingStrategy.php b/lib/symfony/validator/Mapping/CascadingStrategy.php new file mode 100644 index 0000000000..6bab8ac4e6 --- /dev/null +++ b/lib/symfony/validator/Mapping/CascadingStrategy.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping; + +/** + * Specifies whether an object should be cascaded. + * + * Cascading is relevant for any node type but class nodes. If such a node + * contains an object of value, and if cascading is enabled, then the node + * traverser will try to find class metadata for that object and validate the + * object against that metadata. + * + * If no metadata is found for a cascaded object, and if that object implements + * {@link \Traversable}, the node traverser will iterate over the object and + * cascade each object or collection contained within, unless iteration is + * prohibited by the specified {@link TraversalStrategy}. + * + * Although the constants currently represent a boolean switch, they are + * implemented as bit mask in order to allow future extensions. + * + * @author Bernhard Schussek + * + * @see TraversalStrategy + */ +class CascadingStrategy +{ + /** + * Specifies that a node should not be cascaded. + */ + public const NONE = 1; + + /** + * Specifies that a node should be cascaded. + */ + public const CASCADE = 2; + + /** + * Not instantiable. + */ + private function __construct() + { + } +} diff --git a/lib/symfony/validator/Mapping/ClassMetadata.php b/lib/symfony/validator/Mapping/ClassMetadata.php new file mode 100644 index 0000000000..bf164faac0 --- /dev/null +++ b/lib/symfony/validator/Mapping/ClassMetadata.php @@ -0,0 +1,519 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\Cascade; +use Symfony\Component\Validator\Constraints\Composite; +use Symfony\Component\Validator\Constraints\GroupSequence; +use Symfony\Component\Validator\Constraints\Traverse; +use Symfony\Component\Validator\Constraints\Valid; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\GroupDefinitionException; +use Symfony\Component\Validator\GroupSequenceProviderInterface; + +/** + * Default implementation of {@link ClassMetadataInterface}. + * + * This class supports serialization and cloning. + * + * @author Bernhard Schussek + * @author Fabien Potencier + */ +class ClassMetadata extends GenericMetadata implements ClassMetadataInterface +{ + /** + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getClassName()} instead. + */ + public string $name; + + /** + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getDefaultGroup()} instead. + */ + public string $defaultGroup; + + /** + * @var MemberMetadata[][] + * + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getPropertyMetadata()} instead. + */ + public array $members = []; + + /** + * @var PropertyMetadata[] + * + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getPropertyMetadata()} instead. + */ + public array $properties = []; + + /** + * @var GetterMetadata[] + * + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getPropertyMetadata()} instead. + */ + public array $getters = []; + + /** + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getGroupSequence()} instead. + */ + public ?GroupSequence $groupSequence = null; + + /** + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link isGroupSequenceProvider()} instead. + */ + public bool $groupSequenceProvider = false; + + /** + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getGroupProvider()} instead. + */ + public ?string $groupProvider = null; + + /** + * The strategy for traversing traversable objects. + * + * By default, only instances of {@link \Traversable} are traversed. + * + * @var TraversalStrategy::* + * + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getTraversalStrategy()} instead. + */ + public int $traversalStrategy = TraversalStrategy::IMPLICIT; + + private \ReflectionClass $reflClass; + + public function __construct(string $class) + { + $this->name = $class; + // class name without namespace + if (false !== $nsSep = strrpos($class, '\\')) { + $this->defaultGroup = substr($class, $nsSep + 1); + } else { + $this->defaultGroup = $class; + } + } + + public function __sleep(): array + { + $parentProperties = parent::__sleep(); + + // Don't store the cascading strategy. Classes never cascade. + unset($parentProperties[array_search('cascadingStrategy', $parentProperties)]); + + return array_merge($parentProperties, [ + 'getters', + 'groupSequence', + 'groupSequenceProvider', + 'groupProvider', + 'members', + 'name', + 'properties', + 'defaultGroup', + ]); + } + + public function getClassName(): string + { + return $this->name; + } + + /** + * Returns the name of the default group for this class. + * + * For each class, the group "Default" is an alias for the group + * "", where is the non-namespaced name of the + * class. All constraints implicitly or explicitly assigned to group + * "Default" belong to both of these groups, unless the class defines + * a group sequence. + * + * If a class defines a group sequence, validating the class in "Default" + * will validate the group sequence. The constraints assigned to "Default" + * can still be validated by validating the class in "". + */ + public function getDefaultGroup(): string + { + return $this->defaultGroup; + } + + /** + * If the constraint {@link Cascade} is added, the cascading strategy will be + * changed to {@link CascadingStrategy::CASCADE}. + * + * If the constraint {@link Traverse} is added, the traversal strategy will be + * changed. Depending on the $traverse property of that constraint, + * the traversal strategy will be set to one of the following: + * + * - {@link TraversalStrategy::IMPLICIT} by default + * - {@link TraversalStrategy::NONE} if $traverse is disabled + * - {@link TraversalStrategy::TRAVERSE} if $traverse is enabled + */ + public function addConstraint(Constraint $constraint): static + { + $this->checkConstraint($constraint); + + if ($constraint instanceof Traverse) { + if ($constraint->traverse) { + // If traverse is true, traversal should be explicitly enabled + $this->traversalStrategy = TraversalStrategy::TRAVERSE; + } else { + // If traverse is false, traversal should be explicitly disabled + $this->traversalStrategy = TraversalStrategy::NONE; + } + + // The constraint is not added + return $this; + } + + if ($constraint instanceof Cascade) { + $this->cascadingStrategy = CascadingStrategy::CASCADE; + + foreach ($this->getReflectionClass()->getProperties() as $property) { + if (isset($constraint->exclude[$property->getName()])) { + continue; + } + + if ($this->canCascade($property->getType())) { + $this->addPropertyConstraint($property->getName(), new Valid()); + } + } + + // The constraint is not added + return $this; + } + + $constraint->addImplicitGroupName($this->getDefaultGroup()); + + parent::addConstraint($constraint); + + return $this; + } + + /** + * Adds a constraint to the given property. + * + * @return $this + */ + public function addPropertyConstraint(string $property, Constraint $constraint): static + { + if (!isset($this->properties[$property])) { + $this->properties[$property] = new PropertyMetadata($this->getClassName(), $property); + + $this->addPropertyMetadata($this->properties[$property]); + } + + $constraint->addImplicitGroupName($this->getDefaultGroup()); + + $this->properties[$property]->addConstraint($constraint); + + return $this; + } + + /** + * @param Constraint[] $constraints + * + * @return $this + */ + public function addPropertyConstraints(string $property, array $constraints): static + { + foreach ($constraints as $constraint) { + $this->addPropertyConstraint($property, $constraint); + } + + return $this; + } + + /** + * Adds a constraint to the getter of the given property. + * + * The name of the getter is assumed to be the name of the property with an + * uppercased first letter and the prefix "get", "is" or "has". + * + * @return $this + */ + public function addGetterConstraint(string $property, Constraint $constraint): static + { + if (!isset($this->getters[$property])) { + $this->getters[$property] = new GetterMetadata($this->getClassName(), $property); + + $this->addPropertyMetadata($this->getters[$property]); + } + + $constraint->addImplicitGroupName($this->getDefaultGroup()); + + $this->getters[$property]->addConstraint($constraint); + + return $this; + } + + /** + * Adds a constraint to the getter of the given property. + * + * @return $this + */ + public function addGetterMethodConstraint(string $property, string $method, Constraint $constraint): static + { + if (!isset($this->getters[$property])) { + $this->getters[$property] = new GetterMetadata($this->getClassName(), $property, $method); + + $this->addPropertyMetadata($this->getters[$property]); + } + + $constraint->addImplicitGroupName($this->getDefaultGroup()); + + $this->getters[$property]->addConstraint($constraint); + + return $this; + } + + /** + * @param Constraint[] $constraints + * + * @return $this + */ + public function addGetterConstraints(string $property, array $constraints): static + { + foreach ($constraints as $constraint) { + $this->addGetterConstraint($property, $constraint); + } + + return $this; + } + + /** + * @param Constraint[] $constraints + * + * @return $this + */ + public function addGetterMethodConstraints(string $property, string $method, array $constraints): static + { + foreach ($constraints as $constraint) { + $this->addGetterMethodConstraint($property, $method, $constraint); + } + + return $this; + } + + /** + * Merges the constraints of the given metadata into this object. + * + * @return void + */ + public function mergeConstraints(self $source) + { + if ($source->isGroupSequenceProvider()) { + $this->setGroupProvider($source->getGroupProvider()); + $this->setGroupSequenceProvider(true); + } + + foreach ($source->getConstraints() as $constraint) { + $this->addConstraint(clone $constraint); + } + + foreach ($source->getConstrainedProperties() as $property) { + foreach ($source->getPropertyMetadata($property) as $member) { + $member = clone $member; + + foreach ($member->getConstraints() as $constraint) { + if (\in_array($constraint::DEFAULT_GROUP, $constraint->groups, true)) { + $member->constraintsByGroup[$this->getDefaultGroup()][] = $constraint; + } + + $constraint->addImplicitGroupName($this->getDefaultGroup()); + } + + if ($member instanceof MemberMetadata && !$member->isPrivate($this->name)) { + $property = $member->getPropertyName(); + $this->members[$property][] = $member; + + if ($member instanceof PropertyMetadata && !isset($this->properties[$property])) { + $this->properties[$property] = $member; + } elseif ($member instanceof GetterMetadata && !isset($this->getters[$property])) { + $this->getters[$property] = $member; + } + } else { + $this->addPropertyMetadata($member); + } + } + } + } + + public function hasPropertyMetadata(string $property): bool + { + return \array_key_exists($property, $this->members); + } + + public function getPropertyMetadata(string $property): array + { + return $this->members[$property] ?? []; + } + + public function getConstrainedProperties(): array + { + return array_keys($this->members); + } + + /** + * Sets the default group sequence for this class. + * + * @param string[]|GroupSequence $groupSequence An array of group names + * + * @return $this + * + * @throws GroupDefinitionException + */ + public function setGroupSequence(array|GroupSequence $groupSequence): static + { + if ($this->isGroupSequenceProvider()) { + throw new GroupDefinitionException('Defining a static group sequence is not allowed with a group sequence provider.'); + } + + if (\is_array($groupSequence)) { + $groupSequence = new GroupSequence($groupSequence); + } + + if (\in_array(Constraint::DEFAULT_GROUP, $groupSequence->groups, true)) { + throw new GroupDefinitionException(\sprintf('The group "%s" is not allowed in group sequences.', Constraint::DEFAULT_GROUP)); + } + + if (!\in_array($this->getDefaultGroup(), $groupSequence->groups, true)) { + throw new GroupDefinitionException(\sprintf('The group "%s" is missing in the group sequence.', $this->getDefaultGroup())); + } + + $this->groupSequence = $groupSequence; + + return $this; + } + + public function hasGroupSequence(): bool + { + return isset($this->groupSequence) && \count($this->groupSequence->groups) > 0; + } + + public function getGroupSequence(): ?GroupSequence + { + return $this->groupSequence; + } + + /** + * Returns a ReflectionClass instance for this class. + */ + public function getReflectionClass(): \ReflectionClass + { + return $this->reflClass ??= new \ReflectionClass($this->getClassName()); + } + + /** + * Sets whether a group sequence provider should be used. + * + * @return void + * + * @throws GroupDefinitionException + */ + public function setGroupSequenceProvider(bool $active) + { + if ($this->hasGroupSequence()) { + throw new GroupDefinitionException('Defining a group sequence provider is not allowed with a static group sequence.'); + } + + if (null === $this->groupProvider && !$this->getReflectionClass()->implementsInterface(GroupSequenceProviderInterface::class)) { + throw new GroupDefinitionException(\sprintf('Class "%s" must implement GroupSequenceProviderInterface.', $this->name)); + } + + $this->groupSequenceProvider = $active; + } + + public function isGroupSequenceProvider(): bool + { + return $this->groupSequenceProvider; + } + + public function setGroupProvider(?string $provider): void + { + $this->groupProvider = $provider; + } + + public function getGroupProvider(): ?string + { + return $this->groupProvider; + } + + public function getCascadingStrategy(): int + { + return $this->cascadingStrategy; + } + + private function addPropertyMetadata(PropertyMetadataInterface $metadata): void + { + $property = $metadata->getPropertyName(); + + $this->members[$property][] = $metadata; + } + + private function checkConstraint(Constraint $constraint): void + { + if (!\in_array(Constraint::CLASS_CONSTRAINT, (array) $constraint->getTargets(), true)) { + throw new ConstraintDefinitionException(\sprintf('The constraint "%s" cannot be put on classes.', get_debug_type($constraint))); + } + + if ($constraint instanceof Composite) { + foreach ($constraint->getNestedConstraints() as $nestedConstraint) { + $this->checkConstraint($nestedConstraint); + } + } + } + + private function canCascade(?\ReflectionType $type = null): bool + { + if (null === $type) { + return false; + } + + if ($type instanceof \ReflectionIntersectionType) { + foreach ($type->getTypes() as $nestedType) { + if ($this->canCascade($nestedType)) { + return true; + } + } + + return false; + } + + if ($type instanceof \ReflectionUnionType) { + foreach ($type->getTypes() as $nestedType) { + if (!$this->canCascade($nestedType)) { + return false; + } + } + + return true; + } + + return $type instanceof \ReflectionNamedType && (\in_array($type->getName(), ['array', 'null'], true) || class_exists($type->getName())); + } +} diff --git a/lib/symfony/validator/Mapping/ClassMetadataInterface.php b/lib/symfony/validator/Mapping/ClassMetadataInterface.php new file mode 100644 index 0000000000..6625e37e60 --- /dev/null +++ b/lib/symfony/validator/Mapping/ClassMetadataInterface.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping; + +use Symfony\Component\Validator\Constraints\GroupSequence; +use Symfony\Component\Validator\GroupSequenceProviderInterface; + +/** + * Stores all metadata needed for validating objects of specific class. + * + * Most importantly, the metadata stores the constraints against which an object + * and its properties should be validated. + * + * Additionally, the metadata stores whether the "Default" group is overridden + * by a group sequence for that class and whether instances of that class + * should be traversed or not. + * + * @author Bernhard Schussek + * + * @see MetadataInterface + * @see GroupSequence + * @see GroupSequenceProviderInterface + * @see TraversalStrategy + * + * @method string|null getGroupProvider() + */ +interface ClassMetadataInterface extends MetadataInterface +{ + /** + * Returns the names of all constrained properties. + * + * @return string[] + */ + public function getConstrainedProperties(): array; + + /** + * Returns whether the "Default" group is overridden by a group sequence. + * + * If it is, you can access the group sequence with {@link getGroupSequence()}. + */ + public function hasGroupSequence(): bool; + + /** + * Returns the group sequence that overrides the "Default" group for this + * class. + */ + public function getGroupSequence(): ?GroupSequence; + + /** + * Returns whether the "Default" group is overridden by a dynamic group + * sequence obtained by the validated objects. + * + * If this method returns true, the class must implement + * {@link GroupSequenceProviderInterface}. + * This interface will be used to obtain the group sequence when an object + * of this class is validated. + */ + public function isGroupSequenceProvider(): bool; + + /** + * Check if there's any metadata attached to the given named property. + * + * @param string $property The property name + */ + public function hasPropertyMetadata(string $property): bool; + + /** + * Returns all metadata instances for the given named property. + * + * If your implementation does not support properties, throw an exception + * in this method (for example a BadMethodCallException). + * + * @param string $property The property name + * + * @return PropertyMetadataInterface[] + */ + public function getPropertyMetadata(string $property): array; + + /** + * Returns the name of the backing PHP class. + */ + public function getClassName(): string; +} diff --git a/lib/symfony/validator/Mapping/Factory/BlackHoleMetadataFactory.php b/lib/symfony/validator/Mapping/Factory/BlackHoleMetadataFactory.php new file mode 100644 index 0000000000..d46dccc66d --- /dev/null +++ b/lib/symfony/validator/Mapping/Factory/BlackHoleMetadataFactory.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Factory; + +use Symfony\Component\Validator\Exception\LogicException; +use Symfony\Component\Validator\Mapping\MetadataInterface; + +/** + * Metadata factory that does not store metadata. + * + * This implementation is useful if you want to validate values against + * constraints only and you don't need to add constraints to classes and + * properties. + * + * @author Fabien Potencier + */ +class BlackHoleMetadataFactory implements MetadataFactoryInterface +{ + public function getMetadataFor(mixed $value): MetadataInterface + { + throw new LogicException('This class does not support metadata.'); + } + + public function hasMetadataFor(mixed $value): bool + { + return false; + } +} diff --git a/lib/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php b/lib/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php new file mode 100644 index 0000000000..f977f20dfd --- /dev/null +++ b/lib/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php @@ -0,0 +1,159 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Factory; + +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Validator\Exception\NoSuchMetadataException; +use Symfony\Component\Validator\Mapping\ClassMetadata; +use Symfony\Component\Validator\Mapping\Loader\LoaderInterface; +use Symfony\Component\Validator\Mapping\MetadataInterface; + +/** + * Creates new {@link ClassMetadataInterface} instances. + * + * Whenever {@link getMetadataFor()} is called for the first time with a given + * class name or object of that class, a new metadata instance is created and + * returned. On subsequent requests for the same class, the same metadata + * instance will be returned. + * + * You can optionally pass a {@link LoaderInterface} instance to the constructor. + * Whenever a new metadata instance is created, it is passed to the loader, + * which can configure the metadata based on configuration loaded from the + * filesystem or a database. If you want to use multiple loaders, wrap them in a + * {@link LoaderChain}. + * + * You can also optionally pass a {@link CacheInterface} instance to the + * constructor. This cache will be used for persisting the generated metadata + * between multiple PHP requests. + * + * @author Bernhard Schussek + */ +class LazyLoadingMetadataFactory implements MetadataFactoryInterface +{ + protected $loader; + protected $cache; + + /** + * The loaded metadata, indexed by class name. + * + * @var ClassMetadata[] + */ + protected $loadedClasses = []; + + public function __construct(?LoaderInterface $loader = null, ?CacheItemPoolInterface $cache = null) + { + $this->loader = $loader; + $this->cache = $cache; + } + + /** + * If the method was called with the same class name (or an object of that + * class) before, the same metadata instance is returned. + * + * If the factory was configured with a cache, this method will first look + * for an existing metadata instance in the cache. If an existing instance + * is found, it will be returned without further ado. + * + * Otherwise, a new metadata instance is created. If the factory was + * configured with a loader, the metadata is passed to the + * {@link LoaderInterface::loadClassMetadata()} method for further + * configuration. At last, the new object is returned. + */ + public function getMetadataFor(mixed $value): MetadataInterface + { + if (!\is_object($value) && !\is_string($value)) { + throw new NoSuchMetadataException(\sprintf('Cannot create metadata for non-objects. Got: "%s".', get_debug_type($value))); + } + + $class = ltrim(\is_object($value) ? $value::class : $value, '\\'); + + if (isset($this->loadedClasses[$class])) { + return $this->loadedClasses[$class]; + } + + if (!class_exists($class) && !interface_exists($class, false)) { + throw new NoSuchMetadataException(\sprintf('The class or interface "%s" does not exist.', $class)); + } + + $cacheItem = $this->cache?->getItem($this->escapeClassName($class)); + if ($cacheItem?->isHit()) { + $metadata = $cacheItem->get(); + + // Include constraints from the parent class + $this->mergeConstraints($metadata); + + return $this->loadedClasses[$class] = $metadata; + } + + $metadata = new ClassMetadata($class); + + $this->loader?->loadClassMetadata($metadata); + + if (null !== $cacheItem) { + $this->cache->save($cacheItem->set($metadata)); + } + + // Include constraints from the parent class + $this->mergeConstraints($metadata); + + return $this->loadedClasses[$class] = $metadata; + } + + private function mergeConstraints(ClassMetadata $metadata): void + { + if ($metadata->getReflectionClass()->isInterface()) { + return; + } + + // Include constraints from the parent class + if ($parent = $metadata->getReflectionClass()->getParentClass()) { + $metadata->mergeConstraints($this->getMetadataFor($parent->name)); + } + + // Include constraints from all directly implemented interfaces + foreach ($metadata->getReflectionClass()->getInterfaces() as $interface) { + if ('Symfony\Component\Validator\GroupSequenceProviderInterface' === $interface->name) { + continue; + } + + if ($parent && \in_array($interface->getName(), $parent->getInterfaceNames(), true)) { + continue; + } + + $metadata->mergeConstraints($this->getMetadataFor($interface->name)); + } + } + + public function hasMetadataFor(mixed $value): bool + { + if (!\is_object($value) && !\is_string($value)) { + return false; + } + + $class = ltrim(\is_object($value) ? $value::class : $value, '\\'); + + return class_exists($class) || interface_exists($class, false); + } + + /** + * Replaces backslashes by dots in a class name. + */ + private function escapeClassName(string $class): string + { + if (str_contains($class, '@')) { + // anonymous class: replace all PSR6-reserved characters + return str_replace(["\0", '\\', '/', '@', ':', '{', '}', '(', ')'], '.', $class); + } + + return str_replace('\\', '.', $class); + } +} diff --git a/lib/symfony/validator/Mapping/Factory/MetadataFactoryInterface.php b/lib/symfony/validator/Mapping/Factory/MetadataFactoryInterface.php new file mode 100644 index 0000000000..8e89d3b7da --- /dev/null +++ b/lib/symfony/validator/Mapping/Factory/MetadataFactoryInterface.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Factory; + +use Symfony\Component\Validator\Exception\NoSuchMetadataException; +use Symfony\Component\Validator\Mapping\MetadataInterface; + +/** + * Returns {@link \Symfony\Component\Validator\Mapping\MetadataInterface} instances for values. + * + * @author Bernhard Schussek + */ +interface MetadataFactoryInterface +{ + /** + * Returns the metadata for the given value. + * + * @throws NoSuchMetadataException If no metadata exists for the given value + */ + public function getMetadataFor(mixed $value): MetadataInterface; + + /** + * Returns whether the class is able to return metadata for the given value. + */ + public function hasMetadataFor(mixed $value): bool; +} diff --git a/lib/symfony/validator/Mapping/GenericMetadata.php b/lib/symfony/validator/Mapping/GenericMetadata.php new file mode 100644 index 0000000000..43992255c9 --- /dev/null +++ b/lib/symfony/validator/Mapping/GenericMetadata.php @@ -0,0 +1,226 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\Cascade; +use Symfony\Component\Validator\Constraints\DisableAutoMapping; +use Symfony\Component\Validator\Constraints\EnableAutoMapping; +use Symfony\Component\Validator\Constraints\Traverse; +use Symfony\Component\Validator\Constraints\Valid; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * A generic container of {@link Constraint} objects. + * + * This class supports serialization and cloning. + * + * @author Bernhard Schussek + */ +class GenericMetadata implements MetadataInterface +{ + /** + * @var Constraint[] + * + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getConstraints()} and {@link findConstraints()} instead. + */ + public array $constraints = []; + + /** + * @var array + * + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link findConstraints()} instead. + */ + public array $constraintsByGroup = []; + + /** + * The strategy for cascading objects. + * + * By default, objects are not cascaded. + * + * @var CascadingStrategy::* + * + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getCascadingStrategy()} instead. + */ + public int $cascadingStrategy = CascadingStrategy::NONE; + + /** + * The strategy for traversing traversable objects. + * + * By default, traversable objects are not traversed. + * + * @var TraversalStrategy::* + * + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getTraversalStrategy()} instead. + */ + public int $traversalStrategy = TraversalStrategy::NONE; + + /** + * Is auto-mapping enabled? + * + * @var AutoMappingStrategy::* + * + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getAutoMappingStrategy()} instead. + */ + public int $autoMappingStrategy = AutoMappingStrategy::NONE; + + /** + * Returns the names of the properties that should be serialized. + * + * @return string[] + */ + public function __sleep(): array + { + return [ + 'constraints', + 'constraintsByGroup', + 'cascadingStrategy', + 'traversalStrategy', + 'autoMappingStrategy', + ]; + } + + /** + * Clones this object. + */ + public function __clone() + { + $constraints = $this->constraints; + + $this->constraints = []; + $this->constraintsByGroup = []; + + foreach ($constraints as $constraint) { + $this->addConstraint(clone $constraint); + } + } + + /** + * Adds a constraint. + * + * If the constraint {@link Valid} is added, the cascading strategy will be + * changed to {@link CascadingStrategy::CASCADE}. Depending on the + * $traverse property of that constraint, the traversal strategy + * will be set to one of the following: + * + * - {@link TraversalStrategy::IMPLICIT} if $traverse is enabled + * - {@link TraversalStrategy::NONE} if $traverse is disabled + * + * @return $this + * + * @throws ConstraintDefinitionException When trying to add the {@link Cascade} + * or {@link Traverse} constraint + */ + public function addConstraint(Constraint $constraint): static + { + if ($constraint instanceof Traverse || $constraint instanceof Cascade) { + throw new ConstraintDefinitionException(\sprintf('The constraint "%s" can only be put on classes. Please use "Symfony\Component\Validator\Constraints\Valid" instead.', get_debug_type($constraint))); + } + + if ($constraint instanceof Valid && null === $constraint->groups) { + $this->cascadingStrategy = CascadingStrategy::CASCADE; + + if ($constraint->traverse) { + $this->traversalStrategy = TraversalStrategy::IMPLICIT; + } else { + $this->traversalStrategy = TraversalStrategy::NONE; + } + + return $this; + } + + if ($constraint instanceof DisableAutoMapping || $constraint instanceof EnableAutoMapping) { + $this->autoMappingStrategy = $constraint instanceof EnableAutoMapping ? AutoMappingStrategy::ENABLED : AutoMappingStrategy::DISABLED; + + // The constraint is not added + return $this; + } + + $this->constraints[] = $constraint; + + foreach ($constraint->groups as $group) { + $this->constraintsByGroup[$group][] = $constraint; + } + + return $this; + } + + /** + * Adds an list of constraints. + * + * @param Constraint[] $constraints The constraints to add + * + * @return $this + */ + public function addConstraints(array $constraints): static + { + foreach ($constraints as $constraint) { + $this->addConstraint($constraint); + } + + return $this; + } + + /** + * @return Constraint[] + */ + public function getConstraints(): array + { + return $this->constraints; + } + + /** + * Returns whether this element has any constraints. + */ + public function hasConstraints(): bool + { + return \count($this->constraints) > 0; + } + + /** + * Aware of the global group (* group). + * + * @return Constraint[] + */ + public function findConstraints(string $group): array + { + return $this->constraintsByGroup[$group] ?? []; + } + + public function getCascadingStrategy(): int + { + return $this->cascadingStrategy; + } + + public function getTraversalStrategy(): int + { + return $this->traversalStrategy; + } + + /** + * @see AutoMappingStrategy + */ + public function getAutoMappingStrategy(): int + { + return $this->autoMappingStrategy; + } +} diff --git a/lib/symfony/validator/Mapping/GetterMetadata.php b/lib/symfony/validator/Mapping/GetterMetadata.php new file mode 100644 index 0000000000..a4e2352ec0 --- /dev/null +++ b/lib/symfony/validator/Mapping/GetterMetadata.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping; + +use Symfony\Component\Validator\Exception\ValidatorException; + +/** + * Stores all metadata needed for validating a class property via its getter + * method. + * + * A property getter is any method that is equal to the property's name, + * prefixed with "get", "is" or "has". That method will be used to access the + * property's value. + * + * The getter will be invoked by reflection, so the access of private and + * protected getters is supported. + * + * This class supports serialization and cloning. + * + * @author Bernhard Schussek + * + * @see PropertyMetadataInterface + */ +class GetterMetadata extends MemberMetadata +{ + /** + * @param string $class The class the getter is defined on + * @param string $property The property which the getter returns + * @param string|null $method The method that is called to retrieve the value being validated (null for auto-detection) + * + * @throws ValidatorException + */ + public function __construct(string $class, string $property, ?string $method = null) + { + if (null === $method) { + $getMethod = 'get'.ucfirst($property); + $isMethod = 'is'.ucfirst($property); + $hasMethod = 'has'.ucfirst($property); + + if (method_exists($class, $getMethod)) { + $method = $getMethod; + } elseif (method_exists($class, $isMethod)) { + $method = $isMethod; + } elseif (method_exists($class, $hasMethod)) { + $method = $hasMethod; + } else { + throw new ValidatorException(\sprintf('Neither of these methods exist in class "%s": "%s", "%s", "%s".', $class, $getMethod, $isMethod, $hasMethod)); + } + } elseif (!method_exists($class, $method)) { + throw new ValidatorException(\sprintf('The "%s()" method does not exist in class "%s".', $method, $class)); + } + + parent::__construct($class, $method, $property); + } + + public function getPropertyValue(mixed $object): mixed + { + return $this->newReflectionMember($object)->invoke($object); + } + + protected function newReflectionMember(object|string $objectOrClassName): \ReflectionMethod|\ReflectionProperty + { + return new \ReflectionMethod($objectOrClassName, $this->getName()); + } +} diff --git a/lib/symfony/validator/Mapping/Loader/AbstractLoader.php b/lib/symfony/validator/Mapping/Loader/AbstractLoader.php new file mode 100644 index 0000000000..5c81baa5dd --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/AbstractLoader.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Symfony\Component\Validator\Attribute\HasNamedArguments; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\MappingException; + +/** + * Base loader for validation metadata. + * + * This loader supports the loading of constraints from Symfony's default + * namespace (see {@link DEFAULT_NAMESPACE}) using the short class names of + * those constraints. Constraints can also be loaded using their fully + * qualified class names. At last, namespace aliases can be defined to load + * constraints with the syntax "alias:ShortName". + * + * @author Bernhard Schussek + */ +abstract class AbstractLoader implements LoaderInterface +{ + /** + * The namespace to load constraints from by default. + */ + public const DEFAULT_NAMESPACE = '\\Symfony\\Component\\Validator\\Constraints\\'; + + protected $namespaces = []; + + /** + * @var array + */ + private array $namedArgumentsCache = []; + + /** + * Adds a namespace alias. + * + * The namespace alias can be used to reference constraints from specific + * namespaces in {@link newConstraint()}: + * + * $this->addNamespaceAlias('mynamespace', '\\Acme\\Package\\Constraints\\'); + * + * $constraint = $this->newConstraint('mynamespace:NotNull'); + * + * @return void + */ + protected function addNamespaceAlias(string $alias, string $namespace) + { + $this->namespaces[$alias] = $namespace; + } + + /** + * Creates a new constraint instance for the given constraint name. + * + * @param string $name The constraint name. Either a constraint relative + * to the default constraint namespace, or a fully + * qualified class name. Alternatively, the constraint + * may be preceded by a namespace alias and a colon. + * The namespace alias must have been defined using + * {@link addNamespaceAlias()}. + * @param mixed $options The constraint options + * + * @throws MappingException If the namespace prefix is undefined + */ + protected function newConstraint(string $name, mixed $options = null): Constraint + { + if (str_contains($name, '\\') && class_exists($name)) { + $className = $name; + } elseif (str_contains($name, ':')) { + [$prefix, $className] = explode(':', $name, 2); + + if (!isset($this->namespaces[$prefix])) { + throw new MappingException(\sprintf('Undefined namespace prefix "%s".', $prefix)); + } + + $className = $this->namespaces[$prefix].$className; + } else { + $className = self::DEFAULT_NAMESPACE.$name; + } + + if ($this->namedArgumentsCache[$className] ??= (bool) (new \ReflectionMethod($className, '__construct'))->getAttributes(HasNamedArguments::class)) { + if (null === $options) { + return new $className(); + } + + if (!\is_array($options)) { + return new $className($options); + } + + if (1 === \count($options) && isset($options['value'])) { + return new $className($options['value']); + } + + return new $className(...$options); + } + + return new $className($options); + } +} diff --git a/lib/symfony/validator/Mapping/Loader/AnnotationLoader.php b/lib/symfony/validator/Mapping/Loader/AnnotationLoader.php new file mode 100644 index 0000000000..f90f9ce5e6 --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/AnnotationLoader.php @@ -0,0 +1,159 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Doctrine\Common\Annotations\Reader; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\Callback; +use Symfony\Component\Validator\Constraints\GroupSequence; +use Symfony\Component\Validator\Constraints\GroupSequenceProvider; +use Symfony\Component\Validator\Exception\MappingException; +use Symfony\Component\Validator\Mapping\ClassMetadata; + +/** + * Loads validation metadata using a Doctrine annotation {@link Reader} or using PHP 8 attributes. + * + * @deprecated since Symfony 6.4, use {@see AttributeLoader} instead + * + * @author Bernhard Schussek + * @author Alexander M. Turek + */ +class AnnotationLoader implements LoaderInterface +{ + /** + * @deprecated since Symfony 6.4, this property will be removed in 7.0 + * + * @var Reader|null + */ + protected $reader; + + public function __construct(?Reader $reader = null) + { + $this->reader = $reader; + } + + public function loadClassMetadata(ClassMetadata $metadata): bool + { + $reflClass = $metadata->getReflectionClass(); + $className = $reflClass->name; + $success = false; + + foreach ($this->getAnnotations($reflClass) as $constraint) { + if ($constraint instanceof GroupSequence) { + $metadata->setGroupSequence($constraint->groups); + } elseif ($constraint instanceof GroupSequenceProvider) { + $metadata->setGroupProvider($constraint->provider); + $metadata->setGroupSequenceProvider(true); + } elseif ($constraint instanceof Constraint) { + $metadata->addConstraint($constraint); + } + + $success = true; + } + + foreach ($reflClass->getProperties() as $property) { + if ($property->getDeclaringClass()->name === $className) { + foreach ($this->getAnnotations($property) as $constraint) { + if ($constraint instanceof Constraint) { + $metadata->addPropertyConstraint($property->name, $constraint); + } + + $success = true; + } + } + } + + foreach ($reflClass->getMethods() as $method) { + if ($method->getDeclaringClass()->name === $className) { + foreach ($this->getAnnotations($method) as $constraint) { + if ($constraint instanceof Callback) { + $constraint->callback = $method->getName(); + + $metadata->addConstraint($constraint); + } elseif ($constraint instanceof Constraint) { + if (preg_match('/^(get|is|has)(.+)$/i', $method->name, $matches)) { + $metadata->addGetterMethodConstraint(lcfirst($matches[2]), $matches[0], $constraint); + } else { + throw new MappingException(\sprintf('The constraint on "%s::%s()" cannot be added. Constraints can only be added on methods beginning with "get", "is" or "has".', $className, $method->name)); + } + } + + $success = true; + } + } + } + + return $success; + } + + private function getAnnotations(\ReflectionMethod|\ReflectionClass|\ReflectionProperty $reflection): iterable + { + $dedup = []; + + foreach ($reflection->getAttributes(GroupSequence::class) as $attribute) { + $dedup[] = $attribute->newInstance(); + yield $attribute->newInstance(); + } + foreach ($reflection->getAttributes(GroupSequenceProvider::class) as $attribute) { + $dedup[] = $attribute->newInstance(); + yield $attribute->newInstance(); + } + foreach ($reflection->getAttributes(Constraint::class, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) { + $dedup[] = $attribute->newInstance(); + yield $attribute->newInstance(); + } + if (!$this->reader) { + return; + } + + $annotations = []; + + if ($reflection instanceof \ReflectionClass && $annotations = $this->reader->getClassAnnotations($reflection)) { + $this->triggerDeprecationIfAnnotationIsUsed($annotations, \sprintf('Class "%s"', $reflection->getName())); + } + if ($reflection instanceof \ReflectionMethod && $annotations = $this->reader->getMethodAnnotations($reflection)) { + $this->triggerDeprecationIfAnnotationIsUsed($annotations, \sprintf('Method "%s::%s()"', $reflection->getDeclaringClass()->getName(), $reflection->getName())); + } + if ($reflection instanceof \ReflectionProperty && $annotations = $this->reader->getPropertyAnnotations($reflection)) { + $this->triggerDeprecationIfAnnotationIsUsed($annotations, \sprintf('Property "%s::$%s"', $reflection->getDeclaringClass()->getName(), $reflection->getName())); + } + + foreach ($dedup as $annotation) { + if ($annotation instanceof Constraint) { + $annotation->groups; // trigger initialization of the "groups" property + } + } + + foreach ($annotations as $annotation) { + if ($annotation instanceof Constraint) { + $annotation->groups; // trigger initialization of the "groups" property + } + if (!\in_array($annotation, $dedup, false)) { + yield $annotation; + } + } + } + + private function triggerDeprecationIfAnnotationIsUsed(array $annotations, string $messagePrefix): void + { + foreach ($annotations as $annotation) { + if ( + $annotation instanceof Constraint + || $annotation instanceof GroupSequence + || $annotation instanceof GroupSequenceProvider + ) { + trigger_deprecation('symfony/validator', '6.4', \sprintf('%s uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.', $messagePrefix)); + break; + } + } + } +} diff --git a/lib/symfony/validator/Mapping/Loader/AttributeLoader.php b/lib/symfony/validator/Mapping/Loader/AttributeLoader.php new file mode 100644 index 0000000000..2a8a75e1e6 --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/AttributeLoader.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +/** + * Loads validation metadata using PHP attributes. + * + * @author Bernhard Schussek + * @author Alexander M. Turek + * @author Alexandre Daubois + */ +class AttributeLoader extends AnnotationLoader +{ + public function __construct() + { + parent::__construct(null); + } +} diff --git a/lib/symfony/validator/Mapping/Loader/AutoMappingTrait.php b/lib/symfony/validator/Mapping/Loader/AutoMappingTrait.php new file mode 100644 index 0000000000..4661ce657c --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/AutoMappingTrait.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Symfony\Component\Validator\Mapping\AutoMappingStrategy; +use Symfony\Component\Validator\Mapping\ClassMetadata; + +/** + * Utility methods to create auto mapping loaders. + * + * @author Kévin Dunglas + */ +trait AutoMappingTrait +{ + private function isAutoMappingEnabledForClass(ClassMetadata $metadata, ?string $classValidatorRegexp = null): bool + { + // Check if AutoMapping constraint is set first + if (AutoMappingStrategy::NONE !== $strategy = $metadata->getAutoMappingStrategy()) { + return AutoMappingStrategy::ENABLED === $strategy; + } + + // Fallback on the config + return null !== $classValidatorRegexp && preg_match($classValidatorRegexp, $metadata->getClassName()); + } +} diff --git a/lib/symfony/validator/Mapping/Loader/FileLoader.php b/lib/symfony/validator/Mapping/Loader/FileLoader.php new file mode 100644 index 0000000000..f1c82bfbf5 --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/FileLoader.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Symfony\Component\Validator\Exception\MappingException; + +/** + * Base loader for loading validation metadata from a file. + * + * @author Bernhard Schussek + * + * @see YamlFileLoader + * @see XmlFileLoader + */ +abstract class FileLoader extends AbstractLoader +{ + protected $file; + + /** + * Creates a new loader. + * + * @param string $file The mapping file to load + * + * @throws MappingException If the file does not exist or is not readable + */ + public function __construct(string $file) + { + if (!is_file($file)) { + throw new MappingException(\sprintf('The mapping file "%s" does not exist.', $file)); + } + + if (!is_readable($file)) { + throw new MappingException(\sprintf('The mapping file "%s" is not readable.', $file)); + } + + if (!stream_is_local($this->file)) { + throw new MappingException(\sprintf('The mapping file "%s" is not a local file.', $file)); + } + + $this->file = $file; + } +} diff --git a/lib/symfony/validator/Mapping/Loader/FilesLoader.php b/lib/symfony/validator/Mapping/Loader/FilesLoader.php new file mode 100644 index 0000000000..c536226c14 --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/FilesLoader.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +/** + * Base loader for loading validation metadata from a list of files. + * + * @author Bulat Shakirzyanov + * @author Bernhard Schussek + * + * @see YamlFilesLoader + * @see XmlFilesLoader + */ +abstract class FilesLoader extends LoaderChain +{ + /** + * Creates a new loader. + * + * @param array $paths An array of file paths + */ + public function __construct(array $paths) + { + parent::__construct($this->getFileLoaders($paths)); + } + + /** + * Returns an array of file loaders for the given file paths. + * + * @return LoaderInterface[] + */ + protected function getFileLoaders(array $paths): array + { + $loaders = []; + + foreach ($paths as $path) { + $loaders[] = $this->getFileLoaderInstance($path); + } + + return $loaders; + } + + /** + * Creates a loader for the given file path. + */ + abstract protected function getFileLoaderInstance(string $path): LoaderInterface; +} diff --git a/lib/symfony/validator/Mapping/Loader/LoaderChain.php b/lib/symfony/validator/Mapping/Loader/LoaderChain.php new file mode 100644 index 0000000000..d6cb4eda7b --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/LoaderChain.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Symfony\Component\Validator\Exception\MappingException; +use Symfony\Component\Validator\Mapping\ClassMetadata; + +/** + * Loads validation metadata from multiple {@link LoaderInterface} instances. + * + * Pass the loaders when constructing the chain. Once + * {@link loadClassMetadata()} is called, that method will be called on all + * loaders in the chain. + * + * @author Bernhard Schussek + */ +class LoaderChain implements LoaderInterface +{ + protected $loaders; + + /** + * @param LoaderInterface[] $loaders The metadata loaders to use + * + * @throws MappingException If any of the loaders has an invalid type + */ + public function __construct(array $loaders) + { + foreach ($loaders as $loader) { + if (!$loader instanceof LoaderInterface) { + throw new MappingException(\sprintf('Class "%s" is expected to implement LoaderInterface.', get_debug_type($loader))); + } + } + + $this->loaders = $loaders; + } + + public function loadClassMetadata(ClassMetadata $metadata): bool + { + $success = false; + + foreach ($this->loaders as $loader) { + $success = $loader->loadClassMetadata($metadata) || $success; + } + + return $success; + } + + /** + * @return LoaderInterface[] + */ + public function getLoaders(): array + { + return $this->loaders; + } +} diff --git a/lib/symfony/validator/Mapping/Loader/LoaderInterface.php b/lib/symfony/validator/Mapping/Loader/LoaderInterface.php new file mode 100644 index 0000000000..159bcdffc2 --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/LoaderInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Symfony\Component\Validator\Mapping\ClassMetadata; + +/** + * Loads validation metadata into {@link ClassMetadata} instances. + * + * @author Bernhard Schussek + */ +interface LoaderInterface +{ + /** + * Loads validation metadata into a {@link ClassMetadata} instance. + */ + public function loadClassMetadata(ClassMetadata $metadata): bool; +} diff --git a/lib/symfony/validator/Mapping/Loader/PropertyInfoLoader.php b/lib/symfony/validator/Mapping/Loader/PropertyInfoLoader.php new file mode 100644 index 0000000000..db6ac33ca3 --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/PropertyInfoLoader.php @@ -0,0 +1,176 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface; +use Symfony\Component\PropertyInfo\PropertyListExtractorInterface; +use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; +use Symfony\Component\PropertyInfo\Type as PropertyInfoType; +use Symfony\Component\Validator\Constraints\All; +use Symfony\Component\Validator\Constraints\NotBlank; +use Symfony\Component\Validator\Constraints\NotNull; +use Symfony\Component\Validator\Constraints\Type; +use Symfony\Component\Validator\Mapping\AutoMappingStrategy; +use Symfony\Component\Validator\Mapping\ClassMetadata; + +/** + * Guesses and loads the appropriate constraints using PropertyInfo. + * + * @author Kévin Dunglas + */ +final class PropertyInfoLoader implements LoaderInterface +{ + use AutoMappingTrait; + + private PropertyListExtractorInterface $listExtractor; + private PropertyTypeExtractorInterface $typeExtractor; + private PropertyAccessExtractorInterface $accessExtractor; + private ?string $classValidatorRegexp; + + public function __construct(PropertyListExtractorInterface $listExtractor, PropertyTypeExtractorInterface $typeExtractor, PropertyAccessExtractorInterface $accessExtractor, ?string $classValidatorRegexp = null) + { + $this->listExtractor = $listExtractor; + $this->typeExtractor = $typeExtractor; + $this->accessExtractor = $accessExtractor; + $this->classValidatorRegexp = $classValidatorRegexp; + } + + public function loadClassMetadata(ClassMetadata $metadata): bool + { + $className = $metadata->getClassName(); + if (!$properties = $this->listExtractor->getProperties($className)) { + return false; + } + + $loaded = false; + $enabledForClass = $this->isAutoMappingEnabledForClass($metadata, $this->classValidatorRegexp); + foreach ($properties as $property) { + if (false === $this->accessExtractor->isWritable($className, $property)) { + continue; + } + + if (!property_exists($className, $property)) { + continue; + } + + $types = $this->typeExtractor->getTypes($className, $property); + if (null === $types) { + continue; + } + + $enabledForProperty = $enabledForClass; + $hasTypeConstraint = false; + $hasNotNullConstraint = false; + $hasNotBlankConstraint = false; + $allConstraint = null; + foreach ($metadata->getPropertyMetadata($property) as $propertyMetadata) { + // Enabling or disabling auto-mapping explicitly always takes precedence + if (AutoMappingStrategy::DISABLED === $propertyMetadata->getAutoMappingStrategy()) { + continue 2; + } + + if (AutoMappingStrategy::ENABLED === $propertyMetadata->getAutoMappingStrategy()) { + $enabledForProperty = true; + } + + foreach ($propertyMetadata->getConstraints() as $constraint) { + if ($constraint instanceof Type) { + $hasTypeConstraint = true; + } elseif ($constraint instanceof NotNull) { + $hasNotNullConstraint = true; + } elseif ($constraint instanceof NotBlank) { + $hasNotBlankConstraint = true; + } elseif ($constraint instanceof All) { + $allConstraint = $constraint; + } + } + } + + if (!$enabledForProperty) { + continue; + } + + $loaded = true; + $builtinTypes = []; + $nullable = false; + $scalar = true; + foreach ($types as $type) { + $builtinTypes[] = $type->getBuiltinType(); + + if ($scalar && !\in_array($type->getBuiltinType(), [PropertyInfoType::BUILTIN_TYPE_INT, PropertyInfoType::BUILTIN_TYPE_FLOAT, PropertyInfoType::BUILTIN_TYPE_STRING, PropertyInfoType::BUILTIN_TYPE_BOOL], true)) { + $scalar = false; + } + + if (!$nullable && $type->isNullable()) { + $nullable = true; + } + } + if (!$hasTypeConstraint) { + if (1 === \count($builtinTypes)) { + if ($types[0]->isCollection() && \count($collectionValueType = $types[0]->getCollectionValueTypes()) > 0) { + [$collectionValueType] = $collectionValueType; + $this->handleAllConstraint($property, $allConstraint, $collectionValueType, $metadata); + } + + $metadata->addPropertyConstraint($property, $this->getTypeConstraint($builtinTypes[0], $types[0])); + } elseif ($scalar) { + $metadata->addPropertyConstraint($property, new Type(['type' => 'scalar'])); + } + } + + if (!$nullable && !$hasNotBlankConstraint && !$hasNotNullConstraint) { + $metadata->addPropertyConstraint($property, new NotNull()); + } + } + + return $loaded; + } + + private function getTypeConstraint(string $builtinType, PropertyInfoType $type): Type + { + if (PropertyInfoType::BUILTIN_TYPE_OBJECT === $builtinType && null !== $className = $type->getClassName()) { + return new Type(['type' => $className]); + } + + return new Type(['type' => $builtinType]); + } + + private function handleAllConstraint(string $property, ?All $allConstraint, PropertyInfoType $propertyInfoType, ClassMetadata $metadata): void + { + $containsTypeConstraint = false; + $containsNotNullConstraint = false; + if (null !== $allConstraint) { + foreach ($allConstraint->constraints as $constraint) { + if ($constraint instanceof Type) { + $containsTypeConstraint = true; + } elseif ($constraint instanceof NotNull) { + $containsNotNullConstraint = true; + } + } + } + + $constraints = []; + if (!$containsNotNullConstraint && !$propertyInfoType->isNullable()) { + $constraints[] = new NotNull(); + } + + if (!$containsTypeConstraint) { + $constraints[] = $this->getTypeConstraint($propertyInfoType->getBuiltinType(), $propertyInfoType); + } + + if (null === $allConstraint) { + $metadata->addPropertyConstraint($property, new All(['constraints' => $constraints])); + } else { + $allConstraint->constraints = array_merge($allConstraint->constraints, $constraints); + } + } +} diff --git a/lib/symfony/validator/Mapping/Loader/StaticMethodLoader.php b/lib/symfony/validator/Mapping/Loader/StaticMethodLoader.php new file mode 100644 index 0000000000..cc978ddef7 --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/StaticMethodLoader.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Symfony\Component\Validator\Exception\MappingException; +use Symfony\Component\Validator\Mapping\ClassMetadata; + +/** + * Loads validation metadata by calling a static method on the loaded class. + * + * @author Bernhard Schussek + */ +class StaticMethodLoader implements LoaderInterface +{ + protected $methodName; + + /** + * Creates a new loader. + * + * @param string $methodName The name of the static method to call + */ + public function __construct(string $methodName = 'loadValidatorMetadata') + { + $this->methodName = $methodName; + } + + public function loadClassMetadata(ClassMetadata $metadata): bool + { + /** @var \ReflectionClass $reflClass */ + $reflClass = $metadata->getReflectionClass(); + + if (!$reflClass->isInterface() && $reflClass->hasMethod($this->methodName)) { + $reflMethod = $reflClass->getMethod($this->methodName); + + if ($reflMethod->isAbstract()) { + return false; + } + + if (!$reflMethod->isStatic()) { + throw new MappingException(\sprintf('The method "%s::%s()" should be static.', $reflClass->name, $this->methodName)); + } + + if ($reflMethod->getDeclaringClass()->name != $reflClass->name) { + return false; + } + + $reflMethod->invoke(null, $metadata); + + return true; + } + + return false; + } +} diff --git a/lib/symfony/validator/Mapping/Loader/XmlFileLoader.php b/lib/symfony/validator/Mapping/Loader/XmlFileLoader.php new file mode 100644 index 0000000000..1c5f528730 --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/XmlFileLoader.php @@ -0,0 +1,236 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Symfony\Component\Config\Util\XmlUtils; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\MappingException; +use Symfony\Component\Validator\Mapping\ClassMetadata; + +/** + * Loads validation metadata from an XML file. + * + * @author Bernhard Schussek + */ +class XmlFileLoader extends FileLoader +{ + /** + * The XML nodes of the mapping file. + * + * @var \SimpleXMLElement[]|null + */ + protected $classes; + + public function __construct(string $file) + { + $this->file = $file; + } + + public function loadClassMetadata(ClassMetadata $metadata): bool + { + if (!isset($this->classes)) { + $this->loadClassesFromXml(); + } + + if (isset($this->classes[$metadata->getClassName()])) { + $classDescription = $this->classes[$metadata->getClassName()]; + + $this->loadClassMetadataFromXml($metadata, $classDescription); + + return true; + } + + return false; + } + + /** + * Return the names of the classes mapped in this file. + * + * @return string[] + */ + public function getMappedClasses(): array + { + if (!isset($this->classes)) { + $this->loadClassesFromXml(); + } + + return array_keys($this->classes); + } + + /** + * Parses a collection of "constraint" XML nodes. + * + * @param \SimpleXMLElement $nodes The XML nodes + * + * @return Constraint[] + */ + protected function parseConstraints(\SimpleXMLElement $nodes): array + { + $constraints = []; + + foreach ($nodes as $node) { + if (\count($node) > 0) { + if (\count($node->value) > 0) { + $options = [ + 'value' => $this->parseValues($node->value), + ]; + } elseif (\count($node->constraint) > 0) { + $options = $this->parseConstraints($node->constraint); + } elseif (\count($node->option) > 0) { + $options = $this->parseOptions($node->option); + } else { + $options = []; + } + } elseif ('' !== (string) $node) { + $options = XmlUtils::phpize(trim($node)); + } else { + $options = null; + } + + if (isset($options['groups']) && !\is_array($options['groups'])) { + $options['groups'] = (array) $options['groups']; + } + + $constraints[] = $this->newConstraint((string) $node['name'], $options); + } + + return $constraints; + } + + /** + * Parses a collection of "value" XML nodes. + * + * @param \SimpleXMLElement $nodes The XML nodes + */ + protected function parseValues(\SimpleXMLElement $nodes): array + { + $values = []; + + foreach ($nodes as $node) { + if (\count($node) > 0) { + if (\count($node->value) > 0) { + $value = $this->parseValues($node->value); + } elseif (\count($node->constraint) > 0) { + $value = $this->parseConstraints($node->constraint); + } else { + $value = []; + } + } else { + $value = trim($node); + } + + if (isset($node['key'])) { + $values[(string) $node['key']] = $value; + } else { + $values[] = $value; + } + } + + return $values; + } + + /** + * Parses a collection of "option" XML nodes. + * + * @param \SimpleXMLElement $nodes The XML nodes + */ + protected function parseOptions(\SimpleXMLElement $nodes): array + { + $options = []; + + foreach ($nodes as $node) { + if (\count($node) > 0) { + if (\count($node->value) > 0) { + $value = $this->parseValues($node->value); + } elseif (\count($node->constraint) > 0) { + $value = $this->parseConstraints($node->constraint); + } else { + $value = []; + } + } else { + $value = XmlUtils::phpize($node); + if (\is_string($value)) { + $value = trim($value); + } + } + + $options[(string) $node['name']] = $value; + } + + return $options; + } + + /** + * Loads the XML class descriptions from the given file. + * + * @throws MappingException If the file could not be loaded + */ + protected function parseFile(string $path): \SimpleXMLElement + { + try { + $dom = XmlUtils::loadFile($path, __DIR__.'/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd'); + } catch (\Exception $e) { + throw new MappingException($e->getMessage(), $e->getCode(), $e); + } + + return simplexml_import_dom($dom); + } + + private function loadClassesFromXml(): void + { + parent::__construct($this->file); + + // This method may throw an exception. Do not modify the class' + // state before it completes + $xml = $this->parseFile($this->file); + + $this->classes = []; + + foreach ($xml->namespace as $namespace) { + $this->addNamespaceAlias((string) $namespace['prefix'], trim((string) $namespace)); + } + + foreach ($xml->class as $class) { + $this->classes[(string) $class['name']] = $class; + } + } + + private function loadClassMetadataFromXml(ClassMetadata $metadata, \SimpleXMLElement $classDescription): void + { + if (\count($classDescription->{'group-sequence-provider'}) > 0) { + $metadata->setGroupProvider($classDescription->{'group-sequence-provider'}[0]->value ?: null); + $metadata->setGroupSequenceProvider(true); + } + + foreach ($classDescription->{'group-sequence'} as $groupSequence) { + if (\count($groupSequence->value) > 0) { + $metadata->setGroupSequence($this->parseValues($groupSequence[0]->value)); + } + } + + foreach ($this->parseConstraints($classDescription->constraint) as $constraint) { + $metadata->addConstraint($constraint); + } + + foreach ($classDescription->property as $property) { + foreach ($this->parseConstraints($property->constraint) as $constraint) { + $metadata->addPropertyConstraint((string) $property['name'], $constraint); + } + } + + foreach ($classDescription->getter as $getter) { + foreach ($this->parseConstraints($getter->constraint) as $constraint) { + $metadata->addGetterConstraint((string) $getter['property'], $constraint); + } + } + } +} diff --git a/lib/symfony/validator/Mapping/Loader/XmlFilesLoader.php b/lib/symfony/validator/Mapping/Loader/XmlFilesLoader.php new file mode 100644 index 0000000000..aab15762da --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/XmlFilesLoader.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +/** + * Loads validation metadata from a list of XML files. + * + * @author Bulat Shakirzyanov + * @author Bernhard Schussek + * + * @see FilesLoader + */ +class XmlFilesLoader extends FilesLoader +{ + public function getFileLoaderInstance(string $file): LoaderInterface + { + return new XmlFileLoader($file); + } +} diff --git a/lib/symfony/validator/Mapping/Loader/YamlFileLoader.php b/lib/symfony/validator/Mapping/Loader/YamlFileLoader.php new file mode 100644 index 0000000000..4fae76bf84 --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/YamlFileLoader.php @@ -0,0 +1,197 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Mapping\ClassMetadata; +use Symfony\Component\Yaml\Exception\ParseException; +use Symfony\Component\Yaml\Parser as YamlParser; +use Symfony\Component\Yaml\Yaml; + +/** + * Loads validation metadata from a YAML file. + * + * @author Bernhard Schussek + */ +class YamlFileLoader extends FileLoader +{ + /** + * An array of YAML class descriptions. + * + * @var array + */ + protected $classes; + + public function __construct(string $file) + { + $this->file = $file; + } + + /** + * Caches the used YAML parser. + */ + private YamlParser $yamlParser; + + public function loadClassMetadata(ClassMetadata $metadata): bool + { + if (!isset($this->classes)) { + $this->loadClassesFromYaml(); + } + + if (isset($this->classes[$metadata->getClassName()])) { + $classDescription = $this->classes[$metadata->getClassName()]; + + $this->loadClassMetadataFromYaml($metadata, $classDescription); + + return true; + } + + return false; + } + + /** + * Return the names of the classes mapped in this file. + * + * @return string[] + */ + public function getMappedClasses(): array + { + if (!isset($this->classes)) { + $this->loadClassesFromYaml(); + } + + return array_keys($this->classes); + } + + /** + * Parses a collection of YAML nodes. + * + * @param array $nodes The YAML nodes + * + * @return array + */ + protected function parseNodes(array $nodes): array + { + $values = []; + + foreach ($nodes as $name => $childNodes) { + if (is_numeric($name) && \is_array($childNodes) && 1 === \count($childNodes)) { + $options = current($childNodes); + + if (\is_array($options)) { + $options = $this->parseNodes($options); + } + + if (null !== $options && (!\is_array($options) || array_is_list($options))) { + $options = [ + 'value' => $options, + ]; + } + + $values[] = $this->newConstraint(key($childNodes), $options); + } else { + if (\is_array($childNodes)) { + $childNodes = $this->parseNodes($childNodes); + } + + $values[$name] = $childNodes; + } + } + + return $values; + } + + /** + * Loads the YAML class descriptions from the given file. + * + * @throws \InvalidArgumentException If the file could not be loaded or did + * not contain a YAML array + */ + private function parseFile(string $path): array + { + try { + $classes = $this->yamlParser->parseFile($path, Yaml::PARSE_CONSTANT); + } catch (ParseException $e) { + throw new \InvalidArgumentException(\sprintf('The file "%s" does not contain valid YAML: ', $path).$e->getMessage(), 0, $e); + } + + // empty file + if (null === $classes) { + return []; + } + + // not an array + if (!\is_array($classes)) { + throw new \InvalidArgumentException(\sprintf('The file "%s" must contain a YAML array.', $this->file)); + } + + return $classes; + } + + private function loadClassesFromYaml(): void + { + parent::__construct($this->file); + + $this->yamlParser ??= new YamlParser(); + $this->classes = $this->parseFile($this->file); + + if (isset($this->classes['namespaces'])) { + foreach ($this->classes['namespaces'] as $alias => $namespace) { + $this->addNamespaceAlias($alias, $namespace); + } + + unset($this->classes['namespaces']); + } + } + + private function loadClassMetadataFromYaml(ClassMetadata $metadata, array $classDescription): void + { + if (isset($classDescription['group_sequence_provider'])) { + if (\is_string($classDescription['group_sequence_provider'])) { + $metadata->setGroupProvider($classDescription['group_sequence_provider']); + } + $metadata->setGroupSequenceProvider( + (bool) $classDescription['group_sequence_provider'] + ); + } + + if (isset($classDescription['group_sequence'])) { + $metadata->setGroupSequence($classDescription['group_sequence']); + } + + if (isset($classDescription['constraints']) && \is_array($classDescription['constraints'])) { + foreach ($this->parseNodes($classDescription['constraints']) as $constraint) { + $metadata->addConstraint($constraint); + } + } + + if (isset($classDescription['properties']) && \is_array($classDescription['properties'])) { + foreach ($classDescription['properties'] as $property => $constraints) { + if (null !== $constraints) { + foreach ($this->parseNodes($constraints) as $constraint) { + $metadata->addPropertyConstraint($property, $constraint); + } + } + } + } + + if (isset($classDescription['getters']) && \is_array($classDescription['getters'])) { + foreach ($classDescription['getters'] as $getter => $constraints) { + if (null !== $constraints) { + foreach ($this->parseNodes($constraints) as $constraint) { + $metadata->addGetterConstraint($getter, $constraint); + } + } + } + } + } +} diff --git a/lib/symfony/validator/Mapping/Loader/YamlFilesLoader.php b/lib/symfony/validator/Mapping/Loader/YamlFilesLoader.php new file mode 100644 index 0000000000..b6e4d5990a --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/YamlFilesLoader.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Loader; + +/** + * Loads validation metadata from a list of YAML files. + * + * @author Bulat Shakirzyanov + * @author Bernhard Schussek + * + * @see FilesLoader + */ +class YamlFilesLoader extends FilesLoader +{ + public function getFileLoaderInstance(string $file): LoaderInterface + { + return new YamlFileLoader($file); + } +} diff --git a/lib/symfony/validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd b/lib/symfony/validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd new file mode 100644 index 0000000000..a744e50b94 --- /dev/null +++ b/lib/symfony/validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/symfony/validator/Mapping/MemberMetadata.php b/lib/symfony/validator/Mapping/MemberMetadata.php new file mode 100644 index 0000000000..1ebc51a1ea --- /dev/null +++ b/lib/symfony/validator/Mapping/MemberMetadata.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\Composite; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +/** + * Stores all metadata needed for validating a class property. + * + * The method of accessing the property's value must be specified by subclasses + * by implementing the {@link newReflectionMember()} method. + * + * This class supports serialization and cloning. + * + * @author Bernhard Schussek + * + * @see PropertyMetadataInterface + */ +abstract class MemberMetadata extends GenericMetadata implements PropertyMetadataInterface +{ + /** + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getClassName()} instead. + */ + public string $class; + + /** + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getName()} instead. + */ + public string $name; + + /** + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getPropertyName()} instead. + */ + public string $property; + + /** + * @var \ReflectionMethod[]|\ReflectionProperty[] + */ + private array $reflMember = []; + + /** + * @param string $class The name of the class this member is defined on + * @param string $name The name of the member + * @param string $property The property the member belongs to + */ + public function __construct(string $class, string $name, string $property) + { + $this->class = $class; + $this->name = $name; + $this->property = $property; + } + + public function addConstraint(Constraint $constraint): static + { + $this->checkConstraint($constraint); + + parent::addConstraint($constraint); + + return $this; + } + + public function __sleep(): array + { + return array_merge(parent::__sleep(), [ + 'class', + 'name', + 'property', + ]); + } + + /** + * Returns the name of the member. + */ + public function getName(): string + { + return $this->name; + } + + /** + * @return string + */ + public function getClassName() + { + return $this->class; + } + + public function getPropertyName(): string + { + return $this->property; + } + + /** + * Returns whether this member is public. + */ + public function isPublic(object|string $objectOrClassName): bool + { + return $this->getReflectionMember($objectOrClassName)->isPublic(); + } + + /** + * Returns whether this member is protected. + */ + public function isProtected(object|string $objectOrClassName): bool + { + return $this->getReflectionMember($objectOrClassName)->isProtected(); + } + + /** + * Returns whether this member is private. + */ + public function isPrivate(object|string $objectOrClassName): bool + { + return $this->getReflectionMember($objectOrClassName)->isPrivate(); + } + + /** + * Returns the reflection instance for accessing the member's value. + */ + public function getReflectionMember(object|string $objectOrClassName): \ReflectionMethod|\ReflectionProperty + { + $className = \is_string($objectOrClassName) ? $objectOrClassName : $objectOrClassName::class; + if (!isset($this->reflMember[$className])) { + $this->reflMember[$className] = $this->newReflectionMember($objectOrClassName); + } + + return $this->reflMember[$className]; + } + + /** + * Creates a new reflection instance for accessing the member's value. + */ + abstract protected function newReflectionMember(object|string $objectOrClassName): \ReflectionMethod|\ReflectionProperty; + + private function checkConstraint(Constraint $constraint): void + { + if (!\in_array(Constraint::PROPERTY_CONSTRAINT, (array) $constraint->getTargets(), true)) { + throw new ConstraintDefinitionException(\sprintf('The constraint "%s" cannot be put on properties or getters.', get_debug_type($constraint))); + } + + if ($constraint instanceof Composite) { + foreach ($constraint->getNestedConstraints() as $nestedConstraint) { + $this->checkConstraint($nestedConstraint); + } + } + } +} diff --git a/lib/symfony/validator/Mapping/MetadataInterface.php b/lib/symfony/validator/Mapping/MetadataInterface.php new file mode 100644 index 0000000000..480d0ecd4c --- /dev/null +++ b/lib/symfony/validator/Mapping/MetadataInterface.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping; + +use Symfony\Component\Validator\Constraint; + +/** + * A container for validation metadata. + * + * Most importantly, the metadata stores the constraints against which an object + * and its properties should be validated. + * + * Additionally, the metadata stores whether objects should be validated + * against their class' metadata and whether traversable objects should be + * traversed or not. + * + * @author Bernhard Schussek + * + * @see CascadingStrategy + * @see TraversalStrategy + */ +interface MetadataInterface +{ + /** + * Returns the strategy for cascading objects. + * + * @see CascadingStrategy + */ + public function getCascadingStrategy(): int; + + /** + * Returns the strategy for traversing traversable objects. + * + * @see TraversalStrategy + */ + public function getTraversalStrategy(): int; + + /** + * Returns all constraints of this element. + * + * @return Constraint[] + */ + public function getConstraints(): array; + + /** + * Returns all constraints for a given validation group. + * + * @param string $group The validation group + * + * @return Constraint[] + */ + public function findConstraints(string $group): array; +} diff --git a/lib/symfony/validator/Mapping/PropertyMetadata.php b/lib/symfony/validator/Mapping/PropertyMetadata.php new file mode 100644 index 0000000000..89a25a5ef9 --- /dev/null +++ b/lib/symfony/validator/Mapping/PropertyMetadata.php @@ -0,0 +1,84 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping; + +use Symfony\Component\Validator\Exception\ValidatorException; + +/** + * Stores all metadata needed for validating a class property. + * + * The value of the property is obtained by directly accessing the property. + * The property will be accessed by reflection, so the access of private and + * protected properties is supported. + * + * This class supports serialization and cloning. + * + * @author Bernhard Schussek + * + * @see PropertyMetadataInterface + */ +class PropertyMetadata extends MemberMetadata +{ + /** + * @param string $class The class this property is defined on + * @param string $name The name of this property + * + * @throws ValidatorException + */ + public function __construct(string $class, string $name) + { + if (!property_exists($class, $name)) { + throw new ValidatorException(\sprintf('Property "%s" does not exist in class "%s".', $name, $class)); + } + + parent::__construct($class, $name, $name); + } + + public function getPropertyValue(mixed $object): mixed + { + $reflProperty = $this->getReflectionMember($object); + + if ($reflProperty->hasType() && !$reflProperty->isInitialized($object)) { + // There is no way to check if a property has been unset or if it is uninitialized. + // When trying to access an uninitialized property, __get method is triggered. + + // If __get method is not present, no fallback is possible + // Otherwise we need to catch an Error in case we are trying to access an uninitialized but set property. + if (!method_exists($object, '__get')) { + return null; + } + + try { + return $reflProperty->getValue($object); + } catch (\Error) { + return null; + } + } + + return $reflProperty->getValue($object); + } + + protected function newReflectionMember(object|string $objectOrClassName): \ReflectionMethod|\ReflectionProperty + { + $originalClass = \is_string($objectOrClassName) ? $objectOrClassName : $objectOrClassName::class; + + while (!property_exists($objectOrClassName, $this->getName())) { + $objectOrClassName = get_parent_class($objectOrClassName); + + if (false === $objectOrClassName) { + throw new ValidatorException(\sprintf('Property "%s" does not exist in class "%s".', $this->getName(), $originalClass)); + } + } + + return new \ReflectionProperty($objectOrClassName, $this->getName()); + } +} diff --git a/lib/symfony/validator/Mapping/PropertyMetadataInterface.php b/lib/symfony/validator/Mapping/PropertyMetadataInterface.php new file mode 100644 index 0000000000..f362186c4f --- /dev/null +++ b/lib/symfony/validator/Mapping/PropertyMetadataInterface.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping; + +/** + * Stores all metadata needed for validating the value of a class property. + * + * Most importantly, the metadata stores the constraints against which the + * property's value should be validated. + * + * Additionally, the metadata stores whether objects stored in the property + * should be validated against their class' metadata and whether traversable + * objects should be traversed or not. + * + * @author Bernhard Schussek + * + * @see MetadataInterface + * @see CascadingStrategy + * @see TraversalStrategy + */ +interface PropertyMetadataInterface extends MetadataInterface +{ + /** + * Returns the name of the property. + */ + public function getPropertyName(): string; + + /** + * Extracts the value of the property from the given container. + */ + public function getPropertyValue(mixed $containingValue): mixed; +} diff --git a/lib/symfony/validator/Mapping/TraversalStrategy.php b/lib/symfony/validator/Mapping/TraversalStrategy.php new file mode 100644 index 0000000000..0df5a7ee8a --- /dev/null +++ b/lib/symfony/validator/Mapping/TraversalStrategy.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping; + +/** + * Specifies whether and how a traversable object should be traversed. + * + * If the node traverser traverses a node whose value is an instance of + * {@link \Traversable}, and if that node is either a class node or if + * cascading is enabled, then the node's traversal strategy will be checked. + * Depending on the requested traversal strategy, the node traverser will + * iterate over the object and cascade each object or collection returned by + * the iterator. + * + * The traversal strategy is ignored for arrays. Arrays are always iterated. + * + * @author Bernhard Schussek + * + * @see CascadingStrategy + */ +class TraversalStrategy +{ + /** + * Specifies that a node's value should be iterated only if it is an + * instance of {@link \Traversable}. + */ + public const IMPLICIT = 1; + + /** + * Specifies that a node's value should never be iterated. + */ + public const NONE = 2; + + /** + * Specifies that a node's value should always be iterated. If the value is + * not an instance of {@link \Traversable}, an exception should be thrown. + */ + public const TRAVERSE = 4; + + /** + * Not instantiable. + */ + private function __construct() + { + } +} diff --git a/lib/symfony/validator/ObjectInitializerInterface.php b/lib/symfony/validator/ObjectInitializerInterface.php new file mode 100644 index 0000000000..629a214a04 --- /dev/null +++ b/lib/symfony/validator/ObjectInitializerInterface.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +/** + * Prepares an object for validation. + * + * Concrete implementations of this interface are used by {@link Validator\ContextualValidatorInterface} + * to initialize objects just before validating them. + * + * @author Fabien Potencier + * @author Bernhard Schussek + */ +interface ObjectInitializerInterface +{ + /** + * @return void + */ + public function initialize(object $object); +} diff --git a/lib/symfony/validator/README.md b/lib/symfony/validator/README.md new file mode 100644 index 0000000000..8f3fd0efb2 --- /dev/null +++ b/lib/symfony/validator/README.md @@ -0,0 +1,16 @@ +Validator Component +=================== + +The Validator component provides tools to validate values following the +[JSR-303 Bean Validation specification][1]. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/validator.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) + +[1]: https://jcp.org/en/jsr/detail?id=303 diff --git a/lib/symfony/validator/Resources/translations/validators.af.xlf b/lib/symfony/validator/Resources/translations/validators.af.xlf new file mode 100644 index 0000000000..61a8b37247 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.af.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Hierdie waarde moet vals wees. + + + This value should be true. + Hierdie waarde moet waar wees. + + + This value should be of type {{ type }}. + Hierdie waarde moet van die soort {{type}} wees. + + + This value should be blank. + Hierdie waarde moet leeg wees. + + + The value you selected is not a valid choice. + Die waarde wat jy gekies het is nie 'n geldige keuse nie. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Jy moet ten minste {{ limit }} kies.|Jy moet ten minste {{ limit }} keuses kies. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Jy moet by die meeste {{ limit }} keuse kies.|Jy moet by die meeste {{ limit }} keuses kies. + + + One or more of the given values is invalid. + Een of meer van die gegewe waardes is ongeldig. + + + This field was not expected. + Die veld is nie verwag nie. + + + This field is missing. + Hierdie veld ontbreek. + + + This value is not a valid date. + Hierdie waarde is nie 'n geldige datum nie. + + + This value is not a valid datetime. + Hierdie waarde is nie 'n geldige datum en tyd nie. + + + This value is not a valid email address. + Hierdie waarde is nie 'n geldige e-pos adres nie. + + + The file could not be found. + Die lêer kon nie gevind word nie. + + + The file is not readable. + Die lêer kan nie gelees word nie. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Die lêer is te groot ({{ size }} {{ suffix }}). Toegelaat maksimum grootte is {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Die MIME-tipe van die lêer is ongeldig ({{ type }}). Toegelaat MIME-tipes is {{ types }}. + + + This value should be {{ limit }} or less. + Hierdie waarde moet {{ limit }} of minder wees. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Hierdie waarde is te lank. Dit moet {{ limit }} karakter of minder wees.|Hierdie waarde is te lank. Dit moet {{ limit }} karakters of minder wees. + + + This value should be {{ limit }} or more. + Hierdie waarde moet {{ limit }} of meer wees. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Hierdie waarde is te kort. Dit moet {{ limit }} karakter of meer wees.|Hierdie waarde is te kort. Dit moet {{ limit }} karakters of meer wees. + + + This value should not be blank. + Hierdie waarde moet nie leeg wees nie. + + + This value should not be null. + Hierdie waarde moet nie nul wees nie. + + + This value should be null. + Hierdie waarde moet nul wees. + + + This value is not valid. + Hierdie waarde is nie geldig nie. + + + This value is not a valid time. + Hierdie waarde is nie 'n geldige tyd nie. + + + This value is not a valid URL. + Hierdie waarde is nie 'n geldige URL nie. + + + The two values should be equal. + Die twee waardes moet gelyk wees. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Die lêer is te groot. Toegelaat maksimum grootte is {{ limit }} {{ suffix }}. + + + The file is too large. + Die lêer is te groot. + + + The file could not be uploaded. + Die lêer kan nie opgelaai word nie. + + + This value should be a valid number. + Hierdie waarde moet 'n geldige nommer wees. + + + This file is not a valid image. + Hierdie lêer is nie 'n geldige beeld nie. + + + This value is not a valid IP address. + Hierdie waarde is nie 'n geldige IP-adres nie. + + + This value is not a valid language. + Hierdie waarde is nie 'n geldige taal nie. + + + This value is not a valid locale. + Hierdie waarde is nie 'n geldige land instelling nie. + + + This value is not a valid country. + Hierdie waarde is nie 'n geldige land nie. + + + This value is already used. + Hierdie waarde word reeds gebruik. + + + The size of the image could not be detected. + Die grootte van die beeld kon nie opgespoor word nie. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Die beeld breedte is te groot ({{ width }}px). Toegelaat maksimum breedte is {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Die beeld breedte is te klein ({{ width }}px). Minimum breedte verwag is {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Die beeld hoogte is te groot ({{ height }}px). Toegelaat maksimum hoogte is {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Die beeld hoogte is te klein ({{ height }}px). Minimum hoogte verwag is {{ min_height }}px. + + + This value should be the user's current password. + Hierdie waarde moet die huidige wagwoord van die gebruiker wees. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Hierdie waarde moet presies {{ limit }} karakter wees.|Hierdie waarde moet presies {{ limit }} karakters wees. + + + The file was only partially uploaded. + Die lêer is slegs gedeeltelik opgelaai. + + + No file was uploaded. + Geen lêer is opgelaai nie. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Geen tydelike gids is in php.ini opgestel nie, of die opgestelde gids bestaan nie. + + + Cannot write temporary file to disk. + Kan nie tydelike lêer skryf op skyf nie. + + + A PHP extension caused the upload to fail. + 'n PHP-uitbreiding veroorsaak die oplaai van die lêer om te misluk. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Hierdie versameling moet {{ limit }} element of meer bevat.|Hierdie versameling moet {{ limit }} elemente of meer bevat. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Hierdie versameling moet {{ limit }} element of minder bevat.|Hierdie versameling moet {{ limit }} elemente of meer bevat. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Hierdie versameling moet presies {{ limit }} element bevat.|Hierdie versameling moet presies {{ limit }} elemente bevat. + + + Invalid card number. + Ongeldige kredietkaart nommer. + + + Unsupported card type or invalid card number. + Nie-ondersteunde tipe kaart of ongeldige kredietkaart nommer. + + + This value is not a valid International Bank Account Number (IBAN). + Hierdie waarde is nie 'n geldige Internasionale Bankrekeningnommer (IBAN) nie. + + + This value is not a valid ISBN-10. + Hierdie waarde is nie 'n geldige ISBN-10 nie. + + + This value is not a valid ISBN-13. + Hierdie waarde is nie 'n geldige ISBN-13 nie. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Hierdie waarde is nie 'n geldige ISBN-10 of ISBN-13 nie. + + + This value is not a valid ISSN. + Hierdie waarde is nie 'n geldige ISSN nie. + + + This value is not a valid currency. + Hierdie waarde is nie 'n geldige geldeenheid nie. + + + This value should be equal to {{ compared_value }}. + Hierdie waarde moet gelyk aan {{ compared_value }} wees. + + + This value should be greater than {{ compared_value }}. + Hierdie waarde moet meer as {{ compared_value }} wees. + + + This value should be greater than or equal to {{ compared_value }}. + Hierdie waarde moet meer of gelyk aan {{ compared_value }} wees. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Hierdie waarde moet identies aan {{ compared_value_type }} {{ compared_value }} wees. + + + This value should be less than {{ compared_value }}. + Hierdie waarde moet minder as {{ compared_value }} wees. + + + This value should be less than or equal to {{ compared_value }}. + Hierdie waarde moet minder of gelyk aan {{ compared_value }} wees. + + + This value should not be equal to {{ compared_value }}. + Hierdie waarde moet nie dieselfde as {{ compared_value }} wees nie. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Hierdie waarde moet nie identies as {{ compared_value_type }} {{ compared_value }} wees nie. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Die beeld aspek is te groot ({{ ratio }}). Die maksimum toegelate aspek is {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Die beeld aspek is te klein ({{ ratio }}). Die minimum toegelate aspek is {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Die beeld is vierkantig ({{ width }}x{{ height }}px). Vierkantige beelde word nie toegelaat nie. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Die beeld is landskap georiënteerd ({{ width }}x{{ height }}px). Landskap georiënteerde beelde word nie toegelaat nie. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Die beeld dis portret georiënteerd ({{ width }}x{{ height }}px). Portret georiënteerde beelde word nie toegelaat nie. + + + An empty file is not allowed. + 'n Leë lêer word nie toegelaat nie. + + + The host could not be resolved. + Die gasheer kon nie opgelos word nie. + + + This value does not match the expected {{ charset }} charset. + Die waarde stem nie ooreen met die verwagte {{ charset }} karakterstel nie. + + + This value is not a valid Business Identifier Code (BIC). + Hierdie waarde is nie 'n geldige Besigheid Identifiseerder Kode (BIC) nie. + + + Error + Fout + + + This value is not a valid UUID. + Hierdie waarde is nie 'n geldige UUID nie. + + + This value should be a multiple of {{ compared_value }}. + Hierdie waarde moet 'n veelvoud van {{ compared_value }} wees. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Hierdie Besigheids Identifikasie Kode (BIK) is nie geassosieer met IBAN {{ iban }} nie. + + + This value should be valid JSON. + Hierdie waarde moet geldige JSON wees. + + + This collection should contain only unique elements. + Hierdie versameling moet net unieke elemente bevat. + + + This value should be positive. + Hierdie waarde moet positief wees. + + + This value should be either positive or zero. + Hierdie waarde moet positief of nul wees. + + + This value should be negative. + Hierdie waarde moet negatief wees. + + + This value should be either negative or zero. + Hierdie waarde moet negatief of nul wees. + + + This value is not a valid timezone. + Hierdie waarde is nie 'n geldige tydsone nie. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Hierdie wagwoord is in 'n data-oortreding uitgelek, dit mag nie gebruik word nie. Gebruik asseblief 'n ander wagwoord. + + + This value should be between {{ min }} and {{ max }}. + Hierdie waarde moet tussen {{ min }} en {{ max }} wees. + + + This value is not a valid hostname. + Hierdie waarde is nie 'n geldige gasheernaam nie. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Die hoeveelheid elemente in hierdie versameling moet 'n meelvoud van {{ compared_value }} wees. + + + This value should satisfy at least one of the following constraints: + Hierdie waarde moet voldoen aan ten minste een van hierdie beperkings: + + + Each element of this collection should satisfy its own set of constraints. + Elke element van hierdie versameling moet voldoen aan hulle eie beperkings. + + + This value is not a valid International Securities Identification Number (ISIN). + Hierdie waarde is nie 'n geldige Internasionale veiligheidsidentifikasienommer (ISIN) nie. + + + This value should be a valid expression. + Hierdie waarde moet 'n geldige uitdrukking wees. + + + This value is not a valid CSS color. + Hierdie waarde is nie 'n geldige CSS-kleur nie. + + + This value is not a valid CIDR notation. + Hierdie waarde is nie 'n geldige CIDR-notasie nie. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Die waarde van die netmasker moet tussen {{ min }} en {{ max }} wees. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Die lêernaam is te lank. Dit moet {{ filename_max_length }} karakter of minder hê.|Die lêernaam is te lank. Dit moet {{ filename_max_length }} karakters of minder hê. + + + The password strength is too low. Please use a stronger password. + Die wagwoordsterkte is te laag. Gebruik asseblief 'n sterker wagwoord. + + + This value contains characters that are not allowed by the current restriction-level. + Hierdie waarde bevat karakters wat nie toegelaat word deur die huidige beperkingsvlak nie. + + + Using invisible characters is not allowed. + Die gebruik van onsigbare karakters word nie toegelaat nie. + + + Mixing numbers from different scripts is not allowed. + Die meng van nommers van verskillende skrifte word nie toegelaat nie. + + + Using hidden overlay characters is not allowed. + Die gebruik van verborge oorvleuelende karakters word nie toegelaat nie. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Die uitbreiding van die lêer is ongeldig ({{ extension }}). Toegelate uitbreidings is {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Die opgespoorde karakterkodering is ongeldig ({{ detected }}). Toegelate koderings is {{ encodings }}. + + + This value is not a valid MAC address. + Hierdie waarde is nie 'n geldige MAC-adres nie. + + + This URL is missing a top-level domain. + Die URL mis 'n topvlakdomein. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Hierdie waarde is te kort. Dit moet ten minste een woord bevat.|Hierdie waarde is te kort. Dit moet ten minste {{ min }} woorde bevat. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Hierdie waarde is te lank. Dit moet een woord bevat.,Hierdie waarde is te lank. Dit moet {{ max }} woorde of minder bevat. + + + This value does not represent a valid week in the ISO 8601 format. + Hierdie waarde stel nie 'n geldige week in die ISO 8601-formaat voor nie. + + + This value is not a valid week. + Hierdie waarde is nie 'n geldige week nie. + + + This value should not be before week "{{ min }}". + Hierdie waarde mag nie voor week "{{ min }}" wees nie. + + + This value should not be after week "{{ max }}". + Hierdie waarde mag nie na week "{{ max }}" kom nie. + + + This value is not a valid Twig template. + Hierdie waarde is nie 'n geldige Twig-sjabloon nie. + + + This file is not a valid video. + Hierdie lêer is nie 'n geldige video nie. + + + The size of the video could not be detected. + Die grootte van die video kon nie bepaal word nie. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Die videowydte is te groot ({{ width }}px). Toegelate maksimum wydte is {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Die videobreedte is te klein ({{ width }}px). Minimum verwagte breedte is {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Die videohoogte is te groot ({{ height }}px). Toegelate maksimum hoogte is {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Die videohoogte is te klein ({{ height }}px). Minimum hoogte verwag is {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Die video het te min pixels ({{ pixels }}). Minimum hoeveelheid verwag is {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Die video het te veel pixels ({{ pixels }}). Maksimum verwagte hoeveelheid is {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Die videoratio is te groot ({{ ratio }}). Toegelate maksimum ratio is {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Die videoratio is te klein ({{ ratio }}). Minimum verwagte ratio is {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Die video is vierkantig ({{ width }}x{{ height }}px). Vierkantige video's word nie toegelaat nie. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Die video is landskap georiënteer ({{ width }}x{{ height }} px). Landskapvideo's word nie toegelaat nie. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Die video is portretgeoriënteerd ({{ width }}x{{ height }}px). Portretgeoriënteerde video's word nie toegelaat nie. + + + The video file is corrupted. + Die videolêer is korrup. + + + The video contains multiple streams. Only one stream is allowed. + Die video bevat veelvuldige strome. Slegs een stroom word toegelaat. + + + Unsupported video codec "{{ codec }}". + Nie-ondersteunde videokodek "{{ codec }}". + + + Unsupported video container "{{ container }}". + Nie-ondersteunde videohouer "{{ container }}". + + + The image file is corrupted. + Die beeldlêer is beskadig. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Die beeld het te min pixels ({{ pixels }}). Minimum hoeveelheid verwag is {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Die beeld het te veel pixels ({{ pixels }}). Maksimum verwagte aantal is {{ max_pixels }}. + + + This filename does not match the expected charset. + Hierdie lêernaam stem nie ooreen met die verwagte karakterstel nie. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.ar.xlf b/lib/symfony/validator/Resources/translations/validators.ar.xlf new file mode 100644 index 0000000000..783f63dd74 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.ar.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + هذه القيمة يجب أن تكون خاطئة. + + + This value should be true. + هذه القيمة يجب أن تكون صحيحة. + + + This value should be of type {{ type }}. + هذه القيمة يجب ان تكون من نوع {{ type }}. + + + This value should be blank. + هذه القيمة يجب ان تكون فارغة. + + + The value you selected is not a valid choice. + القيمة المختارة ليست خيار صحيح. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + يجب ان تختار {{ limit }} اختيار على الاقل.|يجب ان تختار {{ limit }} اختيار على الاقل.|يجب ان تختار {{ limit }} اختيارات على الاقل.|يجب ان تختار {{ limit }} اختيار على الاقل.|يجب ان تختار {{ limit }} اختيار على الاقل.|يجب ان تختار {{ limit }} اختيار على الاقل. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + يجب ان تختار {{ limit }} اختيار على الاكثر.|يجب ان تختار {{ limit }} اختيار على الاكثر.|يجب ان تختار {{ limit }} اختيارات على الاكثر.|يجب ان تختار {{ limit }} اختيار على الاكثر.|يجب ان تختار {{ limit }} اختيار على الاكثر.|يجب ان تختار {{ limit }} اختيار على الاكثر. + + + One or more of the given values is invalid. + واحد أو أكثر من القيم المعطاه خاطئ. + + + This field was not expected. + لم يكن من المتوقع هذا الحقل. + + + This field is missing. + هذا الحقل مفقود. + + + This value is not a valid date. + هذه القيمة ليست تاريخ صالح. + + + This value is not a valid datetime. + هذه القيمة ليست تاريخ و وقت صالح. + + + This value is not a valid email address. + هذه القيمة ليست لها عنوان بريد إلكتروني صحيح. + + + The file could not be found. + لا يمكن العثور على الملف. + + + The file is not readable. + الملف غير قابل للقراءة. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + الملف كبير جدا ({{ size }} {{ suffix }}).اقصى مساحه مسموح بها ({{ limit }} {{ suffix }}). + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + نوع الملف غير صحيح ({{ type }}). الانواع المسموح بها هى {{ types }}. + + + This value should be {{ limit }} or less. + هذه القيمة يجب ان تكون {{ limit }} او اقل. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حروف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل. + + + This value should be {{ limit }} or more. + هذه القيمة يجب ان تكون {{ limit }} او اكثر. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حروف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر. + + + This value should not be blank. + هذه القيمة يجب لا تكون فارغة. + + + This value should not be null. + هذه القيمة يجب لا تكون فارغة. + + + This value should be null. + هذه القيمة يجب ان تكون فارغة. + + + This value is not valid. + هذه القيمة غير صحيحة. + + + This value is not a valid time. + هذه القيمة ليست وقت صحيح. + + + This value is not a valid URL. + هذه القيمة ليست رابط الكترونى صحيح. + + + The two values should be equal. + القيمتان يجب ان تكونا متساويتان. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + الملف كبير جدا. اقصى مساحه مسموح بها {{ limit }} {{ suffix }}. + + + The file is too large. + الملف كبير جدا. + + + The file could not be uploaded. + تعذر تحميل الملف. + + + This value should be a valid number. + هذه القيمة يجب ان تكون رقم. + + + This file is not a valid image. + هذا الملف غير صالح للصورة. + + + This value is not a valid IP address. + هذا ليس عنوان IP صحيح. + + + This value is not a valid language. + هذه القيمة ليست لغة صحيحة. + + + This value is not a valid locale. + هذه القيمة ليست موقع صحيح. + + + This value is not a valid country. + هذه القيمة ليست بلدا صالحا. + + + This value is already used. + هذه القيمة مستخدمة بالفعل. + + + The size of the image could not be detected. + لم استطع معرفة حجم الصورة. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + عرض الصورة كبير جدا ({{ width }}px). اقصى عرض مسموح به هو{{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + عرض الصورة صغير جدا ({{ width }}px). اقل عرض مسموح به هو{{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + طول الصورة كبير جدا ({{ height }}px). اقصى طول مسموح به هو{{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + طول الصورة صغير جدا ({{ height }}px). اقل طول مسموح به هو{{ min_height }}px. + + + This value should be the user's current password. + هذه القيمة يجب ان تكون كلمة سر المستخدم الحالية. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حروف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط. + + + The file was only partially uploaded. + تم استقبال جزء من الملف فقط. + + + No file was uploaded. + لم يتم ارسال اى ملف. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + لم يتم تكوين مجلد مؤقت في ملف php.ini. + + + Cannot write temporary file to disk. + لم استطع كتابة الملف المؤقت. + + + A PHP extension caused the upload to fail. + احد اضافات PHP تسببت فى فشل استقبال الملف. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عناصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عناصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عناصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط. + + + Invalid card number. + رقم البطاقه غير صحيح. + + + Unsupported card type or invalid card number. + نوع البطاقه غير مدعوم او الرقم غير صحيح. + + + This value is not a valid International Bank Account Number (IBAN). + هذه القيمة ليست رقم حساب بنكي دولي (IBAN) صالحًا. + + + This value is not a valid ISBN-10. + هذه القيمة ليست ISBN-10 صالحة. + + + This value is not a valid ISBN-13. + هذه القيمة ليست ISBN-13 صالحة. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + هذه القيمة ليست ISBN-10 صالحة ولا ISBN-13 صالحة. + + + This value is not a valid ISSN. + هذه القيمة ليست ISSN صالحة. + + + This value is not a valid currency. + العُملة غير صحيحة. + + + This value should be equal to {{ compared_value }}. + القيمة يجب ان تساوي {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + القيمة يجب ان تكون اعلي من {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + القيمة يجب ان تكون مساوية او اعلي من {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + القيمة يجب ان تطابق {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + القيمة يجب ان تكون اقل من {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + القيمة يجب ان تساوي او تقل عن {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + القيمة يجب ان لا تساوي {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + القيمة يجب ان لا تطابق {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + نسبة العرض على الارتفاع للصورة كبيرة جدا ({{ ratio }}). الحد الأقصى للنسبة المسموح به هو {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + نسبة العرض على الارتفاع للصورة صغيرة جدا ({{ ratio }}). الحد الأدنى للنسبة المسموح به هو {{ max_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + الصورة مربعة ({{ width }}x{{ height }}px). الصور المربعة غير مسموح بها. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + الصورة في وضع أفقي ({{ width }}x{{ height }}px). الصور في وضع أفقي غير مسموح بها. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + الصورة في وضع عمودي ({{ width }}x{{ height }}px). الصور في وضع عمودي غير مسموح بها. + + + An empty file is not allowed. + ملف فارغ غير مسموح به. + + + The host could not be resolved. + يتعذر الإتصال بالنطاق. + + + This value does not match the expected {{ charset }} charset. + هذه القيمة غير متطابقة مع صيغة التحويل {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + هذه القيمة ليست رمز معرف أعمال (BIC) صالحًا. + + + Error + خطأ + + + This value is not a valid UUID. + هذه القيمة ليست UUID صالحًا. + + + This value should be a multiple of {{ compared_value }}. + هذه القيمة يجب أن تكون مضاعف ل {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + رمز المعرّف نشاط تجاري (BIC) هذا لا يرتبط مع IBAN {{ iban }}. + + + This value should be valid JSON. + هذه القيمة يجب أن تكون صالحة ل JSON. + + + This collection should contain only unique elements. + يجب أن تحتوي هذه المجموعة علي عناصر فريدة فقط. + + + This value should be positive. + يجب أن تكون هذه القيمة موجبة. + + + This value should be either positive or zero. + يجب أن تكون هذه القيمة إما موجبة او صفر. + + + This value should be negative. + يجب أن تكون هذه القيمة سالبة. + + + This value should be either negative or zero. + يجب أن تكون هذه القيمة إما سالبة او صفر. + + + This value is not a valid timezone. + هذه القيمة ليست منطقة زمنية صحيحة. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + تم تسريب كلمة المرور هذه في خرق للبيانات، ويجب عدم استخدامها. يرجي استخدام كلمة مرور أخري. + + + This value should be between {{ min }} and {{ max }}. + يجب أن تكون هذه القيمة بين {{ min }} و {{ max }}. + + + This value is not a valid hostname. + هذه القيمة ليست اسم مضيف صالح. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + يجب أن يكون عدد العناصر في هذه المجموعة مضاعف {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + يجب أن تستوفي هذه القيمة واحدة من القيود التالية: + + + Each element of this collection should satisfy its own set of constraints. + يجب أن يفي كل عنصر من عناصر هذه المجموعة بمجموعة القيود الخاصة به. + + + This value is not a valid International Securities Identification Number (ISIN). + صالح (ISIN) هذه القيمة ليست رقم تعريف الأوراق المالية الدولي. + + + This value should be a valid expression. + يجب أن تكون هذه القيمة تعبيرًا صالحًا. + + + This value is not a valid CSS color. + هذه القيمة ليست لون CSS صالحًا. + + + This value is not a valid CIDR notation. + هذه القيمة ليست تدوين CIDR صالحًا. + + + The value of the netmask should be between {{ min }} and {{ max }}. + يجب أن تكون قيمة netmask بين {{ min }} و {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + اسم الملف طويل جدا. يجب أن يحتوي على {{ filename_max_length }} حرف أو أقل.|اسم الملف طويل جدا. يجب أن يحتوي على {{ filename_max_length }} أحرف أو أقل. + + + The password strength is too low. Please use a stronger password. + قوة كلمة المرور منخفضة للغاية. يرجى استخدام كلمة مرور أقوى. + + + This value contains characters that are not allowed by the current restriction-level. + تحتوي هذه القيمة على أحرف غير مسموح بها بواسطة مستوى التقييد الحالي. + + + Using invisible characters is not allowed. + لا يسمح باستخدام أحرف غير مرئية. + + + Mixing numbers from different scripts is not allowed. + لا يسمح بخلط الأرقام من نصوص مختلفة. + + + Using hidden overlay characters is not allowed. + لا يسمح باستخدام أحرف التراكب المخفية. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + امتداد الملف غير صحيح ({{ extension }}). الامتدادات المسموح بها هي {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + تم اكتشاف ترميز أحرف غير صالح ({{ detected }}). الترميزات المسموح بها هي {{ encodings }}. + + + This value is not a valid MAC address. + هذه القيمة ليست عنوان MAC صالحًا. + + + This URL is missing a top-level domain. + هذا الرابط يفتقر إلى نطاق المستوى الأعلى. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + هذه القيمة قصيرة جدًا. يجب أن تحتوي على كلمة واحدة على الأقل.|هذه القيمة قصيرة جدًا. يجب أن تحتوي على {{ min }} كلمة على الأقل. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + هذه القيمة طويلة جدًا. يجب أن تحتوي على كلمة واحدة فقط.|هذه القيمة طويلة جدًا. يجب أن تحتوي على {{ max }} كلمة أو أقل. + + + This value does not represent a valid week in the ISO 8601 format. + هذه القيمة لا تمثل أسبوعًا صالحًا وفق تنسيق ISO 8601. + + + This value is not a valid week. + هذه القيمة ليست أسبوعًا صالحًا. + + + This value should not be before week "{{ min }}". + يجب ألا تكون هذه القيمة قبل الأسبوع "{{ min }}". + + + This value should not be after week "{{ max }}". + يجب ألا تكون هذه القيمة بعد الأسبوع "{{ max }}". + + + This value is not a valid Twig template. + هذه القيمة ليست نموذج Twig صالح. + + + This file is not a valid video. + هذا الملف غير صالح كفيديو. + + + The size of the video could not be detected. + تعذّر تحديد حجم الفيديو. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + عرض الفيديو كبير جدًا ({{ width }}px). الحد الأقصى المسموح للعرض هو {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + عرض الفيديو صغير جدًا ({{ width }}px). العرض الأدنى المتوقع هو {{ min_width }} بكسل. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + ارتفاع الفيديو كبير جدًا ({{ height }}px). الحد الأقصى المسموح للارتفاع هو {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + ارتفاع الفيديو صغير جدًا ({{ height }} بكسل). الارتفاع الأدنى المتوقع هو {{ min_height }} بكسل. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + الفيديو منخفض الجودة جداً ({{ pixels }} بكسل). الحد الأدنى المتوقع هو {{ min_pixels }} بكسل. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + دقة الفيديو مرتفعة جداً ({{ pixels }} بكسل). الحد الأقصى المتوقع هو {{ max_pixels }} بكسل. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + نسبة أبعاد الفيديو كبيرة جدًا ({{ ratio }}). أعلى نسبة متوقعة هي {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + نسبة أبعاد الفيديو صغيرة جدًا ({{ ratio }}). أقل نسبة متوقعة هي {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + الفيديو مربع ({{ width }}x{{ height }}px). مقاطع الفيديو ذات الشكل المربع غير مسموح بها. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + الفيديو بوضعية أفقية ({{ width }}x{{ height }} بكسل). مقاطع الفيديو الأفقية غير مسموح بها. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + الفيديو ذو اتجاه عمودي ({{ width }}x{{ height }} بكسل). مقاطع الفيديو ذات الاتجاه العمودي غير مسموح بها. + + + The video file is corrupted. + ملف الفيديو تالف. + + + The video contains multiple streams. Only one stream is allowed. + الفيديو يحتوي على عدة مسارات (صوت أو صورة)، ومسموح بمسار واحد فقط. + + + Unsupported video codec "{{ codec }}". + الترميز المستخدم في الفيديو غير مدعوم. "{{ codec }}". + + + Unsupported video container "{{ container }}". + ملف الفيديو بصيغة غير مدعومة "{{ container }}". + + + The image file is corrupted. + ملف الصورة تالف. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + الصورة منخفضة الجودة جدًا ({{ pixels }} بكسل)، و الحد الأدنى المتوقع: {{ min_pixels }} بكسل. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + جودة الصورة مرتفعة جدًا ({{ pixels }} بكسل). العدد الأقصى المتوقع هو {{ max_pixels }} بكسل. + + + This filename does not match the expected charset. + اسم الملف يحتوي على أحرف غير مسموح بها. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.az.xlf b/lib/symfony/validator/Resources/translations/validators.az.xlf new file mode 100644 index 0000000000..a9d281384c --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.az.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Bu dəyər false olmalıdır. + + + This value should be true. + Bu dəyər true olmalıdır. + + + This value should be of type {{ type }}. + Bu dəyərin tipi {{ type }} olmalıdır. + + + This value should be blank. + Bu dəyər boş olmalıdır. + + + The value you selected is not a valid choice. + Seçdiyiniz dəyər düzgün bir seçim değil. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Ən az {{ limit }} seçim qeyd edilməlidir. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Ən çox {{ limit }} seçim qeyd edilməlidir. + + + One or more of the given values is invalid. + Təqdim edilən dəyərlərdən bir və ya bir neçəsi yanlışdır. + + + This field was not expected. + Bu sahə gözlənilmirdi. + + + This field is missing. + Bu sahə əksikdir. + + + This value is not a valid date. + Bu dəyər düzgün bir tarix deyil. + + + This value is not a valid datetime. + Bu dəyər düzgün bir tarixsaat deyil. + + + This value is not a valid email address. + Bu dəyər düzgün bir e-poçt adresi deyil. + + + The file could not be found. + Fayl tapılmadı. + + + The file is not readable. + Fayl oxunabilən deyil. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Fayl çox böyükdür ({{ size }} {{ suffix }}). İcazə verilən maksimum fayl ölçüsü {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Faylın mime tipi yanlışdr ({{ type }}). İcazə verilən mime tipləri {{ types }}. + + + This value should be {{ limit }} or less. + Bu dəyər {{ limit }} və ya altında olmalıdır. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Bu dəyər çox uzundur. {{ limit }} və ya daha az simvol olmalıdır. + + + This value should be {{ limit }} or more. + Bu dəyər {{ limit }} veya daha fazla olmalıdır. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Bu dəyər çox qısadır. {{ limit }} və ya daha çox simvol olmalıdır. + + + This value should not be blank. + Bu dəyər boş olmamalıdır. + + + This value should not be null. + Bu dəyər boş olmamalıdır. + + + This value should be null. + Bu dəyər boş olmamalıdır. + + + This value is not valid. + Bu dəyər doğru deyil. + + + This value is not a valid time. + Bu dəyər doğru bir saat deyil. + + + This value is not a valid URL. + Bu dəyər doğru bir URL değil. + + + The two values should be equal. + İki dəyər eyni olmalıdır. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Fayl çox böyükdür. İcazə verilən ən böyük fayl ölçüsü {{ limit }} {{ suffix }}. + + + The file is too large. + Fayl çox böyükdür. + + + The file could not be uploaded. + Fayl yüklənəbilmir. + + + This value should be a valid number. + Bu dəyər rəqəm olmalıdır. + + + This file is not a valid image. + Bu fayl düzgün bir şəkil deyil. + + + This value is not a valid IP address. + Bu dəyər etibarlı bir IP ünvanı deyil. + + + This value is not a valid language. + Bu dəyər düzgün bir dil deyil. + + + This value is not a valid locale. + Bu dəyər düzgün bir dil deyil. + + + This value is not a valid country. + Bu dəyər düzgün bir ölkə deyil. + + + This value is already used. + Bu dəyər hal-hazırda istifadədədir. + + + The size of the image could not be detected. + Şəklin ölçüsü hesablana bilmir. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Şəklin genişliyi çox böyükdür ({{ width }}px). İcazə verilən ən böyük genişlik {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Şəklin genişliyi çox kiçikdir ({{ width }}px). Ən az {{ min_width }}px olmalıdır. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Şəklin yüksəkliyi çox böyükdür ({{ height }}px). İcazə verilən ən böyük yüksəklik {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Şəklin yüksəkliyi çox kiçikdir ({{ height }}px). Ən az {{ min_height }}px olmalıdır. + + + This value should be the user's current password. + Bu dəyər istifadəçinin hazırkı parolu olmalıdır. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Bu dəyər tam olaraq {{ limit }} simvol olmaldır. + + + The file was only partially uploaded. + Fayl qismən yükləndi. + + + No file was uploaded. + Fayl yüklənmədi. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + php.ini-də müvəqqəti qovluq quraşdırılmayıb, və ya quraşdırılmış qovluq mövcud deyil. + + + Cannot write temporary file to disk. + Müvəqqəti fayl diskə yazıla bilmir. + + + A PHP extension caused the upload to fail. + Bir PHP əlavəsi faylın yüklənməsinə mane oldu. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Bu kolleksiyada {{ limit }} və ya daha çox element olmalıdır. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Bu kolleksiyada {{ limit }} və ya daha az element olmalıdır. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Bu kolleksiyada tam olaraq {{ limit }} element olmalıdır. + + + Invalid card number. + Yanlış kart nömrəsi. + + + Unsupported card type or invalid card number. + Dəstəklənməyən kart tipi və ya yanlış kart nömrəsi. + + + This value is not a valid International Bank Account Number (IBAN). + Bu dəyər etibarlı bir Beynəlxalq Bank Hesab Nömrəsi (IBAN) deyil. + + + This value is not a valid ISBN-10. + Bu dəyər doğru bir ISBN-10 deyil. + + + This value is not a valid ISBN-13. + Bu dəyər doğru bir ISBN-13 deyil. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Bu dəyər doğru bir ISBN-10 və ya ISBN-13 deyil. + + + This value is not a valid ISSN. + Bu dəyər doğru bir ISSN deyil. + + + This value is not a valid currency. + Bu dəyər doğru bir valyuta deyil. + + + This value should be equal to {{ compared_value }}. + Bu dəyər {{ compared_value }} ilə bərabər olmalıdır. + + + This value should be greater than {{ compared_value }}. + Bu dəyər {{ compared_value }} dəyərindən büyük olmalıdır. + + + This value should be greater than or equal to {{ compared_value }}. + Bu dəyər {{ compared_value }} ilə bərabər və ya daha böyük olmaldır. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Bu dəyər {{ compared_value_type }} {{ compared_value }} ilə eyni olmalıdır. + + + This value should be less than {{ compared_value }}. + Bu dəyər {{ compared_value }} dəyərindən kiçik olmalıdır. + + + This value should be less than or equal to {{ compared_value }}. + Bu dəyər {{ compared_value }} dəyərindən kiçik və ya bərabər olmalıdır. + + + This value should not be equal to {{ compared_value }}. + Bu değer {{ compared_value }} ile eşit olmamalıdır. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Bu dəyər {{ compared_value_type }} {{ compared_value }} ilə eyni olmamalıdır. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Şəkil nisbəti çox büyükdür ({{ ratio }}). İcazə verilən maksimum nisbət: {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Şəkil nisbəti çox balacadır ({{ ratio }}). İcazə verilən minimum nisbət: {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Şəkil kvadratdır ({{ width }}x{{ height }}px). Kvadrat şəkillərə icazə verilmir. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Şəkil albom rejimindədir ({{ width }}x{{ height }}px). Albom rejimli şəkillərə icazə verilmir. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Şəkil portret rejimindədir ({{ width }}x{{ height }}px). Portret rejimli şəkillərə icazə verilmir. + + + An empty file is not allowed. + Boş fayla icazə verilmir. + + + The host could not be resolved. + Ünvan tapılmadı. + + + This value does not match the expected {{ charset }} charset. + Bu dəyər gözlənilən {{ charset }} simvol cədvəli ilə uyğun gəlmir. + + + This value is not a valid Business Identifier Code (BIC). + Bu dəyər etibarlı bir Biznes Təyinat Kodu (BIC) deyil. + + + Error + Xəta + + + This value is not a valid UUID. + Bu dəyər etibarlı bir UUID deyil. + + + This value should be a multiple of {{ compared_value }}. + Bu dəyər {{ compare_value }} dəyərinin bölənlərindən biri olmalıdır. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Bu Biznes Təyinedici Kodu (BIC) {{ iban }} IBAN kodu ilə əlaqəli deyil. + + + This value should be valid JSON. + Bu dəyər doğru bir JSON olmalıdır. + + + This collection should contain only unique elements. + Bu kolleksiyada sadəcə unikal elementlər olmalıdır. + + + This value should be positive. + Bu dəyər müsbət olmalıdır. + + + This value should be either positive or zero. + Bu dəyər müsbət və ya sıfır olmalıdır. + + + This value should be negative. + Bu dəyər mənfi olmaldır. + + + This value should be either negative or zero. + Bu dəyər mənfi və ya sıfır olmaldır. + + + This value is not a valid timezone. + Bu dəyər doğru bir zaman zolağı deyil. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Bu parol data oğurluğunda tapıldığı üçün işlədilməməlidir. Zəhmət olmasa, başqa parol seçin. + + + This value should be between {{ min }} and {{ max }}. + Bu dəyər {{ min }} və {{ max }} arasında olmaldır. + + + This value is not a valid hostname. + Bu dəyər doğru bir host adı deyil. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Bu kolleksiyadakı elementlerin sayı {{ compared_value }} tam bölünəni olmalıdır. + + + This value should satisfy at least one of the following constraints: + Bu dəyər aşağıdakı məcburiyyətlərdən birini qarşılamalıdır: + + + Each element of this collection should satisfy its own set of constraints. + Bu kolleksiyadakı hər element öz məcburiyyətlərini qarşılamalıdır. + + + This value is not a valid International Securities Identification Number (ISIN). + Bu dəyər doğru bir Qiymətli Kağızın Beynəlxalq İdentifikasiya Kodu (ISIN) deyil. + + + This value should be a valid expression. + Bu dəyər etibarlı ifadə olmalıdır. + + + This value is not a valid CSS color. + Bu dəyər etibarlı CSS rəngi deyil. + + + This value is not a valid CIDR notation. + Bu dəyər etibarlı CIDR notasiyası deyil. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Şəbəkə maskasının dəyəri {{ min }} və {{ max }} arasında olmalıdır. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Fayl adı çox uzundur. {{ filename_max_length }} və ya daha az simvol olmalıdır. + + + The password strength is too low. Please use a stronger password. + Parolun gücü çox zəifdir. Zəhmət olmasa, daha güclü bir parol istifadə edin. + + + This value contains characters that are not allowed by the current restriction-level. + Bu dəyərdə cari məhdudiyyət səviyyəsi tərəfindən icazə verilməyən simvollar var. + + + Using invisible characters is not allowed. + Görünməz simvolların istifadəsinə icazə verilmir. + + + Mixing numbers from different scripts is not allowed. + Fərqli skriptlərdən nömrələrin qarışdırılmasına icazə verilmir. + + + Using hidden overlay characters is not allowed. + Gizli örtülü simvolların istifadəsinə icazə verilmir. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Faylın uzantısı yanlışdır ({{ extension }}). İcazə verilən uzantılar {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Təsbit edilən simvol şifrləməsi yanlışdır. ({{ detected }}). İcazə verilən şifrləmələr bunlardır: {{ encodings }}. + + + This value is not a valid MAC address. + Bu dəyər etibarlı bir MAC ünvanı deyil. + + + This URL is missing a top-level domain. + Bu URL yuxarı səviyyəli domeni çatışmır. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Bu dəyər çox qısadır. Heç olmasa bir söz daxil etməlisiniz.|Bu dəyər çox qısadır. Heç olmasa {{ min }} söz daxil etməlisiniz. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Bu dəyər çox uzundur. Yalnız bir söz daxil etməlisiniz.|Bu dəyər çox uzundur. {{ max }} və ya daha az söz daxil etməlisiniz. + + + This value does not represent a valid week in the ISO 8601 format. + Bu dəyər ISO 8601 formatında etibarlı bir həftəni təmsil etmir. + + + This value is not a valid week. + Bu dəyər etibarlı bir həftə deyil. + + + This value should not be before week "{{ min }}". + Bu dəyər "{{ min }}" həftəsindən əvvəl olmamalıdır. + + + This value should not be after week "{{ max }}". + Bu dəyər "{{ max }}" həftəsindən sonra olmamalıdır. + + + This value is not a valid Twig template. + Bu dəyər etibarlı Twig şablonu deyil. + + + This file is not a valid video. + Bu fayl etibarlı video deyil. + + + The size of the video could not be detected. + Videonun ölçüsünü təyin etmək mümkün olmadı. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Video enliyi çox böyükdür ({{ width }}px). İcazə verilən maksimal enlik {{ max_width }}px-dir. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Video eni çox kiçikdir ({{ width }}px). Gözlənilən minimum en {{ min_width }}px-dir. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Video hündürlüyü çox böyükdür ({{ height }}px). İcazə verilən maksimum hündürlük {{ max_height }}px-dir. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Videonun hündürlüyü çox kiçikdir ({{ height }}px). Gözlənilən minimum hündürlük {{ min_height }}px-dir. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Videoda piksellərin sayı çox azdır ({{ pixels }}). Gözlənilən minimum miqdar {{ min_pixels }}-dir. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Videoda həddindən artıq piksel var ({{ pixels }}). Gözlənilən maksimum miqdar {{ max_pixels }}-dir. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Video nisbəti çox böyükdür ({{ ratio }}). İcazə verilən maksimal nisbət {{ max_ratio }}‑dir. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Video nisbəti çox kiçikdir ({{ ratio }}). Gözlənilən minimal nisbət {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video kvadratdır ({{ width }}x{{ height }}px). Kvadrat videolara icazə verilmir. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video üfiqi istiqamətdədir ({{ width }}x{{ height }} piksel). Üfiqi videolara icazə verilmir. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video portret istiqamətindədir ({{ width }}x{{ height }} piksel). Portret istiqamətli videolara icazə verilmir. + + + The video file is corrupted. + Video faylı zədələnib. + + + The video contains multiple streams. Only one stream is allowed. + Video bir neçə axın ehtiva edir. Yalnız bir axına icazə verilir. + + + Unsupported video codec "{{ codec }}". + Dəstəklənməyən video kodeki "{{ codec }}". + + + Unsupported video container "{{ container }}". + Dəstəklənməyən video konteyneri "{{ container }}". + + + The image file is corrupted. + Şəkil faylı korlanıb. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Şəkildə piksel sayı çox azdır ({{ pixels }}). Gözlənilən minimum miqdar {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Şəkildə çox piksel var ({{ pixels }}). Gözlənilən maksimum say {{ max_pixels }}. + + + This filename does not match the expected charset. + Bu fayl adı gözlənilən simvol dəstinə uyğun gəlmir. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.be.xlf b/lib/symfony/validator/Resources/translations/validators.be.xlf new file mode 100644 index 0000000000..13c6d43a23 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.be.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Значэнне павінна быць Не. + + + This value should be true. + Значэнне павінна быць Так. + + + This value should be of type {{ type }}. + Тып значэння павінен быць {{ type }}. + + + This value should be blank. + Значэнне павінна быць пустым. + + + The value you selected is not a valid choice. + Выбранае вамі значэнне не з’яўляецца сапраўдным. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Вы павінны выбраць хаця б {{ limit }} варыянт.|Вы павінны выбраць хаця б {{ limit }} варыянтаў. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Вы павінны выбраць не больш за {{ limit }} варыянт.|Вы павінны выбраць не больш за {{ limit }} варыянтаў. + + + One or more of the given values is invalid. + Адно або некалькі з зададзеных значэнняў не з’яўляюцца сапраўднымі. + + + This field was not expected. + Гэта поле не чакаецца. + + + This field is missing. + Гэта поле адсутнічае. + + + This value is not a valid date. + Гэта значэнне не з'яўляецца карэктнай датай. + + + This value is not a valid datetime. + Гэта значэнне не з'яўляецца карэктнай датай i часом. + + + This value is not a valid email address. + Гэта значэнне не з'яўляецца карэктным адрасам электроннай пошты. + + + The file could not be found. + Файл не знойдзен. + + + The file is not readable. + Файл не чытаецца. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Файл занадта вялікі ({{ size }} {{ suffix }}). Максімальна дазволены памер {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + MIME-тып файлу некарэкты ({{ type }}). Дазволеныя MIME-тыпы файлу {{ types }}. + + + This value should be {{ limit }} or less. + Значэнне павінна быць {{ limit }} або менш. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Значэнне занадта доўгае. Яно павінна мець не больш за {{ limit }} сімвал.|Значэнне занадта доўгае. Яно павінна мець не больш за {{ limit }} сімвалаў. + + + This value should be {{ limit }} or more. + Значэнне павінна быць не менш за {{ limit }}. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Значэнне занадта кароткае. Яно павінна мець не менш за {{ limit }} сімвал.|Значэнне занадта кароткае. Яно павінна мець не менш за {{ limit }} сімвалаў. + + + This value should not be blank. + Значэнне не павінна быць пустым. + + + This value should not be null. + Значэнне не павінна быць null. + + + This value should be null. + Значэнне павінна быць null. + + + This value is not valid. + Значэнне не з'яўляецца сапраўдным. + + + This value is not a valid time. + Значэнне не з'яўляецца сапраўдным часам. + + + This value is not a valid URL. + Значэнне не з'яўляецца сапраўдным URL-адрасам. + + + The two values should be equal. + Абодва значэнні павінны супадаць. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Файл занадта вялікі. Максімальна дазволены памер {{ limit }} {{ suffix }}. + + + The file is too large. + Файл занадта вялікі. + + + The file could not be uploaded. + Немагчыма запампаваць файл. + + + This value should be a valid number. + Значэнне павінна быць лікам. + + + This file is not a valid image. + Гэты файл не з'яўляецца сапраўднай выявай. + + + This value is not a valid IP address. + Гэта значэнне не з'яўляецца сапраўдным IP-адрасам. + + + This value is not a valid language. + Значэнне не з'яўляецца сапраўднай мовай. + + + This value is not a valid locale. + Значэнне не з'яўляецца сапраўднай лакаллю. + + + This value is not a valid country. + Значэнне не з'яўляецца сапраўднай краінай. + + + This value is already used. + Гэта значэнне ўжо выкарыстоўваецца. + + + The size of the image could not be detected. + Немагчыма вызначыць памер выявы. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Гэта выява занадта вялікая ({{ width }}px). Дазваляецца максімальная шырыня {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Гэта выява занадта маленькая ({{ width }}px). Дазваляецца мінімальная шырыня {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Гэтая выява занадта высокая ({{ height }}px). Дазваляецца максімальная вышыня — {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Гэтая выява занадта нізкая ({{ height }}px). Дазваляецца мінімальная вышыня — {{ min_height }}px. + + + This value should be the user's current password. + Значэнне павінна быць цяперашнім паролем карыстальніка. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Значэнне павінна мець {{ limit }} сімвал.|Значэнне павінна мець {{ limit }} сімвалаў. + + + The file was only partially uploaded. + Файл быў запампаваны толькі часткова. + + + No file was uploaded. + Файл не быў запампаваны. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + У php.ini не была налажана часовая папка, або часовая папка не існуе. + + + Cannot write temporary file to disk. + Немагчыма запісаць часовы файл на дыск. + + + A PHP extension caused the upload to fail. + Пашырэнне PHP выклікала памылку загрузкі. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Калекцыя павінна змяшчаць не менш за {{ limit }} элемент.|Калекцыя павінна змяшчаць не менш за {{ limit }} элементаў. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Калекцыя павінна змяшчаць не больш за {{ limit }} элемент.|Калекцыя павінна змяшчаць не больш за {{ limit }} элементаў. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Калекцыя павінна змяшчаць роўна {{ limit }} элемент.|Калекцыя павінна змяшчаць роўна {{ limit }} элементаў. + + + Invalid card number. + Несапраўдны нумар карты. + + + Unsupported card type or invalid card number. + Тып карты не падтрымліваецца або несапраўдны нумар карты. + + + This value is not a valid International Bank Account Number (IBAN). + Гэта значэнне не з'яўляецца сапраўдным міжнародным нумарам банкаўскага рахунку (IBAN). + + + This value is not a valid ISBN-10. + Гэта значэнне не з'яўляецца сапраўдным ISBN-10. + + + This value is not a valid ISBN-13. + Гэта значэнне не з'яўляецца сапраўдным ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Гэта значэнне не з'яўляецца ні сапраўдным ISBN-10, ні сапраўдным ISBN-13. + + + This value is not a valid ISSN. + Гэта значэнне не з'яўляецца сапраўдным ISSN. + + + This value is not a valid currency. + Гэта значэнне не з'яўляецца сапраўднай валютай. + + + This value should be equal to {{ compared_value }}. + Значэнне павінна раўняцца {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Значэнне павінна быць больш за {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Значэнне павінна быць больш за або роўнае {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Значэнне павінна быць ідэнтычным {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Значэнне павінна быць менш за {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Значэнне павінна быць менш за або роўнае {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Значэнне не павінна раўняцца {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Значэнне не павінна быць ідэнтычным {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Суадносіны бакоў выявы занадта вялікія ({{ ratio }}). Дазваляецца максімальныя суадносіны {{max_ratio}} . + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Суадносіны бакоў выявы занадта малыя ({{ ratio }}). Дазваляецца мінімальныя суадносіны {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Выява квадратная ({{width}}x{{height}}px). Квадратныя выявы не дазволены. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Выява ў альбомнай арыентацыі ({{ width }}x{{ height }}px). Выявы ў альбомнай арыентацыі не дазволены. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Выява ў партрэтнай арыентацыі ({{ width }}x{{ height }}px). Выявы ў партрэтнай арыентацыі не дазволены. + + + An empty file is not allowed. + Пусты файл не дазволены. + + + The host could not be resolved. + Не магчыма вызначыць імя хоста. + + + This value does not match the expected {{ charset }} charset. + Гэта значэнне не супадае з чаканай {{ charset }} кадыроўкай. + + + This value is not a valid Business Identifier Code (BIC). + Гэта значэнне не з'яўляецца сапраўдным кодам ідэнтыфікацыі банка (BIC). + + + Error + Памылка + + + This value is not a valid UUID. + Гэта значэнне не з'яўляецца сапраўдным UUID. + + + This value should be a multiple of {{ compared_value }}. + Значэнне павінна быць кратным {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Банкаўскі ідэнтыфікацыйны код (BIC) не звязан з IBAN {{ iban }}. + + + This value should be valid JSON. + Гэта значэнне павінна быць у фармаце JSON. + + + This collection should contain only unique elements. + Калекцыя павінна змяшчаць толькі ўнікальныя элементы. + + + This value should be positive. + Значэнне павінна быць дадатным. + + + This value should be either positive or zero. + Значэнне павінна быць або дадатным, або роўным нулю. + + + This value should be negative. + Значэнне павінна быць адмоўным. + + + This value should be either negative or zero. + Значэнне павінна быць або адмоўным, або роўным нулю. + + + This value is not a valid timezone. + Значэнне не з'яўляецца сапраўдным гадзінным поясам. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Гэты пароль быў выкрадзены ў выніку ўзлому дадзеных, таму яго нельга выкарыстоўваць. Калі ласка, выкарыстоўвайце іншы пароль. + + + This value should be between {{ min }} and {{ max }}. + Значэнне павінна быць паміж {{min}} і {{max}}. + + + This value is not a valid hostname. + Значэнне не з'яўляецца сапраўднай/карэктнай назвай хоста. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Колькасць элементаў у гэтай калекцыі павінна быць кратнай {{compared_value}}. + + + This value should satisfy at least one of the following constraints: + Значэнне павінна задавальняць як мінімум аднаму з наступных абмежаванняў: + + + Each element of this collection should satisfy its own set of constraints. + Кожны элемент гэтай калекцыі павінен задавальняць свайму ўласнаму набору абмежаванняў. + + + This value is not a valid International Securities Identification Number (ISIN). + Значэнне не з'яўляецца карэктным міжнародным ідэнтыфікацыйным нумарам каштоўных папер (ISIN). + + + This value should be a valid expression. + Значэнне павінна быць сапраўдным выразам. + + + This value is not a valid CSS color. + Значэнне не з'яўляецца дапушчальным колерам CSS. + + + This value is not a valid CIDR notation. + Значэнне не з'яўляецца сапраўднай натацыяй CIDR. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Значэнне сеткавай маскі павінна быць ад {{min}} да {{max}}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Назва файла занадта доўгая. Яна павинна мець {{ filename_max_length }} сімвал або менш.|Назва файла занадта доўгая. Яна павінна мець {{ filename_max_length }} сімвалы або менш.|Назва файла занадта доўгая. Яна павінна мець {{ filename_max_length }} сімвалаў або менш. + + + The password strength is too low. Please use a stronger password. + Надзейнасць пароля занадта нізкая. Выкарыстоўвайце больш надзейны пароль. + + + This value contains characters that are not allowed by the current restriction-level. + Гэта значэнне змяшчае сімвалы, якія не дазволены цяперашнім узроўнем абмежаванняў. + + + Using invisible characters is not allowed. + Выкарыстанне нябачных сімвалаў не дазваляецца. + + + Mixing numbers from different scripts is not allowed. + Змешванне лічбаў з розных алфавітаў не дапускаецца. + + + Using hidden overlay characters is not allowed. + Выкарыстанне схаваных накладзеных сімвалаў не дазваляецца. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Пашырэнне файла недапушчальнае ({{ extension }}). Дазволеныя пашырэнні: {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Выяўленая кадзіроўка недапушчальная ({{ detected }}). Дазволеныя кадзіроўкі: {{ encodings }}. + + + This value is not a valid MAC address. + Гэта значэнне не з'яўляецца сапраўдным MAC-адрасам. + + + This URL is missing a top-level domain. + У гэтым URL няма дамена верхняга ўзроўню. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Гэта значэнне занадта кароткае. Яно павінна ўтрымліваць хаця б адно слова.|Гэта значэнне занадта кароткае. Яно павінна ўтрымліваць хаця б {{ min }} слоў. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Гэта значэнне занадта доўгае. Яно павінна ўтрымліваць адно слова.|Гэта значэнне занадта доўгае. Яно павінна ўтрымліваць {{ max }} слоў або менш. + + + This value does not represent a valid week in the ISO 8601 format. + Гэта значэнне не адпавядае сапраўднаму тыдню ў фармаце ISO 8601. + + + This value is not a valid week. + Гэта значэнне не з'яўляецца сапраўдным тыднем. + + + This value should not be before week "{{ min }}". + Гэта значэнне не павінна быць раней за тыдзень "{{ min }}". + + + This value should not be after week "{{ max }}". + Гэта значэнне не павінна быць пасля тыдня "{{ max }}". + + + This value is not a valid Twig template. + Гэта значэнне не з'яўляецца сапраўдным шаблонам Twig. + + + This file is not a valid video. + Гэты файл не з'яўляецца сапраўдным відэа. + + + The size of the video could not be detected. + Не ўдалося вызначыць памер відэа. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Шырыня відэа занадта вялікая ({{ width }}px). Дапушчальная максімальная шырыня — {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Шырыня відэа занадта малая ({{ width }}px). Мінімальная чаканая шырыня — {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Вышыня відэа занадта вялікая ({{ height }}px). Дазволеная максімальная вышыня — {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Вышыня відэа занадта малая ({{ height }}px). Чаканая мінімальная вышыня — {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Відэа мае занадта мала пікселяў ({{ pixels }}). Мінімальная колькасць чакаецца {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Відэа мае занадта шмат пікселяў ({{ pixels }}). Максімальна дапушчальная колькасць — {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Суадносіны відэа занадта вялікія ({{ ratio }}). Дапушчальнае максімальнае суадносіна — {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Суадносіны відэа занадта малыя ({{ ratio }}). Мінімальнае чаканае суадносіна — {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Відэа квадратнае ({{ width }}x{{ height }}px). Квадратныя відэа не дазваляюцца. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Відэа ў ландшафтнай арыентацыі ({{ width }}x{{ height }} px). Ландшафтныя відэа не дазваляюцца. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Відэа ў партрэтнай арыентацыі ({{ width }}x{{ height }}px). Відэа ў партрэтнай арыентацыі не дазваляюцца. + + + The video file is corrupted. + Відэафайл пашкоджаны. + + + The video contains multiple streams. Only one stream is allowed. + Відэа змяшчае некалькі патокаў. Дазволены толькі адзін паток. + + + Unsupported video codec "{{ codec }}". + Непадтрымліваемы відэакодэк «{{ codec }}». + + + Unsupported video container "{{ container }}". + Непадтрымліваемы кантэйнер відэа "{{ container }}". + + + The image file is corrupted. + Файл выявы пашкоджаны. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + У выяве занадта мала пікселяў ({{ pixels }}). Мінімальная колькасць — {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Малюнак мае занадта шмат пікселяў ({{ pixels }}). Максімальная дапушчальная колькасць {{ max_pixels }}. + + + This filename does not match the expected charset. + Гэта назва файла не адпавядае чаканаму набору знакаў. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.bg.xlf b/lib/symfony/validator/Resources/translations/validators.bg.xlf new file mode 100644 index 0000000000..79c06e5bc9 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.bg.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Стойността трябва да бъде лъжа (false). + + + This value should be true. + Стойността трябва да бъде истина (true). + + + This value should be of type {{ type }}. + Стойността трябва да бъде от тип {{ type }}. + + + This value should be blank. + Стойността трябва да бъде празна. + + + The value you selected is not a valid choice. + Избраната стойност е невалидна. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Трябва да изберете поне {{ limit }} опция.|Трябва да изберете поне {{ limit }} опции. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Трябва да изберете най-много {{ limit }} опция.|Трябва да изберете най-много {{ limit }} опции. + + + One or more of the given values is invalid. + Една или повече от зададените стойности е невалидна. + + + This field was not expected. + Полето не се е очаквало. + + + This field is missing. + Полето липсва. + + + This value is not a valid date. + Стойността не е валидна дата. + + + This value is not a valid datetime. + Стойността не е валидна дата и час. + + + This value is not a valid email address. + Стойността не е валиден имейл адрес. + + + The file could not be found. + Файлът не беше открит. + + + The file is not readable. + Файлът не може да бъде прочетен. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Файлът е твърде голям ({{ size }} {{ suffix }}). Максималният размер е {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mime типът на файла е невалиден ({{ type }}). Разрешени mime типове са {{ types }}. + + + This value should be {{ limit }} or less. + Стойността трябва да бъде {{ limit }} или по-малко. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Стойността е твърде дълга. Трябва да съдържа най-много {{ limit }} символ.|Стойността е твърде дълга. Трябва да съдържа най-много {{ limit }} символа. + + + This value should be {{ limit }} or more. + Стойността трябва да бъде {{ limit }} или повече. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Стойността е твърде кратка. Трябва да съдържа поне {{ limit }} символ.|Стойността е твърде кратка. Трябва да съдържа поне {{ limit }} символа. + + + This value should not be blank. + Стойността не трябва да бъде празна. + + + This value should not be null. + Стойността не трябва да бъде null. + + + This value should be null. + Стойността трябва да бъде null. + + + This value is not valid. + Стойността не е валидна. + + + This value is not a valid time. + Стойността не е валидно време. + + + This value is not a valid URL. + Стойността не е валиден URL. + + + The two values should be equal. + Двете стойности трябва да бъдат равни. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Файлът е твърде голям. Разрешеният максимален размер е {{ limit }} {{ suffix }}. + + + The file is too large. + Файлът е твърде голям. + + + The file could not be uploaded. + Файлът не може да бъде качен. + + + This value should be a valid number. + Стойността трябва да бъде валиден номер. + + + This file is not a valid image. + Файлът не е валидно изображение. + + + This value is not a valid IP address. + Стойността не е валиден IP адрес. + + + This value is not a valid language. + Стойността не е валиден език. + + + This value is not a valid locale. + Стойността не е валидна локализация. + + + This value is not a valid country. + Стойността не е валидна държава. + + + This value is already used. + Стойността вече е в употреба. + + + The size of the image could not be detected. + Размерът на изображението не може да бъде определен. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Изображението е твърде широко ({{ width }}px). Широчината трябва да бъде максимум {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Изображението е с твърде малка широчина ({{ width }}px). Широчината трябва да бъде минимум {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Изображението е с твърде голяма височина ({{ height }}px). Височината трябва да бъде максимум {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Изображението е с твърде малка височина ({{ height }}px). Височина трябва да бъде минимум {{ min_height }}px. + + + This value should be the user's current password. + Стойността трябва да бъде текущата потребителска парола. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Стойността трябва да бъде точно {{ limit }} символ.|Стойността трябва да бъде точно {{ limit }} символа. + + + The file was only partially uploaded. + Файлът е качен частично. + + + No file was uploaded. + Файлът не беше качен. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + В php.ini не е конфигурирана временна директория или конфигурираната директория не съществува. + + + Cannot write temporary file to disk. + Не може да запише временен файл на диска. + + + A PHP extension caused the upload to fail. + PHP разширение предизвика прекъсване на качването. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Колекцията трябва да съдържа поне {{ limit }} елемент.|Колекцията трябва да съдържа поне {{ limit }} елемента. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Колекцията трябва да съдържа най-много {{ limit }} елемент.|Колекцията трябва да съдържа най-много {{ limit }} елемента. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Колекцията трябва да съдържа точно {{ limit }} елемент.|Колекцията трябва да съдържа точно {{ limit }} елемента. + + + Invalid card number. + Невалиден номер на карта. + + + Unsupported card type or invalid card number. + Неподдържан тип карта или невалиден номер на карта. + + + This value is not a valid International Bank Account Number (IBAN). + Стойността не е валиден Международен номер на банкова сметка (IBAN). + + + This value is not a valid ISBN-10. + Стойността не е валиден ISBN-10. + + + This value is not a valid ISBN-13. + Стойността не е валиден ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Стойността не е нито валиден ISBN-10, нито валиден ISBN-13. + + + This value is not a valid ISSN. + Стойността не е валиден ISSN. + + + This value is not a valid currency. + Стойността не е валидна валута. + + + This value should be equal to {{ compared_value }}. + Стойността трябва да бъде равна на {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Стойността трябва да бъде по-голяма от {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Стойността трябва да бъде по-голяма или равна на {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Стойността трябва да бъде идентична с {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Стойността трябва да бъде по-малка {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Стойността трябва да бъде по-малка или равна на {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Стойността не трябва да бъде равна на {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Стойността не трябва да бъде идентична с {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Изображението е с твърде голяма пропорция ({{ ratio }}). Максималната пропорция трябва да е {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Изображението е с твърде малка пропорция ({{ ratio }}). Минималната пропорция трябва да е {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Изображението е квадрат ({{ width }}x{{ height }}px). Такива изображения не са разрешени. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Изображението е с пейзажна ориентация ({{ width }}x{{ height }}px). Изображения с такава ориентация не са разрешени. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Изображението е с портретна ориентация ({{ width }}x{{ height }}px). Изображения с такава ориентация не са разрешени. + + + An empty file is not allowed. + Празни файлове не са разрешени. + + + The host could not be resolved. + Хостът е недостъпен. + + + This value does not match the expected {{ charset }} charset. + Стойността не съвпада с очакваната {{ charset }} кодировка. + + + This value is not a valid Business Identifier Code (BIC). + Стойността не е валиден Бизнес идентификационен код (BIC). + + + Error + Грешка + + + This value is not a valid UUID. + Стойността не е валиден UUID. + + + This value should be a multiple of {{ compared_value }}. + Стойността трябва да бъде кратно число на {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Бизнес идентификационният код (BIC) не е свързан с IBAN {{ iban }}. + + + This value should be valid JSON. + Стойността трябва да е валиден JSON. + + + This collection should contain only unique elements. + Колекцията трябва да съдържа само уникални елементи. + + + This value should be positive. + Стойността трябва да бъде положително число. + + + This value should be either positive or zero. + Стойността трябва бъде положително число или нула. + + + This value should be negative. + Стойността трябва да бъде отрицателно число. + + + This value should be either negative or zero. + Стойността трябва да бъде отрицателно число или нула. + + + This value is not a valid timezone. + Стойността не е валидна часова зона. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Тази парола е компрометирана, не може да бъде използвана. Моля използвайте друга парола. + + + This value should be between {{ min }} and {{ max }}. + Стойността трябва да бъде между {{ min }} и {{ max }}. + + + This value is not a valid hostname. + Стойността не е валиден hostname. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Броят на елементите в тази колекция трябва да бъде кратен на {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Стойността трябва да отговаря на поне едно от следните ограничения: + + + Each element of this collection should satisfy its own set of constraints. + Всеки елемент от тази колекция трябва да отговаря на собствения си набор от ограничения. + + + This value is not a valid International Securities Identification Number (ISIN). + Стойността не е валиден Международен идентификационен номер на ценни книжа (ISIN). + + + This value should be a valid expression. + Стойността трябва да бъде валиден израз. + + + This value is not a valid CSS color. + Стойността не е валиден CSS цвят. + + + This value is not a valid CIDR notation. + Стойността не е валидна CIDR нотация. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Стойността на мрежовата маска трябва да бъде между {{ min }} и {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Името на файла е твърде дълго. Трябва да съдържа не повече от {{ filename_max_length }} символ.|Името на файла е твърде дълго. Трябва да съдържа не повече от {{ filename_max_length }} символа. + + + The password strength is too low. Please use a stronger password. + Сложността на паролата е твърде малка. Моля използвайте по-сложна парола. + + + This value contains characters that are not allowed by the current restriction-level. + Стойността съдържа символи, които не са позволени от текущото ниво на ограничение. + + + Using invisible characters is not allowed. + Използването на невидими символи не е позволено. + + + Mixing numbers from different scripts is not allowed. + Смесването на числа от различни скриптове не е позволено. + + + Using hidden overlay characters is not allowed. + Използването на скрити насложени символи не е позволено. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Разширението на файла е невалидно ({{ extension }}). Разрешените разширения са {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Откритото кодиране на знаците е невалидно ({{ detected }}). Разрешените кодирания са {{ encodings }}. + + + This value is not a valid MAC address. + Стойността не е валиден MAC адрес. + + + This URL is missing a top-level domain. + На този URL липсва домейн от най-високо ниво. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Тази стойност е твърде кратка. Трябва да съдържа поне една дума.|Тази стойност е твърде кратка. Трябва да съдържа поне {{ min }} думи. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Тази стойност е твърде дълга. Трябва да съдържа само една дума.|Тази стойност е твърде дълга. Трябва да съдържа {{ max }} думи или по-малко. + + + This value does not represent a valid week in the ISO 8601 format. + Тази стойност не представлява валидна седмица във формат ISO 8601. + + + This value is not a valid week. + Тази стойност не е валидна седмица. + + + This value should not be before week "{{ min }}". + Тази стойност не трябва да бъде преди седмица "{{ min }}". + + + This value should not be after week "{{ max }}". + Тази стойност не трябва да бъде след седмица "{{ max }}". + + + This value is not a valid Twig template. + Тази стойност не е валиден Twig шаблон. + + + This file is not a valid video. + Този файл не е валидно видео. + + + The size of the video could not be detected. + Размерът на видеото не може да бъде установен. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ширината на видеото е твърде голяма ({{ width }}px). Допустимата максимална ширина е {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ширината на видеото е твърде малка ({{ width }}px). Минималната изисквана ширина е {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Височината на видеото е твърде голяма ({{ height }}px). Максимално допустимата височина е {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Височината на видеото е твърде малка ({{ height }}px). Очакваната минимална височина е {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Видеото има твърде малко пиксели ({{ pixels }}). Минимално изискуемото количество е {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Видеото има твърде много пиксели ({{ pixels }}). Очакваният максимум е {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Съотношението на видеото е твърде голямо ({{ ratio }}). Позволеното максимално съотношение е {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Съотношението на видеото е твърде малко ({{ ratio }}). Минималното очаквано съотношение е {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Видеото е квадратно ({{ width }}x{{ height }}px). Квадратни видеа не са позволени. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Видеото е в хоризонтална ориентация ({{ width }}x{{ height }} px). Хоризонтални видеа не са позволени. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Видеото е с портретна ориентация ({{ width }}x{{ height }}px). Видеа с портретна ориентация не са позволени. + + + The video file is corrupted. + Видеофайлът е повреден. + + + The video contains multiple streams. Only one stream is allowed. + Видеото съдържа множество потоци. Разрешен е само един поток. + + + Unsupported video codec "{{ codec }}". + Неподдържан видео кодек „{{ codec }}“. + + + Unsupported video container "{{ container }}". + Неподдържан видео контейнер "{{ container }}". + + + The image file is corrupted. + Файлът с изображение е повреден. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Изображението има твърде малко пиксели ({{ pixels }}). Очакваният минимален брой е {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Изображението има твърде много пиксели ({{ pixels }}). Очакваният максимален брой е {{ max_pixels }}. + + + This filename does not match the expected charset. + Името на файла не съответства на очаквания набор от знаци. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.bs.xlf b/lib/symfony/validator/Resources/translations/validators.bs.xlf new file mode 100644 index 0000000000..43a118e089 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.bs.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Ova vrijednost bi trebalo da bude "netačno" (false). + + + This value should be true. + Ova vrijednost bi trebalo da bude "tačno" (true). + + + This value should be of type {{ type }}. + Ova vrijednost bi trebalo da bude tipa {{ type }}. + + + This value should be blank. + Ova vrijednost bi trebalo da bude prazna. + + + The value you selected is not a valid choice. + Odabrana vrijednost nije validan izbor. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Morate odabrati barem {{ limit }} mogućnost.|Morate odabrati barem {{ limit }} mogućnosti.|Morate odabrati barem {{ limit }} mogućnosti. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Morate odabrati najviše {{ limit }} mogućnost.|Morate odabrati najviše {{ limit }} mogućnosti.|Morate odabrati najviše {{ limit }} mogućnosti. + + + One or more of the given values is invalid. + Jedna ili više datih vrijednosti nisu validne. + + + This field was not expected. + Ovo polje nije očekivano. + + + This field is missing. + Ovo polje nedostaje. + + + This value is not a valid date. + Ova vrijednost nije ispravan datum. + + + This value is not a valid datetime. + Ova vrijednost nije ispravnog datum-vrijeme (datetime) formata. + + + This value is not a valid email address. + Ova vrijednost nije ispravna e-mail adresa. + + + The file could not be found. + Ova datoteka ne može biti pronađena. + + + The file is not readable. + Ova datoteka nije čitljiva. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Ova datoteka je prevelika ({{ size }} {{ suffix }}). Najveća dozvoljena veličina je {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mime tip datoteke nije ispravan ({{ type }}). Dozvoljeni mime tipovi su {{ types }}. + + + This value should be {{ limit }} or less. + Ova vrijednost bi trebalo da bude {{ limit }} ili manje. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Ova vrijednost je predugačka. Trebalo bi da ima {{ limit }} karakter ili manje.|Ova vrijednost je predugačka. Trebalo bi da ima {{ limit }} karaktera ili manje.|Ova vrijednost je predugačka. Trebalo bi da ima {{ limit }} karaktera ili manje. + + + This value should be {{ limit }} or more. + Ova vrijednost bi trebalo da bude {{ limit }} ili više. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Ova vrijednost je prekratka. Trebalo bi da ima {{ limit }} karakter ili više.|Ova vrijednost je prekratka. Trebalo bi da ima {{ limit }} karaktera ili više.|Ova vrijednost je prekratka. Trebalo bi da ima {{ limit }} karaktera ili više. + + + This value should not be blank. + Ova vrijednost ne bi trebalo da bude prazna. + + + This value should not be null. + Ova vrijednost ne bi trebalo da bude null. + + + This value should be null. + Ova vrijednost bi trebalo da bude null. + + + This value is not valid. + Ova vrijednost nije ispravna. + + + This value is not a valid time. + Ova vrijednost nije ispravno vrijeme. + + + This value is not a valid URL. + Ova vrijednost nije ispravan URL. + + + The two values should be equal. + Obje vrijednosti bi trebalo da budu jednake. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Ova datoteka je prevelika. Najveća dozvoljena veličina je {{ limit }} {{ suffix }}. + + + The file is too large. + Ova datoteka je prevelika. + + + The file could not be uploaded. + Ova datoteka ne može biti prenijeta (uploaded). + + + This value should be a valid number. + Ova vrijednost bi trebalo da bude ispravan broj. + + + This file is not a valid image. + Ova datoteka nije validna slika. + + + This value is not a valid IP address. + Ova vrijednost nije valjana IP adresa. + + + This value is not a valid language. + Ova vrijednost nije validan jezik. + + + This value is not a valid locale. + Ova vrijednost nije validna regionalna oznaka. + + + This value is not a valid country. + Ova vrijednost nije validna država. + + + This value is already used. + Ova vrijednost je već upotrebljena. + + + The size of the image could not be detected. + Nije moguće otkriti veličinu ove slike. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Širina slike je prevelika ({{ width }}px). Najveća dozvoljena širina je {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Širina slike je premala ({{ width }}px). Najmanja dozvoljena širina je {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Dužina slike je prevelika ({{ height }}px). Najveća dozvoljena dužina je {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Dužina slike je premala ({{ height }}px). Najmanja dozvoljena dužina je {{ min_height }}px. + + + This value should be the user's current password. + Ova vrijednost bi trebalo da bude trenutna korisnička lozinka. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ova vrijednost bi trebalo da ima tačno {{ limit }} karakter.|Ova vrijednost bi trebalo da ima tačno {{ limit }} karaktera. + + + The file was only partially uploaded. + Datoteka je samo djelimično prenijeta (uploaded). + + + No file was uploaded. + Nijedna datoteka nije prenijeta (uploaded). + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Privremeni direktorij nije konfiguriran u php.ini, ili konfigurirani direktorij ne postoji. + + + Cannot write temporary file to disk. + Privremenu datoteku nije moguće upisati na disk. + + + A PHP extension caused the upload to fail. + Prenos datoteke nije uspio zbog PHP ekstenzije. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ova kolekcija bi trebalo da sadrži {{ limit }} ili više elemenata.|Ova kolekcija bi trebalo da sadrži {{ limit }} ili više elemenata.|Ova kolekcija bi trebalo da sadrži {{ limit }} ili više elemenata. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ova kolekcija bi trebalo da sadrži {{ limit }} ili manje elemenata.|Ova kolekcija bi trebalo da sadrži {{ limit }} ili manje elemenata.|Ova kolekcija bi trebalo da sadrži {{ limit }} ili manje elemenata. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ova kolekcija bi trebalo da sadrži tačno {{ limit }} element.|Ova kolekcija bi trebalo da sadrži tačno {{ limit }} elementa.|Ova kolekcija bi trebalo da sadrži tačno {{ limit }} elemenata. + + + Invalid card number. + Broj kartice je neispravan. + + + Unsupported card type or invalid card number. + Tip kartice nije podržan ili je broj kartice neispravan. + + + This value is not a valid International Bank Account Number (IBAN). + Ova vrijednost nije valjan Međunarodni broj bankovnog računa (IBAN). + + + This value is not a valid ISBN-10. + Ova vrijednost nije ispravan ISBN-10. + + + This value is not a valid ISBN-13. + Ova vrijednost nije ispravan ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ova vrijednost nije ispravan ISBN-10 niti ISBN-13. + + + This value is not a valid ISSN. + Ova vrijednost nije ispravan ISSN. + + + This value is not a valid currency. + Ova vrijednost nije ispravna valuta. + + + This value should be equal to {{ compared_value }}. + Ova vrijednost bi trebalo da bude jednaka {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ova vrijednost bi trebalo da bude veća od {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ova vrijednost bi trebalo da bude jednaka ili veća od {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ova vrijednost bi trebalo da bude identična {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ova vrijednost bi trebalo da bude manja od {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ova vrijednost bi trebalo da bude jednaka ili manja od {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ova vrijednost bi trebalo da bude različita od {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ova vrijednost bi trebalo da bude identična sa {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Razmjera ove slike je prevelika ({{ ratio }}). Maksimalna dozvoljena razmjera je {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Razmjera ove slike je premala ({{ ratio }}). Minimalna očekivana razmjera je {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Ova slika je kvadratnog oblika ({{ width }}x{{ height }}px). Kvadratne slike nisu dozvoljene. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Ova slika je orijentisana horizontalno (landscape) ({{ width }}x{{ height }}px). Horizontalno orijentisane slike nisu dozvoljene. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Ova slika je orijentisana vertikalno (portrait) ({{ width }}x{{ height }}px). Vertikalno orijentisane slike nisu dozvoljene. + + + An empty file is not allowed. + Prazna datoteka nije dozvoljena. + + + The host could not be resolved. + Nije moguće odrediti poslužitelja (host). + + + This value does not match the expected {{ charset }} charset. + Ova vrijednost ne odgovara očekivanom {{ charset }} setu karaktera (charset). + + + This value is not a valid Business Identifier Code (BIC). + Ova vrijednost nije valjan Poslovni identifikacijski kod (BIC). + + + Error + Greška + + + This value is not a valid UUID. + Ova vrijednost nije valjan UUID. + + + This value should be a multiple of {{ compared_value }}. + Ova vrijednost bi trebalo da bude djeljiva sa {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Ovaj poslovni identifikacioni kod (BIC) nije povezan sa IBAN-om {{ iban }}. + + + This value should be valid JSON. + Ova vrijednost bi trebalo da bude validan JSON. + + + This collection should contain only unique elements. + Ova kolekcija bi trebala da sadrži samo jedinstvene elemente. + + + This value should be positive. + Ova vrijednost bi trebalo da bude pozitivna. + + + This value should be either positive or zero. + Ova vrijednost bi trebalo da bude pozitivna ili jednaka nuli. + + + This value should be negative. + Ova vrijednost bi trebalo da bude negativna. + + + This value should be either negative or zero. + Ova vrijednost bi trebalo da bude negativna ili jednaka nuli. + + + This value is not a valid timezone. + Ova vrijednost nije validna vremenska zona. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Ova lozinka je procurila u nekom od slučajeva kompromitovanja podataka, nemojte je koristiti. Koristite drugu lozinku. + + + This value should be between {{ min }} and {{ max }}. + Ova vrijednosti bi trebala biti između {{ min }} i {{ max }}. + + + This value is not a valid hostname. + Ova vrijednost nije ispravno ime poslužitelja (hostname). + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Broj elemenata u ovoj kolekciji bi trebalo da bude djeljiv sa {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Ova vrijednost bi trebalo da zadovoljava namjanje jedno od narednih ograničenja: + + + Each element of this collection should satisfy its own set of constraints. + Svaki element ove kolekcije bi trebalo da zadovolji sopstveni skup ograničenja. + + + This value is not a valid International Securities Identification Number (ISIN). + Ova vrijednost nije ispravna međunarodna identifikaciona oznaka hartija od vrijednosti (ISIN). + + + This value should be a valid expression. + Ova vrijednost bi trebala biti važeći izraz. + + + This value is not a valid CSS color. + Ova vrijednost nije važeća CSS boja. + + + This value is not a valid CIDR notation. + Ova vrijednost nije važeća CIDR notacija. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Vrijednost NetMask bi trebala biti između {{min}} i {{max}}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Ime datoteke je predugačko. Trebao bi imati {{ filename_max_length }} znak ili manje.|Naziv fajla je predugačak. Trebao bi imati {{ filename_max_length }} znakova ili manje. + + + The password strength is too low. Please use a stronger password. + Jačina lozinke je preniska. Molimo koristite jaču lozinku. + + + This value contains characters that are not allowed by the current restriction-level. + Ova vrijednost sadrži znakove koji nisu dozvoljeni trenutnim nivoom ograničenja. + + + Using invisible characters is not allowed. + Upotreba nevidljivih znakova nije dozvoljena. + + + Mixing numbers from different scripts is not allowed. + Nije dozvoljeno miješanje brojeva iz različitih pisama. + + + Using hidden overlay characters is not allowed. + Upotreba skrivenih preklapajućih znakova nije dozvoljena. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Ekstenzija datoteke je nevažeća ({{ extension }}). Dozvoljene ekstenzije su {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Otkriveno kodiranje karaktera je nevažeće ({{ detected }}). Dozvoljena kodiranja su {{ encodings }}. + + + This value is not a valid MAC address. + Ova vrijednost nije valjana MAC adresa. + + + This URL is missing a top-level domain. + Ovom URL-u nedostaje domena najvišeg nivoa. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Ova vrijednost je prekratka. Trebala bi sadržavati barem jednu riječ.|Ova vrijednost je prekratka. Trebala bi sadržavati barem {{ min }} riječi. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Ova vrijednost je predugačka. Trebala bi sadržavati samo jednu riječ.|Ova vrijednost je predugačka. Trebala bi sadržavati {{ max }} riječi ili manje. + + + This value does not represent a valid week in the ISO 8601 format. + Ova vrijednost ne predstavlja valjani tjedan u ISO 8601 formatu. + + + This value is not a valid week. + Ova vrijednost nije važeća sedmica. + + + This value should not be before week "{{ min }}". + Ova vrijednost ne smije biti prije tjedna "{{ min }}". + + + This value should not be after week "{{ max }}". + Ova vrijednost ne bi trebala biti nakon sedmice "{{ max }}". + + + This value is not a valid Twig template. + Ova vrijednost nije važeći Twig šablon. + + + This file is not a valid video. + Ova datoteka nije važeći video. + + + The size of the video could not be detected. + Veličina videa nije mogla biti utvrđena. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Širina videa je prevelika ({{ width }}px). Dozvoljena maksimalna širina je {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Širina videa je premala ({{ width }}px). Minimalna očekivana širina je {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Visina videa je prevelika ({{ height }}px). Dozvoljena maksimalna visina je {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Visina videa je premala ({{ height }}px). Očekivana minimalna visina je {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Video ima premalo piksela ({{ pixels }}). Očekivana minimalna količina je {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Video ima previše piksela ({{ pixels }}). Očekivana maksimalna količina je {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Omjer videa je prevelik ({{ ratio }}). Dozvoljeni maksimalni omjer je {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Omjer videa je premali ({{ ratio }}). Minimalni očekivani omjer je {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video je kvadratan ({{ width }}x{{ height }}px). Kvadratni video zapisi nisu dozvoljeni. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video je vodoravne orijentacije ({{ width }}x{{ height }} px). Vodoravni video zapisi nisu dozvoljeni. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video je uspravno orijentisan ({{ width }}x{{ height }}px). Video zapisi uspravne orijentacije nisu dozvoljeni. + + + The video file is corrupted. + Video datoteka je oštećena. + + + The video contains multiple streams. Only one stream is allowed. + Video sadrži više tokova. Dozvoljen je samo jedan tok. + + + Unsupported video codec "{{ codec }}". + Nepodržani video kodek "{{ codec }}". + + + Unsupported video container "{{ container }}". + Nepodržani video kontejner "{{ container }}". + + + The image file is corrupted. + Datoteka slike je oštećena. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Slika ima premalo piksela ({{ pixels }}). Očekivani minimalni broj je {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Slika ima previše piksela ({{ pixels }}). Očekivani maksimalni broj je {{ max_pixels }}. + + + This filename does not match the expected charset. + Naziv ove datoteke ne odgovara očekivanom skupu znakova. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.ca.xlf b/lib/symfony/validator/Resources/translations/validators.ca.xlf new file mode 100644 index 0000000000..e78fd8724a --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.ca.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Aquest valor hauria de ser fals. + + + This value should be true. + Aquest valor hauria de ser cert. + + + This value should be of type {{ type }}. + Aquest valor hauria de ser del tipus {{ type }}. + + + This value should be blank. + Aquest valor hauria d'estar buit. + + + The value you selected is not a valid choice. + El valor seleccionat no és una opció vàlida. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Ha de seleccionar almenys {{ limit }} opció.|Ha de seleccionar almenys {{ limit }} opcions. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Ha de seleccionar com a màxim {{ limit }} opció.|Ha de seleccionar com a màxim {{ limit }} opcions. + + + One or more of the given values is invalid. + Un o més dels valors facilitats són incorrectes. + + + This field was not expected. + Aquest camp no s'esperava. + + + This field is missing. + Aquest camp està desaparegut. + + + This value is not a valid date. + Aquest valor no és una data vàlida. + + + This value is not a valid datetime. + Aquest valor no és una data i hora vàlida. + + + This value is not a valid email address. + Aquest valor no és una adreça d'email vàlida. + + + The file could not be found. + No s'ha pogut trobar l'arxiu. + + + The file is not readable. + No es pot llegir l'arxiu. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + L'arxiu és massa gran ({{ size }} {{ suffix }}). La grandària màxima permesa és {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + El tipus mime de l'arxiu no és vàlid ({{ type }}). Els tipus mime vàlids són {{ types }}. + + + This value should be {{ limit }} or less. + Aquest valor hauria de ser {{ limit }} o menys. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Aquest valor és massa llarg. Hauria de tenir {{ limit }} caràcter o menys.|Aquest valor és massa llarg. Hauria de tenir {{ limit }} caràcters o menys. + + + This value should be {{ limit }} or more. + Aquest valor hauria de ser {{ limit }} o més. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Aquest valor és massa curt. Hauria de tenir {{ limit }} caràcters o més. + + + This value should not be blank. + Aquest valor no hauria d'estar buit. + + + This value should not be null. + Aquest valor no hauria de ser null. + + + This value should be null. + Aquest valor hauria de ser null. + + + This value is not valid. + Aquest valor no és vàlid. + + + This value is not a valid time. + Aquest valor no és una hora vàlida. + + + This value is not a valid URL. + Aquest valor no és un URL vàlid. + + + The two values should be equal. + Els dos valors haurien de ser iguals. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + L'arxiu és massa gran. La mida màxima permesa és {{ limit }} {{ suffix }}. + + + The file is too large. + L'arxiu és massa gran. + + + The file could not be uploaded. + No es pot pujar l'arxiu. + + + This value should be a valid number. + Aquest valor hauria de ser un nombre vàlid. + + + This file is not a valid image. + L'arxiu no és una imatge vàlida. + + + This value is not a valid IP address. + Aquest valor no és una adreça IP vàlida. + + + This value is not a valid language. + Aquest valor no és un idioma vàlid. + + + This value is not a valid locale. + Aquest valor no és una localització vàlida. + + + This value is not a valid country. + Aquest valor no és un país vàlid. + + + This value is already used. + Aquest valor ja s'ha utilitzat. + + + The size of the image could not be detected. + No s'ha pogut determinar la grandària de la imatge. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + L'amplària de la imatge és massa gran ({{ width }}px). L'amplària màxima permesa és {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + L'amplària de la imatge és massa petita ({{ width }}px). L'amplària mínima requerida és {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + L'altura de la imatge és massa gran ({{ height }}px). L'altura màxima permesa és {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + L'altura de la imatge és massa petita ({{ height }}px). L'altura mínima requerida és {{ min_height }}px. + + + This value should be the user's current password. + Aquest valor hauria de ser la contrasenya actual de l'usuari. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Aquest valor hauria de tenir exactament {{ limit }} caràcter.|Aquest valor hauria de tenir exactament {{ limit }} caràcters. + + + The file was only partially uploaded. + L'arxiu va ser només pujat parcialment. + + + No file was uploaded. + Cap arxiu va ser pujat. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + No s'ha configurat cap carpeta temporal en php.ini, o la carpeta configurada no existeix. + + + Cannot write temporary file to disk. + No es va poder escriure l'arxiu temporal en el disc. + + + A PHP extension caused the upload to fail. + Una extensió de PHP va fer que la pujada fallarà. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Aquesta col·lecció ha de contenir {{ limit }} element o més.|Aquesta col·lecció ha de contenir {{ limit }} elements o més. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Aquesta col·lecció ha de contenir {{ limit }} element o menys.|Aquesta col·lecció ha de contenir {{ limit }} elements o menys. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Aquesta col·lecció ha de contenir exactament {{ limit }} element.|Aquesta col·lecció ha de contenir exactament {{ limit }} elements. + + + Invalid card number. + Número de targeta invàlid. + + + Unsupported card type or invalid card number. + Tipus de targeta no suportada o número de targeta invàlid. + + + This value is not a valid International Bank Account Number (IBAN). + Aquest valor no és un Número de Compte Bancari Internacional (IBAN) vàlid. + + + This value is not a valid ISBN-10. + Aquest valor no és un ISBN-10 vàlid. + + + This value is not a valid ISBN-13. + Aquest valor no és un ISBN-13 vàlid. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Aquest valor no és ni un ISBN-10 vàlid ni un ISBN-13 vàlid. + + + This value is not a valid ISSN. + Aquest valor no és un ISSN vàlid. + + + This value is not a valid currency. + Aquest valor no és una divisa vàlida. + + + This value should be equal to {{ compared_value }}. + Aquest valor hauria de ser igual a {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Aquest valor hauria de ser més gran a {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Aquest valor hauria de ser major o igual a {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Aquest valor hauria de ser idèntic a {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Aquest valor hauria de ser menor a {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Aquest valor hauria de ser menor o igual a {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Aquest valor no hauria de ser igual a {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Aquest valor no hauria de ser idèntic a {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + La proporció de la imatge és massa gran ({{ ratio }}). La màxima proporció permesa és {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + La proporció de la imatge és massa petita ({{ ratio }}). La mínima proporció permesa és {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + La imatge és quadrada({{ width }}x{{ height }}px). Les imatges quadrades no estan permeses. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + La imatge està orientada horitzontalment ({{ width }}x{{ height }}px). Les imatges orientades horitzontalment no estan permeses. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + La imatge està orientada verticalment ({{ width }}x{{ height }}px). Les imatges orientades verticalment no estan permeses. + + + An empty file is not allowed. + No està permès un fitxer buit. + + + The host could not be resolved. + No s'ha pogut resoldre l'amfitrió. + + + This value does not match the expected {{ charset }} charset. + Aquest valor no coincideix amb l'esperat {{ charset }} joc de caràcters. + + + This value is not a valid Business Identifier Code (BIC). + Aquest valor no és un Codi d'identificació bancari (BIC) vàlid. + + + Error + Error + + + This value is not a valid UUID. + Aquest valor no és un UUID vàlid. + + + This value should be a multiple of {{ compared_value }}. + Aquest valor ha de ser múltiple de {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Aquest Codi d'identificació bancari (BIC) no està associat amb l'IBAN {{ iban }}. + + + This value should be valid JSON. + Aquest valor hauria de ser un JSON vàlid. + + + This collection should contain only unique elements. + Aquesta col·lecció només hauria de contenir elements únics. + + + This value should be positive. + Aquest valor hauria de ser positiu. + + + This value should be either positive or zero. + Aquest valor ha de ser positiu o zero. + + + This value should be negative. + Aquest valor ha de ser negatiu. + + + This value should be either negative or zero. + Aquest valor ha de ser negatiu o zero. + + + This value is not a valid timezone. + Aquest valor no és una zona horària vàlida. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Aquesta contrasenya s'ha filtrat en cas de violació de dades, no s'ha d'utilitzar. Utilitzeu una altra contrasenya. + + + This value should be between {{ min }} and {{ max }}. + Aquest valor ha d'estar entre {{ min }} i {{ max }}. + + + This value is not a valid hostname. + Aquest valor no és un nom d'amfitrió vàlid. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + El nombre d'elements d'aquesta col·lecció ha de ser múltiple de {{compared_value}}. + + + This value should satisfy at least one of the following constraints: + Aquest valor ha de satisfer almenys una de les restriccions següents: + + + Each element of this collection should satisfy its own set of constraints. + Cada element d'aquesta col·lecció hauria de satisfer el seu propi conjunt de restriccions. + + + This value is not a valid International Securities Identification Number (ISIN). + Aquest valor no és un número d'identificació de valors internacionals (ISIN) vàlid. + + + This value should be a valid expression. + Aquest valor hauria de ser una expressió vàlida. + + + This value is not a valid CSS color. + Aquest valor no és un color CSS vàlid. + + + This value is not a valid CIDR notation. + Aquest valor no és una notació CIDR vàlida. + + + The value of the netmask should be between {{ min }} and {{ max }}. + El valor de la màscara de xarxa hauria d'estar entre {{ min }} i {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + El nom del fitxer és massa llarg. Ha de tenir {{ filename_max_length }} caràcter o menys.|El nom del fitxer és massa llarg. Ha de tenir {{ filename_max_length }} caràcters o menys. + + + The password strength is too low. Please use a stronger password. + La contrasenya és massa feble. Si us plau, feu servir una contrasenya més segura. + + + This value contains characters that are not allowed by the current restriction-level. + Aquest valor conté caràcters que no estan permisos segons el nivell de restricció actual. + + + Using invisible characters is not allowed. + No es permet l'ús de caràcters invisibles. + + + Mixing numbers from different scripts is not allowed. + No es permet barrejar números de diferents scripts. + + + Using hidden overlay characters is not allowed. + No es permet l'ús de caràcters superposats ocults. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + L'extensió del fitxer no és vàlida ({{ extension }}). Les extensions permeses són {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + S'ha detectat que la codificació de caràcters no és vàlida ({{ detected }}). Les codificacions permeses són {{ encodings }}. + + + This value is not a valid MAC address. + Aquest valor no és una adreça MAC vàlida. + + + This URL is missing a top-level domain. + Aquesta URL no conté un domini de primer nivell. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Aquest valor és massa curt. Ha de contenir almenys una paraula.|Aquest valor és massa curt. Ha de contenir almenys {{ min }} paraules. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Aquest valor és massa llarg. Ha de contenir una paraula.|Aquest valor és massa llarg. Ha de contenir {{ max }} paraules o menys. + + + This value does not represent a valid week in the ISO 8601 format. + Aquest valor no representa una setmana vàlida en el format ISO 8601. + + + This value is not a valid week. + Aquest valor no és una setmana vàlida. + + + This value should not be before week "{{ min }}". + Aquest valor no ha de ser anterior a la setmana "{{ min }}". + + + This value should not be after week "{{ max }}". + Aquest valor no ha de ser posterior a la setmana "{{ max }}". + + + This value is not a valid Twig template. + Aquest valor no és una plantilla Twig vàlida. + + + This file is not a valid video. + Aquest fitxer no és un vídeo vàlid. + + + The size of the video could not be detected. + No s'ha pogut detectar la mida del vídeo. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + L'amplada del vídeo és massa gran ({{ width }}px). L'amplada màxima permesa és {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + L'amplada del vídeo és massa petita ({{ width }}px). L'amplada mínima esperada és {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + L'altura del vídeo és massa gran ({{ height }}px). L'altura màxima permesa és {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + L'altura del vídeo és massa petita ({{ height }}px). L'altura mínima esperada és {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + El vídeo no té suficients píxels ({{ pixels }}). La quantitat mínima esperada és {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + El vídeo té massa píxels ({{ pixels }}). La quantitat màxima prevista és {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + La relació del vídeo és massa gran ({{ ratio }}). La relació màxima permesa és {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + La relació del vídeo és massa petita ({{ ratio }}). La relació mínima esperada és {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + El vídeo és quadrat ({{ width }}x{{ height }}px). No es permeten vídeos quadrats. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + El vídeo té orientació horitzontal ({{ width }}x{{ height }} px). No es permeten vídeos horitzontals. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + El vídeo és en orientació vertical ({{ width }}x{{ height }} px). No es permeten vídeos en orientació vertical. + + + The video file is corrupted. + El fitxer de vídeo està espatllat. + + + The video contains multiple streams. Only one stream is allowed. + El vídeo conté diversos fluxos. Només es permet un sol flux. + + + Unsupported video codec "{{ codec }}". + Còdec de vídeo incompatible «{{ codec }}». + + + Unsupported video container "{{ container }}". + Contenidor de vídeo incompatible "{{ container }}". + + + The image file is corrupted. + El fitxer d'imatge està espatllat. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + La imatge no té suficients píxels ({{ pixels }}). La quantitat mínima esperada és {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + La imatge té massa píxels ({{ pixels }}). El nombre màxim esperat és {{ max_pixels }}. + + + This filename does not match the expected charset. + Aquest nom de fitxer no coincideix amb el charset esperat. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.cs.xlf b/lib/symfony/validator/Resources/translations/validators.cs.xlf new file mode 100644 index 0000000000..11a8cbab80 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.cs.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Tato hodnota musí být nepravdivá (false). + + + This value should be true. + Tato hodnota musí být pravdivá (true). + + + This value should be of type {{ type }}. + Tato hodnota musí být typu {{ type }}. + + + This value should be blank. + Tato hodnota musí být prázdná. + + + The value you selected is not a valid choice. + Vybraná hodnota není platnou možností. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Musí být vybrána nejméně {{ limit }} možnost.|Musí být vybrány nejméně {{ limit }} možnosti.|Musí být vybráno nejméně {{ limit }} možností. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Musí být vybrána maximálně {{ limit }} možnost.|Musí být vybrány maximálně {{ limit }} možnosti.|Musí být vybráno maximálně {{ limit }} možností. + + + One or more of the given values is invalid. + Některé z uvedených hodnot jsou neplatné. + + + This field was not expected. + Toto pole nebylo očekáváno. + + + This field is missing. + Toto pole chybí. + + + This value is not a valid date. + Tato hodnota není platné datum. + + + This value is not a valid datetime. + Tato hodnota není platné datum s časovým údajem. + + + This value is not a valid email address. + Tato hodnota není platná e-mailová adresa. + + + The file could not be found. + Soubor nebyl nalezen. + + + The file is not readable. + Soubor je nečitelný. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Soubor je příliš velký ({{ size }} {{ suffix }}). Maximální povolená velikost souboru je {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Neplatný mime typ souboru ({{ type }}). Povolené mime typy souborů jsou {{ types }}. + + + This value should be {{ limit }} or less. + Tato hodnota musí být {{ limit }} nebo méně. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Tato hodnota je příliš dlouhá. Musí obsahovat maximálně {{ limit }} znak.|Tato hodnota je příliš dlouhá. Musí obsahovat maximálně {{ limit }} znaky.|Tato hodnota je příliš dlouhá. Musí obsahovat maximálně {{ limit }} znaků. + + + This value should be {{ limit }} or more. + Tato hodnota musí být {{ limit }} nebo více. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Tato hodnota je příliš krátká. Musí obsahovat minimálně {{ limit }} znak.|Tato hodnota je příliš krátká. Musí obsahovat minimálně {{ limit }} znaky.|Tato hodnota je příliš krátká. Musí obsahovat minimálně {{ limit }} znaků. + + + This value should not be blank. + Tato hodnota nesmí být prázdná. + + + This value should not be null. + Tato hodnota nesmí být null. + + + This value should be null. + Tato hodnota musí být null. + + + This value is not valid. + Tato hodnota není platná. + + + This value is not a valid time. + Tato hodnota není platný časový údaj. + + + This value is not a valid URL. + Tato hodnota není platná URL adresa. + + + The two values should be equal. + Tyto dvě hodnoty musí být stejné. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Soubor je příliš velký. Maximální povolená velikost souboru je {{ limit }} {{ suffix }}. + + + The file is too large. + Soubor je příliš velký. + + + The file could not be uploaded. + Soubor se nepodařilo nahrát. + + + This value should be a valid number. + Tato hodnota musí být číslo. + + + This file is not a valid image. + Tento soubor není obrázek. + + + This value is not a valid IP address. + Tato hodnota není platnou IP adresou. + + + This value is not a valid language. + Tento jazyk neexistuje. + + + This value is not a valid locale. + Tato lokalizace neexistuje. + + + This value is not a valid country. + Tato země neexistuje. + + + This value is already used. + Tato hodnota je již používána. + + + The size of the image could not be detected. + Nepodařily se zjistit rozměry obrázku. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Obrázek je příliš široký ({{ width }}px). Maximální povolená šířka je {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Obrázek je příliš úzký ({{ width }}px). Minimální očekávaná šířka je {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Obrázek je příliš vysoký ({{ height }}px). Maximální povolená výška je {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Obrázek je příliš nízký ({{ height }}px). Minimální očekávaná výška je {{ min_height }}px. + + + This value should be the user's current password. + Tato hodnota musí být aktuální heslo uživatele. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Tato hodnota musí mít přesně {{ limit }} znak.|Tato hodnota musí mít přesně {{ limit }} znaky.|Tato hodnota musí mít přesně {{ limit }} znaků. + + + The file was only partially uploaded. + Byla nahrána jen část souboru. + + + No file was uploaded. + Žádný soubor nebyl nahrán. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + V php.ini nebyla nastavena cesta k dočasnému adresáři, nebo nastavený adresář neexistuje. + + + Cannot write temporary file to disk. + Dočasný soubor se nepodařilo zapsat na disk. + + + A PHP extension caused the upload to fail. + Rozšíření PHP zabránilo nahrání souboru. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Tato kolekce musí obsahovat minimálně {{ limit }} prvek.|Tato kolekce musí obsahovat minimálně {{ limit }} prvky.|Tato kolekce musí obsahovat minimálně {{ limit }} prvků. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Tato kolekce musí obsahovat maximálně {{ limit }} prvek.|Tato kolekce musí obsahovat maximálně {{ limit }} prvky.|Tato kolekce musí obsahovat maximálně {{ limit }} prvků. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Tato kolekce musí obsahovat přesně {{ limit }} prvek.|Tato kolekce musí obsahovat přesně {{ limit }} prvky.|Tato kolekce musí obsahovat přesně {{ limit }} prvků. + + + Invalid card number. + Neplatné číslo karty. + + + Unsupported card type or invalid card number. + Nepodporovaný typ karty nebo neplatné číslo karty. + + + This value is not a valid International Bank Account Number (IBAN). + Tato hodnota není platným Mezinárodním bankovním číslem účtu (IBAN). + + + This value is not a valid ISBN-10. + Tato hodnota není platné ISBN-10. + + + This value is not a valid ISBN-13. + Tato hodnota není platné ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Tato hodnota není platné ISBN-10 ani ISBN-13. + + + This value is not a valid ISSN. + Tato hodnota není platné ISSN. + + + This value is not a valid currency. + Tato měna neexistuje. + + + This value should be equal to {{ compared_value }}. + Tato hodnota musí být rovna {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Tato hodnota musí být větší než {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Tato hodnota musí být větší nebo rovna {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Tato hodnota musí být typu {{ compared_value_type }} a zároveň musí být rovna {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Tato hodnota musí být menší než {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Tato hodnota musí být menší nebo rovna {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Tato hodnota nesmí být rovna {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Tato hodnota nesmí být typu {{ compared_value_type }} a zároveň nesmí být rovna {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Poměr stran obrázku je příliš velký ({{ ratio }}). Maximální povolený poměr stran je {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Poměr stran obrázku je příliš malý ({{ ratio }}). Minimální očekávaný poměr stran je {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Obrázek je čtvercový ({{ width }}x{{ height }}px). Čtvercové obrázky nejsou povolené. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Obrázek je orientovaný na šířku ({{ width }}x{{ height }}px). Obrázky orientované na šířku nejsou povolené. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Obrázek je orientovaný na výšku ({{ width }}x{{ height }}px). Obrázky orientované na výšku nejsou povolené. + + + An empty file is not allowed. + Soubor nesmí být prázdný. + + + The host could not be resolved. + Hostitele nebylo možné rozpoznat. + + + This value does not match the expected {{ charset }} charset. + Tato hodnota neodpovídá očekávané znakové sadě {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Tato hodnota není platným Kódem obchodního identifikátoru (BIC). + + + Error + Chyba + + + This value is not a valid UUID. + Tato hodnota není platným UUID. + + + This value should be a multiple of {{ compared_value }}. + Tato hodnota musí být násobek hodnoty {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Bankovní identifikační kód (BIC) neodpovídá mezinárodnímu číslu účtu (IBAN) {{ iban }}. + + + This value should be valid JSON. + Tato hodnota musí být validní JSON. + + + This collection should contain only unique elements. + Tato kolekce musí obsahovat pouze unikátní prvky. + + + This value should be positive. + Tato hodnota musí být kladná. + + + This value should be either positive or zero. + Tato hodnota musí být buď kladná nebo nula. + + + This value should be negative. + Tato hodnota musí být záporná. + + + This value should be either negative or zero. + Tato hodnota musí být buď záporná nebo nula. + + + This value is not a valid timezone. + Tato časová zóna neexistuje. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Zadané heslo bylo součástí úniku dat, takže ho není možné použít. Použijte prosím jiné heslo. + + + This value should be between {{ min }} and {{ max }}. + Hodnota musí být mezi {{ min }} a {{ max }}. + + + This value is not a valid hostname. + Tato hodnota není platný hostname. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Počet prvků v této kolekci musí být násobek {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Tato hodnota musí splňovat alespoň jedno z následujících omezení: + + + Each element of this collection should satisfy its own set of constraints. + Každý prvek v této kolekci musí splňovat svá vlastní omezení. + + + This value is not a valid International Securities Identification Number (ISIN). + Tato hodnota není platné mezinárodní identifikační číslo cenného papíru (ISIN). + + + This value should be a valid expression. + Tato hodnota musí být platný výraz. + + + This value is not a valid CSS color. + Tato hodnota není platná barva CSS. + + + This value is not a valid CIDR notation. + Tato hodnota není platná notace CIDR. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Hodnota masky sítě musí být mezi {{ min }} a {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Název souboru je příliš dlouhý. Měl by obsahovat {{ filename_max_length }} znak nebo méně.|Název souboru je příliš dlouhý. Měl by obsahovat {{ filename_max_length }} znaky nebo méně.|Název souboru je příliš dlouhý. Měl by obsahovat {{ filename_max_length }} znaků nebo méně. + + + The password strength is too low. Please use a stronger password. + Síla hesla je příliš nízká. Použijte silnější heslo, prosím. + + + This value contains characters that are not allowed by the current restriction-level. + Tato hodnota obsahuje znaky, které nejsou povoleny aktuální úrovní omezení. + + + Using invisible characters is not allowed. + Používání neviditelných znaků není povoleno. + + + Mixing numbers from different scripts is not allowed. + Kombinování čísel z různých písem není povoleno. + + + Using hidden overlay characters is not allowed. + Použití skrytých překrývajících znaků není povoleno. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Přípona souboru je neplatná ({{ extension }}). Povolené přípony jsou {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Zjištěné kódování znaků je neplatné ({{ detected }}). Povolená kódování jsou {{ encodings }}. + + + This value is not a valid MAC address. + Tato hodnota není platnou MAC adresou. + + + This URL is missing a top-level domain. + Této URL není doména nejvyššího řádu. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Tato hodnota je příliš krátká, měla by obsahovat alespoň jedno slovo|Tato hodnota je příliš krátká, měla by obsahovat alespoň {{ min }} slova. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Tato hodnota je příliš dlouhá, měla obsahovat pouze jedno slovo.|Tato hodnota je příliš dlouhá, měla by obsahovat {{ max }} slova a nebo méně. + + + This value does not represent a valid week in the ISO 8601 format. + Tato hodnota není validní týden v ISO 8601 formatu. + + + This value is not a valid week. + Tato hodnota není validní týden. + + + This value should not be before week "{{ min }}". + Tato hodnota by neměla být týden před "{{ min }}". + + + This value should not be after week "{{ max }}". + Tato hodnota by neměla být týden za "{{ max }}". + + + This value is not a valid Twig template. + Tato hodnota není platná Twig šablona. + + + This file is not a valid video. + Tento soubor není video. + + + The size of the video could not be detected. + Nepodařily se zjistit rozměry videa. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Video je příliš široké ({{ width }}px). Maximální povolená šířka je {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Video je příliš úzké ({{ width }}px). Minimální očekávaná šířka je {{ min_width }} px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Video je příliš vysoké ({{ height }}px). Maximální povolená výška je {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Video je příliš nízké ({{ height }}px). Minimální očekávaná výška je {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Video má příliš málo pixelů ({{ pixels }} pixelů). Minimální očekávané množství je {{ min_pixels }} pixelů. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Video má příliš mnoho pixelů ({{ pixels }} pixelů). Maximální očekávané množství je {{ max_pixels }} pixelů. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Poměr stran videa je příliš velký ({{ ratio }}). Maximální povolený poměr stran je {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Poměr stran videa je příliš malý ({{ ratio }}). Minimální očekávaný poměr stran je {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video je čtvercové ({{ width }}x{{ height }}px). Čtvercová videa nejsou povolená. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video je orientované na šířku ({{ width }}x{{ height }} px). Videa orientovaná na šířku nejsou povolená. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video je orientované na výšku ({{ width }}x{{ height }} px). Videa orientovaná na výšku nejsou povolená. + + + The video file is corrupted. + Soubor videa je poškozený. + + + The video contains multiple streams. Only one stream is allowed. + Video obsahuje více proudů. Povolen je pouze jeden proud. + + + Unsupported video codec "{{ codec }}". + Nepodporovaný kodek videa "{{ codec }}". + + + Unsupported video container "{{ container }}". + Nepodporovaný kontejner videa "{{ container }}". + + + The image file is corrupted. + Soubor obrázku je poškozený. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Obrázek má příliš málo pixelů ({{ pixels }} pixelů). Minimální očekávané množství je {{ min_pixels }} pixelů. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Obrázek má příliš mnoho pixelů ({{ pixels }} pixelů). Maximální očekávané množství je {{ max_pixels }} pixelů. + + + This filename does not match the expected charset. + Tento název souboru neodpovídá očekávané znakové sadě. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.cy.xlf b/lib/symfony/validator/Resources/translations/validators.cy.xlf new file mode 100644 index 0000000000..366edef035 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.cy.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Dylid bod y gwerth hwn yn ffug. + + + This value should be true. + Dylid bod y gwerth hwn yn wir. + + + This value should be of type {{ type }}. + Dylid bod y gwerth hwn bod o fath {{ type }}. + + + This value should be blank. + Dylid bod y gwerth hwn yn wag. + + + The value you selected is not a valid choice. + Nid yw'r gwerth â ddewiswyd yn ddilys. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Rhaid dewis o leiaf {{ limit }} opsiwn. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Rhaid dewis dim mwy na {{ limit }} opsiwn. + + + One or more of the given values is invalid. + Mae un neu fwy o'r gwerthoedd a roddwyd yn annilys. + + + This field was not expected. + Nid oedd disgwyl y maes hwn. + + + This field is missing. + Mae'r maes hwn ar goll. + + + This value is not a valid date. + Nid yw'r gwerth yn ddyddiad dilys. + + + This value is not a valid datetime. + Nid yw'r gwerth yn datetime dilys. + + + This value is not a valid email address. + Nid yw'r gwerth yn gyfeiriad ebost dilys. + + + The file could not be found. + Ni ddarganfyddwyd y ffeil. + + + The file is not readable. + Ni ellir darllen y ffeil. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Mae'r ffeil yn rhy fawr ({{ size }} {{ suffix }}). Yr uchafswm â ganiateir yw {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Nid yw math mime y ffeil yn ddilys ({{ type }}). Dyma'r mathau â ganiateir {{ types }}. + + + This value should be {{ limit }} or less. + Dylai'r gwerth hwn fod yn {{ limit }} neu lai. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Mae'r gwerth hwn rhy hir. Dylai gynnwys {{ limit }} nodyn cyfrifiadurol neu lai. + + + This value should be {{ limit }} or more. + Dylai'r gwerth hwn fod yn {{ limit }} neu fwy. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Mae'r gwerth hwn yn rhy fyr. Dylai gynnwys {{ limit }} nodyn cyfrifiadurol neu fwy. + + + This value should not be blank. + Ni ddylai'r gwerth hwn fod yn wag. + + + This value should not be null. + Ni ddylai'r gwerth hwn fod yn null. + + + This value should be null. + Dylai'r gwerth fod yn null. + + + This value is not valid. + Nid yw'r gwerth hwn yn ddilys. + + + This value is not a valid time. + Nid yw'r gwerth hwn yn amser dilys. + + + This value is not a valid URL. + Nid yw'r gwerth hwn yn URL dilys. + + + The two values should be equal. + Rhaid i'r ddau werth fod yn gyfystyr a'u gilydd. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Mae'r ffeil yn rhy fawr. Yr uchafswm â ganiateir yw {{ limit }} {{ suffix }}. + + + The file is too large. + Mae'r ffeil yn rhy fawr. + + + The file could not be uploaded. + Methwyd ag uwchlwytho'r ffeil. + + + This value should be a valid number. + Dylai'r gwerth hwn fod yn rif dilys. + + + This file is not a valid image. + Nid yw'r ffeil hon yn ddelwedd dilys. + + + This value is not a valid IP address. + Nid yw'r gwerth hwn yn gyfeiriad IP dilys. + + + This value is not a valid language. + Nid yw'r gwerth hwn yn iaith ddilys. + + + This value is not a valid locale. + Nid yw'r gwerth hwn yn locale dilys. + + + This value is not a valid country. + Nid yw'r gwerth hwn yn wlad dilys. + + + This value is already used. + Mae'r gwerth hwn eisoes yn cael ei ddefnyddio. + + + The size of the image could not be detected. + Methwyd â darganfod maint y ddelwedd. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Mae lled y ddelwedd yn rhy fawr ({{ width }}px). Y lled mwyaf â ganiateir yw {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Mae lled y ddelwedd yn rhy fach ({{ width }}px). Y lled lleiaf â ganiateir yw {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Mae uchder y ddelwedd yn rhy fawr ({{ width }}px). Yr uchder mwyaf â ganiateir yw {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Mae uchder y ddelwedd yn rhy fach ({{ width }}px). Yr uchder lleiaf â ganiateir yw {{ min_height }}px. + + + This value should be the user's current password. + Dylaid bod y gwerth hwn yn gyfrinair presenol y defnyddiwr. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Dylai'r gwerth hwn fod yn union {{ limit }} nodyn cyfrifiadurol o hyd. + + + The file was only partially uploaded. + Dim ond rhan o'r ffeil ag uwchlwythwyd. + + + No file was uploaded. + Ni uwchlwythwyd unrhyw ffeil. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Nid oedd ffolder dros dro wedi'i ffurfweddu yn php.ini, neu nid yw'r ffolder a ffurfweddiwyd yn bodoli. + + + Cannot write temporary file to disk. + Methwyd ag ysgrifennu'r ffeil dros-dro ar ddisg. + + + A PHP extension caused the upload to fail. + Methwyd ag uwchlwytho oherwydd ategyn PHP. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Dylai'r casgliad hwn gynnwys {{ limit }} elfen neu fwy. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Dylai'r casgliad hwn gynnwys {{ limit }} elfen neu lai. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Dylai'r casgliad hwn gynnwys union {{ limit }} elfen. + + + Invalid card number. + Nid oedd rhif y cerdyn yn ddilys. + + + Unsupported card type or invalid card number. + Unai ni dderbynir y math yna o gerdyn, neu nid yw rhif y cerdyn yn ddilys. + + + This value is not a valid International Bank Account Number (IBAN). + Nid yw'r gwerth hwn yn Rhif Cyfrif Banc Rhyngwladol (IBAN) dilys. + + + This value is not a valid ISBN-10. + Nid yw'r gwerth hwn yn ISBN-10 dilys. + + + This value is not a valid ISBN-13. + Nid yw'r gwerth hwn yn ISBN-13 dilys. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Nid yw'r gwerth hwn yn Rhif ISBN-10 dilys nac yn ISBN-13 dilys. + + + This value is not a valid ISSN. + Nid yw'r gwerth hwn yn ISSN dilys. + + + This value is not a valid currency. + Nid yw'r gwerth hwn yn arian dilys. + + + This value should be equal to {{ compared_value }}. + Dylai'r gwerth hwn fod yn gyfartal â {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Dylai'r gwerth hwn fod yn fwy na {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Dylai'r gwerth hwn fod yn fwy na neu'n hafal i {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Dylai'r gwerth hwn fod yn union yr un fath â {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Dylai'r gwerth hwn fod yn llai na {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Dylai'r gwerth hwn fod yn llai na neu'n hafal i {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ni ddylai'r gwerth hwn fod yn hafal i {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ni ddylai'r gwerth hwn fod yn union yr un fath â {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Mae'r gymhareb delwedd yn rhy fawr ({{ ratio }}). Y gymhareb uchaf a ganiateir yw {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Mae'r gymhareb delwedd yn rhy fach ({{ ratio }}). Y gymhareb isaf a ddisgwylir yw {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Mae'r ddelwedd yn sgwâr ({{ width }}x{{ height }}px). Ni chaniateir delweddau sgwâr. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Mae'r ddelwedd mewn fformat tirlun ({{ width }}x{{ height }}px). Ni chaniateir delweddau mewn fformat tirlun. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Mae'r ddelwedd mewn fformat portread ({{ width }}x{{ height }}px). Ni chaniateir delweddau mewn fformat portread. + + + An empty file is not allowed. + Ni chaniateir ffeil wag. + + + The host could not be resolved. + Ni fu modd datrys y gwesteiwr. + + + This value does not match the expected {{ charset }} charset. + Nid yw'r gwerth hwn yn cyfateb â'r {{ charset }} set nodau ddisgwyliedig. + + + This value is not a valid Business Identifier Code (BIC). + Nid yw'r gwerth hwn yn God Adnabod Busnes (BIC) dilys. + + + Error + Gwall + + + This value is not a valid UUID. + Nid yw'r gwerth hwn yn UUID dilys. + + + This value should be a multiple of {{ compared_value }}. + Dylai'r gwerth hwn fod yn luosrif o {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Nid yw'r Cod Adnabod Busnes (BIC) hwn yn gysylltiedig ag IBAN {{ iban }}. + + + This value should be valid JSON. + Dylai'r gwerth hwn fod yn JSON dilys. + + + This collection should contain only unique elements. + Dylai'r casgliad hwn gynnwys elfennau unigryw yn unig. + + + This value should be positive. + Dylai'r gwerth hwn fod yn gadarnhaol. + + + This value should be either positive or zero. + Dylai'r gwerth hwn fod yn gadarnhaol neu sero. + + + This value should be negative. + Dylai'r gwerth hwn fod yn negyddol. + + + This value should be either negative or zero. + Dylai'r gwerth hwn fod yn negyddol neu sero. + + + This value is not a valid timezone. + Nid yw'r gwerth hwn yn gyfnod parth amser dilys. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Mae'r cyfrinair hwn wedi'i ddatgelu mewn toriad data, ni ddylid ei ddefnyddio. Defnyddiwch gyfrinair arall. + + + This value should be between {{ min }} and {{ max }}. + Dylai'r gwerth hwn fod rhwng {{ min }} a {{ max }}. + + + This value is not a valid hostname. + Nid yw'r gwerth hwn yn enw gwesteiwr dilys. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Dylai nifer yr elfennau yn y casgliad hwn fod yn luosrif o {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Dylai'r gwerth hwn fodloni o leiaf un o'r cyfyngiadau canlynol: + + + Each element of this collection should satisfy its own set of constraints. + Dylai pob elfen o'r casgliad hwn fodloni ei gyfres ei hun o gyfyngiadau. + + + This value is not a valid International Securities Identification Number (ISIN). + Nid yw'r gwerth hwn yn Rhif Adnabod Diogelwch Rhyngwladol (ISIN) dilys. + + + This value should be a valid expression. + Dylai'r gwerth hwn fod yn fynegiant dilys. + + + This value is not a valid CSS color. + Nid yw'r gwerth hwn yn lliw CSS dilys. + + + This value is not a valid CIDR notation. + Nid yw'r gwerth hwn yn nodiant CIDR dilys. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Dylai gwerth y mwgwd rhwydwaith fod rhwng {{ min }} a {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Mae'r enw ffeil yn rhy hir. Dylai fod â {{ filename_max_length }} cymeriad neu lai.|Mae'r enw ffeil yn rhy hir. Dylai fod â {{ filename_max_length }} nodau neu lai. + + + The password strength is too low. Please use a stronger password. + Mae cryfder y cyfrinair yn rhy isel. Defnyddiwch gyfrinair cryfach os gwelwch yn dda. + + + This value contains characters that are not allowed by the current restriction-level. + Mae'r gwerth hwn yn cynnwys cymeriadau nad ydynt yn cael eu caniatáu gan y lefel cyfyngu presennol. + + + Using invisible characters is not allowed. + Ni chaniateir defnyddio cymeriadau anweledig. + + + Mixing numbers from different scripts is not allowed. + Ni chaniateir cymysgu rhifau o sgriptiau gwahanol. + + + Using hidden overlay characters is not allowed. + Ni chaniateir defnyddio cymeriadau goruwchlwytho cudd. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Mae estyniad y ffeil yn annilys ({{ extension }}). Mae'r estyniadau a ganiateir yn {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Mae'r codio cymeriadau a ganfuwyd yn annilys ({{ detected }}). Mae'r codiadau a ganiateir yn {{ encodings }}. + + + This value is not a valid MAC address. + Nid yw'r gwerth hwn yn gyfeiriad MAC dilys. + + + This URL is missing a top-level domain. + Mae'r URL hwn yn colli parth lefel uchaf. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Mae'r gwerth hwn yn rhy fyr. Dylai gynnwys o leiaf un gair.|Mae'r gwerth hwn yn rhy fyr. Dylai gynnwys o leiaf {{ min }} gair. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Mae'r gwerth hwn yn rhy hir. Dylai gynnwys un gair yn unig.|Mae'r gwerth hwn yn rhy hir. Dylai gynnwys {{ max }} gair neu lai. + + + This value does not represent a valid week in the ISO 8601 format. + Nid yw'r gwerth hwn yn cynrychioli wythnos dilys yn fformat ISO 8601. + + + This value is not a valid week. + Nid yw'r gwerth hwn yn wythnos ddilys. + + + This value should not be before week "{{ min }}". + Ni ddylai'r gwerth hwn fod cyn wythnos "{{ min }}". + + + This value should not be after week "{{ max }}". + Ni ddylai'r gwerth hwn fod ar ôl yr wythnos "{{ max }}". + + + This value is not a valid Twig template. + Nid yw'r gwerth hwn yn dempled Twig dilys. + + + This file is not a valid video. + Nid yw’r ffeil hon yn fideo dilys. + + + The size of the video could not be detected. + Nid oedd modd canfod maint y fideo. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Mae lled y fideo yn rhy fawr ({{ width }}px). Y lled uchaf a ganiateir yw {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Mae lled y fideo yn rhy fach ({{ width }}px). Lled lleiaf disgwyliedig yw {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Mae uchder y fideo yn rhy fawr ({{ height }}px). Yr uchder mwyaf a ganiateir yw {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Mae uchder y fideo yn rhy fach ({{ height }}px). Yr uchder lleiaf disgwyliedig yw {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Mae gan y fideo rhy ychydig o bicseli ({{ pixels }}). Y swm lleiaf disgwyliedig yw {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Mae gan y fideo ormod o bicseli ({{ pixels }}). Y swm uchaf disgwyliedig yw {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Mae cymhareb y fideo yn rhy fawr ({{ ratio }}). Y gymhareb uchaf a ganiateir yw {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Mae cymhareb y fideo yn rhy fach ({{ ratio }}). Y gymhareb leiaf ddisgwyliedig yw {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Mae'r fideo'n sgwâr ({{ width }}x{{ height }}px). Nid yw fideos sgwâr yn cael eu caniatáu. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Mae’r fideo yn dirwedd ({{ width }}x{{ height }} px). Ni chaniateir fideos tirwedd. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Mae'r fideo wedi'i gyfeirio'n bortread ({{ width }}x{{ height }}px). Nid yw fideos portread yn cael eu caniatáu. + + + The video file is corrupted. + Mae'r ffeil fideo wedi'i llygru. + + + The video contains multiple streams. Only one stream is allowed. + Mae'r fideo yn cynnwys sawl ffrwd. Dim ond un ffrwd a ganiateir. + + + Unsupported video codec "{{ codec }}". + Codec fideo heb ei gefnogi "{{ codec }}". + + + Unsupported video container "{{ container }}". + Cynhwysydd fideo heb ei gefnogi "{{ container }}". + + + The image file is corrupted. + Mae'r ffeil delwedd wedi'i llygru. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Mae gan y ddelwedd rhy ychydig o bicseli ({{ pixels }}). Y lleiafswm disgwyliedig yw {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Mae gan y ddelwedd ormod o bicseli ({{ pixels }}). Y nifer uchaf disgwyliedig yw {{ max_pixels }}. + + + This filename does not match the expected charset. + Nid yw'r enw ffeil hwn yn cyfateb i'r set nodau ddisgwyliedig. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.da.xlf b/lib/symfony/validator/Resources/translations/validators.da.xlf new file mode 100644 index 0000000000..ee93fae920 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.da.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Værdien skal være falsk. + + + This value should be true. + Værdien skal være sand. + + + This value should be of type {{ type }}. + Værdien skal være af typen {{ type }}. + + + This value should be blank. + Værdien skal være blank. + + + The value you selected is not a valid choice. + Den valgte værdi er ikke gyldig. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Du skal vælge mindst én mulighed.|Du skal vælge mindst {{ limit }} muligheder. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Du kan højst vælge én mulighed.|Du kan højst vælge {{ limit }} muligheder. + + + One or more of the given values is invalid. + En eller flere af de angivne værdier er ugyldige. + + + This field was not expected. + Feltet blev ikke forventet. + + + This field is missing. + Dette felt mangler. + + + This value is not a valid date. + Værdien er ikke en gyldig dato. + + + This value is not a valid datetime. + Værdien er ikke et gyldigt tidspunkt. + + + This value is not a valid email address. + Værdien er ikke en gyldig e-mailadresse. + + + The file could not be found. + Filen kunne ikke findes. + + + The file is not readable. + Filen kan ikke læses. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Filen er for stor ({{ size }} {{ suffix }}). Maksimale tilladte størrelse er {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Filens MIME-type er ugyldig ({{ type }}). Tilladte MIME-typer er {{ types }}. + + + This value should be {{ limit }} or less. + Værdien skal være {{ limit }} eller mindre. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Værdien er for lang. Den må højst indeholde {{ limit }} tegn. + + + This value should be {{ limit }} or more. + Værdien skal være {{ limit }} eller mere. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Værdien er for kort. Den skal indeholde mindst {{ limit }} tegn. + + + This value should not be blank. + Værdien må ikke være blank. + + + This value should not be null. + Værdien må ikke være tom (null). + + + This value should be null. + Værdien skal være tom (null). + + + This value is not valid. + Værdien er ikke gyldig. + + + This value is not a valid time. + Værdien er ikke et gyldigt klokkeslæt. + + + This value is not a valid URL. + Værdien er ikke en gyldig URL. + + + The two values should be equal. + De to værdier skal være ens. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Filen er for stor. Den maksimale størrelse er {{ limit }} {{ suffix }}. + + + The file is too large. + Filen er for stor. + + + The file could not be uploaded. + Filen kunne ikke uploades. + + + This value should be a valid number. + Værdien skal være et gyldigt tal. + + + This file is not a valid image. + Filen er ikke gyldigt billede. + + + This value is not a valid IP address. + Denne værdi er ikke en gyldig IP-adresse. + + + This value is not a valid language. + Værdien er ikke et gyldigt sprog. + + + This value is not a valid locale. + Værdien er ikke en gyldig lokalitet. + + + This value is not a valid country. + Værdien er ikke et gyldigt land. + + + This value is already used. + Værdien er allerede i brug. + + + The size of the image could not be detected. + Størrelsen på billedet kunne ikke detekteres. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Billedet er for bredt ({{ width }}px). Største tilladte bredde er {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Billedet er for smalt ({{ width }}px). Mindste forventede bredde er {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Billedet er for højt ({{ height }}px). Største tilladte højde er {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Billedet er for lavt ({{ height }}px). Mindste forventede højde er {{ min_height }}px. + + + This value should be the user's current password. + Værdien skal være brugerens nuværende adgangskode. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Værdien skal være på præcis {{ limit }} tegn. + + + The file was only partially uploaded. + Filen blev kun delvist uploadet. + + + No file was uploaded. + Ingen fil blev uploadet. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Der blev ikke konfigureret en midlertidig mappe i php.ini, eller den konfigurerede mappe eksisterer ikke. + + + Cannot write temporary file to disk. + Kan ikke skrive midlertidig fil til disk. + + + A PHP extension caused the upload to fail. + En PHP-udvidelse forårsagede fejl i upload. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Denne samling skal indeholde mindst ét element.|Denne samling skal indeholde mindst {{ limit }} elementer. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Denne samling skal indeholde højst ét element.|Denne samling skal indeholde højst {{ limit }} elementer. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Denne samling skal indeholde præcis ét element.|Denne samling skal indeholde præcis {{ limit }} elementer. + + + Invalid card number. + Ugyldigt kortnummer. + + + Unsupported card type or invalid card number. + Ikke-understøttet korttype eller ugyldigt kortnummer. + + + This value is not a valid International Bank Account Number (IBAN). + Denne værdi er ikke et gyldigt internationalt bankkontonummer (IBAN). + + + This value is not a valid ISBN-10. + Værdien er ikke en gyldig ISBN-10. + + + This value is not a valid ISBN-13. + Værdien er ikke en gyldig ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Værdien er hverken en gyldig ISBN-10 eller en gyldig ISBN-13. + + + This value is not a valid ISSN. + Værdien er ikke en gyldig ISSN. + + + This value is not a valid currency. + Denne værdi er ikke en gyldig valuta. + + + This value should be equal to {{ compared_value }}. + Denne værdi skal være lig med {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Denne værdi skal være større end {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Denne værdi skal være større end eller lig med {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Denne værdi skal være identisk med {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Denne værdi skal være mindre end {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Denne værdi skal være mindre end eller lig med {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Denne værdi bør ikke være lig med {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Denne værdi bør ikke være identisk med {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Billedforholdet er for stort ({{ratio}}). Tilladt maksimumsforhold er {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Billedforholdet er for lille ({{ ratio }}). Minimumsforventet forventet er {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Billedet er firkantet ({{ width }} x {{ height }} px). Firkantede billeder er ikke tilladt. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Billedet er landskabsorienteret ({{width}} x {{height}} px). Landskabsorienterede billeder er ikke tilladt + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Billedet er portrætorienteret ({{ width }}x{{ height }}px). Portrætorienterede billeder er ikke tilladt. + + + An empty file is not allowed. + En tom fil er ikke tilladt. + + + The host could not be resolved. + Værten kunne ikke løses. + + + This value does not match the expected {{ charset }} charset. + Denne værdi stemmer ikke overens med den forventede {{ charset }} charset. + + + This value is not a valid Business Identifier Code (BIC). + Denne værdi er ikke en gyldig forretningsidentifikationskode (BIC). + + + Error + Fejl + + + This value is not a valid UUID. + Denne værdi er ikke en gyldig UUID. + + + This value should be a multiple of {{ compared_value }}. + Denne værdi skal være et multiplikation af {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Denne Business Identifier Code (BIC) er ikke forbundet med IBAN {{ iban }}. + + + This value should be valid JSON. + Denne værdi skal være gyldig JSON. + + + This collection should contain only unique elements. + Denne samling bør kun indeholde unikke elementer. + + + This value should be positive. + Denne værdi skal være positiv. + + + This value should be either positive or zero. + Denne værdi skal være enten positiv eller nul. + + + This value should be negative. + Denne værdi skal være negativ. + + + This value should be either negative or zero. + Denne værdi skal være enten negativ eller nul. + + + This value is not a valid timezone. + Denne værdi er ikke en gyldig tidszone. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Denne adgangskode er blevet lækket i et databrud, det må ikke bruges. Brug venligst en anden adgangskode. + + + This value should be between {{ min }} and {{ max }}. + Værdien skal være mellem {{ min }} og {{ max }}. + + + This value is not a valid hostname. + Værdien er ikke et gyldigt værtsnavn. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Antallet af elementer i denne samling skal være en multiplikation af {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Værdien skal overholde mindst én af følgende krav: + + + Each element of this collection should satisfy its own set of constraints. + Hvert element i denne samling skal overholde dens egne krav. + + + This value is not a valid International Securities Identification Number (ISIN). + Værdien er ikke et gyldig International Securities Identification Number (ISIN). + + + This value should be a valid expression. + Værdien skal være et gyldigt udtryk. + + + This value is not a valid CSS color. + Værdien skal være en gyldig CSS farve. + + + This value is not a valid CIDR notation. + Værdien er ikke en gyldig CIDR notation. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Værdien af netmasken skal være mellem {{ min }} og {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Filnavnet er for langt. Det bør indeholde {{ filename_max_length }} tegn eller mindre.|Filnavnet er for langt. Det bør indeholde {{ filename_max_length }} tegn eller mindre. + + + The password strength is too low. Please use a stronger password. + Kodeordets styrke er for lav. Du bedes indtaste et stærkere kodeord. + + + This value contains characters that are not allowed by the current restriction-level. + Denne værdi indeholder tegn, som ikke er tilladt med det nuværende restriktionsniveau. + + + Using invisible characters is not allowed. + Brug af usynlige tegn er ikke tilladt. + + + Mixing numbers from different scripts is not allowed. + At blande numre fra forskellige scripts er ikke tilladt. + + + Using hidden overlay characters is not allowed. + At bruge skjulte overlejringstegn er ikke tilladt. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Udvidelsen til filen er ugyldig ({{ extension }}). De tilladte udvidelser er {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Det registrerede tegnsæt er ugyldigt ({{ detected }}). De tilladte tegnsæt er {{ encodings }}. + + + This value is not a valid MAC address. + Denne værdi er ikke en gyldig MAC-adresse. + + + This URL is missing a top-level domain. + Denne URL mangler et topdomæne. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Denne værdi er for kort. Den skal indeholde mindst ét ord.|Denne værdi er for kort. Den skal indeholde mindst {{ min }} ord. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Denne værdi er for lang. Den skal indeholde ét ord.|Denne værdi er for lang. Den skal indeholde {{ max }} ord eller færre. + + + This value does not represent a valid week in the ISO 8601 format. + Denne værdi repræsenterer ikke en gyldig uge i ISO 8601-formatet. + + + This value is not a valid week. + Denne værdi er ikke en gyldig uge. + + + This value should not be before week "{{ min }}". + Denne værdi bør ikke være før uge "{{ min }}". + + + This value should not be after week "{{ max }}". + Denne værdi bør ikke være efter uge "{{ max }}". + + + This value is not a valid Twig template. + Denne værdi er ikke en gyldig Twig-skabelon. + + + This file is not a valid video. + Denne fil er ikke en gyldig video. + + + The size of the video could not be detected. + Videostørrelsen kunne ikke registreres. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Videobredden er for stor ({{ width }}px). Tilladt maksimal bredde er {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Videobredden er for lille ({{ width }}px). Mindste forventede bredde er {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Videoens højde er for stor ({{ height }}px). Tilladt maksimal højde er {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Videoens højde er for lille ({{ height }}px). Forventet minimumshøjde er {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Videoen har for få pixels ({{ pixels }}). Forventet minimum er {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Videoen har for mange pixels ({{ pixels }}). Forventet maksimummængde er {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Videoforholdet er for stort ({{ ratio }}). Tilladt maksimalforhold er {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Videoforholdet er for lille ({{ ratio }}). Forventet minimumsforhold er {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Videoen er kvadratisk ({{ width }}x{{ height }}px). Kvadratiske videoer er ikke tilladt. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Videoen er i liggende format ({{ width }}x{{ height }} px). Liggende videoer er ikke tilladt. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Videoen er i portrætformat ({{ width }}x{{ height }}px). Portrætvideoer er ikke tilladt. + + + The video file is corrupted. + Videofilen er beskadiget. + + + The video contains multiple streams. Only one stream is allowed. + Videoen indeholder flere streams. Kun én stream er tilladt. + + + Unsupported video codec "{{ codec }}". + Ikke-understøttet videokodek "{{ codec }}". + + + Unsupported video container "{{ container }}". + Ikke-understøttet videocontainer "{{ container }}". + + + The image file is corrupted. + Billedfilen er beskadiget. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Billedet har for få pixels ({{ pixels }}). Forventet minimum er {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Billedet har for mange pixels ({{ pixels }}). Forventet maksimalt antal er {{ max_pixels }}. + + + This filename does not match the expected charset. + Dette filnavn matcher ikke det forventede tegnsæt. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.de.xlf b/lib/symfony/validator/Resources/translations/validators.de.xlf new file mode 100644 index 0000000000..36463f3c0c --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.de.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Dieser Wert sollte false sein. + + + This value should be true. + Dieser Wert sollte true sein. + + + This value should be of type {{ type }}. + Dieser Wert sollte vom Typ {{ type }} sein. + + + This value should be blank. + Dieser Wert sollte leer sein. + + + The value you selected is not a valid choice. + Sie haben einen ungültigen Wert ausgewählt. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Sie müssen mindestens {{ limit }} Möglichkeit wählen.|Sie müssen mindestens {{ limit }} Möglichkeiten wählen. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Sie dürfen höchstens {{ limit }} Möglichkeit wählen.|Sie dürfen höchstens {{ limit }} Möglichkeiten wählen. + + + One or more of the given values is invalid. + Einer oder mehrere der angegebenen Werte sind ungültig. + + + This field was not expected. + Dieses Feld wurde nicht erwartet. + + + This field is missing. + Dieses Feld fehlt. + + + This value is not a valid date. + Dieser Wert entspricht keiner gültigen Datumsangabe. + + + This value is not a valid datetime. + Dieser Wert entspricht keiner gültigen Datums- und Zeitangabe. + + + This value is not a valid email address. + Dieser Wert ist keine gültige E-Mail-Adresse. + + + The file could not be found. + Die Datei wurde nicht gefunden. + + + The file is not readable. + Die Datei ist nicht lesbar. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Die Datei ist zu groß ({{ size }} {{ suffix }}). Die maximal zulässige Größe beträgt {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Der Dateityp ist ungültig ({{ type }}). Erlaubte Dateitypen sind {{ types }}. + + + This value should be {{ limit }} or less. + Dieser Wert sollte kleiner oder gleich {{ limit }} sein. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Diese Zeichenkette ist zu lang. Sie sollte höchstens {{ limit }} Zeichen haben.|Diese Zeichenkette ist zu lang. Sie sollte höchstens {{ limit }} Zeichen haben. + + + This value should be {{ limit }} or more. + Dieser Wert sollte größer oder gleich {{ limit }} sein. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Diese Zeichenkette ist zu kurz. Sie sollte mindestens {{ limit }} Zeichen haben.|Diese Zeichenkette ist zu kurz. Sie sollte mindestens {{ limit }} Zeichen haben. + + + This value should not be blank. + Dieser Wert sollte nicht leer sein. + + + This value should not be null. + Dieser Wert sollte nicht null sein. + + + This value should be null. + Dieser Wert sollte null sein. + + + This value is not valid. + Dieser Wert ist nicht gültig. + + + This value is not a valid time. + Dieser Wert entspricht keiner gültigen Zeitangabe. + + + This value is not a valid URL. + Dieser Wert ist keine gültige URL. + + + The two values should be equal. + Die beiden Werte sollten identisch sein. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Die Datei ist zu groß. Die maximal zulässige Größe beträgt {{ limit }} {{ suffix }}. + + + The file is too large. + Die Datei ist zu groß. + + + The file could not be uploaded. + Die Datei konnte nicht hochgeladen werden. + + + This value should be a valid number. + Dieser Wert sollte eine gültige Zahl sein. + + + This file is not a valid image. + Diese Datei ist kein gültiges Bild. + + + This value is not a valid IP address. + Dieser Wert ist keine gültige IP-Adresse. + + + This value is not a valid language. + Dieser Wert entspricht keiner gültigen Sprache. + + + This value is not a valid locale. + Dieser Wert entspricht keinem gültigen Gebietsschema. + + + This value is not a valid country. + Dieser Wert entspricht keinem gültigen Land. + + + This value is already used. + Dieser Wert wird bereits verwendet. + + + The size of the image could not be detected. + Die Größe des Bildes konnte nicht ermittelt werden. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Die Bildbreite ist zu groß ({{ width }}px). Die maximal zulässige Breite beträgt {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Die Bildbreite ist zu gering ({{ width }}px). Die erwartete Mindestbreite beträgt {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Die Bildhöhe ist zu groß ({{ height }}px). Die maximal zulässige Höhe beträgt {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Die Bildhöhe ist zu gering ({{ height }}px). Die erwartete Mindesthöhe beträgt {{ min_height }}px. + + + This value should be the user's current password. + Dieser Wert sollte dem aktuellen Benutzerpasswort entsprechen. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Dieser Wert sollte genau {{ limit }} Zeichen lang sein.|Dieser Wert sollte genau {{ limit }} Zeichen lang sein. + + + The file was only partially uploaded. + Die Datei wurde nur teilweise hochgeladen. + + + No file was uploaded. + Es wurde keine Datei hochgeladen. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Es wurde kein temporärer Ordner in der php.ini konfiguriert oder der temporäre Ordner existiert nicht. + + + Cannot write temporary file to disk. + Kann die temporäre Datei nicht speichern. + + + A PHP extension caused the upload to fail. + Eine PHP-Erweiterung verhinderte den Upload. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Diese Sammlung sollte {{ limit }} oder mehr Elemente beinhalten.|Diese Sammlung sollte {{ limit }} oder mehr Elemente beinhalten. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Diese Sammlung sollte {{ limit }} oder weniger Elemente beinhalten.|Diese Sammlung sollte {{ limit }} oder weniger Elemente beinhalten. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Diese Sammlung sollte genau {{ limit }} Element beinhalten.|Diese Sammlung sollte genau {{ limit }} Elemente beinhalten. + + + Invalid card number. + Ungültige Kartennummer. + + + Unsupported card type or invalid card number. + Nicht unterstützter Kartentyp oder ungültige Kartennummer. + + + This value is not a valid International Bank Account Number (IBAN). + Dieser Wert ist keine gültige Internationale Bankkontonummer (IBAN). + + + This value is not a valid ISBN-10. + Dieser Wert entspricht keiner gültigen ISBN-10. + + + This value is not a valid ISBN-13. + Dieser Wert entspricht keiner gültigen ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Dieser Wert ist weder eine gültige ISBN-10 noch eine gültige ISBN-13. + + + This value is not a valid ISSN. + Dieser Wert ist keine gültige ISSN. + + + This value is not a valid currency. + Dieser Wert ist keine gültige Währung. + + + This value should be equal to {{ compared_value }}. + Dieser Wert sollte gleich {{ compared_value }} sein. + + + This value should be greater than {{ compared_value }}. + Dieser Wert sollte größer als {{ compared_value }} sein. + + + This value should be greater than or equal to {{ compared_value }}. + Dieser Wert sollte größer oder gleich {{ compared_value }} sein. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Dieser Wert sollte identisch sein mit {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Dieser Wert sollte kleiner als {{ compared_value }} sein. + + + This value should be less than or equal to {{ compared_value }}. + Dieser Wert sollte kleiner oder gleich {{ compared_value }} sein. + + + This value should not be equal to {{ compared_value }}. + Dieser Wert sollte nicht {{ compared_value }} sein. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Dieser Wert sollte nicht identisch sein mit {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Das Seitenverhältnis des Bildes ist zu groß ({{ ratio }}). Der erlaubte Maximalwert ist {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Das Seitenverhältnis des Bildes ist zu klein ({{ ratio }}). Der erwartete Minimalwert ist {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Das Bild ist quadratisch ({{ width }}x{{ height }}px). Quadratische Bilder sind nicht erlaubt. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Das Bild ist im Querformat ({{ width }}x{{ height }}px). Bilder im Querformat sind nicht erlaubt. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Das Bild ist im Hochformat ({{ width }}x{{ height }}px). Bilder im Hochformat sind nicht erlaubt. + + + An empty file is not allowed. + Eine leere Datei ist nicht erlaubt. + + + The host could not be resolved. + Der Hostname konnte nicht aufgelöst werden. + + + This value does not match the expected {{ charset }} charset. + Dieser Wert entspricht nicht dem erwarteten Zeichensatz {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Dieser Wert ist keine gültige internationale Bankleitzahl (BIC). + + + Error + Fehler + + + This value is not a valid UUID. + Dieser Wert ist keine gültige UUID. + + + This value should be a multiple of {{ compared_value }}. + Dieser Wert sollte ein Vielfaches von {{ compared_value }} sein. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Diese internationale Bankleitzahl (BIC) ist nicht mit der IBAN {{ iban }} assoziiert. + + + This value should be valid JSON. + Dieser Wert sollte gültiges JSON sein. + + + This collection should contain only unique elements. + Diese Sammlung darf keine doppelten Elemente enthalten. + + + This value should be positive. + Diese Zahl sollte positiv sein. + + + This value should be either positive or zero. + Diese Zahl sollte entweder positiv oder 0 sein. + + + This value should be negative. + Diese Zahl sollte negativ sein. + + + This value should be either negative or zero. + Diese Zahl sollte entweder negativ oder 0 sein. + + + This value is not a valid timezone. + Dieser Wert ist keine gültige Zeitzone. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Dieses Passwort ist Teil eines Datenlecks, es darf nicht verwendet werden. + + + This value should be between {{ min }} and {{ max }}. + Dieser Wert sollte zwischen {{ min }} und {{ max }} sein. + + + This value is not a valid hostname. + Dieser Wert ist kein gültiger Hostname. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Die Anzahl an Elementen in dieser Sammlung sollte ein Vielfaches von {{ compared_value }} sein. + + + This value should satisfy at least one of the following constraints: + Dieser Wert sollte eine der folgenden Bedingungen erfüllen: + + + Each element of this collection should satisfy its own set of constraints. + Jedes Element dieser Sammlung sollte seine eigene Menge an Bedingungen erfüllen. + + + This value is not a valid International Securities Identification Number (ISIN). + Dieser Wert ist keine gültige Internationale Wertpapierkennnummer (ISIN). + + + This value should be a valid expression. + Dieser Wert sollte eine gültige Expression sein. + + + This value is not a valid CSS color. + Dieser Wert ist keine gültige CSS-Farbe. + + + This value is not a valid CIDR notation. + Dieser Wert entspricht nicht der CIDR-Notation. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Der Wert der Subnetzmaske sollte zwischen {{ min }} und {{ max }} liegen. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Der Dateiname ist zu lang. Er sollte nicht länger als {{ filename_max_length }} Zeichen sein.|Der Dateiname ist zu lang. Er sollte nicht länger als {{ filename_max_length }} Zeichen sein. + + + The password strength is too low. Please use a stronger password. + Das Passwort ist zu schwach. + + + This value contains characters that are not allowed by the current restriction-level. + Der Wert enthält Zeichen, die auf der aktuellen Einschränkungsstufe nicht erlaubt sind. + + + Using invisible characters is not allowed. + Unsichtbare Zeichen sind nicht erlaubt. + + + Mixing numbers from different scripts is not allowed. + Das Mischen von Zahlen aus verschiedenen Skripten ist nicht erlaubt. + + + Using hidden overlay characters is not allowed. + Verstecke Overlay-Zeichen sind nicht erlaubt. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Die Dateiendung ist ungültig ({{ extension }}). Gültige Dateiendungen sind {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Der erkannte Zeichensatz ist nicht gültig ({{ detected }}). Gültige Zeichensätze sind {{ encodings }}. + + + This value is not a valid MAC address. + Dieser Wert ist keine gültige MAC-Adresse. + + + This URL is missing a top-level domain. + Dieser URL fehlt eine Top-Level-Domain. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Dieser Wert ist zu kurz. Er muss aus mindestens einem Wort bestehen.|Dieser Wert ist zu kurz. Er muss mindestens {{ min }} Wörter enthalten. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Dieser Wert ist zu lang. Er darf maximal aus einem Wort bestehen.|Dieser Wert ist zu lang. Er darf maximal {{ max }} Wörter enthalten. + + + This value does not represent a valid week in the ISO 8601 format. + Dieser Wert ist keine Wochenangabe im ISO 8601-Format. + + + This value is not a valid week. + Dieser Wert ist keine gültige Woche. + + + This value should not be before week "{{ min }}". + Dieser Wert darf nicht vor der Woche "{{ min }}" sein. + + + This value should not be after week "{{ max }}". + Dieser Wert darf nicht nach der Woche "{{ max }}" sein. + + + This value is not a valid Twig template. + Dieser Wert ist kein valides Twig-Template. + + + This file is not a valid video. + Diese Datei ist kein gültiges Video. + + + The size of the video could not be detected. + Die Größe des Videos konnte nicht ermittelt werden. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Das Video ist zu breit ({{ width }}px). Die zulässige maximale Breite ist {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Das Video ist nicht breit genug ({{ width }}px). Die erwartete Mindestbreite ist {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Die Videohöhe ist zu hoch ({{ height }}px). Die zulässige maximale Höhe ist {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Die Videohöhe ist zu klein ({{ height }}px). Die erwartete Mindesthöhe ist {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Das Video hat zu wenige Pixel ({{ pixels }}). Die erwartete Mindestanzahl ist {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Das Video hat zu viele Pixel ({{ pixels }}). Die erwartete Höchstanzahl ist {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Das Video-Seitenverhältnis ist zu hoch ({{ ratio }}). Das zulässige maximale Verhältnis ist {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Das Video-Seitenverhältnis ist zu klein ({{ ratio }}). Das erwartete Mindestverhältnis ist {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Das Video ist quadratisch ({{ width }}x{{ height }}px). Quadratische Videos sind nicht erlaubt. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Das Video ist im Querformat ({{ width }}x{{ height }} px). Querformat-Videos sind nicht erlaubt. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Das Video ist hochkant ausgerichtet ({{ width }}x{{ height }}px). Hochkant-Videos sind nicht erlaubt. + + + The video file is corrupted. + Die Videodatei ist beschädigt. + + + The video contains multiple streams. Only one stream is allowed. + Das Video enthält mehrere Streams. Es ist nur ein Stream erlaubt. + + + Unsupported video codec "{{ codec }}". + Nicht unterstützter Videocodec "{{ codec }}". + + + Unsupported video container "{{ container }}". + Nicht unterstützter Videocontainer "{{ container }}". + + + The image file is corrupted. + Die Bilddatei ist beschädigt. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Das Bild hat zu wenige Pixel ({{ pixels }}). Erwartete Mindestanzahl ist {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Das Bild hat zu viele Pixel ({{ pixels }}). Erwartete Höchstanzahl ist {{ max_pixels }}. + + + This filename does not match the expected charset. + Dieser Dateiname entspricht nicht dem erwarteten Zeichensatz. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.el.xlf b/lib/symfony/validator/Resources/translations/validators.el.xlf new file mode 100644 index 0000000000..dc5f1a961d --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.el.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Αυτή η τιμή πρέπει να είναι ψευδής. + + + This value should be true. + Αυτή η τιμή πρέπει να είναι αληθής. + + + This value should be of type {{ type }}. + Αυτή η τιμή πρέπει να είναι τύπου {{ type }}. + + + This value should be blank. + Αυτή η τιμή πρέπει να είναι κενή. + + + The value you selected is not a valid choice. + Η τιμή που επιλέχθηκε δεν αντιστοιχεί σε έγκυρη επιλογή. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Πρέπει να επιλέξτε τουλάχιστον {{ limit }} επιλογή.|Πρέπει να επιλέξτε τουλάχιστον {{ limit }} επιλογές. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Πρέπει να επιλέξτε το πολύ {{ limit }} επιλογή.|Πρέπει να επιλέξτε το πολύ {{ limit }} επιλογές. + + + One or more of the given values is invalid. + Μια ή περισσότερες τιμές δεν είναι έγκυρες. + + + This field was not expected. + Αυτό το πεδίο δεν ήταν αναμενόμενο. + + + This field is missing. + Λείπει αυτό το πεδίο. + + + This value is not a valid date. + Η τιμή δεν αντιστοιχεί σε έγκυρη ημερομηνία. + + + This value is not a valid datetime. + Η τιμή δεν αντιστοιχεί σε έγκυρη ημερομηνία και ώρα. + + + This value is not a valid email address. + Η τιμή δεν αντιστοιχεί σε έγκυρο email. + + + The file could not be found. + Το αρχείο δε μπορεί να βρεθεί. + + + The file is not readable. + Το αρχείο δεν είναι αναγνώσιμο. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Το αρχείο είναι πολύ μεγάλο ({{ size }} {{ suffix }}). Το μέγιστο επιτρεπτό μέγεθος είναι {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Ο τύπος mime του αρχείου δεν είναι έγκυρος ({{ type }}). Οι έγκυροι τύποι mime είναι {{ types }}. + + + This value should be {{ limit }} or less. + Αυτή η τιμή θα έπρεπε να είναι {{ limit }} ή λιγότερο. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Αυτή η τιμή είναι πολύ μεγάλη. Θα έπρεπε να έχει {{ limit }} χαρακτήρα ή λιγότερο.|Αυτή η τιμή είναι πολύ μεγάλη. Θα έπρεπε να έχει {{ limit }} χαρακτήρες ή λιγότερο. + + + This value should be {{ limit }} or more. + Αυτή η τιμή θα έπρεπε να είναι {{ limit }} ή περισσότερο. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Αυτή η τιμή είναι πολύ μικρή. Θα έπρεπε να έχει {{ limit }} χαρακτήρα ή περισσότερο.|Αυτή η τιμή είναι πολύ μικρή. Θα έπρεπε να έχει {{ limit }} χαρακτήρες ή περισσότερο. + + + This value should not be blank. + Αυτή η τιμή δεν πρέπει να είναι κενή. + + + This value should not be null. + Αυτή η τιμή δεν πρέπει να είναι μηδενική. + + + This value should be null. + Αυτή η τιμή πρέπει να είναι μηδενική. + + + This value is not valid. + Αυτή η τιμή δεν είναι έγκυρη. + + + This value is not a valid time. + Αυτή η τιμή δεν αντιστοιχεί σε έγκυρη ώρα. + + + This value is not a valid URL. + Αυτή η τιμή δεν αντιστοιχεί σε έγκυρο URL. + + + The two values should be equal. + Οι δύο τιμές θα πρέπει να είναι ίδιες. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Το αρχείο είναι πολύ μεγάλο. Το μέγιστο επιτρεπτό μέγεθος είναι {{ limit }} {{ suffix }}. + + + The file is too large. + Το αρχείο είναι πολύ μεγάλο. + + + The file could not be uploaded. + Το αρχείο δε μπορεί να ανέβει. + + + This value should be a valid number. + Αυτή η τιμή θα πρέπει να είναι ένας έγκυρος αριθμός. + + + This file is not a valid image. + Το αρχείο δεν αποτελεί έγκυρη εικόνα. + + + This value is not a valid IP address. + Αυτή η IP διεύθυνση δεν είναι έγκυρη. + + + This value is not a valid language. + Αυτή η τιμή δεν αντιστοιχεί σε μια έγκυρη γλώσσα. + + + This value is not a valid locale. + Αυτή η τιμή δεν αντιστοιχεί σε έγκυρο κωδικό τοποθεσίας. + + + This value is not a valid country. + Αυτή η τιμή δεν αντιστοιχεί σε μια έγκυρη χώρα. + + + This value is already used. + Αυτή η τιμή χρησιμοποιείται ήδη. + + + The size of the image could not be detected. + Το μέγεθος της εικόνας δεν ήταν δυνατό να ανιχνευθεί. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Το πλάτος της εικόνας είναι πολύ μεγάλο ({{ width }}px). Το μέγιστο επιτρεπτό πλάτος είναι {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Το πλάτος της εικόνας είναι πολύ μικρό ({{ width }}px). Το ελάχιστο επιτρεπτό πλάτος είναι {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Το ύψος της εικόνας είναι πολύ μεγάλο ({{ height }}px). Το μέγιστο επιτρεπτό ύψος είναι {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Το ύψος της εικόνας είναι πολύ μικρό ({{ height }}px). Το ελάχιστο επιτρεπτό ύψος είναι {{ min_height }}px. + + + This value should be the user's current password. + Αυτή η τιμή θα έπρεπε να είναι ο τρέχων κωδικός. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Αυτή η τιμή θα έπρεπε να έχει ακριβώς {{ limit }} χαρακτήρα.|Αυτή η τιμή θα έπρεπε να έχει ακριβώς {{ limit }} χαρακτήρες. + + + The file was only partially uploaded. + Το αρχείο δεν ανέβηκε ολόκληρο. + + + No file was uploaded. + Δεν ανέβηκε κανένα αρχείο. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Δεν έχει ρυθμιστεί προσωρινός φάκελος στο php.ini, ή ο ρυθμισμένος φάκελος δεν υπάρχει. + + + Cannot write temporary file to disk. + Αδυναμία εγγραφής προσωρινού αρχείου στο δίσκο. + + + A PHP extension caused the upload to fail. + Μια επέκταση PHP προκάλεσε αδυναμία ανεβάσματος. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Αυτή η συλλογή θα πρέπει να περιέχει {{ limit }} στοιχείο ή περισσότερα.|Αυτή η συλλογή θα πρέπει να περιέχει {{ limit }} στοιχεία ή περισσότερα. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Αυτή η συλλογή θα πρέπει να περιέχει {{ limit }} στοιχείo ή λιγότερα.|Αυτή η συλλογή θα πρέπει να περιέχει {{ limit }} στοιχεία ή λιγότερα. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Αυτή η συλλογή θα πρέπει να περιέχει ακριβώς {{ limit }} στοιχείo.|Αυτή η συλλογή θα πρέπει να περιέχει ακριβώς {{ limit }} στοιχεία. + + + Invalid card number. + Μη έγκυρος αριθμός κάρτας. + + + Unsupported card type or invalid card number. + Μη υποστηριζόμενος τύπος κάρτας ή μη έγκυρος αριθμός κάρτας. + + + This value is not a valid International Bank Account Number (IBAN). + Αυτός δεν είναι έγκυρος διεθνής αριθμός τραπεζικού λογαριασμού (IBAN). + + + This value is not a valid ISBN-10. + Αυτό δεν είναι έγκυρος κωδικός ISBN-10. + + + This value is not a valid ISBN-13. + Αυτό δεν είναι έγκυρος κωδικός ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Αυτό δεν είναι ούτε έγκυρος κωδικός ISBN-10 ούτε έγκυρος κωδικός ISBN-13. + + + This value is not a valid ISSN. + Αυτό δεν είναι έγκυρος κωδικός ISSN. + + + This value is not a valid currency. + Αυτό δεν αντιστοιχεί σε έγκυρο νόμισμα. + + + This value should be equal to {{ compared_value }}. + Αυτή η τιμή θα πρέπει να είναι ίση με {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Αυτή η τιμή θα πρέπει να είναι μεγαλύτερη από {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Αυτή η τιμή θα πρέπει να είναι μεγαλύτερη ή ίση με {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Αυτή η τιμή θα πρέπει να είναι πανομοιότυπη με {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Αυτή η τιμή θα πρέπει να είναι μικρότερη από {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Αυτή η τιμή θα πρέπει να είναι μικρότερη ή ίση με {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Αυτή η τιμή δεν θα πρέπει να είναι ίση με {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Αυτή η τιμή δεν πρέπει να είναι πανομοιότυπη με {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Η αναλογία πλάτους-ύψους της εικόνας είναι πολύ μεγάλη ({{ ratio }}). Μέγιστη επιτρεπτή αναλογία {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Η αναλογία πλάτους-ύψους της εικόνας είναι πολύ μικρή ({{ ratio }}). Ελάχιστη επιτρεπτή αναλογία {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Η εικόνα είναι τετράγωνη ({{ width }}x{{ height }}px). Δεν επιτρέπονται τετράγωνες εικόνες. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Η εικόνα έχει οριζόντιο προσανατολισμό ({{ width }}x{{ height }}px). Δεν επιτρέπονται εικόνες με οριζόντιο προσανατολισμό. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Η εικόνα έχει κάθετο προσανατολισμό ({{ width }}x{{ height }}px). Δεν επιτρέπονται εικόνες με κάθετο προσανατολισμό. + + + An empty file is not allowed. + Δεν επιτρέπεται κενό αρχείο. + + + The host could not be resolved. + Η διεύθυνση δεν μπόρεσε να επιλυθεί. + + + This value does not match the expected {{ charset }} charset. + Αυτή η τιμή δεν ταιριάζει στο αναμενόμενο {{ charset }} σύνολο χαρακτήρων. + + + This value is not a valid Business Identifier Code (BIC). + Αυτός ο αριθμός δεν είναι έγκυρος Κωδικός Ταυτοποίησης Επιχείρησης (BIC). + + + Error + Σφάλμα + + + This value is not a valid UUID. + Αυτός ο αριθμός δεν είναι έγκυρη UUID. + + + This value should be a multiple of {{ compared_value }}. + Αυτή η τιμή θα έπρεπε να είναι πολλαπλάσιο του {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Αυτός ο κωδικός BIC δεν σχετίζεται με το IBAN {{ iban }}. + + + This value should be valid JSON. + Αυτή η τιμή θα πρέπει να είναι έγκυρο JSON. + + + This collection should contain only unique elements. + Αυτή η συλλογή θα πρέπει να περιέχει μόνο μοναδικά στοιχεία. + + + This value should be positive. + Αυτή η τιμή θα πρέπει να είναι θετική. + + + This value should be either positive or zero. + Αυτή η τιμή θα πρέπει να είναι θετική ή μηδενική. + + + This value should be negative. + Αυτή η τιμή θα πρέπει να είναι αρνητική. + + + This value should be either negative or zero. + Αυτή η τιμή θα πρέπει να είναι αρνητική ή μηδενική. + + + This value is not a valid timezone. + Αυτή η τιμή θα δεν είναι έγκυρη ζώνη ώρας. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Αυτός ο κωδικός πρόσβασης έχει διαρρεύσει σε παραβίαση δεδομένων. Παρακαλούμε να χρησιμοποιήσετε έναν άλλο κωδικό. + + + This value should be between {{ min }} and {{ max }}. + Αυτή η τιμή θα πρέπει να είναι μεταξύ {{ min }} και {{ max }}. + + + This value is not a valid hostname. + Αυτή η τιμή δεν είναι έγκυρο όνομα υποδοχής. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Το νούμερο των στοιχείων σε αυτή τη συλλογή θα πρέπει να είναι πολλαπλάσιο του {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Αυτή η τιμή θα πρέπει να ικανοποιεί τουλάχιστον έναν από τους παρακάτω περιορισμούς: + + + Each element of this collection should satisfy its own set of constraints. + Κάθε στοιχείο σε αυτή τη συλλογή θα πρέπει να ικανοποιεί το δικό του σύνολο περιορισμών. + + + This value is not a valid International Securities Identification Number (ISIN). + Αυτή η τιμή δεν είναι έγκυρο International Securities Identification Number (ISIN). + + + This value should be a valid expression. + Αυτή η τιμή θα πρέπει να είναι μία έγκυρη έκφραση. + + + This value is not a valid CSS color. + Αυτή η τιμή δεν είναι έγκυρο χρώμα CSS. + + + This value is not a valid CIDR notation. + Αυτή η τιμή δεν είναι έγκυρη CIDR σημειογραφία. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Η τιμή του netmask πρέπει να είναι ανάμεσα σε {{ min }} και {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Το όνομα αρχείου είναι πολύ μεγάλο. Θα πρέπει να έχει έως {{ filename_max_length }} χαρακτήρα.|Το όνομα αρχείου είναι πολύ μεγάλο. Θα πρέπει να έχει έως {{ filename_max_length }} χαρακτήρες. + + + The password strength is too low. Please use a stronger password. + Η ισχύς του κωδικού πρόσβασης είναι πολύ χαμηλή. Χρησιμοποιήστε έναν ισχυρότερο κωδικό πρόσβασης. + + + This value contains characters that are not allowed by the current restriction-level. + Αυτή η τιμή περιέχει χαρακτήρες που δεν επιτρέπονται από το τρέχον επίπεδο περιορισμού. + + + Using invisible characters is not allowed. + Δεν επιτρέπεται η χρήση αόρατων χαρακτήρων. + + + Mixing numbers from different scripts is not allowed. + Δεν επιτρέπεται η μίξη αριθμών από διαφορετικά γραφήματα. + + + Using hidden overlay characters is not allowed. + Δεν επιτρέπεται η χρήση κρυφών χαρακτήρων επικάλυψης. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Η επέκταση του αρχείου δεν είναι έγκυρη ({{ extension }}). Οι επιτρεπτόμενες επεκτάσεις είναι {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Η κωδικοποίηση χαρακτήρων που ανιχνεύτηκε δεν είναι έγκυρη ({{ detected }}). Οι επιτρεπόμενες κωδικοποιήσεις είναι {{ encodings }}. + + + This value is not a valid MAC address. + Αυτός ο αριθμός δεν είναι έγκυρη διεύθυνση MAC. + + + This URL is missing a top-level domain. + Αυτή η διεύθυνση URL λείπει ένας τομέας ανώτατου επιπέδου. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Αυτή η τιμή είναι πολύ σύντομη. Πρέπει να περιέχει τουλάχιστον μία λέξη.|Αυτή η τιμή είναι πολύ σύντομη. Πρέπει να περιέχει τουλάχιστον {{ min }} λέξεις. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Αυτή η τιμή είναι πολύ μεγάλη. Πρέπει να περιέχει μόνο μία λέξη.|Αυτή η τιμή είναι πολύ μεγάλη. Πρέπει να περιέχει {{ max }} λέξεις ή λιγότερες. + + + This value does not represent a valid week in the ISO 8601 format. + Αυτή η τιμή δεν αντιπροσωπεύει έγκυρη εβδομάδα στη μορφή ISO 8601. + + + This value is not a valid week. + Αυτή η τιμή δεν είναι έγκυρη εβδομάδα. + + + This value should not be before week "{{ min }}". + Αυτή η τιμή δεν πρέπει να είναι πριν από την εβδομάδα "{{ min }}". + + + This value should not be after week "{{ max }}". + Αυτή η τιμή δεν πρέπει να είναι μετά την εβδομάδα "{{ max }}". + + + This value is not a valid Twig template. + Αυτή η τιμή δεν είναι έγκυρο πρότυπο Twig. + + + This file is not a valid video. + Αυτό το αρχείο δεν είναι έγκυρο βίντεο. + + + The size of the video could not be detected. + Δεν ήταν δυνατός ο εντοπισμός του μεγέθους του βίντεο. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Το πλάτος του βίντεο είναι πολύ μεγάλο ({{ width }}px). Το επιτρεπόμενο μέγιστο πλάτος είναι {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Το πλάτος του βίντεο είναι πολύ μικρό ({{ width }}px). Το ελάχιστο αναμενόμενο πλάτος είναι {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Το ύψος του βίντεο είναι πολύ μεγάλο ({{ height }}px). Το επιτρεπόμενο μέγιστο ύψος είναι {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Το ύψος του βίντεο είναι πολύ μικρό ({{ height }}px). Το αναμενόμενο ελάχιστο ύψος είναι {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Το βίντεο έχει πολύ λίγα εικονοστοιχεία ({{ pixels }}). Η ελάχιστη αναμενόμενη ποσότητα είναι {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Το βίντεο έχει πάρα πολλά εικονοστοιχεία ({{ pixels }}). Η μέγιστη αναμενόμενη ποσότητα είναι {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Η αναλογία του βίντεο είναι πολύ μεγάλη ({{ ratio }}). Η μέγιστη επιτρεπτή αναλογία είναι {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Η αναλογία βίντεο είναι πολύ μικρή ({{ ratio }}). Η ελάχιστη αναμενόμενη αναλογία είναι {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Το βίντεο είναι τετράγωνο ({{ width }}x{{ height }}px). Τα τετράγωνα βίντεο δεν επιτρέπονται. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Το βίντεο είναι σε οριζόντιο προσανατολισμό ({{ width }}x{{ height }} px). Τα οριζόντια βίντεο δεν επιτρέπονται. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Το βίντεο είναι σε κατακόρυφο προσανατολισμό ({{ width }}x{{ height }}px). Βίντεο κάθετου προσανατολισμού δεν επιτρέπονται. + + + The video file is corrupted. + Το αρχείο βίντεο είναι κατεστραμμένο. + + + The video contains multiple streams. Only one stream is allowed. + Το βίντεο περιέχει πολλαπλά ρεύματα. Επιτρέπεται μόνο ένα ρεύμα. + + + Unsupported video codec "{{ codec }}". + Μη υποστηριζόμενος κωδικοποιητής βίντεο «{{ codec }}». + + + Unsupported video container "{{ container }}". + Μη υποστηριζόμενο κοντέινερ βίντεο "{{ container }}". + + + The image file is corrupted. + Το αρχείο εικόνας είναι κατεστραμμένο. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Η εικόνα έχει πολύ λίγα εικονοστοιχεία ({{ pixels }}). Η αναμενόμενη ελάχιστη ποσότητα είναι {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Η εικόνα έχει πάρα πολλούς εικονοστοιχείους ({{ pixels }}). Ο μέγιστος αναμενόμενος αριθμός είναι {{ max_pixels }}. + + + This filename does not match the expected charset. + Αυτό το όνομα αρχείου δεν αντιστοιχεί στο αναμενόμενο σύνολο χαρακτήρων. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.en.xlf b/lib/symfony/validator/Resources/translations/validators.en.xlf new file mode 100644 index 0000000000..9a00253e31 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.en.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + This value should be false. + + + This value should be true. + This value should be true. + + + This value should be of type {{ type }}. + This value should be of type {{ type }}. + + + This value should be blank. + This value should be blank. + + + The value you selected is not a valid choice. + The value you selected is not a valid choice. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + + + One or more of the given values is invalid. + One or more of the given values is invalid. + + + This field was not expected. + This field was not expected. + + + This field is missing. + This field is missing. + + + This value is not a valid date. + This value is not a valid date. + + + This value is not a valid datetime. + This value is not a valid datetime. + + + This value is not a valid email address. + This value is not a valid email address. + + + The file could not be found. + The file could not be found. + + + The file is not readable. + The file is not readable. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + + + This value should be {{ limit }} or less. + This value should be {{ limit }} or less. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + + + This value should be {{ limit }} or more. + This value should be {{ limit }} or more. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + + + This value should not be blank. + This value should not be blank. + + + This value should not be null. + This value should not be null. + + + This value should be null. + This value should be null. + + + This value is not valid. + This value is not valid. + + + This value is not a valid time. + This value is not a valid time. + + + This value is not a valid URL. + This value is not a valid URL. + + + The two values should be equal. + The two values should be equal. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + + + The file is too large. + The file is too large. + + + The file could not be uploaded. + The file could not be uploaded. + + + This value should be a valid number. + This value should be a valid number. + + + This file is not a valid image. + This file is not a valid image. + + + This is not a valid IP address. + This value is not a valid IP address. + + + This value is not a valid language. + This value is not a valid language. + + + This value is not a valid locale. + This value is not a valid locale. + + + This value is not a valid country. + This value is not a valid country. + + + This value is already used. + This value is already used. + + + The size of the image could not be detected. + The size of the image could not be detected. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + + + This value should be the user's current password. + This value should be the user's current password. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + + + The file was only partially uploaded. + The file was only partially uploaded. + + + No file was uploaded. + No file was uploaded. + + + No temporary folder was configured in php.ini. + No temporary folder was configured in php.ini, or the configured folder does not exist. + + + Cannot write temporary file to disk. + Cannot write temporary file to disk. + + + A PHP extension caused the upload to fail. + A PHP extension caused the upload to fail. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + + + Invalid card number. + Invalid card number. + + + Unsupported card type or invalid card number. + Unsupported card type or invalid card number. + + + This is not a valid International Bank Account Number (IBAN). + This value is not a valid International Bank Account Number (IBAN). + + + This value is not a valid ISBN-10. + This value is not a valid ISBN-10. + + + This value is not a valid ISBN-13. + This value is not a valid ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + This value is neither a valid ISBN-10 nor a valid ISBN-13. + + + This value is not a valid ISSN. + This value is not a valid ISSN. + + + This value is not a valid currency. + This value is not a valid currency. + + + This value should be equal to {{ compared_value }}. + This value should be equal to {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + This value should be greater than {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + This value should be greater than or equal to {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + This value should be less than {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + This value should be less than or equal to {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + This value should not be equal to {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + + + An empty file is not allowed. + An empty file is not allowed. + + + The host could not be resolved. + The host could not be resolved. + + + This value does not match the expected {{ charset }} charset. + This value does not match the expected {{ charset }} charset. + + + This is not a valid Business Identifier Code (BIC). + This value is not a valid Business Identifier Code (BIC). + + + Error + Error + + + This is not a valid UUID. + This value is not a valid UUID. + + + This value should be a multiple of {{ compared_value }}. + This value should be a multiple of {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + + + This value should be valid JSON. + This value should be valid JSON. + + + This collection should contain only unique elements. + This collection should contain only unique elements. + + + This value should be positive. + This value should be positive. + + + This value should be either positive or zero. + This value should be either positive or zero. + + + This value should be negative. + This value should be negative. + + + This value should be either negative or zero. + This value should be either negative or zero. + + + This value is not a valid timezone. + This value is not a valid timezone. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + This password has been leaked in a data breach, it must not be used. Please use another password. + + + This value should be between {{ min }} and {{ max }}. + This value should be between {{ min }} and {{ max }}. + + + This value is not a valid hostname. + This value is not a valid hostname. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + The number of elements in this collection should be a multiple of {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + This value should satisfy at least one of the following constraints: + + + Each element of this collection should satisfy its own set of constraints. + Each element of this collection should satisfy its own set of constraints. + + + This value is not a valid International Securities Identification Number (ISIN). + This value is not a valid International Securities Identification Number (ISIN). + + + This value should be a valid expression. + This value should be a valid expression. + + + This value is not a valid CSS color. + This value is not a valid CSS color. + + + This value is not a valid CIDR notation. + This value is not a valid CIDR notation. + + + The value of the netmask should be between {{ min }} and {{ max }}. + The value of the netmask should be between {{ min }} and {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + + + The password strength is too low. Please use a stronger password. + The password strength is too low. Please use a stronger password. + + + This value contains characters that are not allowed by the current restriction-level. + This value contains characters that are not allowed by the current restriction-level. + + + Using invisible characters is not allowed. + Using invisible characters is not allowed. + + + Mixing numbers from different scripts is not allowed. + Mixing numbers from different scripts is not allowed. + + + Using hidden overlay characters is not allowed. + Using hidden overlay characters is not allowed. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + + + This value is not a valid MAC address. + This value is not a valid MAC address. + + + This URL is missing a top-level domain. + This URL is missing a top-level domain. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + + + This value does not represent a valid week in the ISO 8601 format. + This value does not represent a valid week in the ISO 8601 format. + + + This value is not a valid week. + This value is not a valid week. + + + This value should not be before week "{{ min }}". + This value should not be before week "{{ min }}". + + + This value should not be after week "{{ max }}". + This value should not be after week "{{ max }}". + + + This value is not a valid Twig template. + This value is not a valid Twig template. + + + This file is not a valid video. + This file is not a valid video. + + + The size of the video could not be detected. + The size of the video could not be detected. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + + + The video file is corrupted. + The video file is corrupted. + + + The video contains multiple streams. Only one stream is allowed. + The video contains multiple streams. Only one stream is allowed. + + + Unsupported video codec "{{ codec }}". + Unsupported video codec "{{ codec }}". + + + Unsupported video container "{{ container }}". + Unsupported video container "{{ container }}". + + + The image file is corrupted. + The image file is corrupted. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + + + This filename does not match the expected charset. + This filename does not match the expected charset. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.es.xlf b/lib/symfony/validator/Resources/translations/validators.es.xlf new file mode 100644 index 0000000000..c2bdb7c4e5 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.es.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Este valor debería ser falso. + + + This value should be true. + Este valor debería ser verdadero. + + + This value should be of type {{ type }}. + Este valor debería ser de tipo {{ type }}. + + + This value should be blank. + Este valor debería estar vacío. + + + The value you selected is not a valid choice. + El valor seleccionado no es una opción válida. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Debe seleccionar al menos {{ limit }} opción.|Debe seleccionar al menos {{ limit }} opciones. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Debe seleccionar como máximo {{ limit }} opción.|Debe seleccionar como máximo {{ limit }} opciones. + + + One or more of the given values is invalid. + Uno o más de los valores indicados no son válidos. + + + This field was not expected. + Este campo no se esperaba. + + + This field is missing. + Este campo falta. + + + This value is not a valid date. + Este valor no es una fecha válida. + + + This value is not a valid datetime. + Este valor no es una fecha y hora válida. + + + This value is not a valid email address. + Este valor no es una dirección de email válida. + + + The file could not be found. + No se pudo encontrar el archivo. + + + The file is not readable. + No se puede leer el archivo. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + El archivo es demasiado grande ({{ size }} {{ suffix }}). El tamaño máximo permitido es {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + El tipo mime del archivo no es válido ({{ type }}). Los tipos mime válidos son {{ types }}. + + + This value should be {{ limit }} or less. + Este valor debería ser {{ limit }} o menos. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Este valor es demasiado largo. Debería tener {{ limit }} carácter o menos.|Este valor es demasiado largo. Debería tener {{ limit }} caracteres o menos. + + + This value should be {{ limit }} or more. + Este valor debería ser {{ limit }} o más. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Este valor es demasiado corto. Debería tener {{ limit }} carácter o más.|Este valor es demasiado corto. Debería tener {{ limit }} caracteres o más. + + + This value should not be blank. + Este valor no debería estar vacío. + + + This value should not be null. + Este valor no debería ser nulo. + + + This value should be null. + Este valor debería ser nulo. + + + This value is not valid. + Este valor no es válido. + + + This value is not a valid time. + Este valor no es una hora válida. + + + This value is not a valid URL. + Este valor no es una URL válida. + + + The two values should be equal. + Los dos valores deberían ser iguales. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + El archivo es demasiado grande. El tamaño máximo permitido es {{ limit }} {{ suffix }}. + + + The file is too large. + El archivo es demasiado grande. + + + The file could not be uploaded. + No se pudo subir el archivo. + + + This value should be a valid number. + Este valor debería ser un número válido. + + + This file is not a valid image. + El archivo no es una imagen válida. + + + This value is not a valid IP address. + Este valor no es una dirección IP válida. + + + This value is not a valid language. + Este valor no es un idioma válido. + + + This value is not a valid locale. + Este valor no es una localización válida. + + + This value is not a valid country. + Este valor no es un país válido. + + + This value is already used. + Este valor ya se ha utilizado. + + + The size of the image could not be detected. + No se pudo determinar el tamaño de la imagen. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + El ancho de la imagen es demasiado grande ({{ width }}px). El ancho máximo permitido es de {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + El ancho de la imagen es demasiado pequeño ({{ width }}px). El ancho mínimo requerido es {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + La altura de la imagen es demasiado grande ({{ height }}px). La altura máxima permitida es de {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + La altura de la imagen es demasiado pequeña ({{ height }}px). La altura mínima requerida es de {{ min_height }}px. + + + This value should be the user's current password. + Este valor debería ser la contraseña actual del usuario. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Este valor debería tener exactamente {{ limit }} carácter.|Este valor debería tener exactamente {{ limit }} caracteres. + + + The file was only partially uploaded. + El archivo se cargó solo parcialmente. + + + No file was uploaded. + No se subió ningún archivo. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Ninguna carpeta temporal fue configurada en php.ini o la carpeta configurada no existe. + + + Cannot write temporary file to disk. + No se pudo escribir el archivo temporal en el disco. + + + A PHP extension caused the upload to fail. + Una extensión de PHP provocó que la carga fallara. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Esta colección debe contener {{ limit }} elemento o más.|Esta colección debe contener {{ limit }} elementos o más. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Esta colección debe contener {{ limit }} elemento o menos.|Esta colección debe contener {{ limit }} elementos o menos. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Esta colección debe contener exactamente {{ limit }} elemento.|Esta colección debe contener exactamente {{ limit }} elementos. + + + Invalid card number. + Número de tarjeta inválido. + + + Unsupported card type or invalid card number. + Tipo de tarjeta no soportado o número de tarjeta inválido. + + + This value is not a valid International Bank Account Number (IBAN). + Este valor no es un Número de Cuenta Bancaria Internacional (IBAN) válido. + + + This value is not a valid ISBN-10. + Este valor no es un ISBN-10 válido. + + + This value is not a valid ISBN-13. + Este valor no es un ISBN-13 válido. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Este valor no es ni un ISBN-10 válido ni un ISBN-13 válido. + + + This value is not a valid ISSN. + Este valor no es un ISSN válido. + + + This value is not a valid currency. + Este valor no es una divisa válida. + + + This value should be equal to {{ compared_value }}. + Este valor debería ser igual que {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Este valor debería ser mayor que {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Este valor debería ser mayor o igual que {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor debería ser idéntico a {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Este valor debería ser menor que {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Este valor debería ser menor o igual que {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Este valor debería ser distinto de {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor no debería ser idéntico a {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + La proporción de la imagen es demasiado grande ({{ ratio }}). La máxima proporción permitida es {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + La proporción de la imagen es demasiado pequeña ({{ ratio }}). La mínima proporción permitida es {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + La imagen es cuadrada ({{ width }}x{{ height }}px). Las imágenes cuadradas no están permitidas. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + La imagen está orientada horizontalmente ({{ width }}x{{ height }}px). Las imágenes orientadas horizontalmente no están permitidas. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + La imagen está orientada verticalmente ({{ width }}x{{ height }}px). Las imágenes orientadas verticalmente no están permitidas. + + + An empty file is not allowed. + No se permite un archivo vacío. + + + The host could not be resolved. + No se puede resolver el host. + + + This value does not match the expected {{ charset }} charset. + La codificación de caracteres para este valor debería ser {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Este valor no es un Código de Identificación de Negocios (BIC) válido. + + + Error + Error + + + This value is not a valid UUID. + Este valor no es un UUID válido. + + + This value should be a multiple of {{ compared_value }}. + Este valor debería ser múltiplo de {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Este Código de Identificación Bancaria (BIC) no está asociado con el IBAN {{ iban }}. + + + This value should be valid JSON. + Este valor debería ser un JSON válido. + + + This collection should contain only unique elements. + Esta colección debería tener exclusivamente elementos únicos. + + + This value should be positive. + Este valor debería ser positivo. + + + This value should be either positive or zero. + Este valor debería ser positivo o igual a cero. + + + This value should be negative. + Este valor debería ser negativo. + + + This value should be either negative or zero. + Este valor debería ser negativo o igual a cero. + + + This value is not a valid timezone. + Este valor no es una zona horaria válida. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Esta contraseña no se puede utilizar porque está incluida en un listado de contraseñas públicas obtenido gracias a fallos de seguridad de otros sitios y aplicaciones. Por favor, utilice otra contraseña. + + + This value should be between {{ min }} and {{ max }}. + Este valor debería estar entre {{ min }} y {{ max }}. + + + This value is not a valid hostname. + Este valor no es un nombre de host válido. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + El número de elementos en esta colección debería ser múltiplo de {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Este valor debería satisfacer al menos una de las siguientes restricciones: + + + Each element of this collection should satisfy its own set of constraints. + Cada elemento de esta colección debería satisfacer su propio conjunto de restricciones. + + + This value is not a valid International Securities Identification Number (ISIN). + Este valor no es un número de identificación internacional de valores (ISIN) válido. + + + This value should be a valid expression. + Este valor debería ser una expresión válida. + + + This value is not a valid CSS color. + Este valor no es un color CSS válido. + + + This value is not a valid CIDR notation. + Este valor no es una notación CIDR válida. + + + The value of the netmask should be between {{ min }} and {{ max }}. + El valor de la máscara de red debería estar entre {{ min }} y {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + El nombre del archivo es demasiado largo. Debe tener {{ filename_max_length }} carácter o menos.|El nombre del archivo es demasiado largo. Debe tener {{ filename_max_length }} caracteres o menos. + + + The password strength is too low. Please use a stronger password. + La seguridad de la contraseña es demasiado baja. Por favor, utilice una contraseña más segura. + + + This value contains characters that are not allowed by the current restriction-level. + Este valor contiene caracteres que no están permitidos según el nivel de restricción actual. + + + Using invisible characters is not allowed. + No se permite el uso de caracteres invisibles. + + + Mixing numbers from different scripts is not allowed. + No está permitido mezclar números de diferentes scripts. + + + Using hidden overlay characters is not allowed. + No está permitido el uso de caracteres superpuestos ocultos. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + La extensión del archivo no es válida ({{ extension }}). Las extensiones permitidas son {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + La codificación de los caracteres detectada es inválida ({{ detected }}). Las codificaciones permitidas son {{ encodings }}. + + + This value is not a valid MAC address. + Este valor no es una dirección MAC válida. + + + This URL is missing a top-level domain. + Esta URL no contiene una extensión de dominio (TLD). + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Este valor es demasiado corto. Debe contener al menos una palabra.|Este valor es demasiado corto. Debe contener al menos {{ min }} palabras. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Este valor es demasiado largo. Debe contener una palabra.|Este valor es demasiado largo. Debe contener {{ max }} palabras o menos. + + + This value does not represent a valid week in the ISO 8601 format. + Este valor no representa una semana válida en formato ISO 8601. + + + This value is not a valid week. + Este valor no es una semana válida. + + + This value should not be before week "{{ min }}". + Este valor no debe ser anterior a la semana "{{ min }}". + + + This value should not be after week "{{ max }}". + Este valor no debe ser posterior a la semana "{{ max }}". + + + This value is not a valid Twig template. + Este valor no es una plantilla Twig válida. + + + This file is not a valid video. + Este archivo no es un video válido. + + + The size of the video could not be detected. + No se pudo detectar el tamaño del video. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + El ancho del vídeo es demasiado grande ({{ width }}px). El ancho máximo permitido es {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + El ancho del video es demasiado pequeño ({{ width }}px). El ancho mínimo esperado es {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + La altura del video es demasiado grande ({{ height }}px). La altura máxima permitida es {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + La altura del video es demasiado pequeña ({{ height }}px). La altura mínima esperada es {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + El vídeo tiene muy pocos píxeles ({{ pixels }}). La cantidad mínima esperada es {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + El vídeo tiene demasiados píxeles ({{ pixels }}). La cantidad máxima esperada es {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + La relación del video es demasiado grande ({{ ratio }}). La relación máxima permitida es {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + La relación del video es demasiado pequeña ({{ ratio }}). La relación mínima esperada es {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + El video es cuadrado ({{ width }}x{{ height }}px). No se permiten videos cuadrados. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + El video tiene orientación horizontal ({{ width }}x{{ height }} px). No se permiten videos en formato horizontal. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + El video tiene orientación vertical ({{ width }}x{{ height }} px). No se permiten videos en orientación vertical. + + + The video file is corrupted. + El archivo de video está dañado. + + + The video contains multiple streams. Only one stream is allowed. + El video contiene múltiples flujos. Solo se permite un flujo. + + + Unsupported video codec "{{ codec }}". + Códec de vídeo no compatible «{{ codec }}». + + + Unsupported video container "{{ container }}". + Contenedor de vídeo no compatible "{{ container }}". + + + The image file is corrupted. + El archivo de imagen está dañado. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + La imagen tiene muy pocos píxeles ({{ pixels }}). La cantidad mínima esperada es {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + La imagen tiene demasiados píxeles ({{ pixels }}). La cantidad máxima esperada es {{ max_pixels }}. + + + This filename does not match the expected charset. + Este nombre de archivo no coincide con el conjunto de caracteres esperado. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.et.xlf b/lib/symfony/validator/Resources/translations/validators.et.xlf new file mode 100644 index 0000000000..12a2671d94 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.et.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Väärtus peaks olema väär. + + + This value should be true. + Väärtus peaks oleme tõene. + + + This value should be of type {{ type }}. + Väärtus peaks olema {{ type }}-tüüpi. + + + This value should be blank. + Väärtus peaks olema tühi. + + + The value you selected is not a valid choice. + Väärtus peaks olema üks etteantud valikutest. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Valima peaks vähemalt {{ limit }} valikut. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Valima peaks mitte rohkem kui {{ limit }} valikut. + + + One or more of the given values is invalid. + Üks või rohkem väärtustest on vigane. + + + This field was not expected. + See väli ei olnud oodatud. + + + This field is missing. + See väli on puudu. + + + This value is not a valid date. + Väärtus pole korrektne kuupäev. + + + This value is not a valid datetime. + Väärtus pole korrektne kuupäev ja kellaeg. + + + This value is not a valid email address. + Väärtus pole korrektne e-maili aadress. + + + The file could not be found. + Faili ei leita. + + + The file is not readable. + Fail ei ole loetav. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Fail on liiga suur ({{ size }} {{ suffix }}). Suurim lubatud suurus on {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Faili sisutüüp on vigane ({{ type }}). Lubatud sisutüübid on {{ types }}. + + + This value should be {{ limit }} or less. + Väärtus peaks olema {{ limit }} või vähem. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Väärtus on liiga pikk. Pikkus peaks olema {{ limit }} tähemärki või vähem. + + + This value should be {{ limit }} or more. + Väärtus peaks olema {{ limit }} või rohkem. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Väärtus on liiga lühike. Pikkus peaks olema {{ limit }} tähemärki või rohkem. + + + This value should not be blank. + Väärtus ei tohiks olla tühi. + + + This value should not be null. + Väärtus ei tohiks olla 'null'. + + + This value should be null. + Väärtus peaks olema 'null'. + + + This value is not valid. + Väärtus on vigane. + + + This value is not a valid time. + Väärtus pole korrektne aeg. + + + This value is not a valid URL. + Väärtus pole korrektne URL. + + + The two values should be equal. + Väärtused peaksid olema võrdsed. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Fail on liiga suur. Maksimaalne lubatud suurus on {{ limit }} {{ suffix }}. + + + The file is too large. + Fail on liiga suur. + + + The file could not be uploaded. + Faili ei saa üles laadida. + + + This value should be a valid number. + Väärtus peaks olema korrektne number. + + + This file is not a valid image. + Fail ei ole korrektne pilt. + + + This value is not a valid IP address. + See väärtus ei ole kehtiv IP-aadress. + + + This value is not a valid language. + Väärtus pole korrektne keel. + + + This value is not a valid locale. + Väärtus pole korrektne asukohakeel. + + + This value is not a valid country. + Väärtus pole olemasolev riik. + + + This value is already used. + Väärtust on juba kasutatud. + + + The size of the image could not be detected. + Pildi suurust polnud võimalik tuvastada. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Pilt on liiga lai ({{ width }}px). Suurim lubatud laius on {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Pilt on liiga kitsas ({{ width }}px). Vähim lubatud laius on {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Pilt on liiga pikk ({{ height }}px). Lubatud suurim pikkus on {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Pilt pole piisavalt pikk ({{ height }}px). Lubatud vähim pikkus on {{ min_height }}px. + + + This value should be the user's current password. + Väärtus peaks olema kasutaja kehtiv salasõna. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Väärtus peaks olema täpselt {{ limit }} tähemärk pikk.|Väärtus peaks olema täpselt {{ limit }} tähemärki pikk. + + + The file was only partially uploaded. + Fail ei laetud täielikult üles. + + + No file was uploaded. + Ühtegi faili ei laetud üles. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Ajutine kaust php.ini-s ei olnud seadistatud või seadistatud kaust ei eksisteeri. + + + Cannot write temporary file to disk. + Ajutist faili ei saa kettale kirjutada. + + + A PHP extension caused the upload to fail. + PHP laiendi tõttu ebaõnnestus faili üleslaadimine. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Kogumikus peaks olema vähemalt {{ limit }} element.|Kogumikus peaks olema vähemalt {{ limit }} elementi. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Kogumikus peaks olema ülimalt {{ limit }} element.|Kogumikus peaks olema ülimalt {{ limit }} elementi. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Kogumikus peaks olema täpselt {{ limit }} element.|Kogumikus peaks olema täpselt {{ limit }}|elementi. + + + Invalid card number. + Vigane kaardi number. + + + Unsupported card type or invalid card number. + Kaardi tüüpi ei toetata või kaardi number on vigane. + + + This value is not a valid International Bank Account Number (IBAN). + See väärtus ei ole kehtiv Rahvusvaheline Kontonumber (IBAN). + + + This value is not a valid ISBN-10. + Väärtus pole korrektne ISBN-10. + + + This value is not a valid ISBN-13. + Väärtus pole korrektne ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Väärtus pole korrektne ISBN-10 ega ISBN-13. + + + This value is not a valid ISSN. + Väärtus pole korrektne ISSN. + + + This value is not a valid currency. + Väärtus pole korrektne valuuta. + + + This value should be equal to {{ compared_value }}. + Väärtus peaks olema võrdne {{ compared_value }}-ga. + + + This value should be greater than {{ compared_value }}. + Väärtus peaks olema suurem kui {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Väärtus peaks olema suurem kui või võrduma {{ compared_value }}-ga. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Väärtus peaks olema identne väärtusega {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Väärtus peaks olema väiksem kui {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Väärtus peaks olema väiksem kui või võrduma {{ compared_value }}-ga. + + + This value should not be equal to {{ compared_value }}. + Väärtus ei tohiks võrduda {{ compared_value }}-ga. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Väärtus ei tohiks olla identne väärtusega {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Kuvasuhe on liiga suur ({{ ratio }}). Lubatud maksimaalne suhe on {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Kuvasuhe on liiga väike ({{ ratio }}). Oodatav minimaalne suhe on {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Pilt on ruudukujuline ({{ width }}x{{ height }}px). Ruudukujulised pildid pole lubatud. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Pilt on horisontaalselt orienteeritud ({{ width }}x{{ height }}px). Maastikulised pildid pole lubatud. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Pilt on vertikaalselt orienteeritud ({{ width }}x{{ height }}px). Portreepildid pole lubatud. + + + An empty file is not allowed. + Tühi fail pole lubatud. + + + The host could not be resolved. + Sellist domeeni ei õnnestunud leida. + + + This value does not match the expected {{ charset }} charset. + See väärtus ei ühti eeldatava tähemärgiga {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + See väärtus ei ole kehtiv BIC-kood. + + + Error + Viga + + + This value is not a valid UUID. + See väärtus ei ole kehtiv UUID. + + + This value should be a multiple of {{ compared_value }}. + See väärtus peaks olema väärtuse {{ compared_value }} kordne. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + See ettevõtte identifitseerimiskood (BIC) ei ole seotud IBAN-iga {{ iban }}. + + + This value should be valid JSON. + See väärtus peaks olema kehtiv JSON. + + + This collection should contain only unique elements. + See kogu peaks sisaldama ainult unikaalseid elemente. + + + This value should be positive. + See väärtus peaks olema positiivne. + + + This value should be either positive or zero. + See väärtus peaks olema kas positiivne või null. + + + This value should be negative. + See väärtus peaks olema negatiivne. + + + This value should be either negative or zero. + See väärtus peaks olema kas negatiivne või null. + + + This value is not a valid timezone. + See väärtus pole kehtiv ajavöönd. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + See parool on lekkinud andmerikkumise korral, seda ei tohi kasutada. Palun kasutage muud parooli. + + + This value should be between {{ min }} and {{ max }}. + See väärtus peaks olema vahemikus {{ min }} kuni {{ max }}. + + + This value is not a valid hostname. + See väärtus pole korrektne domeeninimi. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Selles kogus olevate elementide arv peab olema arvu {{ compared_value }} kordne. + + + This value should satisfy at least one of the following constraints: + See väärtus peab vastama vähemalt ühele järgmistest tingimustest: + + + Each element of this collection should satisfy its own set of constraints. + Kõik väärtused selles kogus peavad vastama oma tingimustele. + + + This value is not a valid International Securities Identification Number (ISIN). + See väärtus pole korrektne ISIN-kood. + + + This value should be a valid expression. + See väärtus pole korrektne avaldis. + + + This value is not a valid CSS color. + See väärtus pole korrektne CSS-i värv. + + + This value is not a valid CIDR notation. + See väärtus pole korrektne CIDR võrguaadress. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Võrgumaski väärtus peaks olema vahemikus {{ min }} kuni {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Failinimi on liiga pikk. See peaks olema {{ filename_max_length }} tähemärk või vähem.|Failinimi on liiga pikk. See peaks olema {{ filename_max_length }} tähemärki või vähem. + + + The password strength is too low. Please use a stronger password. + Parooli tugevus on liiga madal. Palun kasuta tugevamat parooli. + + + This value contains characters that are not allowed by the current restriction-level. + See väärtus sisaldab tähemärke, mida praegune piirangu tase ei luba. + + + Using invisible characters is not allowed. + Mittenähtavate tähemärkide kasutamine ei ole lubatud. + + + Mixing numbers from different scripts is not allowed. + Eri kirjasüsteemidest pärit numbrite koos kasutamine pole lubatud. + + + Using hidden overlay characters is not allowed. + Peidetud tähemärkide kasutamine pole lubatud. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Faili laiend on vigane ({{ extension }}). Lubatud laiendid on {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Tuvastatud teksti kodeering on vigane ({{ detected }}). Lubatud kodeeringud on {{ encodings }}. + + + This value is not a valid MAC address. + See väärtus ei ole kehtiv MAC-aadress. + + + This URL is missing a top-level domain. + Sellel URL-il puudub ülataseme domeen. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + See väärtus on liiga lühike. See peaks sisaldama vähemalt ühte sõna.|See väärtus on liiga lühike. See peaks sisaldama vähemalt {{ min }} sõna. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + See väärtus on liiga pikk. See peaks sisaldama ainult ühte sõna.|See väärtus on liiga pikk. See peaks sisaldama {{ max }} sõna või vähem. + + + This value does not represent a valid week in the ISO 8601 format. + See väärtus ei esinda kehtivat nädalat ISO 8601 formaadis. + + + This value is not a valid week. + See väärtus ei ole kehtiv nädal. + + + This value should not be before week "{{ min }}". + See väärtus ei tohiks olla enne nädalat "{{ min }}". + + + This value should not be after week "{{ max }}". + See väärtus ei tohiks olla pärast nädalat "{{ max }}". + + + This value is not a valid Twig template. + See väärtus ei ole kehtiv Twig'i mall. + + + This file is not a valid video. + See fail ei ole kehtiv video. + + + The size of the video could not be detected. + Video suurust ei õnnestunud tuvastada. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Video laius on liiga suur ({{ width }}px). Lubatud maksimaalne laius on {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Video laius on liiga väike ({{ width }}px). Oodatav minimaalne laius on {{ min_width }} px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Video kõrgus on liiga suur ({{ height }}px). Lubatud maksimaalne kõrgus on {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Video kõrgus on liiga väike ({{ height }}px). Oodatav minimaalne kõrgus on {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Videol on liiga vähe piksleid ({{ pixels }}). Oodatav miinimum on {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Videol on liiga palju piksleid ({{ pixels }}). Eeldatav maksimaalne kogus on {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Video suhe on liiga suur ({{ ratio }}). Lubatud maksimaalne suhe on {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Video kuvasuhe on liiga väike ({{ ratio }}). Eeldatav miinimumsuhe on {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video on ruudukujuline ({{ width }}x{{ height }}px). Ruutvideod pole lubatud. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video on horisontaalses asendis ({{ width }}x{{ height }} px). Horisontaalseid videoid ei ole lubatud. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video on püstsuunas ({{ width }}x{{ height }} px). Püstsuunalised videod pole lubatud. + + + The video file is corrupted. + Videofail on rikutud. + + + The video contains multiple streams. Only one stream is allowed. + Video sisaldab mitu voogu. Lubatud on ainult üks voog. + + + Unsupported video codec "{{ codec }}". + Toetamata videokoodek „{{ codec }}“. + + + Unsupported video container "{{ container }}". + Toetamata videokonteiner "{{ container }}". + + + The image file is corrupted. + Pildifail on rikutud. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Pildil on liiga vähe piksleid ({{ pixels }}). Oodatav miinimum on {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Pildil on liiga palju piksleid ({{ pixels }}). Oodatav maksimaalne hulk on {{ max_pixels }}. + + + This filename does not match the expected charset. + See failinimi ei vasta eeldatavale märgistikule. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.eu.xlf b/lib/symfony/validator/Resources/translations/validators.eu.xlf new file mode 100644 index 0000000000..e498afc261 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.eu.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Balio hau faltsua izan beharko litzateke. + + + This value should be true. + Balio hau egia izan beharko litzateke. + + + This value should be of type {{ type }}. + Balio hau {{ type }} motakoa izan beharko litzateke. + + + This value should be blank. + Balio hau hutsik egon beharko litzateke. + + + The value you selected is not a valid choice. + Hautatu duzun balioa ez da aukera egoki bat. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Gutxienez aukera {{ limit }} hautatu behar duzu.|Gutxienez {{ limit }} aukera hautatu behar dituzu. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Gehienez aukera {{ limit }} hautatu behar duzu.|Gehienez {{ limit }} aukera hautatu behar dituzu. + + + One or more of the given values is invalid. + Emandako balioetatik gutxienez bat ez da egokia. + + + This field was not expected. + Eremu hau ez zen espero. + + + This field is missing. + Eremu hau falta da. + + + This value is not a valid date. + Balio hau ez da data egoki bat. + + + This value is not a valid datetime. + Balio hau ez da data-ordu egoki bat. + + + This value is not a valid email address. + Balio hau ez da posta elektroniko egoki bat. + + + The file could not be found. + Ezin izan da fitxategia aurkitu. + + + The file is not readable. + Fitxategia ez da irakurgarria. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Fitxategia handiegia da ({{ size }} {{ suffix }}). Baimendutako tamaina handiena {{ limit }} {{ suffix }} da. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Fitxategiaren mime mota ez da egokia ({{ type }}). Hauek dira baimendutako mime motak: {{ types }}. + + + This value should be {{ limit }} or less. + Balio hau gehienez {{ limit }} izan beharko litzateke. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Balio hau luzeegia da. Gehienez karaktere {{ limit }} eduki beharko luke.|Balio hau luzeegia da. Gehienez {{ limit }} karaktere eduki beharko lituzke. + + + This value should be {{ limit }} or more. + Balio hau gutxienez {{ limit }} izan beharko litzateke. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Balio hau motzegia da. Karaktere {{ limit }} gutxienez eduki beharko luke.|Balio hau motzegia da. Gutxienez {{ limit }} karaktere eduki beharko lituzke. + + + This value should not be blank. + Balio hau ez litzateke hutsik egon behar. + + + This value should not be null. + Balio hau ez litzateke nulua izan behar. + + + This value should be null. + Balio hau nulua izan beharko litzateke. + + + This value is not valid. + Balio hau ez da egokia. + + + This value is not a valid time. + Balio hau ez da ordu egoki bat. + + + This value is not a valid URL. + Balio hau ez da baliabideen kokatzaile uniforme (URL) egoki bat. + + + The two values should be equal. + Bi balioak berdinak izan beharko lirateke. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Fitxategia handiegia da. Baimendutako tamaina handiena {{ limit }} {{ suffix }} da. + + + The file is too large. + Fitxategia handiegia da. + + + The file could not be uploaded. + Ezin izan da fitxategia igo. + + + This value should be a valid number. + Balio hau zenbaki egoki bat izan beharko litzateke. + + + This file is not a valid image. + Fitxategi hau ez da irudi egoki bat. + + + This value is not a valid IP address. + Balio hau ez da IP helbide baliozko bat. + + + This value is not a valid language. + Balio hau ez da hizkuntza egoki bat. + + + This value is not a valid locale. + Balio hau ez da kokapen egoki bat. + + + This value is not a valid country. + Balio hau ez da herrialde egoki bat. + + + This value is already used. + Balio hau jadanik erabilia izan da. + + + The size of the image could not be detected. + Ezin izan da irudiaren tamaina detektatu. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Irudiaren zabalera handiegia da ({{ width }}px). Onartutako gehienezko zabalera {{ max_width }}px dira. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Irudiaren zabalera txikiegia da ({{ width }}px). Onartutako gutxieneko zabalera {{ min_width }}px dira. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Irudiaren altuera handiegia da ({{ height }}px). Onartutako gehienezko altuera {{ max_height }}px dira. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Irudiaren altuera txikiegia da ({{ height }}px). Onartutako gutxieneko altuera {{ min_height }}px dira. + + + This value should be the user's current password. + Balio hau uneko erabiltzailearen pasahitza izan beharko litzateke. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Balio honek zehazki karaktere {{ limit }} izan beharko luke.|Balio honek zehazki {{ limit }} karaktere izan beharko lituzke. + + + The file was only partially uploaded. + Fitxategiaren zati bat bakarrik igo da. + + + No file was uploaded. + Ez da fitxategirik igo. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Ez da aldi baterako karpetarik konfiguratu php.ini-n, edo konfiguratutako karpeta ez da existitzen. + + + Cannot write temporary file to disk. + Ezin izan da aldi baterako fitxategia diskoan idatzi. + + + A PHP extension caused the upload to fail. + PHP luzapen batek igoeraren hutsa eragin du. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Bilduma honek gutxienez elementu {{ limit }} eduki beharko luke.|Bilduma honek gutxienez {{ limit }} elementu eduki beharko lituzke. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Bilduma honek gehienez elementu {{ limit }} eduki beharko luke.|Bilduma honek gehienez {{ limit }} elementu eduki beharko lituzke. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Bilduma honek zehazki elementu {{ limit }} eduki beharko luke.|Bilduma honek zehazki {{ limit }} elementu eduki beharko lituzke. + + + Invalid card number. + Txartel zenbaki baliogabea. + + + Unsupported card type or invalid card number. + Txartel mota onartezina edo txartel zenbaki baliogabea. + + + This value is not a valid International Bank Account Number (IBAN). + Balio hau ez da Nazioarteko Banku Kontu Zenbaki (IBAN) baliozko bat. + + + This value is not a valid ISBN-10. + Balio hau ez da onartutako ISBN-10 bat. + + + This value is not a valid ISBN-13. + Balio hau ez da onartutako ISBN-13 bat. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Balio hau ez da onartutako ISBN-10 edo ISBN-13 bat. + + + This value is not a valid ISSN. + Balio hau ez da onartutako ISSN bat. + + + This value is not a valid currency. + Balio hau ez da baliozko moneta bat. + + + This value should be equal to {{ compared_value }}. + Balio hau {{ compared_value }}-(r)en berbera izan beharko litzateke. + + + This value should be greater than {{ compared_value }}. + Balio hau {{ compared_value }} baino handiagoa izan beharko litzateke. + + + This value should be greater than or equal to {{ compared_value }}. + Balio hau {{ compared_value }}-(r)en berdina edota handiagoa izan beharko litzateke. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Balio hau {{ compared_value_type }} {{ compared_value }}-(r)en berbera izan beharko litzateke. + + + This value should be less than {{ compared_value }}. + Balio hau {{ compared_value }} baino txikiagoa izan beharko litzateke. + + + This value should be less than or equal to {{ compared_value }}. + Balio hau {{ compared_value }}-(r)en berdina edota txikiagoa izan beharko litzateke. + + + This value should not be equal to {{ compared_value }}. + Balio hau ez litzateke {{ compared_value }}-(r)en berdina izan behar. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Balio hau ez litzateke {{ compared_value_type }} {{ compared_value }}-(r)en berbera izan behar. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Irudiaren proportzioa oso handia da ({{ ratio }}). Onartutako proportzio handienda {{ max_ratio }} da. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Irudiaren proportzioa oso txikia da ({{ ratio }}). Onartutako proportzio txikiena {{ min_ratio }} da. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Irudia karratua da ({{ width }}x{{ height }}px). Karratuak diren irudiak ez dira onartzen. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Irudia horizontalki bideratua dago ({{ width }}x{{ height }}px). Horizontalki bideratutako irudiak ez dira onartzen. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Irudia bertikalki bideratua dago ({{ width }}x{{ height }}px). Bertikalki bideratutako irudiak ez dira onartzen. + + + An empty file is not allowed. + Hutsik dagoen fitxategia ez da onartzen. + + + The host could not be resolved. + Host-a ezin da ebatzi. + + + This value does not match the expected {{ charset }} charset. + Balio honen karaktere kodea ez da esperotakoa {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Balio hau ez da Negozioaren Identifikazio Kode (BIC) baliozko bat. + + + Error + Errore + + + This value is not a valid UUID. + Balio hau ez da UUID baliozko bat. + + + This value should be a multiple of {{ compared_value }}. + Balio honek {{ compared_value }}-ren multiploa izan beharko luke. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Banku Identifikazioko Kode hau ez dago lotuta {{ IBAN }} IBAN-rekin. + + + This value should be valid JSON. + Balio honek baliozko JSON bat izan behar luke. + + + This collection should contain only unique elements. + Bilduma honek elementu bakarrak soilik izan beharko lituzke. + + + This value should be positive. + Balio honek positiboa izan beharko luke. + + + This value should be either positive or zero. + Balio honek positiboa edo zero izan behar luke. + + + This value should be negative. + Balio honek negatiboa izan behar luke. + + + This value should be either negative or zero. + Balio honek negatiboa edo zero izan behar luke. + + + This value is not a valid timezone. + Balio hori ez da baliozko ordu-eremua. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Pasahitz hori ezin da erabili, beste gune eta aplikazio batzuetako segurtasun-akatsei esker lortutako pasahitz publikoen zerrendan sartuta dagoelako. Mesedez, erabili beste pasahitz bat. + + + This value should be between {{ min }} and {{ max }}. + Balio honek {{ min }} eta {{ max }} artean egon behar luke. + + + This value is not a valid hostname. + Balio hori ez da ostalari-izen onargarria. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Bilduma honetako elementu-kopuruak {{ compared_value }}-ren multiploa izan behar luke. + + + This value should satisfy at least one of the following constraints: + Balio honek, gutxienez, murrizketa hauetako bat bete behar du: + + + Each element of this collection should satisfy its own set of constraints. + Bilduma honetako elementu bakoitzak bere murriztapen-multzoa bete behar du. + + + This value is not a valid International Securities Identification Number (ISIN). + Balio hori ez da baliozko baloreen nazioarteko identifikazio-zenbaki bat (ISIN). + + + This value should be a valid expression. + Balio hori baliozko adierazpena izan beharko litzateke. + + + This value is not a valid CSS color. + Balio hori ez da baliozko CSS kolorea. + + + This value is not a valid CIDR notation. + Balio hori ez da baliozko CIDR notazioa. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Maskararen balioa {{ min }} eta {{ max }} artekoa izan beharko litzateke. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Fitxategiaren izena luzeegia da. Karaktere {{ filename_max_length }} edo gutxiago izan beharko lituzke.|Fitxategiaren izena luzeegia da. {{ filename_max_length }} karaktere edo gutxiago izan beharko lituzke. + + + The password strength is too low. Please use a stronger password. + Pasahitzaren sendotasuna baxuegia da. Mesedez, erabili pasahitz seguruagoa. + + + This value contains characters that are not allowed by the current restriction-level. + Egungo murrizte-mailak ez du balio honek dituen karaktereak onartzen. + + + Using invisible characters is not allowed. + Ez da onartzen karaktere ikusezinak erabiltzea. + + + Mixing numbers from different scripts is not allowed. + Ez da onartzen script ezberdinetako zenbakiak nahastea + + + Using hidden overlay characters is not allowed. + Ez da onartzen karaktere gainjarri ezkutuen erabilera. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Fitxategiaren luzapena ez da zuzena ({{ extension }}). Baimendutako luzapenak hauek dira: {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Detektatutako karaktere-kodetzea ez da zuzena ({{ detected }}). Baimendutako kodetzeak hauek dira: {{ encodings }}. + + + This value is not a valid MAC address. + Balio hau ez da MAC helbide baliozko bat. + + + This URL is missing a top-level domain. + URL honek ez du goi-mailako domeinurik. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Balio hau oso laburra da. Gutxienez hitz bat izan behar du.|Balio hau oso laburra da. Gutxienez {{ min }} hitz izan behar ditu. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Balio hau oso luzea da. Hitz bat bakarrik izan behar du.|Balio hau oso luzea da. {{ max }} hitz edo gutxiago izan behar ditu. + + + This value does not represent a valid week in the ISO 8601 format. + Balio honek ez du ISO 8601 formatuan aste baliozko bat adierazten. + + + This value is not a valid week. + Balio hau ez da aste balioduna. + + + This value should not be before week "{{ min }}". + Balio hau ez luke aste "{{ min }}" baino lehenagokoa izan behar. + + + This value should not be after week "{{ max }}". + Balio hau ez luke astearen "{{ max }}" ondoren egon behar. + + + This value is not a valid Twig template. + Balio hau ez da Twig txantiloi baliozko bat. + + + This file is not a valid video. + Fitxategi hau ez da baliozko bideo bat. + + + The size of the video could not be detected. + Ezin izan da bideoaren tamaina detektatu. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Bideoaren zabalera handiegia da ({{ width }}px). Baimendutako gehieneko zabalera {{ max_width }}px da. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Bideoaren zabalera txikiegia da ({{ width }}px). Gutxieneko espero den zabalera {{ min_width }}px da. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Bideoaren altuera handiegia da ({{ height }}px). Onartutako gehienezko altuera {{ max_height }}px da. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Bideoaren altuera txikiegia da ({{ height }}px). Espero den gutxieneko altuera {{ min_height }}px da. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Bideoak pixel gutiegi ditu ({{ pixels }}). Gutxieneko espero den kopurua {{ min_pixels }} da. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Bideoak pixel gehiegi ditu ({{ pixels }}). Espero den gehieneko kopurua {{ max_pixels }} da. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Bideoaren erlazioa handiegia da ({{ ratio }}). Onartutako gehieneko erlazioa {{ max_ratio }} da. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Bideoaren erlazioa txikiegia da ({{ ratio }}). Espero den gutxieneko erlazioa {{ min_ratio }} da. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Bideoa karratua da ({{ width }}x{{ height }}px). Bideo karratuak ez dira onartzen. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Bideoa paisaia orientazioan dago ({{ width }}x{{ height }} px). Paisaia-orientazioko bideoak ez daude baimenduta. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Bideoa bertikal orientatuta dago ({{ width }}x{{ height }} px). Orientazio bertikaleko bideoak ez dira onartzen. + + + The video file is corrupted. + Bideo fitxategia hondatuta dago. + + + The video contains multiple streams. Only one stream is allowed. + Bideoak korronte anitz ditu. Korronte bakarra onartzen da. + + + Unsupported video codec "{{ codec }}". + Bideo kodek onartugabea "{{ codec }}". + + + Unsupported video container "{{ container }}". + Onartzen ez den bideo edukiontzia "{{ container }}". + + + The image file is corrupted. + Irudi fitxategia hondatuta dago. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Irudiak pixelen kopuru gutiegi du ({{ pixels }}). Espero den gutxienekoa {{ min_pixels }} da. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Irudiak pixel gehiegi ditu ({{ pixels }}). Espero den gehienezko kopurua {{ max_pixels }} da. + + + This filename does not match the expected charset. + Fitxategi-izen honek ez du espero zen karaktere multzoarekin bat egiten. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.fa.xlf b/lib/symfony/validator/Resources/translations/validators.fa.xlf new file mode 100644 index 0000000000..2e75167995 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.fa.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + این مقدار باید نادرست (False) باشد. + + + This value should be true. + این مقدار باید درست (True) باشد. + + + This value should be of type {{ type }}. + این مقدار باید از نوع {{ type }} باشد. + + + This value should be blank. + این مقدار باید خالی باشد. + + + The value you selected is not a valid choice. + مقدار انتخاب شده یک گزینه معتبر نمی‌باشد. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + شما باید حداقل {{ limit }} گزینه انتخاب نمایید.|شما باید حداقل {{ limit }} گزینه انتخاب نمایید. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + شما باید حداکثر {{ limit }} گزینه انتخاب نمایید.|شما باید حداکثر {{ limit }} گزینه انتخاب نمایید. + + + One or more of the given values is invalid. + یک یا چند مقدار داده شده نامعتبر است. + + + This field was not expected. + این ورودی مورد انتظار نبود. + + + This field is missing. + این فیلد وارد نشده است. + + + This value is not a valid date. + این مقدار یک تاریخ معتبر نمی‌باشد. + + + This value is not a valid datetime. + این مقدار یک تاریخ و زمان معتبر نمی‌باشد. + + + This value is not a valid email address. + این یک آدرس رایانامه (ایمیل) معتبر نمی‌باشد. + + + The file could not be found. + فایل یافت نشد. + + + The file is not readable. + فایل قابل خواندن نیست. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + فایل بیش از اندازه بزرگ است({{ size }} {{ suffix }}). بیشینه (حداکثر) اندازه مجاز برابر با {{ limit }} {{ suffix }} می‌باشد. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + نوع mime این فایل نامعتبر است({{ type }}). انواع mime مجاز {{ types }} هستند. + + + This value should be {{ limit }} or less. + این مقدار باید کوچکتر و یا مساوی {{ limit }} باشد. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + این مقدار بسیار طولانی است. باید دارای {{limit}} کاراکتر یا کمتر باشد. | این مقدار بسیار طولانی است. باید دارای {{limit}} کاراکتر یا کمتر باشد. + + + This value should be {{ limit }} or more. + این مقدار باید بزرگتر و یا مساوی {{ limit }} باشد. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + این مقدار بیش از اندازه کوتاه است. باید {{ limit }} کاراکتر یا بیشتر داشته باشد.|این مقدار بیش از اندازه کوتاه است. باید {{ limit }} کاراکتر یا بیشتر داشته باشد. + + + This value should not be blank. + این مقدار نباید خالی باشد. + + + This value should not be null. + این مقدار نباید خالی باشد. + + + This value should be null. + این مقدار باید خالی باشد. + + + This value is not valid. + این مقدار معتبر نمی‌باشد. + + + This value is not a valid time. + این مقدار یک زمان معتبر نمی‌باشد. + + + This value is not a valid URL. + این مقدار شامل یک URL معتبر نمی‌باشد. + + + The two values should be equal. + دو مقدار باید با یکدیگر برابر باشند. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + فایل بیش از اندازه بزرگ است. بیشینه (حداکثر) اندازه مجاز {{ limit }} {{ suffix }} است. + + + The file is too large. + فایل بیش از اندازه بزرگ است. + + + The file could not be uploaded. + بارگذاری فایل با شکست مواجه گردید. + + + This value should be a valid number. + این مقدار باید یک عدد معتبر باشد. + + + This file is not a valid image. + این فایل یک تصویر معتبر نمی‌باشد. + + + This value is not a valid IP address. + این مقدار یه آدرس آی‌پی معتبر نمی‌باشد. + + + This value is not a valid language. + این مقدار یک زبان معتبر نمی‌باشد. + + + This value is not a valid locale. + این مقدار یک محل (locale) معتبر نمی‌باشد. + + + This value is not a valid country. + این مقدار یک کشور معتبر نمی‌باشد. + + + This value is already used. + این مقدار قبلاً استفاده شده است. + + + The size of the image could not be detected. + اندازه تصویر قابل شناسایی نمی‌باشد. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + عرض تصویر بسیار بزرگ است({{ width }}px). بیشینه (حداکثر) عرض مجاز {{ max_width }}px می‌باشد. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + عرض تصویر بسیار کوچک است({{ width }}px). کمینه (حداقل) عرض مورد انتظار {{ min_width }}px می‌باشد. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + ارتفاع تصویر بسیار بزرگ است({{ height }}px). بیشینه (حداکثر) ارتفاع مجاز {{ max_height }}px می‌باشد. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + ارتفاع تصویر بسیار کوچک است({{ height }}px). کمینه (حداقل) ارتفاع مورد انتظار {{ min_height }}px می‌باشد. + + + This value should be the user's current password. + این مقدار باید رمزعبور فعلی کاربر باشد. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + این مقدار باید دقیقا {{ limit }} کاراکتر داشته باشد.| این مقدار باید دقیقا {{ limit }} کاراکتر داشته باشد. + + + The file was only partially uploaded. + فایل به صورت جزئی بارگذاری گردیده است. + + + No file was uploaded. + هیچ فایلی بارگذاری نشد. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + هیچ پوشه موقتی در php.ini پیکربندی نشده است، یا پوشه پیکربندی شده وجود ندارد. + + + Cannot write temporary file to disk. + فایل موقتی را نمی‌توان در دیسک نوشت. + + + A PHP extension caused the upload to fail. + یک افزونه PHP باعث شد بارگذاری ناموفق باشد. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + این مجموعه باید حاوی {{ limit }} عنصر یا بیشتر باشد.|این مجموعه باید حاوی {{ limit }} عنصر یا بیشتر باشد. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + این مجموعه باید حاوی {{ limit }} عنصر یا کمتر باشد.|این مجموعه باید حاوی {{ limit }} عنصر یا کمتر باشد. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + این مجموعه باید دقیقا حاوی {{ limit }} عنصر باشد.|این مجموعه باید دقیقا حاوی {{ limit }} عنصر باشد. + + + Invalid card number. + شماره کارت نامعتبر است. + + + Unsupported card type or invalid card number. + نوع کارت پشتیبانی نمی‌شود و یا شماره کارت نامعتبر می‌باشد. + + + This value is not a valid International Bank Account Number (IBAN). + این مقدار یک شماره شبای معتبر نمی‌باشد. + + + This value is not a valid ISBN-10. + این مقدار یک ISBN-10 معتبر نمی‌باشد. + + + This value is not a valid ISBN-13. + این مقدار یک ISBN-13 معتبر نمی‌باشد. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + این مقدار یک ISBN-10 معتبر و یا ISBN-13 معتبر نمی‌باشد. + + + This value is not a valid ISSN. + این مقدار یک ISSN معتبر نمی‌باشد. + + + This value is not a valid currency. + این مقدار یک واحد پول معتبر نمی‌باشد. + + + This value should be equal to {{ compared_value }}. + این مقدار باید برابر با {{ compared_value }} باشد. + + + This value should be greater than {{ compared_value }}. + این مقدار باید از {{ compared_value }} بیشتر باشد. + + + This value should be greater than or equal to {{ compared_value }}. + این مقدار باید بزرگتر و یا مساوی با {{ compared_value }} باشد. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + این مقدار باید برابر {{ compared_value_type }} {{ compared_value }} باشد. + + + This value should be less than {{ compared_value }}. + این مقدار باید کمتر از {{ compared_value }} باشد. + + + This value should be less than or equal to {{ compared_value }}. + این مقدار باید کمتر و یا مساوی با {{ compared_value }} باشد. + + + This value should not be equal to {{ compared_value }}. + این مقدار نباید با {{ compared_value }} برابر باشد. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + این مقدار نباید برابر {{ compared_value_type }} {{ compared_value }} باشد. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + ابعاد ({{ ratio }}) عکس بیش از حد بزرگ است. بیشینه (حداکثر) ابعاد مجاز {{ max_ratio }} می‌باشد. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + ابعاد ({{ ratio }}) عکس بیش از حد کوچک است. کمینه (حداقل) ابعاد مورد انتظار {{ min_ratio }} می‌باشد. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + این تصویر یک مربع ({{ width }}x{{ height }}px) می‌باشد. تصاویر مربع شکل مجاز نمی‌باشند. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + این تصویر افقی ({{ width }}x{{ height }}px) می‌باشد. تصاویر افقی مجاز نمی‌باشند. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + این تصویر عمودی ({{ width }}x{{ height }}px) می‌باشد. تصاویر عمودی مجاز نمی‌باشند. + + + An empty file is not allowed. + فایل خالی مجاز نمی‌باشد. + + + The host could not be resolved. + میزبان (Host) شناسایی نشد. + + + This value does not match the expected {{ charset }} charset. + این مقدار مطابق charset مورد انتظار {{ charset }} نمی باشد. + + + This value is not a valid Business Identifier Code (BIC). + این مقدار یک کد شناسه کسب‌وکار (BIC) معتبر نیست. + + + Error + خطا + + + This value is not a valid UUID. + این مقدار یک UUID معتبر نیست. + + + This value should be a multiple of {{ compared_value }}. + این مقدار باید چند برابر {{ compared_value }} باشد. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + این کد شناسایی کسب‌و‌کار (BIC) با شماره حساب بانکی بین‌المللی (IBAN) {{ iban }} مرتبط نیست. + + + This value should be valid JSON. + این مقدار باید یک JSON معتبر باشد. + + + This collection should contain only unique elements. + این مجموعه باید فقط حاوی عناصر یکتا باشد. + + + This value should be positive. + این مقدار باید مثبت باشد. + + + This value should be either positive or zero. + این مقدار باید مثبت یا صفر باشد. + + + This value should be negative. + این مقدار باید منفی باشد. + + + This value should be either negative or zero. + این مقدار باید منفی یا صفر باشد. + + + This value is not a valid timezone. + این مقدار یک منطقه‌زمانی (timezone) معتبر نیست. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + این رمزعبور در یک رخنه‌ی اطلاعاتی نشت کرده است. لطفاً از یک رمزعبور دیگر استفاده کنید. + + + This value should be between {{ min }} and {{ max }}. + این مقدار باید بین {{ min }} و {{ max }} باشد + + + This value is not a valid hostname. + این مقدار یک hostname معتبر نیست. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + تعداد عناصر این مجموعه باید ضریبی از {{ compared_value }} باشد. + + + This value should satisfy at least one of the following constraints: + این مقدار باید حداقل یکی از محدودیت‌های زیر را ارضا کند: + + + Each element of this collection should satisfy its own set of constraints. + هر یک از عناصر این مجموعه باید دسته محدودیت‌های خودش را ارضا کند. + + + This value is not a valid International Securities Identification Number (ISIN). + این مقدار یک شماره شناسایی بین‌المللی اوراق بهادار (ISIN) معتبر نیست. + + + This value should be a valid expression. + این مقدار باید یک عبارت معتبر باشد. + + + This value is not a valid CSS color. + این مقدار یک رنگ معتبر در CSS نیست. + + + This value is not a valid CIDR notation. + این مقدار یک نماد معتبر در CIDR نیست. + + + The value of the netmask should be between {{ min }} and {{ max }}. + مقدار ماسک شبکه (NetMask) باید بین {{ min }} و {{ max }} باشد. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + نام فایل طولانی است. نام فایل باید {{ filename_max_length }} کاراکتر یا کمتر باشد.|نام فایل طولانی است. نام فایل باید {{ filename_max_length }} کاراکتر یا کمتر باشد. + + + The password strength is too low. Please use a stronger password. + رمز عبور ضعیف است. لطفا از رمز عبور قوی‌تری استفاده کنید. + + + This value contains characters that are not allowed by the current restriction-level. + این مقدار حاوی کاراکترهایی است که در سطح محدودیت فعلی مجاز نیستند. + + + Using invisible characters is not allowed. + استفاده از کاراکترهای نامرئی مجاز نمی‌باشد. + + + Mixing numbers from different scripts is not allowed. + مخلوط کردن اعداد از اسکریپت های مختلف مجاز نیست. + + + Using hidden overlay characters is not allowed. + استفاده از کاراکترهای همپوشانی پنهان (hidden overlay characters) مجاز نیست. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + پسوند فایل ({{ extension }}) نامعتبر است. پسوندهای مجاز {{ extensions }} هستند. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + رمزگذاری کاراکتر تشخیص داده شده ({{ detected }}) نامعتبر است. رمزگذاری‌های مجاز {{ encodings }} هستند. + + + This value is not a valid MAC address. + این مقدار یک آدرس MAC معتبر نیست. + + + This URL is missing a top-level domain. + این آدرس دارای دامنه نمی‌باشد. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + این مقدار بسیار کوتاه است. باید حداقل یک کلمه داشته باشد.|این مقدار بسیار کوتاه است. باید حداقل {{ min }} کلمه داشته باشد. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + این مقدار بیش از حد طولانی است. باید فقط یک کلمه باشد.|این مقدار بیش از حد طولانی است. باید حداکثر {{ max }} کلمه داشته باشد. + + + This value does not represent a valid week in the ISO 8601 format. + این مقدار یک هفته معتبر در قالب ISO 8601 را نشان نمی‌دهد. + + + This value is not a valid week. + این مقدار یک هفته معتبر نیست. + + + This value should not be before week "{{ min }}". + این مقدار نباید قبل از هفته "{{ min }}" باشد. + + + This value should not be after week "{{ max }}". + این مقدار نباید بعد از هفته "{{ max }}" باشد. + + + This value is not a valid Twig template. + این مقدار یک قالب معتبر Twig نیست. + + + This file is not a valid video. + این فایل یک ویدیوی معتبر نیست. + + + The size of the video could not be detected. + اندازه ویدئو قابل تشخیص نبود. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + عرض ویدئو خیلی زیاد است ({{ width }}px). حداکثر عرض مجاز {{ max_width }}px است. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + عرض ویدئو خیلی کم است ({{ width }}px). حداقل عرض مورد انتظار {{ min_width }} پیکسل است. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + ارتفاع ویدیو خیلی زیاد است ({{ height }}px). حداکثر ارتفاع مجاز {{ max_height }}px است. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + ارتفاع ویدیو خیلی کم است ({{ height }}px). حداقل ارتفاع مورد انتظار {{ min_height }}px است. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + ویدیو پیکسل‌های بسیار کمی دارد ({{ pixels }}). حداقل مقدار مورد انتظار {{ min_pixels }} است. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + ویدئو پیکسل‌های زیادی دارد ({{ pixels }}). حداکثر مقدار مورد انتظار {{ max_pixels }} است. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + نسبت ویدیو خیلی بزرگ است ({{ ratio }}). حداکثر نسبت مجاز {{ max_ratio }} است. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + نسبت ویدیو خیلی کوچک است ({{ ratio }}). نسبت حداقل مورد انتظار {{ min_ratio }} است. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + ویدئو مربعی است ({{ width }}x{{ height }}px). ویدئوهای مربعی مجاز نیستند. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + ویدیو به صورت افقی است ({{ width }}x{{ height }} پیکسل). ویدیوهای افقی مجاز نیستند. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + ویدیو با جهت عمودی است ({{ width }}x{{ height }}px). ویدیوهای با جهت عمودی مجاز نیستند. + + + The video file is corrupted. + فایل ویدیو خراب است. + + + The video contains multiple streams. Only one stream is allowed. + ویدئو شامل چندین استریم است. فقط یک استریم مجاز است. + + + Unsupported video codec "{{ codec }}". + کُدک ویدیویی پشتیبانی نمی‌شود «{{ codec }}». + + + Unsupported video container "{{ container }}". + ظرف ویدئو پشتیبانی نمی‌شود "{{ container }}". + + + The image file is corrupted. + فایل تصویر خراب است. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + تصویر پیکسل‌های بسیار کمی دارد ({{ pixels }}). حداقل مقدار مورد انتظار {{ min_pixels }} است. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + تصویر پیکسل‌های زیادی دارد ({{ pixels }}). حداکثر مقدار مورد انتظار {{ max_pixels }} است. + + + This filename does not match the expected charset. + نام این فایل با مجموعه نویسه‌های مورد انتظار مطابقت ندارد. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.fi.xlf b/lib/symfony/validator/Resources/translations/validators.fi.xlf new file mode 100644 index 0000000000..04d99cf57f --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.fi.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Arvon tulee olla epätosi. + + + This value should be true. + Arvon tulee olla tosi. + + + This value should be of type {{ type }}. + Arvon tulee olla tyyppiä {{ type }}. + + + This value should be blank. + Arvon tulee olla tyhjä. + + + The value you selected is not a valid choice. + Arvon tulee olla yksi annetuista vaihtoehdoista. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Sinun tulee valita vähintään yksi vaihtoehto.|Sinun tulee valita vähintään {{ limit }} vaihtoehtoa. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Sinun tulee valita enintään yksi vaihtoehto.|Sinun tulee valita enintään {{ limit }} vaihtoehtoa. + + + One or more of the given values is invalid. + Yksi tai useampi annetuista arvoista on virheellinen. + + + This field was not expected. + Tätä kenttää ei odotettu. + + + This field is missing. + Tämä kenttä puuttuu. + + + This value is not a valid date. + Annettu arvo ei ole kelvollinen päivämäärä. + + + This value is not a valid datetime. + Annettu arvo ei ole kelvollinen päivämäärä ja kellonaika. + + + This value is not a valid email address. + Annettu arvo ei ole kelvollinen sähköpostiosoite. + + + The file could not be found. + Tiedostoa ei löydy. + + + The file is not readable. + Tiedostoa ei voi lukea. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Tiedostonkoko ({{ size }} {{ suffix }}) on liian iso. Suurin sallittu tiedostonkoko on {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Tiedostotyyppi ({{ type }}) on virheellinen. Sallittuja tiedostotyyppejä ovat {{ types }}. + + + This value should be {{ limit }} or less. + Arvon tulee olla {{ limit }} tai vähemmän. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Liian pitkä syöte. Syöte saa olla enintään yhden merkin.|Liian pitkä syöte. Syöte saa olla enintään {{ limit }} merkkiä. + + + This value should be {{ limit }} or more. + Arvon tulee olla {{ limit }} tai enemmän. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Liian lyhyt syöte. Syötteen tulee olla vähintään yhden merkin.|Liian lyhyt syöte. Syötteen tulee olla vähintään {{ limit }} merkkiä. + + + This value should not be blank. + Kenttä ei voi olla tyhjä. + + + This value should not be null. + Annettu arvo ei voi olla null. + + + This value should be null. + Annetun arvon tulee olla null. + + + This value is not valid. + Virheellinen arvo. + + + This value is not a valid time. + Annettu arvo ei ole kelvollinen kellonaika. + + + This value is not a valid URL. + Annettu arvo ei ole kelvollinen URL-osoite. + + + The two values should be equal. + Kahden annetun arvon tulee olla samat. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Annettu tiedosto on liian iso. Suurin sallittu tiedostokoko on {{ limit }} {{ suffix }}. + + + The file is too large. + Tiedosto on liian iso. + + + The file could not be uploaded. + Tiedoston siirto epäonnistui. + + + This value should be a valid number. + Arvon tulee olla numero. + + + This file is not a valid image. + Tiedosto ei ole kelvollinen kuva. + + + This value is not a valid IP address. + Tämä arvo ei ole kelvollinen IP-osoite. + + + This value is not a valid language. + Arvo ei ole kelvollinen kieli. + + + This value is not a valid locale. + Arvo ei ole kelvollinen kieli- ja alueasetus (locale). + + + This value is not a valid country. + Arvo ei ole kelvollinen maa. + + + This value is already used. + Arvo on jo käytetty. + + + The size of the image could not be detected. + Kuvan kokoa ei tunnistettu. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Kuva on liian leveä ({{ width }} px). Leveyden tulee olla enintään {{ max_width }} px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Kuva on liian kapea ({{ width }} px). Leveyden tulee olla vähintään {{ min_width }} px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Kuva on liian korkea ({{ width }} px). Korkeuden tulee olla enintään {{ max_width }} px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Kuva on liian matala ({{ height }} px). Korkeuden tulee olla vähintään {{ min_height }} px. + + + This value should be the user's current password. + Arvon tulee olla käyttäjän tämänhetkinen salasana. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Arvon tulee olla tasan yhden merkin pituinen.|Arvon tulee olla tasan {{ limit }} merkin pituinen. + + + The file was only partially uploaded. + Tiedosto ladattiin vain osittain. + + + No file was uploaded. + Tiedostoa ei ladattu. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Väliaikaista kansiota ei ole määritetty php.ini:ssä, tai määritetty kansio ei ole olemassa. + + + Cannot write temporary file to disk. + Väliaikaistiedostoa ei voitu kirjoittaa levylle. + + + A PHP extension caused the upload to fail. + PHP-laajennoksen vuoksi tiedoston lataus epäonnistui. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Tässä ryhmässä tulee olla vähintään yksi elementti.|Tässä ryhmässä tulee olla vähintään {{ limit }} elementtiä. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Tässä ryhmässä tulee olla enintään yksi elementti.|Tässä ryhmässä tulee olla enintään {{ limit }} elementtiä. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Tässä ryhmässä tulee olla tasan yksi elementti.|Tässä ryhmässä tulee olla tasan {{ limit }} elementtiä. + + + Invalid card number. + Virheellinen korttinumero. + + + Unsupported card type or invalid card number. + Tätä korttityyppiä ei tueta tai korttinumero on virheellinen. + + + This value is not a valid International Bank Account Number (IBAN). + Tämä arvo ei ole kelvollinen kansainvälinen pankkitilinumero (IBAN). + + + This value is not a valid ISBN-10. + Arvo ei ole kelvollinen ISBN-10. + + + This value is not a valid ISBN-13. + Arvo ei ole kelvollinen ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Arvo ei ole kelvollinen ISBN-10 eikä ISBN-13. + + + This value is not a valid ISSN. + Arvo ei ole kelvollinen ISSN. + + + This value is not a valid currency. + Arvo ei ole kelvollinen valuutta. + + + This value should be equal to {{ compared_value }}. + Arvo ei ole sama kuin {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Arvon tulee olla suurempi kuin {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Arvon tulee olla suurempi tai yhtä suuri kuin {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Arvon tulee olla sama kuin {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Arvon tulee olla pienempi kuin {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Arvon tulee olla pienempi tai yhtä suuri kuin {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Arvon ei tule olla sama kuin {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Arvon ei tule olla sama kuin {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Kuvasuhde on liian suuri ({{ ratio }}). Suurin sallittu suhde on {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Kuvasuhde on liian pieni ({{ ratio }}). Pienin sallittu suhde on {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Kuva on neliö ({{ width }}x{{ height }} px). Neliönmuotoiset kuvat eivät ole sallittuja. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Kuva on vaakasuuntainen ({{ width }}x{{ height }} px). Vaakasuuntaiset kuvat eivät ole sallittuja. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Kuva on pystysuuntainen ({{ width }}x{{ height }} px). Pystysuuntaiset kuvat eivät ole sallittuja. + + + An empty file is not allowed. + Tiedosto ei saa olla tyhjä. + + + The host could not be resolved. + Palvelimeen ei saatu yhteyttä. + + + This value does not match the expected {{ charset }} charset. + Arvo ei vastaa odotettua merkistöä {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Tämä arvo ei ole kelvollinen liiketoiminnan tunnistekoodi (BIC). + + + Error + Virhe + + + This value is not a valid UUID. + Tämä arvo ei ole kelvollinen UUID. + + + This value should be a multiple of {{ compared_value }}. + Tämän arvon tulee olla luvun {{ compared_value }} kerrannainen. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Tätä yritystunnusta (BIC) ei ole liitetty IBAN-tilinumeroon {{ iban }}. + + + This value should be valid JSON. + Arvon tulee olla kelvollinen JSON. + + + This collection should contain only unique elements. + Ryhmän tulee sisältää vain yksilöllisiä arvoja. + + + This value should be positive. + Arvon tulee olla positiivinen. + + + This value should be either positive or zero. + Arvon tulee olla joko positiivinen tai nolla. + + + This value should be negative. + Arvon tulee olla negatiivinen. + + + This value should be either negative or zero. + Arvon tulee olla joko negatiivinen tai nolla. + + + This value is not a valid timezone. + Arvo ei ole kelvollinen aikavyöhyke. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Tämä salasana on vuotanut tietomurrossa, eikä sitä saa käyttää. Käytä toista salasanaa. + + + This value should be between {{ min }} and {{ max }}. + Arvon tulee olla {{ min }} - {{ max }}. + + + This value is not a valid hostname. + Arvo ei ole kelvollinen laitenimi (hostname). + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Ryhmässä olevien elementtien määrän pitää olla luvun {{ compared_value }} kerrannainen. + + + This value should satisfy at least one of the following constraints: + Arvon tulee läpäistä vähintään yksi seuraavista tarkistuksista: + + + Each element of this collection should satisfy its own set of constraints. + Ryhmän jokaisen elementin tulee läpäistä omat tarkistuksensa. + + + This value is not a valid International Securities Identification Number (ISIN). + Tämä arvo ei ole kelvollinen ISIN-koodi (International Securities Identification Number). + + + This value should be a valid expression. + Tämän arvon on oltava kelvollinen lauseke. + + + This value is not a valid CSS color. + Tämä arvo ei ole kelvollinen CSS-värimääritys. + + + This value is not a valid CIDR notation. + Tämä arvo ei ole kelvollinen CIDR-merkintä. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Verkkomaskille annetun arvon tulee olla {{ min }} - {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Tiedostonimi on liian pitkä. Nimi saa olla enintään yhden merkin pituinen.|Tiedostonimi on liian pitkä. Nimi saa olla enintään {{ filename_max_length }} merkin pituinen. + + + The password strength is too low. Please use a stronger password. + Salasana on liian heikko. Valitse vahvempi salasana. + + + This value contains characters that are not allowed by the current restriction-level. + Arvo sisältää merkkejä, joita nykyinen rajoitustaso ei salli. + + + Using invisible characters is not allowed. + Näkymättömiä merkkejä ei saa käyttää. + + + Mixing numbers from different scripts is not allowed. + Eri kirjaimistojen numeroita ei saa sekoittaa. + + + Using hidden overlay characters is not allowed. + Piilotettuja tarkemerkkejä ei saa käyttää. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Tiedostopääte ({{ extension }}) on virheellinen. Sallitut tiedostopäätteet ovat: {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Havaittu merkistö on virheellinen ({{ detected }}). Sallitut merkistöt ovat {{ encodings }}. + + + This value is not a valid MAC address. + Tämä arvo ei ole kelvollinen MAC-osoite. + + + This URL is missing a top-level domain. + Tästä URL-osoitteesta puuttuu ylätason verkkotunnus. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Tämä arvo on liian lyhyt. Sen pitäisi sisältää vähintään yksi sana.|Tämä arvo on liian lyhyt. Sen pitäisi sisältää vähintään {{ min }} sanaa. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Tämä arvo on liian pitkä. Sen pitäisi sisältää vain yksi sana.|Tämä arvo on liian pitkä. Sen pitäisi sisältää {{ max }} sanaa tai vähemmän. + + + This value does not represent a valid week in the ISO 8601 format. + Tämä arvo ei esitä kelvollista viikkoa ISO 8601 -muodossa. + + + This value is not a valid week. + Tämä arvo ei ole kelvollinen viikko. + + + This value should not be before week "{{ min }}". + Tämän arvon ei pitäisi olla ennen viikkoa "{{ min }}". + + + This value should not be after week "{{ max }}". + Tämän arvon ei pitäisi olla viikon "{{ max }}" jälkeen. + + + This value is not a valid Twig template. + Tämä arvo ei ole kelvollinen Twig-malli. + + + This file is not a valid video. + Tämä tiedosto ei ole kelvollinen video. + + + The size of the video could not be detected. + Videon kokoa ei voitu tunnistaa. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Videon leveys on liian suuri ({{ width }} px). Leveyden tulee olla enintään {{ max_width }} px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Videon leveys on liian pieni ({{ width }} px). Leveyden tulee olla vähintään {{ min_width }} px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Videon korkeus on liian suuri ({{ height }} px). Korkeuden tulee olla enintään {{ max_height }} px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Videon korkeus on liian pieni ({{ height }} px). Korkeuden tulee olla vähintään {{ min_height }} px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Videossa on liian vähän pikseleitä ({{ pixels }}). Pikseleitä tulee olla vähintään {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Videossa on liikaa pikseleitä ({{ pixels }}). Pikseleitä tulee olla enintään {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Videon kuvasuhde on liian suuri ({{ ratio }}). Suurin sallittu suhde on {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Videon kuvasuhde on liian pieni ({{ ratio }}). Pienin sallittu suhde on {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video on neliön muotoinen ({{ width }}x{{ height }}px). Neliönmuotoiset videot eivät ole sallittuja. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video on vaakasuuntainen ({{ width }}x{{ height }} px). Vaakasuuntaiset videot eivät ole sallittuja. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video on pystysuuntainen ({{ width }}x{{ height }} px). Pystysuuntaiset videot eivät ole sallittuja. + + + The video file is corrupted. + Videotiedosto on vioittunut. + + + The video contains multiple streams. Only one stream is allowed. + Videossa on useita virtoja. Vain yksi virta on sallittu. + + + Unsupported video codec "{{ codec }}". + Videokoodekkia ei tueta ({{ codec }}). + + + Unsupported video container "{{ container }}". + Videon säiliömuotoa ei tueta ({{ container }}). + + + The image file is corrupted. + Kuvatiedosto on vioittunut. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Kuvassa on liian vähän pikseleitä ({{ pixels }}). Pikseleitä tulee olla vähintään {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Kuvassa on liikaa pikseleitä ({{ pixels }}). Pikseleitä tulee olla enintään {{ max_pixels }}. + + + This filename does not match the expected charset. + Tämä tiedostonimi ei vastaa odotettua merkistöä. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.fr.xlf b/lib/symfony/validator/Resources/translations/validators.fr.xlf new file mode 100644 index 0000000000..e682e16a40 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.fr.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Cette valeur doit être fausse. + + + This value should be true. + Cette valeur doit être vraie. + + + This value should be of type {{ type }}. + Cette valeur doit être de type {{ type }}. + + + This value should be blank. + Cette valeur doit être vide. + + + The value you selected is not a valid choice. + Cette valeur doit être l'un des choix proposés. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Vous devez sélectionner au moins {{ limit }} choix.|Vous devez sélectionner au moins {{ limit }} choix. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Vous devez sélectionner au maximum {{ limit }} choix.|Vous devez sélectionner au maximum {{ limit }} choix. + + + One or more of the given values is invalid. + Une ou plusieurs des valeurs soumises sont invalides. + + + This field was not expected. + Ce champ n'a pas été prévu. + + + This field is missing. + Ce champ est manquant. + + + This value is not a valid date. + Cette valeur n'est pas une date valide. + + + This value is not a valid datetime. + Cette valeur n'est pas une date valide. + + + This value is not a valid email address. + Cette valeur n'est pas une adresse email valide. + + + The file could not be found. + Le fichier n'a pas été trouvé. + + + The file is not readable. + Le fichier n'est pas lisible. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Le fichier est trop volumineux ({{ size }} {{ suffix }}). Sa taille ne doit pas dépasser {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Le type du fichier est invalide ({{ type }}). Les types autorisés sont {{ types }}. + + + This value should be {{ limit }} or less. + Cette valeur doit être inférieure ou égale à {{ limit }}. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Cette chaîne est trop longue. Elle doit avoir au maximum {{ limit }} caractère.|Cette chaîne est trop longue. Elle doit avoir au maximum {{ limit }} caractères. + + + This value should be {{ limit }} or more. + Cette valeur doit être supérieure ou égale à {{ limit }}. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Cette chaîne est trop courte. Elle doit avoir au minimum {{ limit }} caractère.|Cette chaîne est trop courte. Elle doit avoir au minimum {{ limit }} caractères. + + + This value should not be blank. + Cette valeur ne doit pas être vide. + + + This value should not be null. + Cette valeur ne doit pas être nulle. + + + This value should be null. + Cette valeur doit être nulle. + + + This value is not valid. + Cette valeur n'est pas valide. + + + This value is not a valid time. + Cette valeur n'est pas une heure valide. + + + This value is not a valid URL. + Cette valeur n'est pas une URL valide. + + + The two values should be equal. + Les deux valeurs doivent être identiques. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Le fichier est trop volumineux. Sa taille ne doit pas dépasser {{ limit }} {{ suffix }}. + + + The file is too large. + Le fichier est trop volumineux. + + + The file could not be uploaded. + Le téléchargement de ce fichier est impossible. + + + This value should be a valid number. + Cette valeur doit être un nombre. + + + This file is not a valid image. + Ce fichier n'est pas une image valide. + + + This value is not a valid IP address. + Cette valeur n'est pas une adresse IP valide. + + + This value is not a valid language. + Cette langue n'est pas valide. + + + This value is not a valid locale. + Ce paramètre régional n'est pas valide. + + + This value is not a valid country. + Ce pays n'est pas valide. + + + This value is already used. + Cette valeur est déjà utilisée. + + + The size of the image could not be detected. + La taille de l'image n'a pas pu être détectée. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + La largeur de l'image est trop grande ({{ width }}px). La largeur maximale autorisée est de {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + La largeur de l'image est trop petite ({{ width }}px). La largeur minimale attendue est de {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + La hauteur de l'image est trop grande ({{ height }}px). La hauteur maximale autorisée est de {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + La hauteur de l'image est trop petite ({{ height }}px). La hauteur minimale attendue est de {{ min_height }}px. + + + This value should be the user's current password. + Cette valeur doit être le mot de passe actuel de l'utilisateur. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Cette chaîne doit avoir exactement {{ limit }} caractère.|Cette chaîne doit avoir exactement {{ limit }} caractères. + + + The file was only partially uploaded. + Le fichier a été partiellement transféré. + + + No file was uploaded. + Aucun fichier n'a été transféré. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Aucun répertoire temporaire n'a été configuré dans le php.ini, ou le répertoire configuré n'existe pas. + + + Cannot write temporary file to disk. + Impossible d'écrire le fichier temporaire sur le disque. + + + A PHP extension caused the upload to fail. + Une extension PHP a empêché le transfert du fichier. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Cette collection doit contenir {{ limit }} élément ou plus.|Cette collection doit contenir {{ limit }} éléments ou plus. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Cette collection doit contenir {{ limit }} élément ou moins.|Cette collection doit contenir {{ limit }} éléments ou moins. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Cette collection doit contenir exactement {{ limit }} élément.|Cette collection doit contenir exactement {{ limit }} éléments. + + + Invalid card number. + Numéro de carte invalide. + + + Unsupported card type or invalid card number. + Type de carte non supporté ou numéro invalide. + + + This value is not a valid International Bank Account Number (IBAN). + Cette valeur n'est pas un Numéro de Compte Bancaire International (IBAN) valide. + + + This value is not a valid ISBN-10. + Cette valeur n'est pas un code ISBN-10 valide. + + + This value is not a valid ISBN-13. + Cette valeur n'est pas un code ISBN-13 valide. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Cette valeur n'est ni un code ISBN-10, ni un code ISBN-13 valide. + + + This value is not a valid ISSN. + Cette valeur n'est pas un code ISSN valide. + + + This value is not a valid currency. + Cette valeur n'est pas une devise valide. + + + This value should be equal to {{ compared_value }}. + Cette valeur doit être égale à {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Cette valeur doit être supérieure à {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Cette valeur doit être supérieure ou égale à {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Cette valeur doit être identique à {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Cette valeur doit être inférieure à {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Cette valeur doit être inférieure ou égale à {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Cette valeur ne doit pas être égale à {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Cette valeur ne doit pas être identique à {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Le rapport largeur/hauteur de l'image est trop grand ({{ ratio }}). Le rapport maximal autorisé est {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Le rapport largeur/hauteur de l'image est trop petit ({{ ratio }}). Le rapport minimal attendu est {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + L'image est carrée ({{ width }}x{{ height }}px). Les images carrées ne sont pas autorisées. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + L'image est au format paysage ({{ width }}x{{ height }}px). Les images au format paysage ne sont pas autorisées. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + L'image est au format portrait ({{ width }}x{{ height }}px). Les images au format portrait ne sont pas autorisées. + + + An empty file is not allowed. + Un fichier vide n'est pas autorisé. + + + The host could not be resolved. + Le nom de domaine n'a pas pu être résolu. + + + This value does not match the expected {{ charset }} charset. + Cette valeur ne correspond pas au jeu de caractères {{ charset }} attendu. + + + This value is not a valid Business Identifier Code (BIC). + Cette valeur n'est pas un Code Identifiant de Business (BIC) valide. + + + Error + Erreur + + + This value is not a valid UUID. + Cette valeur n'est pas un UUID valide. + + + This value should be a multiple of {{ compared_value }}. + Cette valeur doit être un multiple de {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Ce code d'identification d'entreprise (BIC) n'est pas associé à l'IBAN {{ iban }}. + + + This value should be valid JSON. + Cette valeur doit être un JSON valide. + + + This collection should contain only unique elements. + Cette collection ne doit pas comporter de doublons. + + + This value should be positive. + Cette valeur doit être strictement positive. + + + This value should be either positive or zero. + Cette valeur doit être supérieure ou égale à zéro. + + + This value should be negative. + Cette valeur doit être strictement négative. + + + This value should be either negative or zero. + Cette valeur doit être inférieure ou égale à zéro. + + + This value is not a valid timezone. + Cette valeur n'est pas un fuseau horaire valide. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Ce mot de passe a été divulgué lors d'une fuite de données, il ne doit plus être utilisé. Veuillez utiliser un autre mot de passe. + + + This value should be between {{ min }} and {{ max }}. + Cette valeur doit être comprise entre {{ min }} et {{ max }}. + + + This value is not a valid hostname. + Cette valeur n'est pas un nom d'hôte valide. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Le nombre d'éléments de cette collection doit être un multiple de {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Cette valeur doit satisfaire à au moins une des contraintes suivantes : + + + Each element of this collection should satisfy its own set of constraints. + Chaque élément de cette collection doit satisfaire à son propre jeu de contraintes. + + + This value is not a valid International Securities Identification Number (ISIN). + Cette valeur n'est pas un code international de sécurité valide (ISIN). + + + This value should be a valid expression. + Cette valeur doit être une expression valide. + + + This value is not a valid CSS color. + Cette valeur n'est pas une couleur CSS valide. + + + This value is not a valid CIDR notation. + Cette valeur n'est pas une notation CIDR valide. + + + The value of the netmask should be between {{ min }} and {{ max }}. + La valeur du masque de réseau doit être comprise entre {{ min }} et {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Le nom du fichier est trop long. Il doit contenir au maximum {{ filename_max_length }} caractère.|Le nom de fichier est trop long. Il doit contenir au maximum {{ filename_max_length }} caractères. + + + The password strength is too low. Please use a stronger password. + La force du mot de passe est trop faible. Veuillez utiliser un mot de passe plus fort. + + + This value contains characters that are not allowed by the current restriction-level. + Cette valeur contient des caractères qui ne sont pas autorisés par le niveau de restriction actuel. + + + Using invisible characters is not allowed. + Utiliser des caractères invisibles n'est pas autorisé. + + + Mixing numbers from different scripts is not allowed. + Mélanger des chiffres provenant de différents scripts n'est pas autorisé. + + + Using hidden overlay characters is not allowed. + Utiliser des caractères de superposition cachés n'est pas autorisé. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + L'extension du fichier est invalide ({{ extension }}). Les extensions autorisées sont {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + L'encodage de caractères détecté est invalide ({{ detected }}). Les encodages autorisés sont {{ encodings }}. + + + This value is not a valid MAC address. + Cette valeur n'est pas une adresse MAC valide. + + + This URL is missing a top-level domain. + Cette URL doit contenir un domaine de premier niveau. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Cette valeur est trop courte. Elle doit contenir au moins un mot.|Cette valeur est trop courte. Elle doit contenir au moins {{ min }} mots. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Cette valeur est trop longue. Elle doit contenir au maximum un mot.|Cette valeur est trop longue. Elle doit contenir au maximum {{ max }} mots. + + + This value does not represent a valid week in the ISO 8601 format. + Cette valeur ne représente pas une semaine valide au format ISO 8601. + + + This value is not a valid week. + Cette valeur n'est pas une semaine valide. + + + This value should not be before week "{{ min }}". + Cette valeur ne doit pas être antérieure à la semaine "{{ min }}". + + + This value should not be after week "{{ max }}". + Cette valeur ne doit pas être postérieure à la semaine "{{ max }}". + + + This value is not a valid Twig template. + Cette valeur n'est pas un modèle Twig valide. + + + This file is not a valid video. + Ce fichier n’est pas une vidéo valide. + + + The size of the video could not be detected. + La taille de la vidéo n’a pas pu être détectée. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + La largeur de la vidéo est trop grande ({{ width }}px). La largeur maximale autorisée est de {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + La largeur de la vidéo est trop petite ({{ width }}px). La largeur minimale attendue est de {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + La hauteur de la vidéo est trop grande ({{ height }}px). La hauteur maximale autorisée est de {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + La hauteur de la vidéo est trop petite ({{ height }}px). La hauteur minimale attendue est de {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + La vidéo a trop peu de pixels ({{ pixels }}). La quantité minimale attendue est de {{ min_pixels }} pixels. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + La vidéo contient trop de pixels ({{ pixels }}). La quantité maximale attendue est de {{ max_pixels }} pixels. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Le ratio de la vidéo est trop élevé ({{ ratio }}). Le ratio maximal autorisé est de {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Le ratio de la vidéo est trop petit ({{ ratio }}). Le ratio minimum attendu est de {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + La vidéo est carrée ({{ width }}x{{ height }}px). Les vidéos carrées ne sont pas autorisées. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + La vidéo est au format paysage ({{ width }}x{{ height }} px). Les vidéos au format paysage ne sont pas autorisées. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + La vidéo est orientée en portrait ({{ width }}x{{ height }} px). Les vidéos en orientation portrait ne sont pas autorisées. + + + The video file is corrupted. + Le fichier vidéo est corrompu. + + + The video contains multiple streams. Only one stream is allowed. + La vidéo contient plusieurs flux. Un seul flux est autorisé. + + + Unsupported video codec "{{ codec }}". + Le codec vidéo «{{ codec }}» est non pris en charge. + + + Unsupported video container "{{ container }}". + Le conteneur vidéo «{{ container }}» est non pris en charge. + + + The image file is corrupted. + Le fichier image est corrompu. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + L’image comporte trop peu de pixels ({{ pixels }}). La quantité minimale attendue est de {{ min_pixels }} pixels. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + L’image contient trop de pixels ({{ pixels }}). La quantité maximale attendue est de {{ max_pixels }} pixels. + + + This filename does not match the expected charset. + Le nom de fichier ne correspond pas au jeu de caractères attendu. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.gl.xlf b/lib/symfony/validator/Resources/translations/validators.gl.xlf new file mode 100644 index 0000000000..489457d548 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.gl.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Este valor debería ser falso. + + + This value should be true. + Este valor debería ser verdadeiro. + + + This value should be of type {{ type }}. + Este valor debería ser de tipo {{ type }}. + + + This value should be blank. + Este valor debería estar baleiro. + + + The value you selected is not a valid choice. + O valor seleccionado non é unha opción válida. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Debe seleccionar polo menos {{ limit }} opción.|Debe seleccionar polo menos {{ limit }} opcions. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Debe seleccionar como máximo {{ limit }} opción.|Debe seleccionar como máximo {{ limit }} opcions. + + + One or more of the given values is invalid. + Un ou máis dos valores indicados non son válidos. + + + This field was not expected. + Este campo non era esperado. + + + This field is missing. + Este campo falta. + + + This value is not a valid date. + Este valor non é unha data válida. + + + This value is not a valid datetime. + Este valor non é unha data e hora válidas. + + + This value is not a valid email address. + Este valor non é unha dirección de correo electrónico válida. + + + The file could not be found. + Non se puido atopar o arquivo. + + + The file is not readable. + O arquivo non se pode ler. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + O arquivo é demasiado grande ({{ size }} {{ suffix }}). O tamaño máximo permitido é {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + O tipo mime do arquivo non é válido ({{ type }}). Os tipos mime válidos son {{ types }}. + + + This value should be {{ limit }} or less. + Este valor debería ser {{ limit }} ou menos. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Este valor é demasiado longo. Debería ter {{ limit }} carácter ou menos.|Este valor é demasiado longo. Debería ter {{ limit }} caracteres ou menos. + + + This value should be {{ limit }} or more. + Este valor debería ser {{ limit }} ou máis. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Este valor é demasiado curto. Debería ter {{ limit }} carácter ou máis.|Este valor é demasiado corto. Debería ter {{ limit }} caracteres ou máis. + + + This value should not be blank. + Este valor non debería estar baleiro. + + + This value should not be null. + Este valor non debería ser null. + + + This value should be null. + Este valor debería ser null. + + + This value is not valid. + Este valor non é válido. + + + This value is not a valid time. + Este valor non é unha hora válida. + + + This value is not a valid URL. + Este valor non é unha URL válida. + + + The two values should be equal. + Os dous valores deberían ser iguais. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + O arquivo é demasiado grande. O tamaño máximo permitido é {{ limit }} {{ suffix }}. + + + The file is too large. + O arquivo é demasiado grande. + + + The file could not be uploaded. + No se puido cargar o arquivo. + + + This value should be a valid number. + Este valor debería ser un número válido. + + + This file is not a valid image. + O arquivo non é unha imaxe válida. + + + This value is not a valid IP address. + Este valor non é un enderezo IP válido. + + + This value is not a valid language. + Este valor non é un idioma válido. + + + This value is not a valid locale. + Este valor non é unha localización válida. + + + This value is not a valid country. + Este valor non é un país válido. + + + This value is already used. + Este valor xa está a ser empregado. + + + The size of the image could not be detected. + Non se puido determinar o tamaño da imaxe. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + A largura da imaxe é demasiado grande ({{ width }}px). A largura máxima permitida son {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + A largura da imaxe é demasiado pequena ({{ width }}px). A largura mínima requerida son {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + A altura da imaxe é demasiado grande ({{ height }}px). A altura máxima permitida son {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + A altura da imaxe é demasiado pequena ({{ height }}px). A altura mínima requerida son {{ min_height }}px. + + + This value should be the user's current password. + Este valor debería ser a contrasinal actual do usuario. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Este valor debería ter exactamente {{ limit }} carácter.|Este valor debería ter exactamente {{ limit }} caracteres. + + + The file was only partially uploaded. + O arquivo foi só subido parcialmente. + + + No file was uploaded. + Non se subiu ningún arquivo. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Ningunha carpeta temporal foi configurada en php.ini, ou a carpeta non existe. + + + Cannot write temporary file to disk. + Non se puido escribir o arquivo temporal no disco. + + + A PHP extension caused the upload to fail. + Unha extensión de PHP provocou que a subida fallara. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Esta colección debe conter {{ limit }} elemento ou máis.|Esta colección debe conter {{ limit }} elementos ou máis. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Esta colección debe conter {{ limit }} elemento ou menos.|Esta colección debe conter {{ limit }} elementos ou menos. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Esta colección debe conter exactamente {{ limit }} elemento.|Esta colección debe conter exactamente {{ limit }} elementos. + + + Invalid card number. + Número de tarxeta non válido. + + + Unsupported card type or invalid card number. + Tipo de tarxeta non soportado ou número de tarxeta non válido. + + + This value is not a valid International Bank Account Number (IBAN). + Este valor non é un Número de Conta Bancaria Internacional (IBAN) válido. + + + This value is not a valid ISBN-10. + Este valor non é un ISBN-10 válido. + + + This value is not a valid ISBN-13. + Este valor non é un ISBN-13 válido. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Este valor non é nin un ISBN-10 válido nin un ISBN-13 válido. + + + This value is not a valid ISSN. + Este valor non é un ISSN válido. + + + This value is not a valid currency. + Este valor non é unha moeda válida. + + + This value should be equal to {{ compared_value }}. + Este valor debería ser igual a {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Este valor debería ser maior que {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Este valor debería ser maior ou igual que {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor debería ser identico a {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Este valor debería ser menor que {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Este valor debería ser menor ou igual que {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Este valor non debería ser igual a {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor non debería ser identico a {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + A proporción da imaxe é demasiado grande ({{ ratio }}). A proporción máxima permitida é {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + A proporción da é demasiado pequena ({{ ratio }}). A proporción mínima permitida é {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + A imaxe é cadrada ({{ width }}x{{ height }}px). As imáxenes cadradas non están permitidas. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + A imaxe está orientada horizontalmente ({{ width }}x{{ height }}px). As imáxenes orientadas horizontalmente non están permitidas. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + A imaxe está orientada verticalmente ({{ width }}x{{ height }}px). As imáxenes orientadas verticalmente non están permitidas. + + + An empty file is not allowed. + Non está permitido un arquivo baleiro. + + + The host could not be resolved. + Non se puido resolver o host. + + + This value does not match the expected {{ charset }} charset. + A codificación de caracteres para este valor debería ser {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Este valor non é un Código de Identificación de Negocios (BIC) válido. + + + Error + Erro + + + This value is not a valid UUID. + Este valor non é un UUID válido. + + + This value should be a multiple of {{ compared_value }}. + Este valor debería ser multiplo de {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Este Código de identificación bancaria (BIC) non está asociado co IBAN {{ iban }}. + + + This value should be valid JSON. + Este valor debería ser un JSON válido. + + + This collection should contain only unique elements. + Esta colección só debería ter elementos únicos. + + + This value should be positive. + Este valor debería ser positivo. + + + This value should be either positive or zero. + Este valor debe ser positivo ou igual a cero. + + + This value should be negative. + Este valor debe ser negativo. + + + This value should be either negative or zero. + Este valor debe ser negativo ou igual a cero. + + + This value is not a valid timezone. + Este valor non é unha zona horaria válida. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Este contrasinal non se pode usar porque está incluído nunha lista de contrasinais públicos obtidos grazas a fallos de seguridade noutros sitios e aplicacións. Utiliza outro contrasinal. + + + This value should be between {{ min }} and {{ max }}. + Este valor debe estar comprendido entre {{ min }} e {{ max }}. + + + This value is not a valid hostname. + Este valor non é un nome de host válido. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + O número de elementos desta colección debería ser múltiplo de {{compare_value}}. + + + This value should satisfy at least one of the following constraints: + Este valor debe cumprir polo menos unha das seguintes restricións: + + + Each element of this collection should satisfy its own set of constraints. + Cada elemento desta colección debe satisfacer o seu propio conxunto de restricións. + + + This value is not a valid International Securities Identification Number (ISIN). + Este valor non é un número de identificación de valores internacionais (ISIN) válido. + + + This value should be a valid expression. + Este valor debe ser unha expresión válida. + + + This value is not a valid CSS color. + Este valor non é unha cor CSS válida. + + + This value is not a valid CIDR notation. + Este valor non ten unha notación CIDR válida. + + + The value of the netmask should be between {{ min }} and {{ max }}. + O valor da máscara de rede debería estar entre {{ min }} e {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + O nome do ficheiro é demasiado longo. Debe ter {{ filename_max_length }} caracteres ou menos. + + + The password strength is too low. Please use a stronger password. + O contrasinal é demasiado débil. Utilice un contrasinal máis seguro. + + + This value contains characters that are not allowed by the current restriction-level. + Este valor contén caracteres que non están permitidos polo nivel de restrición actual. + + + Using invisible characters is not allowed. + Non se permite usar caracteres invisíbeis. + + + Mixing numbers from different scripts is not allowed. + Non se permite mesturar números de diferentes scripts. + + + Using hidden overlay characters is not allowed. + Non se permite usar caracteres de superposición ocultos. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + A extensión do ficheiro non é válida ({{ extension }}). As extensións permitidas son {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + A codificación de caracteres detectada non é válida ({{ detected }}). As codificacións permitidas son {{ encodings }}. + + + This value is not a valid MAC address. + Este valor non é un enderezo MAC válido. + + + This URL is missing a top-level domain. + A esta URL fáltalle un dominio de nivel superior. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Este valor é curto de máis. Debe conter polo menos unha palabra.|Este valor é curto de máis. Debe conter polo menos {{ min }} palabras. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Este valor é longo de máis. Debe conter só unha palabra.|Este valor é longo de máis. Debe conter {{ max }} palabras ou menos. + + + This value does not represent a valid week in the ISO 8601 format. + Este valor non representa unha semana válida no formato ISO 8601. + + + This value is not a valid week. + Este valor non é unha semana válida. + + + This value should not be before week "{{ min }}". + Este valor non debe ser anterior á semana "{{ min }}". + + + This value should not be after week "{{ max }}". + Este valor non debe estar despois da semana "{{ max }}". + + + This value is not a valid Twig template. + Este valor non é un modelo Twig válido. + + + This file is not a valid video. + Este ficheiro non é un vídeo válido. + + + The size of the video could not be detected. + Non se puido detectar o tamaño do vídeo. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + A anchura do vídeo é demasiado grande ({{ width }}px). A anchura máxima permitida é {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + A anchura do vídeo é demasiado pequena ({{ width }}px). A anchura mínima agardada é {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + A altura do vídeo é demasiado grande ({{ height }}px). A altura máxima permitida é {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + A altura do vídeo é demasiado pequena ({{ height }}px). A altura mínima agardada é {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + O vídeo ten moi poucos píxeles ({{ pixels }}). A cantidade mínima agardada é {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + O vídeo ten demasiados píxeles ({{ pixels }}). A cantidade máxima agardada é {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + A relación do vídeo é demasiado grande ({{ ratio }}). A relación máxima permitida é {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + A relación do vídeo é demasiado pequena ({{ ratio }}). A relación mínima agardada é {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + O vídeo é cadrado ({{ width }}x{{ height }}px). Non se permiten vídeos cadrados. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + O vídeo está en orientación horizontal ({{ width }}x{{ height }} px). Non se permiten vídeos en horizontal. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + O vídeo está en orientación vertical ({{ width }}x{{ height }} px). Non se permiten vídeos en orientación vertical. + + + The video file is corrupted. + O ficheiro de vídeo está danado. + + + The video contains multiple streams. Only one stream is allowed. + O vídeo contén múltiples fluxos. Só se permite un fluxo. + + + Unsupported video codec "{{ codec }}". + Códec de vídeo non compatible «{{ codec }}». + + + Unsupported video container "{{ container }}". + Contedor de vídeo non compatible "{{ container }}". + + + The image file is corrupted. + O ficheiro de imaxe está danado. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + A imaxe ten moi poucos píxeles ({{ pixels }}). A cantidade mínima esperada é {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + A imaxe ten demasiados píxeles ({{ pixels }}). A cantidade máxima esperada é {{ max_pixels }}. + + + This filename does not match the expected charset. + Este nome de ficheiro non coincide co charset agardado. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.he.xlf b/lib/symfony/validator/Resources/translations/validators.he.xlf new file mode 100644 index 0000000000..e19c438e41 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.he.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + הערך צריך להיות שקר. + + + This value should be true. + הערך צריך להיות אמת. + + + This value should be of type {{ type }}. + הערך צריך להיות מסוג {{ type }}. + + + This value should be blank. + הערך צריך להיות ריק. + + + The value you selected is not a valid choice. + הערך שבחרת אינו חוקי. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + אתה צריך לבחור לפחות {{ limit }} אפשרויות.|אתה צריך לבחור לפחות {{ limit }} אפשרויות. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + אתה צריך לבחור לכל היותר {{ limit }} אפשרויות.|אתה צריך לבחור לכל היותר {{ limit }} אפשרויות. + + + One or more of the given values is invalid. + אחד או יותר מהערכים אינו חוקי. + + + This field was not expected. + שדה זה לא היה צפוי + + + This field is missing. + שדה זה חסר. + + + This value is not a valid date. + הערך אינו תאריך חוקי. + + + This value is not a valid datetime. + הערך אינו תאריך ושעה חוקיים. + + + This value is not a valid email address. + כתובת המייל אינה תקינה. + + + The file could not be found. + הקובץ לא נמצא. + + + The file is not readable. + לא ניתן לקרוא את הקובץ. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + הקובץ גדול מדי ({{ size }} {{ suffix }}). הגודל המרבי המותר הוא {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + סוג MIME של הקובץ אינו חוקי ({{ type }}). מותרים סוגי MIME {{ types }}. + + + This value should be {{ limit }} or less. + הערך צריך להכיל {{ limit }} תווים לכל היותר. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + הערך ארוך מידי. הוא צריך להכיל {{ limit }} תווים לכל היותר.|הערך ארוך מידי. הוא צריך להכיל {{ limit }} תווים לכל היותר. + + + This value should be {{ limit }} or more. + הערך צריך להכיל {{ limit }} תווים לפחות. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + הערך קצר מידי. הוא צריך להכיל {{ limit }} תווים לפחות.|הערך קצר מידי. הערך צריך להכיל {{ limit }} תווים לפחות. + + + This value should not be blank. + הערך לא אמור להיות ריק. + + + This value should not be null. + הערך לא אמור להיות ריק. + + + This value should be null. + הערך צריך להיות ריק. + + + This value is not valid. + הערך אינו חוקי. + + + This value is not a valid time. + הערך אינו זמן תקין. + + + This value is not a valid URL. + זאת אינה כתובת אתר תקינה. + + + The two values should be equal. + שני הערכים צריכים להיות שווים. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + הקובץ גדול מדי. הגודל המרבי המותר הוא {{ limit }} {{ suffix }}. + + + The file is too large. + הקובץ גדול מדי. + + + The file could not be uploaded. + לא ניתן לעלות את הקובץ. + + + This value should be a valid number. + הערך צריך להיות מספר חוקי. + + + This file is not a valid image. + הקובץ הזה אינו תמונה תקינה. + + + This value is not a valid IP address. + ערך זה אינו כתובת IP תקפה. + + + This value is not a valid language. + הערך אינו שפה חוקית. + + + This value is not a valid locale. + הערך אינו אזור תקף. + + + This value is not a valid country. + הערך אינו ארץ חוקית. + + + This value is already used. + הערך כבר בשימוש. + + + The size of the image could not be detected. + לא ניתן לקבוע את גודל התמונה. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + רוחב התמונה גדול מדי ({{ width }}px). הרוחב המקסימלי הוא {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + רוחב התמונה קטן מדי ({{ width }}px). הרוחב המינימלי הוא {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + גובה התמונה גדול מדי ({{ height }}px). הגובה המקסימלי הוא {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + גובה התמונה קטן מדי ({{ height }}px). הגובה המינימלי הוא {{ min_height }}px. + + + This value should be the user's current password. + הערך צריך להיות סיסמת המשתמש הנוכחי. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + הערך צריך להיות בדיוק {{ limit }} תווים.|הערך צריך להיות בדיוק {{ limit }} תווים. + + + The file was only partially uploaded. + הקובץ הועלה באופן חלקי. + + + No file was uploaded. + הקובץ לא הועלה. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + לא הוגדרה תיקייה זמנית ב-php.ini, או שהתיקייה המוגדרת אינה קיימת. + + + Cannot write temporary file to disk. + לא ניתן לכתוב קובץ זמני לדיסק. + + + A PHP extension caused the upload to fail. + סיומת PHP גרם להעלאה להיכשל. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + האוסף אמור להכיל {{ limit }} אלמנטים או יותר.|האוסף אמור להכיל {{ limit }} אלמנטים או יותר. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + האוסף אמור להכיל {{ limit }} אלמנטים או פחות.|האוסף אמור להכיל {{ limit }} אלמנטים או פחות. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + האוסף צריך להכיל בדיוק {{ limit }} אלמנטים.|האוסף צריך להכיל בדיוק {{ limit }} אלמנטים. + + + Invalid card number. + מספר הכרטיס אינו חוקי. + + + Unsupported card type or invalid card number. + סוג הכרטיס אינו נתמך או לא חוקי. + + + This value is not a valid International Bank Account Number (IBAN). + ערך זה אינו מספר זה"ב (IBAN) תקף. + + + This value is not a valid ISBN-10. + הערך אינו ערך ISBN-10 חוקי. + + + This value is not a valid ISBN-13. + הערך אינו ערך ISBN-13 חוקי. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + הערך אינו ערך ISBN-10 חוקי או ערך ISBN-13 חוקי. + + + This value is not a valid ISSN. + הערך אינו ערך ISSN חוקי. + + + This value is not a valid currency. + הערך אינו ערך מטבע חוקי. + + + This value should be equal to {{ compared_value }}. + הערך חייב להיות שווה ל {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + הערך חייב להיות גדול מ {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + הערך חייב להיות גדול או שווה ל {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + הערך חייב להיות זהה ל {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + הערך חייב להיות קטן מ {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + הערך חייב להיות קטן או שווה ל {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + הערך חייב להיות לא שווה ל {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + הערך חייב להיות לא זהה ל {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + היחס של התמונה הוא גדול מדי ({{ ratio }}). היחס המקסימלי האפשרי הוא {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + היחס של התמונה הוא קטן מדי ({{ ratio }}). היחס המינימלי האפשרי הוא {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + התמונה מרובעת ({{ width }}x{{ height }}px). אסורות תמונות מרובעות. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + התמונה היא לרוחב ({{ width }}x{{ height }}px). אסורות תמונות לרוחב. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + התמונה היא לאורך ({{ width }}x{{ height }}px). אסורות תמונות לאורך. + + + An empty file is not allowed. + אסור קובץ ריק. + + + The host could not be resolved. + לא הייתה אפשרות לזהות את המארח. + + + This value does not match the expected {{ charset }} charset. + הערך אינו תואם למערך התווים {{ charset }} הצפוי. + + + This value is not a valid Business Identifier Code (BIC). + ערך זה אינו קוד מזהה עסקי (BIC) תקף. + + + Error + שגיאה + + + This value is not a valid UUID. + ערך זה אינו UUID תקף. + + + This value should be a multiple of {{ compared_value }}. + הערך חייב להיות כפולה של {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + הקוד זיהוי עסקי (BIC) אינו משוייך ל IBAN {{ iban }}. + + + This value should be valid JSON. + הערך אינו ערך JSON תקין. + + + This collection should contain only unique elements. + האוסף חייב להכיל רק אלמנטים ייחודיים. + + + This value should be positive. + הערך חייב להיות חיובי. + + + This value should be either positive or zero. + הערך חייב להיות חיובי או אפס. + + + This value should be negative. + הערך חייב להיות שלילי. + + + This value should be either negative or zero. + הערך חייב להיות שלילי או אפס. + + + This value is not a valid timezone. + הערך אינו אזור זמן תקין. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + סיסמא זו הודלפה בהדלפת מידע, אסור להשתמש בה. אנא השתמש בסיסמה אחרת. + + + This value should be between {{ min }} and {{ max }}. + הערך חייב להיות בין {{ min }} ו- {{ max }}. + + + This value is not a valid hostname. + ערך זה אינו שם מארח חוקי. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + מספר האלמנטים באוסף זה צריך להיות מכפיל של {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + ערך זה אמור לעמוד לפחות באחד התנאים הבאים: + + + Each element of this collection should satisfy its own set of constraints. + כל אלמנט באוסף זה אמור לעמוד בקבוצת התנאים שלו. + + + This value is not a valid International Securities Identification Number (ISIN). + ערך זה אינו מספר זיהוי ניירות ערך בינלאומי תקף (ISIN). + + + This value should be a valid expression. + ערך זה חייב להיות ביטוי חוקי. + + + This value is not a valid CSS color. + ערך זה אינו צבע CSS חוקי. + + + This value is not a valid CIDR notation. + ערך זה אינו סימון CIDR חוקי. + + + The value of the netmask should be between {{ min }} and {{ max }}. + הערך של מסכת הרשת חייב להיות בין {{ min }} ו {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + שם הקובץ ארוך מדי. עליו להכיל {{ filename_max_length }} תווים או פחות. + + + The password strength is too low. Please use a stronger password. + חוזק הסיסמה נמוך מדי. אנא השתמש בסיסמה חזקה יותר. + + + This value contains characters that are not allowed by the current restriction-level. + הערך כולל תווים שאינם מותרים על פי רמת ההגבלה הנוכחית. + + + Using invisible characters is not allowed. + אסור להשתמש בתווים בלתי נראים. + + + Mixing numbers from different scripts is not allowed. + אסור לערבב מספרים מסקריפטים שונים. + + + Using hidden overlay characters is not allowed. + אסור להשתמש בתווים חופפים נסתרים. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + סיומת הקובץ אינה תקינה ({{ extension }}). הסיומות המותרות הן {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + קידוד התווים שזוהה אינו חוקי ({{ detected }}). הקידודים המותרים הם {{ encodings }}. + + + This value is not a valid MAC address. + ערך זה אינו כתובת MAC תקפה. + + + This URL is missing a top-level domain. + לכתובת URL זו חסר דומיין רמה עליונה. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + ערך זה קצר מדי. הוא צריך להכיל לפחות מילה אחת.|ערך זה קצר מדי. הוא צריך להכיל לפחות {{ min }} מילים. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + ערך זה ארוך מדי. הוא צריך להכיל רק מילה אחת.|ערך זה ארוך מדי. הוא צריך להכיל {{ max }} מילים או פחות. + + + This value does not represent a valid week in the ISO 8601 format. + ערך זה אינו מייצג שבוע תקף בפורמט ISO 8601. + + + This value is not a valid week. + ערך זה אינו שבוע חוקי. + + + This value should not be before week "{{ min }}". + ערך זה לא אמור להיות לפני שבוע "{{ min }}". + + + This value should not be after week "{{ max }}". + ערך זה לא אמור להיות לאחר שבוע "{{ max }}". + + + This value is not a valid Twig template. + ערך זה אינו תבנית Twig חוקית. + + + This file is not a valid video. + קובץ זה אינו וידאו תקין. + + + The size of the video could not be detected. + לא ניתן היה לזהות את גודל הווידאו. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + רוחב הווידאו גדול מדי ({{ width }}px). רוחב מרבי מותר הוא {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + רוחב הווידאו קטן מדי ({{ width }}px). רוחב מינימלי צפוי הוא {{ min_width }} פיקסלים. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + גובה הווידאו גדול מדי ({{ height }}px). הגובה המקסימלי המותר הוא {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + גובה הווידאו קטן מדי ({{ height }}px). הגובה המינימלי הצפוי הוא {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + לסרטון יש מעט מדי פיקסלים ({{ pixels }}). הכמות המינימלית הצפויה היא {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + לסרטון יש יותר מדי פיקסלים ({{ pixels }}). הכמות המרבית הצפויה היא {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + יחס הווידאו גדול מדי ({{ ratio }}). יחס מקסימלי מותר הוא {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + יחס הווידאו קטן מדי ({{ ratio }}). יחס מינימלי צפוי הוא {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + הווידאו הוא מרובע ({{ width }}x{{ height }}px). סרטוני וידאו מרובעים אינם מותרים. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + הווידאו במצב לרוחב ({{ width }}x{{ height }} פיקסלים). סרטוני לרוחב אינם מותרים. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + הווידאו הוא בתצורת דיוקן ({{ width }}x{{ height }}px). סרטוני וידאו בתצורת דיוקן אינם מותרים. + + + The video file is corrupted. + קובץ הווידאו פגום. + + + The video contains multiple streams. Only one stream is allowed. + הווידאו מכיל מספר זרמים. מותר זרם אחד בלבד. + + + Unsupported video codec "{{ codec }}". + מקודד וידאו שאינו נתמך "{{ codec }}". + + + Unsupported video container "{{ container }}". + מיכל וידאו שאינו נתמך "{{ container }}". + + + The image file is corrupted. + קובץ התמונה פגום. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + לתמונה יש מעט מדי פיקסלים ({{ pixels }}). הכמות המינימלית הצפויה היא {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + לתמונה יש יותר מדי פיקסלים ({{ pixels }}). הכמות המרבית הצפויה היא {{ max_pixels }}. + + + This filename does not match the expected charset. + שם הקובץ הזה אינו תואם את מערך התווים הצפוי. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.hr.xlf b/lib/symfony/validator/Resources/translations/validators.hr.xlf new file mode 100644 index 0000000000..2be0ff60c1 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.hr.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Ova vrijednost treba biti netočna (false). + + + This value should be true. + Ova vrijednost treba biti točna (true). + + + This value should be of type {{ type }}. + Ova vrijednost treba biti tipa {{ type }}. + + + This value should be blank. + Ova vrijednost treba biti prazna. + + + The value you selected is not a valid choice. + Ova vrijednost nije valjan izbor. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Izaberite barem {{ limit }} mogućnosti. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Izaberite najviše {{ limit }} mogućnosti. + + + One or more of the given values is invalid. + Jedna ili više danih vrijednosti nije ispravna. + + + This field was not expected. + Ovo polje nije očekivano. + + + This field is missing. + Ovo polje nedostaje. + + + This value is not a valid date. + Ova vrijednost nije ispravan datum. + + + This value is not a valid datetime. + Ova vrijednost nije ispravnog datum-vrijeme formata. + + + This value is not a valid email address. + Ova vrijednost nije ispravna e-mail adresa. + + + The file could not be found. + Datoteka ne može biti pronađena. + + + The file is not readable. + Datoteka nije čitljiva. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Datoteka je prevelika ({{ size }} {{ suffix }}). Najveća dozvoljena veličina je {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mime tip datoteke nije ispravan ({{ type }}). Dozvoljeni mime tipovi su {{ types }}. + + + This value should be {{ limit }} or less. + Ova vrijednost treba biti {{ limit }} ili manje. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Ova vrijednost je predugačka. Treba imati {{ limit }} znakova ili manje. + + + This value should be {{ limit }} or more. + Ova vrijednost treba biti {{ limit }} ili više. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Ova vrijednost je prekratka. Treba imati {{ limit }} znakova ili više. + + + This value should not be blank. + Ova vrijednost ne bi trebala biti prazna. + + + This value should not be null. + Ova vrijednost ne bi trebala biti null. + + + This value should be null. + Ova vrijednost treba biti null. + + + This value is not valid. + Ova vrijednost nije ispravna. + + + This value is not a valid time. + Ova vrijednost nije ispravno vrijeme. + + + This value is not a valid URL. + Ova vrijednost nije ispravan URL. + + + The two values should be equal. + Obje vrijednosti trebaju biti jednake. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Ova datoteka je prevelika. Najveća dozvoljena veličina je {{ limit }} {{ suffix }}. + + + The file is too large. + Ova datoteka je prevelika. + + + The file could not be uploaded. + Ova datoteka ne može biti prenesena. + + + This value should be a valid number. + Ova vrijednost treba biti ispravan broj. + + + This file is not a valid image. + Ova datoteka nije ispravna slika. + + + This value is not a valid IP address. + Ova vrijednost nije valjana IP adresa. + + + This value is not a valid language. + Ova vrijednost nije ispravan jezik. + + + This value is not a valid locale. + Ova vrijednost nije ispravana regionalna oznaka. + + + This value is not a valid country. + Ova vrijednost nije ispravna država. + + + This value is already used. + Ova vrijednost je već iskorištena. + + + The size of the image could not be detected. + Veličina slike se ne može odrediti. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Širina slike je prevelika ({{ width }}px). Najveća dozvoljena širina je {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Širina slike je premala ({{ width }}px). Najmanja dozvoljena širina je {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Visina slike je prevelika ({{ height }}px). Najveća dozvoljena visina je {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Visina slike je premala ({{ height }}px). Najmanja dozvoljena visina je {{ min_height }}px. + + + This value should be the user's current password. + Ova vrijednost treba biti trenutna korisnička lozinka. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ova vrijednost treba imati točno {{ limit }} znakova. + + + The file was only partially uploaded. + Datoteka je samo djelomično prenesena. + + + No file was uploaded. + Niti jedna datoteka nije prenesena. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Privremena mapa nije konfigurirana u php.ini-u, ili konfigurirana mapa ne postoji. + + + Cannot write temporary file to disk. + Ne mogu zapisati privremenu datoteku na disk. + + + A PHP extension caused the upload to fail. + Prijenos datoteke nije uspio zbog PHP ekstenzije. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ova kolekcija treba sadržavati {{ limit }} ili više elemenata.|Ova kolekcija treba sadržavati {{ limit }} ili više elemenata.|Ova kolekcija treba sadržavati {{ limit }} ili više elemenata. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ova kolekcija treba sadržavati {{ limit }} ili manje elemenata.|Ova kolekcija treba sadržavati {{ limit }} ili manje elemenata.|Ova kolekcija treba sadržavati {{ limit }} ili manje elemenata. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ova kolekcija treba sadržavati točno {{ limit }} element.|Ova kolekcija treba sadržavati točno {{ limit }} elementa.|Ova kolekcija treba sadržavati točno {{ limit }} elemenata. + + + Invalid card number. + Neispravan broj kartice. + + + Unsupported card type or invalid card number. + Tip kartice nije podržan ili je broj kartice neispravan. + + + This value is not a valid International Bank Account Number (IBAN). + Ova vrijednost nije valjani međunarodni bankovni broj računa (IBAN). + + + This value is not a valid ISBN-10. + Ova vrijednost nije ispravan ISBN-10. + + + This value is not a valid ISBN-13. + Ova vrijednost nije ispravan ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ova vrijednost nije ispravan ISBN-10 niti ISBN-13. + + + This value is not a valid ISSN. + Ova vrijednost nije ispravan ISSN. + + + This value is not a valid currency. + Ova vrijednost nije ispravna valuta. + + + This value should be equal to {{ compared_value }}. + Ova vrijednost treba biti jednaka {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ova vrijednost treba biti veća od {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ova vrijednost treba biti veća od ili jednaka {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ova vrijednost treba biti {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ova vrijednost treba biti manja od {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ova vrijednost treba biti manja od ili jednaka {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ova vrijednost treba biti različita od {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ova vrijednost treba biti različita od {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Omjer slike je prevelik ({{ ratio }}). Dozvoljeni maksimalni omjer je {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Omjer slike je premali ({{ ratio }}). Minimalni očekivani omjer je {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Slika je kvadratnog oblika ({{ width }}x{{ height }}px). Kvadratne slike nisu dozvoljene. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Slika je orijentirana horizontalno ({{ width }}x{{ height }}px). Horizontalno orijentirane slike nisu dozvoljene. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Slika je orijentirana vertikalno ({{ width }}x{{ height }}px). Vertikalno orijentirane slike nisu dozvoljene. + + + An empty file is not allowed. + Prazna datoteka nije dozvoljena. + + + The host could not be resolved. + Poslužitelj ne može biti pronađen. + + + This value does not match the expected {{ charset }} charset. + Ova vrijednost ne odgovara očekivanom {{ charset }} znakovnom skupu. + + + This value is not a valid Business Identifier Code (BIC). + Ova vrijednost nije valjani poslovni identifikacijski kod (BIC). + + + Error + Greška + + + This value is not a valid UUID. + Ova vrijednost nije valjani UUID. + + + This value should be a multiple of {{ compared_value }}. + Ova vrijednost treba biti višekratnik od {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Poslovni identifikacijski broj (BIC) nije povezan sa IBAN brojem {{ iban }}. + + + This value should be valid JSON. + Ova vrijednost treba biti validan JSON. + + + This collection should contain only unique elements. + Ova kolekcija treba sadržavati samo unikatne elemente. + + + This value should be positive. + Ova vrijednost treba biti pozitivna. + + + This value should be either positive or zero. + Ova vrijednost treba biti pozitivna ili jednaka nuli. + + + This value should be negative. + Ova vrijednost treba biti negativna. + + + This value should be either negative or zero. + Ova vrijednost treba biti negativna ili jednaka nuli. + + + This value is not a valid timezone. + Ova vrijednost nije validna vremenska zona. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Ova lozinka je procurila u nekom od sigurnosnih propusta, te je potrebno koristiti drugu lozinku. + + + This value should be between {{ min }} and {{ max }}. + Ova vrijednost treba biti između {{ min }} i {{ max }}. + + + This value is not a valid hostname. + Ova vrijednost nije ispravno ime poslužitelja (engl. hostname). + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Broj elemenata u kolekciji treba biti djeljiv s {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Ova vrijednost mora zadovoljiti jedan od sljedećih ograničenja: + + + Each element of this collection should satisfy its own set of constraints. + Svaki element ove kolekcije mora zadovoljiti vlastiti skup ograničenja. + + + This value is not a valid International Securities Identification Number (ISIN). + Ova vrijednost nije ispravan međunarodni identifikacijski broj vrijednosnih papira (ISIN). + + + This value should be a valid expression. + Ova vrijednost mora biti valjani izraz. + + + This value is not a valid CSS color. + Ova vrijednost nije važeća CSS boja. + + + This value is not a valid CIDR notation. + Ova vrijednost nije valjana CIDR notacija. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Vrijednost mrežne maske trebala bi biti između {{ min }} i {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Naziv datoteke je predug. Treba imati {{ filename_max_length }} znak ili manje.|Naziv datoteke je predug. Treba imati {{ filename_max_length }} znaka ili manje.|Naziv datoteke je predug. Treba imati {{ filename_max_length }} znakova ili manje. + + + The password strength is too low. Please use a stronger password. + Jačina lozinke je preniska. Molim koristite jaču lozinku. + + + This value contains characters that are not allowed by the current restriction-level. + Ova vrijednost sadrži znakove koji nisu dopušteni prema trenutnoj razini ograničenja. + + + Using invisible characters is not allowed. + Korištenje nevidljivih znakova nije dopušteno. + + + Mixing numbers from different scripts is not allowed. + Miješanje brojeva iz različitih pisama nije dopušteno. + + + Using hidden overlay characters is not allowed. + Korištenje skrivenih preklapajućih znakova nije dopušteno. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Ekstenzija datoteke nije valjana ({{ extension }}). Dozvoljene ekstenzije su {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Otkriveno kodiranje znakova je nevažeće ({{ detected }}). Dopuštena kodiranja su {{ encodings }}. + + + This value is not a valid MAC address. + Ova vrijednost nije valjana MAC adresa. + + + This URL is missing a top-level domain. + Ovom URL-u nedostaje vršna domena. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Ova vrijednost je prekratka. Trebala bi sadržavati barem jednu riječ.|Ova vrijednost je prekratka. Trebala bi sadržavati barem {{ min }} riječi. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Ova vrijednost je predugačka. Trebala bi sadržavati samo jednu riječ.|Ova vrijednost je predugačka. Trebala bi sadržavati {{ max }} riječi ili manje. + + + This value does not represent a valid week in the ISO 8601 format. + Ova vrijednost ne predstavlja valjani tjedan u ISO 8601 formatu. + + + This value is not a valid week. + Ova vrijednost nije valjani tjedan. + + + This value should not be before week "{{ min }}". + Ova vrijednost ne bi trebala biti prije tjedna "{{ min }}". + + + This value should not be after week "{{ max }}". + Ova vrijednost ne bi trebala biti nakon tjedna "{{ max }}". + + + This value is not a valid Twig template. + Ova vrijednost nije valjani Twig predložak. + + + This file is not a valid video. + Ova datoteka nije valjani videozapis. + + + The size of the video could not be detected. + Veličina videozapisa nije mogla biti određena. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Širina videozapisa je prevelika ({{ width }}px). Dopuštenа maksimalna širina je {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Širina videozapisa je premala ({{ width }}px). Očekivana minimalna širina je {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Visina videozapisa je prevelika ({{ height }}px). Dopuštena maksimalna visina je {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Visina videozapisa je premala ({{ height }}px). Očekivana minimalna visina je {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Video ima premalo piksela ({{ pixels }}). Očekivani minimalni broj je {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Video ima previše piksela ({{ pixels }}). Očekivani maksimalni broj je {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Omjer videa je prevelik ({{ ratio }}). Dopušteni maksimalni omjer je {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Omjer videa je premalen ({{ ratio }}). Minimalni očekivani omjer je {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video je kvadratan ({{ width }}x{{ height }}px). Kvadratni videozapisi nisu dopušteni. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video je vodoravne orijentacije ({{ width }}x{{ height }} px). Vodoravni videozapisi nisu dopušteni. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video je okomite orijentacije ({{ width }}x{{ height }} px). Videozapisi okomite orijentacije nisu dopušteni. + + + The video file is corrupted. + Videodatoteka je oštećena. + + + The video contains multiple streams. Only one stream is allowed. + Video sadrži više tokova. Dopušten je samo jedan tok. + + + Unsupported video codec "{{ codec }}". + Nepodržani video kodek "{{ codec }}". + + + Unsupported video container "{{ container }}". + Nepodržani video spremnik "{{ container }}". + + + The image file is corrupted. + Datoteka slike je oštećena. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Slika ima premalo piksela ({{ pixels }}). Očekivani minimalni broj je {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Slika ima previše piksela ({{ pixels }}). Očekivani maksimalni broj je {{ max_pixels }}. + + + This filename does not match the expected charset. + Naziv ove datoteke ne odgovara očekivanom skupu znakova. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.hu.xlf b/lib/symfony/validator/Resources/translations/validators.hu.xlf new file mode 100644 index 0000000000..05bd279ae7 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.hu.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Ennek az értéknek hamisnak kell lennie. + + + This value should be true. + Ennek az értéknek igaznak kell lennie. + + + This value should be of type {{ type }}. + Ennek az értéknek {{ type }} típusúnak kell lennie. + + + This value should be blank. + Ennek az értéknek üresnek kell lennie. + + + The value you selected is not a valid choice. + A választott érték érvénytelen. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Legalább {{ limit }} értéket kell kiválasztani.|Legalább {{ limit }} értéket kell kiválasztani. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Legfeljebb {{ limit }} értéket lehet kiválasztani.|Legfeljebb {{ limit }} értéket lehet kiválasztani. + + + One or more of the given values is invalid. + A megadott értékek közül legalább egy érvénytelen. + + + This field was not expected. + Nem várt mező. + + + This field is missing. + Ez a mező hiányzik. + + + This value is not a valid date. + Ez az érték nem egy érvényes dátum. + + + This value is not a valid datetime. + Ez az érték nem egy érvényes időpont. + + + This value is not a valid email address. + Ez az érték nem egy érvényes e-mail cím. + + + The file could not be found. + A fájl nem található. + + + The file is not readable. + A fájl nem olvasható. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + A fájl túl nagy ({{ size }} {{ suffix }}). A legnagyobb megengedett méret {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + A fájl MIME típusa érvénytelen ({{ type }}). Az engedélyezett MIME típusok: {{ types }}. + + + This value should be {{ limit }} or less. + Ez az érték legfeljebb {{ limit }} lehet. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Ez az érték túl hosszú. Legfeljebb {{ limit }} karaktert tartalmazhat.|Ez az érték túl hosszú. Legfeljebb {{ limit }} karaktert tartalmazhat. + + + This value should be {{ limit }} or more. + Ez az érték legalább {{ limit }} kell, hogy legyen. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Ez az érték túl rövid. Legalább {{ limit }} karaktert kell tartalmaznia.|Ez az érték túl rövid. Legalább {{ limit }} karaktert kell tartalmaznia. + + + This value should not be blank. + Ez az érték nem lehet üres. + + + This value should not be null. + Ez az érték nem lehet null. + + + This value should be null. + Ennek az értéknek nullnak kell lennie. + + + This value is not valid. + Ez az érték nem érvényes. + + + This value is not a valid time. + Ez az érték nem egy érvényes időpont. + + + This value is not a valid URL. + Ez az érték nem egy érvényes URL. + + + The two values should be equal. + A két értéknek azonosnak kell lennie. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + A fájl túl nagy. A megengedett maximális méret: {{ limit }} {{ suffix }}. + + + The file is too large. + A fájl túl nagy. + + + The file could not be uploaded. + A fájl nem tölthető fel. + + + This value should be a valid number. + Ennek az értéknek érvényes számnak kell lennie. + + + This file is not a valid image. + Ez a fájl nem egy érvényes kép. + + + This value is not a valid IP address. + Ez az érték nem érvényes IP-cím. + + + This value is not a valid language. + Ez az érték nem egy érvényes nyelv. + + + This value is not a valid locale. + Ez az érték nem egy érvényes területi beállítás. + + + This value is not a valid country. + Ez az érték nem egy érvényes ország. + + + This value is already used. + Ez az érték már használatban van. + + + The size of the image could not be detected. + A kép méretét nem lehet megállapítani. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + A kép szélessége túl nagy ({{ width }}px). A megengedett legnagyobb szélesség {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + A kép szélessége túl kicsi ({{ width }}px). Az elvárt legkisebb szélesség {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + A kép magassága túl nagy ({{ height }}px). A megengedett legnagyobb magasság {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + A kép magassága túl kicsi ({{ height }}px). Az elvárt legkisebb magasság {{ min_height }}px. + + + This value should be the user's current password. + Ez az érték a felhasználó jelenlegi jelszavával kell megegyezzen. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ennek az értéknek pontosan {{ limit }} karaktert kell tartalmaznia.|Ennek az értéknek pontosan {{ limit }} karaktert kell tartalmaznia. + + + The file was only partially uploaded. + A fájl csak részben lett feltöltve. + + + No file was uploaded. + Nem lett fájl feltöltve. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Nem lett ideiglenes mappa beállítva a php.ini-ben, vagy a beállított mappa nem létezik. + + + Cannot write temporary file to disk. + Az ideiglenes fájl nem írható a lemezre. + + + A PHP extension caused the upload to fail. + Egy PHP bővítmény miatt a feltöltés nem sikerült. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ennek a gyűjteménynek legalább {{ limit }} elemet kell tartalmaznia.|Ennek a gyűjteménynek legalább {{ limit }} elemet kell tartalmaznia. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ez a gyűjtemény legfeljebb {{ limit }} elemet tartalmazhat.|Ez a gyűjtemény legfeljebb {{ limit }} elemet tartalmazhat. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ennek a gyűjteménynek pontosan {{ limit }} elemet kell tartalmaznia.|Ennek a gyűjteménynek pontosan {{ limit }} elemet kell tartalmaznia. + + + Invalid card number. + Érvénytelen kártyaszám. + + + Unsupported card type or invalid card number. + Nem támogatott kártyatípus vagy érvénytelen kártyaszám. + + + This value is not a valid International Bank Account Number (IBAN). + Ez az érték nem érvényes Nemzetközi Bankszámlaszám (IBAN). + + + This value is not a valid ISBN-10. + Ez az érték nem egy érvényes ISBN-10. + + + This value is not a valid ISBN-13. + Ez az érték nem egy érvényes ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ez az érték nem egy érvényes ISBN-10 vagy ISBN-13. + + + This value is not a valid ISSN. + Ez az érték nem egy érvényes ISSN. + + + This value is not a valid currency. + Ez az érték nem egy érvényes pénznem. + + + This value should be equal to {{ compared_value }}. + Ez az érték legyen {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ez az érték nagyobb legyen, mint {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ez az érték nagyobb vagy egyenlő legyen, mint {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ez az érték ugyanolyan legyen, mint {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ez az érték kisebb legyen, mint {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ez az érték kisebb vagy egyenlő legyen, mint {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ez az érték ne legyen {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ez az érték ne legyen ugyanolyan, mint {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + A képarány túl nagy ({{ ratio }}). A megengedett legnagyobb képarány {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + A képarány túl kicsi ({{ ratio }}). A megengedett legkisebb képarány {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + A kép négyzet alakú ({{ width }}x{{ height }}px). A négyzet alakú képek nem engedélyezettek. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + A kép fekvő tájolású ({{ width }}x{{ height }}px). A fekvő tájolású képek nem engedélyezettek. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + A kép álló tájolású ({{ width }}x{{ height }}px). Az álló tájolású képek nem engedélyezettek. + + + An empty file is not allowed. + Üres fájl nem megengedett. + + + The host could not be resolved. + Az állomásnevet nem lehet feloldani. + + + This value does not match the expected {{ charset }} charset. + Ez az érték nem az elvárt {{ charset }} karakterkódolást használja. + + + This value is not a valid Business Identifier Code (BIC). + Ez az érték nem érvényes Üzleti Azonosító Kód (BIC). + + + Error + Hiba + + + This value is not a valid UUID. + Ez az érték nem érvényes UUID. + + + This value should be a multiple of {{ compared_value }}. + Ennek az értéknek oszthatónak kell lennie a következővel: {{ compared_value }} + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Ez a Bankazonosító kód (BIC) nem kapcsolódik az IBAN kódhoz ({{ iban }}). + + + This value should be valid JSON. + Ez az érték érvényes JSON kell, hogy legyen. + + + This collection should contain only unique elements. + Ez a gyűjtemény csak egyedi elemeket tartalmazhat. + + + This value should be positive. + Ennek az értéknek pozitívnak kell lennie. + + + This value should be either positive or zero. + Ennek az értéknek pozitívnak vagy nullának kell lennie. + + + This value should be negative. + Ennek az értéknek negatívnak kell lennie. + + + This value should be either negative or zero. + Ennek az értéknek negatívnak vagy nullának kell lennie. + + + This value is not a valid timezone. + Ez az érték nem egy érvényes időzóna. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Ez a jelszó korábban egy adatvédelmi incidens során illetéktelenek kezébe került, így nem használható. Kérjük, használjon másik jelszót. + + + This value should be between {{ min }} and {{ max }}. + Ennek az értéknek {{ min }} és {{ max }} között kell lennie. + + + This value is not a valid hostname. + Ez az érték nem egy érvényes állomásnév (hosztnév). + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + A gyűjteményben lévő elemek számának oszthatónak kell lennie a következővel: {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Ennek az értéknek meg kell felelni legalább egynek a következő feltételek közül: + + + Each element of this collection should satisfy its own set of constraints. + A gyűjtemény minden elemének meg kell felelni a saját feltételeinek. + + + This value is not a valid International Securities Identification Number (ISIN). + Ez az érték nem egy érvényes nemzetközi értékpapír-azonosító szám (ISIN). + + + This value should be a valid expression. + Ennek az értéknek érvényes kifejezésnek kell lennie. + + + This value is not a valid CSS color. + Ez az érték nem egy érvényes CSS szín. + + + This value is not a valid CIDR notation. + Ez az érték nem egy érvényes CIDR jelölés. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Ennek a netmask értéknek {{ min }} és {{ max }} között kell lennie. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + A fájlnév túl hosszú. {{ filename_max_length }} karakter vagy kevesebb legyen.|A fájlnév túl hosszú. {{ filename_max_length }} karakter vagy kevesebb legyen. + + + The password strength is too low. Please use a stronger password. + A jelszó túl egyszerű. Kérjük, használjon egy erősebb jelszót. + + + This value contains characters that are not allowed by the current restriction-level. + Ez az érték olyan karaktereket tartalmaz, amik nem megengedettek. + + + Using invisible characters is not allowed. + Láthatatlan karakterek használata nem megengedett. + + + Mixing numbers from different scripts is not allowed. + Különböző szám írásmódok használata nem megengedett. + + + Using hidden overlay characters is not allowed. + Rejtett módosító karakterek használata nem megengedett. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + A fájl kiterjesztése érvénytelen ({{ extension }}). Engedélyezett kiterjesztések: {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Az érzékelt karakterkódolás érvénytelen ({{ detected }}). Engedélyezett karakterkódolások: {{ encodings }}. + + + This value is not a valid MAC address. + Ez az érték nem érvényes MAC-cím. + + + This URL is missing a top-level domain. + Az URL-ből hiányzik a legfelső szintű tartomány (top-level domain). + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Ez az érték túl rövid. Tartalmaznia kell legalább egy szót.|Ez az érték túl rövid. Tartalmaznia kell legalább {{ min }} szót. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Ez az érték túl hosszú. Csak egy szót tartalmazhat.|Ez az érték túl hosszú. Legfeljebb {{ max }} szót vagy kevesebbet tartalmazhat. + + + This value does not represent a valid week in the ISO 8601 format. + Ez a érték érvénytelen hetet jelent az ISO 8601 formátumban. + + + This value is not a valid week. + Ez az érték érvénytelen hét. + + + This value should not be before week "{{ min }}". + Ez az érték nem lehet a "{{ min }}". hétnél korábbi. + + + This value should not be after week "{{ max }}". + Ez az érték nem lehet a "{{ max }}". hétnél későbbi. + + + This value is not a valid Twig template. + Ez az érték nem érvényes Twig sablon. + + + This file is not a valid video. + Ez a fájl nem érvényes videó. + + + The size of the video could not be detected. + A videó méretét nem sikerült megállapítani. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + A videó szélessége túl nagy ({{ width }}px). A megengedett maximális szélesség {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + A videó szélessége túl kicsi ({{ width }}px). A várható minimális szélesség {{ min_width }} px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + A videó magassága túl nagy ({{ height }}px). A megengedett maximális magasság {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + A videó magassága túl kicsi ({{ height }}px). A minimálisan elvárt magasság {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + A videóban túl kevés a képpont ({{ pixels }}). Az elvárt minimális mennyiség {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + A videóban túl sok a képpont ({{ pixels }}). A várható maximális mennyiség {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + A videó aránya túl nagy ({{ ratio }}). A megengedett maximális arány {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + A videó képaránya túl kicsi ({{ ratio }}). A minimálisan elvárt arány {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + A videó négyzetes ({{ width }}x{{ height }}px). A négyzetes videók nem engedélyezettek. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + A videó fekvő tájolású ({{ width }}x{{ height }} px). Fekvő tájolású videók nem engedélyezettek. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + A videó álló tájolású ({{ width }}x{{ height }} px). Álló tájolású videók nem engedélyezettek. + + + The video file is corrupted. + A videófájl sérült. + + + The video contains multiple streams. Only one stream is allowed. + A videó több adatfolyamot tartalmaz. Csak egy adatfolyam engedélyezett. + + + Unsupported video codec "{{ codec }}". + Nem támogatott videokodek „{{ codec }}”. + + + Unsupported video container "{{ container }}". + Nem támogatott videokonténer "{{ container }}". + + + The image file is corrupted. + A képfájl sérült. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + A képen túl kevés pixel van ({{ pixels }}). Az elvárt minimum {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + A kép túl sok pixelt tartalmaz ({{ pixels }}). A várható maximális mennyiség {{ max_pixels }}. + + + This filename does not match the expected charset. + Ez a fájlnév nem felel meg a várt karakterkészletnek. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.hy.xlf b/lib/symfony/validator/Resources/translations/validators.hy.xlf new file mode 100644 index 0000000000..e537733c76 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.hy.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Արժեքը պետք է լինի կեղծ։ + + + This value should be true. + Արժեքը պետք է լինի իրական։ + + + This value should be of type {{ type }}. + Արժեքը պետք է լինի {{ type }} տեսակի։ + + + This value should be blank. + Արժեքը պետք է լինի դատարկ։ + + + The value you selected is not a valid choice. + Ձեր ընտրած արժեքը անվավեր ընտրություն է։ + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Դուք պետք է ընտրեք ամենաքիչը {{ limit }} տարբերակներ։ + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Դուք պետք է ընտրեք ոչ ավելի քան {{ limit }} տարբերակներ։ + + + One or more of the given values is invalid. + Մեկ կամ ավելի տրված արժեքները անվավեր են։ + + + This field was not expected. + Այս դաշտը չի սպասվում։ + + + This field is missing. + Այս դաշտը բացակայում է։ + + + This value is not a valid date. + Արժեքը սխալ ամսաթիվ է։ + + + This value is not a valid datetime. + Ամսաթվի և ժամանակի արժեքը անվավեր է։ + + + This value is not a valid email address. + Անվավեր էլ֊փոստի արժեք։ + + + The file could not be found. + Նիշքը չի գտնվել։ + + + The file is not readable. + Նիշքը անընթեռնելի է։ + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Նիշքը չափազանց մեծ է ({{ size }} {{ suffix }}): Մաքսիմալ թույլատրելի չափսը՝ {{ limit }} {{ suffix }}։ + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + MIME-տեսակը անվավեր է է({{ type }}): Նիշքերի թույլատրելի MIME-տեսակներն են: {{ types }}։ + + + This value should be {{ limit }} or less. + Արժեքը պետք է լինի {{ limit }} կամ փոքր։ + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Արժեքը չափազանց երկար է: Պետք է լինի {{ limit }} կամ ավել սիմվոլներ։ + + + This value should be {{ limit }} or more. + Արժեքը պետ է լինի {{ limit }} կամ շատ։ + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Արժեքը չափազանց կարճ է: Պետք է լինի {{ limit }} կամ ավելի սիմվոլներ։ + + + This value should not be blank. + Արժեքը չպետք է դատարկ լինի։ + + + This value should not be null. + Արժեքը չպետք է լինի null։ + + + This value should be null. + Արժեքը պետք է լինի null։ + + + This value is not valid. + Անվավեր արժեք։ + + + This value is not a valid time. + Ժամանակի արժեքը անվավեր է։ + + + This value is not a valid URL. + Արժեքը URL չէ։ + + + The two values should be equal. + Երկու արժեքները պետք է նույնը լինեն։ + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Նիշքը չափազանց մեծ է: Մաքսիմալ թույլատրելի չափսը {{ limit }} {{ suffix }} է։ + + + The file is too large. + Նիշքը չափազանց մեծ է։ + + + The file could not be uploaded. + Նիշքը չի կարող բեռնվել։ + + + This value should be a valid number. + Արժեքը պետք է լինի թիվ։ + + + This file is not a valid image. + Նիշքը նկարի վավեր ֆորմատ չէ։ + + + This value is not a valid IP address. + Այս արժեքը վավեր IP հասցե չէ։ + + + This value is not a valid language. + Արժեքը վավեր լեզու չէ։ + + + This value is not a valid locale. + Արժեքը չի հանդիսանում վավեր տեղայնացում։ + + + This value is not a valid country. + Արժեքը պետք է լինի երկիր։ + + + This value is already used. + Այդ արժեքն արդեն օգտագործվում է։ + + + The size of the image could not be detected. + Նկարի չափսերը չստացվեց որոշել։ + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Նկարի լայնությունը չափազանց մեծ է({{ width }}px). Մաքսիմալ չափն է {{ max_width }}px։ + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Նկարի լայնությունը չափազանց փոքր է ({{ width }}px). Մինիմալ չափն է {{ min_ width }}px։ + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Նկարի բարձրությունը չափազանց մեծ է ({{ height }}px). Մաքսիմալ չափն է {{ max_height }}px։ + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Նկարի բարձրությունը չափազանց փոքր է ({{ height }}px). Մինիմալ չափն է {{ min_height }}px։ + + + This value should be the user's current password. + Այս արժեքը պետք է լինի օգտագործողի ներկա ծածկագիրը։ + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Այս արժեքը պետք է ունենա ճիշտ {{ limit }} սիմվոլներ։ + + + The file was only partially uploaded. + Նիշքի մասնակի բեռնման սխալ։ + + + No file was uploaded. + Նիշքը չի բեռնվել։ + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + php.ini-ում չի կարգավորվել ժամանակավոր թղթապանակ, կամ կարգավորված թղթապանակը չկա։ + + + Cannot write temporary file to disk. + Ժամանակավոր նիշքը հնարավոր չէ գրել սկավառակի վրա։ + + + A PHP extension caused the upload to fail. + PHP ֆորմատը դարձել է բեռնման չհաջողման պատճառ։ + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Այս համախումբը պետք է պաուրակի {{ limit }} կամ ավելի տարրեր։|Այս հավելվածը պետք է պարունակի limit }} տարր կամ ավելին։|Այս համախումբը պետք է պարունակի {{ limit }} տարրերին կամ ավելի։ + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Այս համախումբը պետք է պաուրակի {{ limit }} տարրեր կամ քիչ։|Այս համախումբը պետք է պաուրակի {{ limit }} տարր կամ քիչ։|Այս համախումբը պետք է պաուրակի {{ limit }} տարրեր կամ քիչ։ + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Այս համախումբը պետք է պաուրակի ուղիղ {{ limit }} տարր։|Այս համախումբը պետք է պաուրակի ուղիղ {{ limit }} տարրեր։|Այս համախումբը պետք է պաուրակի {{ limit }} տարրեր։ + + + Invalid card number. + Քարտի սխալ համար: + + + Unsupported card type or invalid card number. + Չսպասարկվող կամ սխալ քարտի համար: + + + This value is not a valid International Bank Account Number (IBAN). + Այս արժեքը վավեր միջազգային բանկային հաշվի համար (IBAN) չէ։ + + + This value is not a valid ISBN-10. + Արժեքը ունի անվավեր ISBN-10 ձևաչափ։ + + + This value is not a valid ISBN-13. + Արժեքը ունի անվավեր ISBN-13 ձևաչափ։ + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Արժեքը չի համապատասխանում ISBN-10 և ISBN-13 ձևաչափերին։ + + + This value is not a valid ISSN. + Արժեքը չի համապաստասխանում ISSN ձևաչափին։ + + + This value is not a valid currency. + Արժեքը վավեր տարադրամ չէ։ + + + This value should be equal to {{ compared_value }}. + Արժեքը պետք է լինի {{ compared_value }}։ + + + This value should be greater than {{ compared_value }}. + Արժեքը պետք է մեծ լինի, քան {{ compared_value }}։ + + + This value should be greater than or equal to {{ compared_value }}. + Արժեքը պետք է լինի հավասար կամ մեծ քան {{ compared_value }}։ + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Արժեքը պետք է լինի ինչպես {{ compared_value_type }} {{ compared_value }}։ + + + This value should be less than {{ compared_value }}. + Արժեքը պետք է լինի փոքր քան {{ compared_value }}։ + + + This value should be less than or equal to {{ compared_value }}. + Արժեքը պետք է լինի փոքր կամ հավասար {{ compared_value }}։ + + + This value should not be equal to {{ compared_value }}. + Արժեքը պետք է լինի հավասար {{ compared_value }}։ + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Արժեքը պետք է լինի նունը {{ compared_value_type }} {{ compared_value }}: + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Պատկերի կողմերի հարաբերակցությունը խիստ մեծ է ({{ ratio }}). Մաքսիմալ հարաբերակցությունը՝ {{ max_ratio }}։ + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Պատկերի կողմերի հարաբերակցությունը խիստ փոքր է ({{ ratio }}). Մինիմալ հարաբերակցությունը՝ {{ min_ratio }}։ + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Պատկերը քառակուսի է({{ width }}x{{ height }}px)։ Քառակուսի նկարներ չեն թույլատրվում։ + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Պատկերը ալբոմային ուղղվածության է({{ width }}x{{ height }}px)․ դա չի թույլատրվում։ + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Պատկերը պորտրետային ուղղվածության է ({{ width }}x{{ height }}px)․ դա չի թույլատրվում։ + + + An empty file is not allowed. + Դատարկ նիշք չի թույլատրվում։ + + + The host could not be resolved. + Հոսթի անունը հնարավոր չի պարզել։ + + + This value does not match the expected {{ charset }} charset. + Արժեքը չի համընկնում {{ charset }} կոդավորման հետ։ + + + This value is not a valid Business Identifier Code (BIC). + Այս արժեքը վավեր բիզնեսի նորմատիվ կոդ (BIC) չէ։ + + + Error + Սխալ + + + This value is not a valid UUID. + Այս արժեքը վավեր UUID չէ։ + + + This value should be a multiple of {{ compared_value }}. + Այս արժեքը պետք է լինի բազմակի {{ compared_value }}։ + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Բիզնեսի նույնականացման կոդը (BIC) կապված չէ IBAN- ի հետ {{ iban }}։ + + + This value should be valid JSON. + Այս արժեքը պետք է լինի վավեր JSON։ + + + This collection should contain only unique elements. + Այս համախումբը պետք է պարունակի միայն եզակի տարրեր։ + + + This value should be positive. + Այս արժեքը պետք է լինի դրական։ + + + This value should be either positive or zero. + Այս արժեքը պետք է լինի դրական կամ զրոյական։ + + + This value should be negative. + Այս արժեքը պետք է լինի բացասական։ + + + This value should be either negative or zero. + Այս արժեքը պետք է լինի բացասական կամ զրոյական։ + + + This value is not a valid timezone. + Այս արժեքը վավեր ժամային գոտի չէ։ + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Գաղտնաբառը գտնվել է տվյալների արտահոսքում. այն չպետք է օգտագործվի: Խնդրում ենք օգտագործել մեկ այլ գաղտնաբառ։ + + + This value should be between {{ min }} and {{ max }}. + Այս արժեքը պետք է լինի {{ min }}-ի և {{ max }}-ի միջև։ + + + This value is not a valid hostname. + Այս հոստի անունը վավեր չէ։ + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Այս համախմբի տարրերի քանակը պետք է հավասար լինի {{ compared_value }}-ի բազմապատիկներին։ + + + This value should satisfy at least one of the following constraints: + Այս արժեքը պետք է բավարարի հետևյալ սահմանափակումներից առնվազն մեկը։ + + + Each element of this collection should satisfy its own set of constraints. + Այս համախմբի յուրաքանչյուր տարր պետք է բավարարի իր սեփական սահմանափակումները։ + + + This value is not a valid International Securities Identification Number (ISIN). + Այս արժեքը արժեթղթերի նույնականացման միջազգային համարը վավեր չէ(ISIN)։ + + + This value should be a valid expression. + Այս արժեքը պետք է լինի վավեր արտահայտություն: + + + This value is not a valid CSS color. + Այս արժեքը վավեր CSS գույն չէ։ + + + This value is not a valid CIDR notation. + Այս արժեքը վավեր CIDR նշում չէ։ + + + The value of the netmask should be between {{ min }} and {{ max }}. + Ցանցային դիմակի արժեքը պետք է լինի {{ min }}-ի և {{ max }}-ի միջև։ + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Ֆայլի անունը շատ երկար է։ Այն պետք է ունենա {{ filename_max_length }} նիշ կամ պակաս։ + + + The password strength is too low. Please use a stronger password. + Գաղտնաբառի անվտանգությունը շատ ցածր է։ Խնդրում ենք գործածել ավելի ամրագույն գաղտնաբառ։ + + + This value contains characters that are not allowed by the current restriction-level. + Այս արժեքը պարունակում է այն նիշերը, որոնք չեն թույլատրվում ըստ ընթացիկ սահմանումների։ + + + Using invisible characters is not allowed. + Անտեսանելի նիշերի օգտագործումը չի թույլատրվում։ + + + Mixing numbers from different scripts is not allowed. + Թվերի խառնուրդը տարբեր սցենարներից չի թույլատրվում։ + + + Using hidden overlay characters is not allowed. + Թաքնված ծածկանիշերի օգտագործումը չի թույլատրվում։ + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Ֆայլի ընդլայնումը անվավեր է ({{ extension }})։ Թույլատրվող ընդլայնումներն են՝ {{ extensions }}։ + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Հայտնաբերված նիշագրության կոդը անվավեր է ({{ detected }})։ Թույլատրվող կոդերն են՝ {{ encodings }}։ + + + This value is not a valid MAC address. + Այս արժեքը վավեր MAC հասցե չէ։ + + + This URL is missing a top-level domain. + Այս URL-ը չունի վերին մակարդակի դոմեյն: + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Այս արժեքը շատ կարճ է: պետք է պարունակի գոնե մեկ բառ.|Այս արժեքը շատ կարճ է: պետք է պարունակի գոնե {{ min }} բառեր: + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Այս արժեքը շատ երկար է: պետք է պարունակի միայն մեկ բառ.|Այս արժեքը շատ երկար է: պետք է պարունակի {{ max }} բառ կամ ավելի քիչ: + + + This value does not represent a valid week in the ISO 8601 format. + Այս արժեքը չի ներկայացնում ISO 8601 ձևաչափով գործող շաբաթ։ + + + This value is not a valid week. + Այս արժեքը վավեր շաբաթ չէ: + + + This value should not be before week "{{ min }}". + Այս արժեքը չպետք է լինի «{{ min }}» շաբաթից առաջ։ + + + This value should not be after week "{{ max }}". + Այս արժեքը չպետք է լինի «{{ max }}» շաբաթից հետո։ + + + This value is not a valid Twig template. + Այս արժեքը վավեր Twig ձևանմուշ չէ: + + + This file is not a valid video. + Այս ֆայլը վավեր տեսանյութ չէ։ + + + The size of the video could not be detected. + Չհաջողվեց հայտնաբերել տեսանյութի չափը. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Տեսահոլովակի լայնությունը չափազանց մեծ է ({{ width }}px)։ Թույլատրելի առավելագույն լայնությունը {{ max_width }}px է։ + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Տեսանյութի լայնությունը չափազանց փոքր է ({{ width }}px). Սպասվող նվազագույն լայնքը {{ min_width }}px է. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Վիդեոյի բարձրությունը չափազանց մեծ է ({{ height }}px)։ Թույլատրելի առավելագույն բարձրությունը {{ max_height }}px է։ + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Վիդեոյի բարձրությունը շատ փոքր է ({{ height }}px)։ Սպասվող նվազագույն բարձրությունը {{ min_height }}px է։ + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Տեսանյութը ունի չափազանց քիչ պիքսելներ ({{ pixels }}). Սպասվող նվազագույն քանակը {{ min_pixels }} է։ + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Տեսանյութը ունի չափազանց շատ պիքսելներ ({{ pixels }}). Սպասվող առավելագույն քանակը {{ max_pixels }} է։ + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Տեսանյութի հարաբերակցությունը չափազանց մեծ է ({{ ratio }}): Թույլատրելի առավելագույն հարաբերակցությունը {{ max_ratio }} է։ + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Վիդեոյի հարաբերակցությունը շատ փոքր է ({{ ratio }}). Ավելի փոքրագույն սպասվող հարաբերակցությունը {{ min_ratio }} է. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Տեսանյութը քառակուսի է ({{ width }}x{{ height }}px). Քառակուսի տեսանյութերը թույլատրելի չեն. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Տեսանյութը հորիզոնական կողմնորոշմամբ է ({{ width }}x{{ height }} px). Հորիզոնական տեսանյութերը թույլատրելի չեն. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Վիդեոն ուղղահայաց կողմնորոշված է ({{ width }}x{{ height }}px)։ Ուղղահայաց կողմնորոշմամբ տեսանյութերը թույլատրելի չեն։ + + + The video file is corrupted. + Տեսանյութի ֆայլը վնասված է. + + + The video contains multiple streams. Only one stream is allowed. + Տեսանյութը պարունակում է բազմաթիվ հոսքեր։ Թույլատրվում է միայն մեկ հոսք։ + + + Unsupported video codec "{{ codec }}". + Չաջակցվող տեսանյութի կոդեկ «{{ codec }}»։ + + + Unsupported video container "{{ container }}". + Չաջակցվող վիդեո կոնտեյներ "{{ container }}". + + + The image file is corrupted. + Պատկերի ֆայլը վնասված է։ + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Պատկերը ունի չափազանց քիչ պիքսելներ ({{ pixels }}). Սպասվող նվազագույնը {{ min_pixels }} է։ + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Պատկերը ունի չափազանց շատ պիքսել ({{ pixels }}). Սպասվող առավելագույն քանակը {{ max_pixels }} է. + + + This filename does not match the expected charset. + Այս ֆայլի անունը չի համապատասխանում սպասվող նիշքերի հավաքածուին. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.id.xlf b/lib/symfony/validator/Resources/translations/validators.id.xlf new file mode 100644 index 0000000000..b303d50e18 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.id.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Nilai ini harus bernilai salah. + + + This value should be true. + Nilai ini harus bernilai benar. + + + This value should be of type {{ type }}. + Nilai ini harus bertipe {{ type }}. + + + This value should be blank. + Nilai ini harus kosong. + + + The value you selected is not a valid choice. + Nilai yang dipilih tidak tepat. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Anda harus memilih paling tidak {{ limit }} pilihan. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Anda harus memilih paling banyak {{ limit }} pilihan. + + + One or more of the given values is invalid. + Satu atau lebih nilai yang diberikan tidak sah. + + + This field was not expected. + Ruas ini tidak diharapkan. + + + This field is missing. + Ruas ini hilang. + + + This value is not a valid date. + Nilai ini bukan merupakan tanggal yang sah. + + + This value is not a valid datetime. + Nilai ini bukan merupakan tanggal dan waktu yang sah. + + + This value is not a valid email address. + Nilai ini bukan alamat surel yang sah. + + + The file could not be found. + Berkas tidak dapat ditemukan. + + + The file is not readable. + Berkas tidak dapat dibaca. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Ukuran berkas terlalu besar ({{ size }} {{ suffix }}). Ukuran maksimum yang diizinkan adalah {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Jenis berkas ({{ type }}) tidak sah. Jenis berkas yang diizinkan adalah {{ types }}. + + + This value should be {{ limit }} or less. + Nilai ini harus {{ limit }} atau kurang. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Nilai ini terlalu panjang. Seharusnya {{ limit }} karakter atau kurang. + + + This value should be {{ limit }} or more. + Nilai ini harus {{ limit }} atau lebih. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Nilai ini terlalu pendek. Seharusnya {{ limit }} karakter atau lebih. + + + This value should not be blank. + Nilai ini tidak boleh kosong. + + + This value should not be null. + Nilai ini tidak boleh 'null'. + + + This value should be null. + Nilai ini harus 'null'. + + + This value is not valid. + Nilai ini tidak sah. + + + This value is not a valid time. + Nilai ini bukan merupakan waktu yang sah. + + + This value is not a valid URL. + Nilai ini bukan URL yang sah. + + + The two values should be equal. + Isi keduanya harus sama. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Ukuran berkas terlalu besar. Ukuran maksimum yang diizinkan adalah {{ limit }} {{ suffix }}. + + + The file is too large. + Ukuran berkas terlalu besar. + + + The file could not be uploaded. + Berkas tidak dapat diunggah. + + + This value should be a valid number. + Nilai ini harus angka yang sah. + + + This file is not a valid image. + Berkas ini tidak termasuk citra. + + + This value is not a valid IP address. + Nilai ini bukan alamat IP yang valid. + + + This value is not a valid language. + Nilai ini bukan bahasa yang sah. + + + This value is not a valid locale. + Nilai ini bukan lokal yang sah. + + + This value is not a valid country. + Nilai ini bukan negara yang sah. + + + This value is already used. + Nilai ini sudah digunakan. + + + The size of the image could not be detected. + Ukuran dari citra tidak bisa dideteksi. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Lebar citra terlalu besar ({{ width }}px). Ukuran lebar maksimum adalah {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Lebar citra terlalu kecil ({{ width }}px). Ukuran lebar minimum yang diharapkan adalah {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Tinggi citra terlalu besar ({{ height }}px). Ukuran tinggi maksimum adalah {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Tinggi citra terlalu kecil ({{ height }}px). Ukuran tinggi minimum yang diharapkan adalah {{ min_height }}px. + + + This value should be the user's current password. + Nilai ini harus kata sandi pengguna saat ini. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Nilai ini harus memiliki tepat {{ limit }} karakter. + + + The file was only partially uploaded. + Berkas hanya terunggah sebagian. + + + No file was uploaded. + Tidak ada berkas terunggah. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Tidak ada folder sementara yang dikonfigurasi di php.ini, atau folder yang dikonfigurasi tidak ada. + + + Cannot write temporary file to disk. + Tidak dapat menuliskan berkas sementara ke dalam media penyimpanan. + + + A PHP extension caused the upload to fail. + Sebuah ekstensi PHP menyebabkan kegagalan unggah. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Kumpulan ini harus memiliki {{ limit }} elemen atau lebih. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Kumpulan ini harus memiliki kurang dari {{ limit }} elemen. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Kumpulan ini harus memiliki tepat {{ limit }} elemen. + + + Invalid card number. + Nomor kartu tidak sah. + + + Unsupported card type or invalid card number. + Jenis kartu tidak didukung atau nomor kartu tidak sah. + + + This value is not a valid International Bank Account Number (IBAN). + Nilai ini bukan Nomor Rekening Bank Internasional (IBAN) yang valid. + + + This value is not a valid ISBN-10. + Nilai ini bukan ISBN-10 yang sah. + + + This value is not a valid ISBN-13. + Nilai ini bukan ISBN-13 yang sah. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Nilai ini bukan ISBN-10 maupun ISBN-13 yang sah. + + + This value is not a valid ISSN. + Nilai ini bukan ISSN yang sah. + + + This value is not a valid currency. + Nilai ini bukan mata uang yang sah. + + + This value should be equal to {{ compared_value }}. + Nilai ini seharusnya sama dengan {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Nilai ini seharusnya lebih dari {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Nilai ini seharusnya lebih dari atau sama dengan {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Nilai ini seharusnya identik dengan {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Nilai ini seharusnya kurang dari {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Nilai ini seharusnya kurang dari atau sama dengan {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Nilai ini seharusnya tidak sama dengan {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Nilai ini seharusnya tidak identik dengan {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Rasio citra terlalu besar ({{ ratio }}). Rasio maksimum yang diizinkan adalah {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Rasio citra terlalu kecil ({{ ratio }}). Rasio minimum yang diharapkan adalah {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Citra persegi ({{ width }}x{{ height }}px). Citra persegi tidak diizinkan. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Citra berorientasi lanskap ({{ width }}x{{ height }}px). Citra berorientasi lanskap tidak diizinkan. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Citra berorientasi potret ({{ width }}x{{ height }}px). Citra berorientasi potret tidak diizinkan. + + + An empty file is not allowed. + Berkas kosong tidak diizinkan. + + + The host could not be resolved. + Host tidak dapat diselesaikan. + + + This value does not match the expected {{ charset }} charset. + Nilai ini tidak memenuhi set karakter {{ charset }} yang diharapkan. + + + This value is not a valid Business Identifier Code (BIC). + Nilai ini bukan Kode Identifikasi Bisnis (BIC) yang valid. + + + Error + Galat + + + This value is not a valid UUID. + Nilai ini bukan UUID yang valid. + + + This value should be a multiple of {{ compared_value }}. + Nilai ini harus kelipatan dari {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Business Identifier Code (BIC) ini tidak terkait dengan IBAN {{ iban }}. + + + This value should be valid JSON. + Nilai ini harus berisi JSON yang sah. + + + This collection should contain only unique elements. + Kumpulan ini harus mengandung elemen yang unik. + + + This value should be positive. + Nilai ini harus positif. + + + This value should be either positive or zero. + Nilai ini harus positif atau nol. + + + This value should be negative. + Nilai ini harus negatif. + + + This value should be either negative or zero. + Nilai ini harus negatif atau nol. + + + This value is not a valid timezone. + Nilai ini harus merupakan zona waktu yang sah. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Kata sandi ini telah bocor di data breach, harus tidak digunakan kembali. Silahkan gunakan kata sandi yang lain. + + + This value should be between {{ min }} and {{ max }}. + Nilai ini harus berada diantara {{ min }} dan {{ max }}. + + + This value is not a valid hostname. + Nilai ini bukan merupakan hostname yang sah. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Angka dari setiap elemen di dalam kumpulan ini harus kelipatan dari {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Nilai ini harus memenuhi setidaknya satu dari batasan berikut: + + + Each element of this collection should satisfy its own set of constraints. + Setiap elemen koleksi ini harus memenuhi batasannya sendiri. + + + This value is not a valid International Securities Identification Number (ISIN). + Nilai ini bukan merupakan International Securities Identification Number (ISIN) yang sah. + + + This value should be a valid expression. + Nilai ini harus berupa ekspresi yang sah. + + + This value is not a valid CSS color. + Nilai ini bukan merupakan warna CSS yang sah. + + + This value is not a valid CIDR notation. + Nilai ini bukan merupakan notasi CIDR yang sah. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Nilai dari netmask harus berada diantara {{ min }} dan {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Nama file terlalu panjang. Harusnya {{ filename_max_length }} karakter atau kurang. + + + The password strength is too low. Please use a stronger password. + Kata sandi terlalu lemah. Harap gunakan kata sandi yang lebih kuat. + + + This value contains characters that are not allowed by the current restriction-level. + Nilai ini mengandung karakter yang tidak diizinkan oleh tingkat pembatasan saat ini. + + + Using invisible characters is not allowed. + Penggunaan karakter tak terlihat tidak diperbolehkan. + + + Mixing numbers from different scripts is not allowed. + Menggabungkan angka-angka dari skrip yang berbeda tidak diperbolehkan. + + + Using hidden overlay characters is not allowed. + Penggunaan karakter overlay yang tersembunyi tidak diperbolehkan. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Ekstensi file tidak valid ({{ extension }}). Ekstensi yang diperbolehkan adalah {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Pengkodean karakter yang terdeteksi tidak valid ({{ detected }}). Pengkodean yang diperbolehkan adalah {{ encodings }}. + + + This value is not a valid MAC address. + Nilai ini bukan alamat MAC yang valid. + + + This URL is missing a top-level domain. + URL ini tidak memiliki domain tingkat atas. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Nilai ini terlalu pendek. Seharusnya berisi setidaknya satu kata.|Nilai ini terlalu pendek. Seharusnya berisi setidaknya {{ min }} kata. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Nilai ini terlalu panjang. Seharusnya hanya berisi satu kata.|Nilai ini terlalu panjang. Seharusnya berisi {{ max }} kata atau kurang. + + + This value does not represent a valid week in the ISO 8601 format. + Nilai ini tidak mewakili minggu yang valid dalam format ISO 8601. + + + This value is not a valid week. + Nilai ini bukan minggu yang valid. + + + This value should not be before week "{{ min }}". + Nilai ini tidak boleh sebelum minggu "{{ min }}". + + + This value should not be after week "{{ max }}". + Nilai ini tidak boleh setelah minggu "{{ max }}". + + + This value is not a valid Twig template. + Nilai ini bukan templat Twig yang valid. + + + This file is not a valid video. + Berkas ini bukan video yang valid. + + + The size of the video could not be detected. + Ukuran video tidak dapat dideteksi. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Lebar video terlalu besar ({{ width }}px). Lebar maksimum yang diizinkan adalah {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Lebar video terlalu kecil ({{ width }}px). Lebar minimum yang diharapkan adalah {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Tinggi video terlalu besar ({{ height }}px). Tinggi maksimum yang diizinkan adalah {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Tinggi video terlalu kecil ({{ height }}px). Tinggi minimum yang diharapkan adalah {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Video memiliki terlalu sedikit piksel ({{ pixels }}). Jumlah minimum yang diharapkan adalah {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Video memiliki terlalu banyak piksel ({{ pixels }}). Jumlah maksimum yang diharapkan adalah {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Rasio video terlalu besar ({{ ratio }}). Rasio maksimum yang diizinkan adalah {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Rasio video terlalu kecil ({{ ratio }}). Rasio minimum yang diharapkan adalah {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video berbentuk persegi ({{ width }}x{{ height }}px). Video persegi tidak diizinkan. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video berorientasi lanskap ({{ width }}x{{ height }}px). Video berorientasi lanskap tidak diizinkan. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video berorientasi potret ({{ width }}x{{ height }}px). Video berorientasi potret tidak diizinkan. + + + The video file is corrupted. + Berkas video rusak. + + + The video contains multiple streams. Only one stream is allowed. + Video berisi beberapa aliran. Hanya satu aliran yang diizinkan. + + + Unsupported video codec "{{ codec }}". + Kodek video tidak didukung "{{ codec }}". + + + Unsupported video container "{{ container }}". + Kontainer video tidak didukung "{{ container }}". + + + The image file is corrupted. + Berkas gambar rusak. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Gambar memiliki terlalu sedikit piksel ({{ pixels }}). Jumlah minimum yang diharapkan adalah {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Gambar memiliki terlalu banyak piksel ({{ pixels }}). Jumlah maksimum yang diharapkan adalah {{ max_pixels }}. + + + This filename does not match the expected charset. + Nama berkas ini tidak sesuai dengan set karakter yang diharapkan. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.it.xlf b/lib/symfony/validator/Resources/translations/validators.it.xlf new file mode 100644 index 0000000000..e22713e8d5 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.it.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Questo valore dovrebbe essere falso. + + + This value should be true. + Questo valore dovrebbe essere vero. + + + This value should be of type {{ type }}. + Questo valore dovrebbe essere di tipo {{ type }}. + + + This value should be blank. + Questo valore dovrebbe essere vuoto. + + + The value you selected is not a valid choice. + Il valore selezionato non è una scelta valida. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Si dovrebbe selezionare almeno {{ limit }} opzione.|Si dovrebbero selezionare almeno {{ limit }} opzioni. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Si dovrebbe selezionare al massimo {{ limit }} opzione.|Si dovrebbero selezionare al massimo {{ limit }} opzioni. + + + One or more of the given values is invalid. + Uno o più valori inseriti non sono validi. + + + This field was not expected. + Questo campo non è stato previsto. + + + This field is missing. + Questo campo è mancante. + + + This value is not a valid date. + Questo valore non è una data valida. + + + This value is not a valid datetime. + Questo valore non è una data e ora valida. + + + This value is not a valid email address. + Questo valore non è un indirizzo email valido. + + + The file could not be found. + Non è stato possibile trovare il file. + + + The file is not readable. + Il file non è leggibile. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Il file è troppo grande ({{ size }} {{ suffix }}). La dimensione massima consentita è {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Il mime type del file non è valido ({{ type }}). I tipi permessi sono {{ types }}. + + + This value should be {{ limit }} or less. + Questo valore dovrebbe essere {{ limit }} o inferiore. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Questo valore è troppo lungo. Dovrebbe essere al massimo di {{ limit }} carattere.|Questo valore è troppo lungo. Dovrebbe essere al massimo di {{ limit }} caratteri. + + + This value should be {{ limit }} or more. + Questo valore dovrebbe essere {{ limit }} o superiore. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Questo valore è troppo corto. Dovrebbe essere almeno di {{ limit }} carattere.|Questo valore è troppo corto. Dovrebbe essere almeno di {{ limit }} caratteri. + + + This value should not be blank. + Questo valore non dovrebbe essere vuoto. + + + This value should not be null. + Questo valore non dovrebbe essere nullo. + + + This value should be null. + Questo valore dovrebbe essere nullo. + + + This value is not valid. + Questo valore non è valido. + + + This value is not a valid time. + Questo valore non è un'ora valida. + + + This value is not a valid URL. + Questo valore non è un URL valido. + + + The two values should be equal. + I due valori dovrebbero essere uguali. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Il file è troppo grande. La dimensione massima è {{ limit }} {{ suffix }}. + + + The file is too large. + Il file è troppo grande. + + + The file could not be uploaded. + Il file non può essere caricato. + + + This value should be a valid number. + Questo valore dovrebbe essere un numero. + + + This file is not a valid image. + Questo file non è una immagine valida. + + + This value is not a valid IP address. + Questo valore non è un indirizzo IP valido. + + + This value is not a valid language. + Questo valore non è una lingua valida. + + + This value is not a valid locale. + Questo valore non è una impostazione regionale valida. + + + This value is not a valid country. + Questo valore non è una nazione valida. + + + This value is already used. + Questo valore è già stato utilizzato. + + + The size of the image could not be detected. + La dimensione dell'immagine non può essere determinata. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + La larghezza dell'immagine è troppo grande ({{ width }}px). La larghezza massima è di {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + La larghezza dell'immagine è troppo piccola ({{ width }}px). La larghezza minima è di {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + L'altezza dell'immagine è troppo grande ({{ height }}px). L'altezza massima è di {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + L'altezza dell'immagine è troppo piccola ({{ height }}px). L'altezza minima è di {{ min_height }}px. + + + This value should be the user's current password. + Questo valore dovrebbe essere la password attuale dell'utente. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Questo valore dovrebbe contenere esattamente {{ limit }} carattere.|Questo valore dovrebbe contenere esattamente {{ limit }} caratteri. + + + The file was only partially uploaded. + Il file è stato caricato solo parzialmente. + + + No file was uploaded. + Nessun file è stato caricato. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Non è stata configurata una cartella temporanea in php.ini, o la cartella configurata non esiste. + + + Cannot write temporary file to disk. + Impossibile scrivere il file temporaneo sul disco. + + + A PHP extension caused the upload to fail. + Un'estensione PHP ha causato il fallimento del caricamento. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Questa collezione dovrebbe contenere almeno {{ limit }} elemento.|Questa collezione dovrebbe contenere almeno {{ limit }} elementi. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Questa collezione dovrebbe contenere massimo {{ limit }} elemento.|Questa collezione dovrebbe contenere massimo {{ limit }} elementi. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Questa collezione dovrebbe contenere esattamente {{ limit }} elemento.|Questa collezione dovrebbe contenere esattamente {{ limit }} elementi. + + + Invalid card number. + Numero di carta non valido. + + + Unsupported card type or invalid card number. + Tipo di carta non supportato o numero non valido. + + + This value is not a valid International Bank Account Number (IBAN). + Questo valore non è un IBAN valido. + + + This value is not a valid ISBN-10. + Questo valore non è un codice ISBN-10 valido. + + + This value is not a valid ISBN-13. + Questo valore non è un codice ISBN-13 valido. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Questo valore non è un codice ISBN-10 o ISBN-13 valido. + + + This value is not a valid ISSN. + Questo valore non è un codice ISSN valido. + + + This value is not a valid currency. + Questo valore non è una valuta valida. + + + This value should be equal to {{ compared_value }}. + Questo valore dovrebbe essere uguale a {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Questo valore dovrebbe essere maggiore di {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Questo valore dovrebbe essere maggiore o uguale a {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Questo valore dovrebbe essere identico a {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Questo valore dovrebbe essere minore di {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Questo valore dovrebbe essere minore o uguale a {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Questo valore dovrebbe essere diverso da {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Questo valore dovrebbe essere diverso da {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Il rapporto di aspetto dell'immagine è troppo grande ({{ ratio }}). Il rapporto massimo consentito è {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Il rapporto di aspetto dell'immagine è troppo piccolo ({{ ratio }}). Il rapporto minimo consentito è {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + L'immagine è quadrata ({{ width }}x{{ height }}px). Le immagini quadrate non sono consentite. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + L'immagine è orizzontale ({{ width }}x{{ height }}px). Le immagini orizzontali non sono consentite. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + L'immagine è verticale ({{ width }}x{{ height }}px). Le immagini verticali non sono consentite. + + + An empty file is not allowed. + Un file vuoto non è consentito. + + + The host could not be resolved. + L'host non può essere risolto. + + + This value does not match the expected {{ charset }} charset. + Questo valore non corrisponde al charset {{ charset }} previsto. + + + This value is not a valid Business Identifier Code (BIC). + Questo valore non è un codice identificativo bancario (BIC) valido. + + + Error + Errore + + + This value is not a valid UUID. + Questo valore non è un UUID valido. + + + This value should be a multiple of {{ compared_value }}. + Questo valore dovrebbe essere un multiplo di {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Questo codice identificativo bancario (BIC) non è associato all'IBAN {{ iban }}. + + + This value should be valid JSON. + Questo valore dovrebbe essere un JSON valido. + + + This collection should contain only unique elements. + Questa collezione dovrebbe contenere solo elementi unici. + + + This value should be positive. + Questo valore dovrebbe essere positivo. + + + This value should be either positive or zero. + Questo valore dovrebbe essere positivo oppure zero. + + + This value should be negative. + Questo valore dovrebbe essere negativo. + + + This value should be either negative or zero. + Questo valore dovrebbe essere negativo oppure zero. + + + This value is not a valid timezone. + Questo valore non è un fuso orario valido. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Questa password è trapelata durante una compromissione di dati, non deve essere usata. Si prega di usare una password diversa. + + + This value should be between {{ min }} and {{ max }}. + Questo valore dovrebbe essere compreso tra {{ min }} e {{ max }}. + + + This value is not a valid hostname. + Questo valore non è un nome di host valido. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Il numero di elementi in questa collezione dovrebbe essere un multiplo di {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Questo valore dovrebbe soddisfare almeno uno dei vincoli seguenti: + + + Each element of this collection should satisfy its own set of constraints. + Ciascun elemento di questa collezione dovrebbe soddisfare il suo insieme di vincoli. + + + This value is not a valid International Securities Identification Number (ISIN). + Questo valore non è un codice identificativo internazionale di valori mobiliari (ISIN) valido. + + + This value should be a valid expression. + Questo valore dovrebbe essere un'espressione valida. + + + This value is not a valid CSS color. + Questo valore non è un colore CSS valido. + + + This value is not a valid CIDR notation. + Questo valore non è una notazione CIDR valida. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Il valore della netmask dovrebbe essere compreso tra {{ min }} e {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Il nome del file è troppo lungo. Dovrebbe avere {{ filename_max_length }} carattere o meno.|Il nome del file è troppo lungo. Dovrebbe avere {{ filename_max_length }} caratteri o meno. + + + The password strength is too low. Please use a stronger password. + La password non è abbastanza sicura. Per favore, utilizza una password più robusta. + + + This value contains characters that are not allowed by the current restriction-level. + Questo valore contiene caratteri che non sono consentiti dal livello di restrizione attuale. + + + Using invisible characters is not allowed. + Utilizzare caratteri invisibili non è consentito. + + + Mixing numbers from different scripts is not allowed. + Non è consentito mescolare numeri provenienti da diversi script. + + + Using hidden overlay characters is not allowed. + Non è consentito utilizzare caratteri sovrapposti nascosti. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + L'estensione del file non è valida ({{ extension }}). Le estensioni consentite sono {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + La codifica dei caratteri rilevata non è valida ({{ detected }}). Le codifiche ammesse sono {{ encodings }}. + + + This value is not a valid MAC address. + Questo valore non è un indirizzo MAC valido. + + + This URL is missing a top-level domain. + Questo URL è privo di un dominio di primo livello. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Questo valore è troppo corto. Dovrebbe contenere almeno una parola.|Questo valore è troppo corto. Dovrebbe contenere almeno {{ min }} parole. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Questo valore è troppo lungo. Dovrebbe contenere una parola.|Questo valore è troppo lungo. Dovrebbe contenere {{ max }} parole o meno. + + + This value does not represent a valid week in the ISO 8601 format. + Questo valore non rappresenta una settimana valida nel formato ISO 8601. + + + This value is not a valid week. + Questo valore non è una settimana valida. + + + This value should not be before week "{{ min }}". + Questo valore non dovrebbe essere prima della settimana "{{ min }}". + + + This value should not be after week "{{ max }}". + Questo valore non dovrebbe essere dopo la settimana "{{ max }}". + + + This value is not a valid Twig template. + Questo valore non è un template Twig valido. + + + This file is not a valid video. + Questo file non è un video valido. + + + The size of the video could not be detected. + Non è stato possibile rilevare la dimensione del video. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + La larghezza del video è troppo grande ({{ width }}px). La larghezza massima consentita è {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + La larghezza del video è troppo piccola ({{ width }}px). La larghezza minima prevista è {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + L'altezza del video è troppo grande ({{ height }}px). L'altezza massima consentita è {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + L'altezza del video è troppo piccola ({{ height }}px). L'altezza minima prevista è {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Il video ha troppo pochi pixel ({{ pixels }}). La quantità minima prevista è {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Il video ha troppi pixel ({{ pixels }}). La quantità massima prevista è {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Il rapporto del video è troppo alto ({{ ratio }}). Il rapporto massimo consentito è {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Il rapporto del video è troppo piccolo ({{ ratio }}). Il rapporto minimo previsto è {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Il video è quadrato ({{ width }}x{{ height }}px). I video quadrati non sono consentiti. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Il video è in orientamento orizzontale ({{ width }}x{{ height }}px). I video orizzontali non sono consentiti. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Il video è in orientamento verticale ({{ width }}x{{ height }}px). I video in orientamento verticale non sono consentiti. + + + The video file is corrupted. + Il file video è danneggiato. + + + The video contains multiple streams. Only one stream is allowed. + Il video contiene più flussi. È consentito un solo flusso. + + + Unsupported video codec "{{ codec }}". + Codec video non supportato «{{ codec }}». + + + Unsupported video container "{{ container }}". + Container video non supportato "{{ container }}". + + + The image file is corrupted. + Il file immagine è danneggiato. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + L’immagine ha troppo pochi pixel ({{ pixels }}). La quantità minima prevista è {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + L’immagine ha troppi pixel ({{ pixels }}). La quantità massima prevista è {{ max_pixels }}. + + + This filename does not match the expected charset. + Questo nome file non corrisponde al set di caratteri previsto. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.ja.xlf b/lib/symfony/validator/Resources/translations/validators.ja.xlf new file mode 100644 index 0000000000..419b77e09e --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.ja.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + この値はfalseでなければなりません。 + + + This value should be true. + この値はtrueでなければなりません。 + + + This value should be of type {{ type }}. + この値は{{ type }}型でなければなりません。 + + + This value should be blank. + この値は空でなければなりません。 + + + The value you selected is not a valid choice. + 有効な選択肢ではありません。 + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + {{ limit }}個以上選択してください。 + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + {{ limit }}個以下で選択してください。 + + + One or more of the given values is invalid. + 無効な値が含まれています。 + + + This field was not expected. + このフィールドは不要です。 + + + This field is missing. + このフィールドを入力してください。 + + + This value is not a valid date. + 有効な日付ではありません。 + + + This value is not a valid datetime. + 有効な日時ではありません。 + + + This value is not a valid email address. + 有効なメールアドレスではありません。 + + + The file could not be found. + ファイルが見つかりません。 + + + The file is not readable. + ファイルが読み込めません。 + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + ファイルのサイズが大きすぎます({{ size }} {{ suffix }})。{{ limit }} {{ suffix }}以下にしてください。 + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + ファイルのMIMEタイプが無効です({{ type }})。有効なMIMEタイプは{{ types }}です。 + + + This value should be {{ limit }} or less. + この値は{{ limit }}以下でなければなりません。 + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + 長すぎます。この値は{{ limit }}文字以下で入力してください。 + + + This value should be {{ limit }} or more. + この値は{{ limit }}以上でなければなりません。 + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + 短すぎます。この値は{{ limit }}文字以上で入力してください。 + + + This value should not be blank. + この値は空にできません。 + + + This value should not be null. + 値を入力してください。 + + + This value should be null. + 入力しないでください。 + + + This value is not valid. + 有効な値ではありません。 + + + This value is not a valid time. + 有効な時刻ではありません。 + + + This value is not a valid URL. + 有効なURLではありません。 + + + The two values should be equal. + 2つの値は同じでなければなりません。 + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + ファイルのサイズが大きすぎます。許可されている最大サイズは{{ limit }} {{ suffix }}です。 + + + The file is too large. + ファイルのサイズが大きすぎます。 + + + The file could not be uploaded. + ファイルをアップロードできませんでした。 + + + This value should be a valid number. + この値は有効な数値でなければなりません。 + + + This file is not a valid image. + 選択されたファイルは有効な画像ではありません。 + + + This value is not a valid IP address. + 有効なIPアドレスではありません。 + + + This value is not a valid language. + 有効な言語名ではありません。 + + + This value is not a valid locale. + 有効なロケールではありません。 + + + This value is not a valid country. + 有効な国名ではありません。 + + + This value is already used. + 既に使用されています。 + + + The size of the image could not be detected. + 画像のサイズが検出できません。 + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + 画像の幅が大きすぎます({{ width }}px)。{{ max_width }}px以下にしてください。 + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + 画像の幅が小さすぎます({{ width }}px)。{{ min_width }}px以上にしてください。 + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + 画像の高さが大きすぎます({{ height }}px)。{{ max_height }}px以下にしてください。 + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + 画像の高さが小さすぎます({{ height }}px)。{{ min_height }}px以上にしてください。 + + + This value should be the user's current password. + 現在のパスワードを入力してください。 + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + この値は{{ limit }}文字ちょうどで入力してください。 + + + The file was only partially uploaded. + ファイルのアップロードが完了しませんでした。 + + + No file was uploaded. + ファイルがアップロードされていません。 + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + php.iniに一時フォルダが設定されていないか、設定されたフォルダが存在しません。 + + + Cannot write temporary file to disk. + 一時ファイルをディスクに書き込むことができません。 + + + A PHP extension caused the upload to fail. + PHP拡張が原因でアップロードに失敗しました。 + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + 要素は{{ limit }}個以上でなければなりません。 + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + 要素は{{ limit }}個以下でなければなりません。 + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + 要素はちょうど{{ limit }}個でなければなりません。 + + + Invalid card number. + 無効なカード番号です。 + + + Unsupported card type or invalid card number. + 対応していないカードまたは無効なカード番号です。 + + + This value is not a valid International Bank Account Number (IBAN). + 有効な国際銀行勘定番号(IBAN)ではありません。 + + + This value is not a valid ISBN-10. + 有効なISBN-10コードではありません。 + + + This value is not a valid ISBN-13. + 有効なISBN-13コードではありません。 + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + 有効なISBN-10コードまたはISBN-13コードではありません。 + + + This value is not a valid ISSN. + 有効なISSNコードではありません。 + + + This value is not a valid currency. + 有効な通貨ではありません。 + + + This value should be equal to {{ compared_value }}. + この値は{{ compared_value }}と同じ値でなければなりません。 + + + This value should be greater than {{ compared_value }}. + この値は{{ compared_value }}より大きくなければなりません。 + + + This value should be greater than or equal to {{ compared_value }}. + この値は{{ compared_value }}以上でなければなりません。 + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + この値は{{ compared_value_type }}型の{{ compared_value }}と同じでなければなりません。 + + + This value should be less than {{ compared_value }}. + この値は{{ compared_value }}未満でなければなりません。 + + + This value should be less than or equal to {{ compared_value }}. + この値は{{ compared_value }}以下でなければなりません。 + + + This value should not be equal to {{ compared_value }}. + この値は{{ compared_value }}と等しくてはいけません。 + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + この値は{{ compared_value_type }}型の{{ compared_value }}と異なる値にしてください。 + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + 画像のアスペクト比が大きすぎます({{ ratio }})。{{ max_ratio }}までにしてください。 + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + 画像のアスペクト比が小さすぎます({{ ratio }})。{{ min_ratio }}以上にしてください。 + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + 画像が正方形になっています({{ width }}x{{ height }}px)。正方形の画像は許可されていません。 + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + 画像が横向きになっています({{ width }}x{{ height }}px)。横向きの画像は許可されていません。 + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + 画像が縦向きになっています({{ width }}x{{ height }}px)。縦向きの画像は許可されていません。 + + + An empty file is not allowed. + 空のファイルは許可されていません。 + + + The host could not be resolved. + ホストを解決できませんでした。 + + + This value does not match the expected {{ charset }} charset. + この値の文字コードが期待される{{ charset }}と一致しません。 + + + This value is not a valid Business Identifier Code (BIC). + 有効な事業者識別コード(BIC)ではありません。 + + + Error + エラー + + + This value is not a valid UUID. + 有効なUUIDではありません。 + + + This value should be a multiple of {{ compared_value }}. + この値は{{ compared_value }}の倍数でなければなりません。 + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + このSWIFTコードはIBANコード({{ iban }})に関連付けられていません。 + + + This value should be valid JSON. + この値は有効なJSONでなければなりません。 + + + This collection should contain only unique elements. + 要素は重複してはなりません。 + + + This value should be positive. + この値は正の数でなければなりません。 + + + This value should be either positive or zero. + この値は正の数、または0でなければなりません。 + + + This value should be negative. + この値は負の数でなければなりません。 + + + This value should be either negative or zero. + この値は負の数、または0でなければなりません。 + + + This value is not a valid timezone. + 有効なタイムゾーンではありません。 + + + This password has been leaked in a data breach, it must not be used. Please use another password. + このパスワードは漏洩しているため使用できません。 + + + This value should be between {{ min }} and {{ max }}. + この値は{{ min }}以上{{ max }}以下でなければなりません。 + + + This value is not a valid hostname. + 有効なホスト名ではありません。 + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + 要素の数は{{ compared_value }}の倍数でなければなりません。 + + + This value should satisfy at least one of the following constraints: + 以下の制約のうち少なくとも1つを満たさなければなりません。 + + + Each element of this collection should satisfy its own set of constraints. + コレクションの各要素は、それぞれの制約を満たさなければなりません。 + + + This value is not a valid International Securities Identification Number (ISIN). + この値は有効な国際証券識別番号(ISIN)ではありません。 + + + This value should be a valid expression. + この値は有効な式形式でなければなりません。 + + + This value is not a valid CSS color. + この値は有効なCSSカラーではありません。 + + + This value is not a valid CIDR notation. + この値は有効なCIDR表記ではありません。 + + + The value of the netmask should be between {{ min }} and {{ max }}. + サブネットマスクは{{ min }}から{{ max }}の範囲で入力してください。 + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + ファイル名が長すぎます。ファイル名は{{ filename_max_length }}文字以下でなければなりません。 + + + The password strength is too low. Please use a stronger password. + パスワードの強度が弱すぎます。より強いパスワードを使用してください。 + + + This value contains characters that are not allowed by the current restriction-level. + 現在の設定では使用できない文字が含まれています。 + + + Using invisible characters is not allowed. + 不可視文字は使用できません。 + + + Mixing numbers from different scripts is not allowed. + 異なる種類の数字を使うことはできません。 + + + Using hidden overlay characters is not allowed. + 隠れたオーバレイ文字は使用できません。 + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + ファイルの拡張子が無効です({{ extension }})。有効な拡張子は{{ extensions }}です。 + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + 検出された文字コードは無効です({{ detected }})。有効な文字コードは{{ encodings }}です。 + + + This value is not a valid MAC address. + 有効なMACアドレスではありません。 + + + This URL is missing a top-level domain. + このURLはトップレベルドメインがありません。 + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + 短すぎます。この値は{{ min }}単語以上にする必要があります。 + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + 長すぎます。この値は{{ max }}単語以下にする必要があります。 + + + This value does not represent a valid week in the ISO 8601 format. + 週の形式が正しくありません(ISO 8601形式)。 + + + This value is not a valid week. + 有効な週形式ではありません。 + + + This value should not be before week "{{ min }}". + 週 "{{ min }}" 以降を指定してください。 + + + This value should not be after week "{{ max }}". + 週 "{{ max }}" までを指定してください。 + + + This value is not a valid Twig template. + 有効なTwigテンプレートではありません。 + + + This file is not a valid video. + 選択されたファイルは有効な動画ではありません。 + + + The size of the video could not be detected. + 動画のファイルサイズを検出できませんでした。 + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + 動画の幅が大きすぎます({{ width }}px)。許可されている最大の幅は {{ max_width }}px です。 + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + 動画の幅が小さすぎます({{ width }}px)。許可されている最小の幅は {{ min_width }}px です。 + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + 動画の高さが大きすぎます ({{ height }}px)。許可されている最大の高さは {{ max_height }}px です。 + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + 動画の高さが小さすぎます ({{ height }}px)。許可されている最小の高さは {{ min_height }}px です。 + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + この動画のピクセル数が少なすぎます ({{ pixels }})。許可されている最小ピクセル数は {{ min_pixels }} です。 + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + この動画のピクセル数が多すぎます ({{ pixels }})。許可されている最大ピクセル数は {{ max_pixels }} です。 + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + 動画のアスペクト比が大きすぎます ({{ ratio }})。許可されている最大比率は {{ max_ratio }} です。 + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + 動画のアスペクト比が小さすぎます ({{ ratio }})。許可されている最小比率は {{ min_ratio }} です。 + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + 動画は正方形です ({{ width }}x{{ height }}px)。正方形の動画は許可されていません。 + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + 動画は横向きです({{ width }}x{{ height }}px)。横向きの動画は許可されていません。 + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + 動画は縦向きです({{ width }}x{{ height }}px)。縦向きの動画は許可されていません。 + + + The video file is corrupted. + 動画ファイルが破損しています。 + + + The video contains multiple streams. Only one stream is allowed. + この動画には複数のストリームが含まれています。許可されるのは1つのストリームのみです。 + + + Unsupported video codec "{{ codec }}". + サポートされていないビデオコーデック「{{ codec }}」です。 + + + Unsupported video container "{{ container }}". + サポートされていない動画コンテナ「{{ container }}」です。 + + + The image file is corrupted. + 画像ファイルが破損しています。 + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + 画像のピクセル数が少なすぎます({{ pixels }})。許可されている最小ピクセル数は {{ min_pixels }} です。 + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + 画像のピクセル数が多すぎます({{ pixels }})。許可されている最大ピクセル数は {{ max_pixels }} です。 + + + This filename does not match the expected charset. + このファイル名は期待される文字セットと一致しません。 + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.lb.xlf b/lib/symfony/validator/Resources/translations/validators.lb.xlf new file mode 100644 index 0000000000..dd4ac75a17 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.lb.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Dëse Wäert sollt falsch sinn. + + + This value should be true. + Dëse Wäert sollt wouer sinn. + + + This value should be of type {{ type }}. + Dëse Wäert sollt vum Typ {{ type }} sinn. + + + This value should be blank. + Dëse Wäert sollt eidel sinn. + + + The value you selected is not a valid choice. + Dëse Wäert sollt enger vun de Wielméiglechkeeten entspriechen. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Et muss mindestens {{ limit }} Méiglechkeet ausgewielt ginn.|Et musse mindestens {{ limit }} Méiglechkeeten ausgewielt ginn. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Et dierf héchstens {{ limit }} Méiglechkeet ausgewielt ginn.|Et dierfen héchstens {{ limit }} Méiglechkeeten ausgewielt ginn. + + + One or more of the given values is invalid. + Een oder méi vun de Wäerter ass ongëlteg. + + + This field was not expected. + D'Feld gouf net erwaart. + + + This field is missing. + D'Feld feelt. + + + This value is not a valid date. + Dëse Wäert entsprécht kenger gëlteger Datumsangab. + + + This value is not a valid datetime. + Dëse Wäert entsprécht kenger gëlteger Datums- an Zäitangab. + + + This value is not a valid email address. + Dëse Wäert ass keng gëlteg Email-Adress. + + + The file could not be found. + De Fichier gouf net fonnt. + + + The file is not readable. + De Fichier ass net liesbar. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + De Fichier ass ze grouss ({{ size }} {{ suffix }}). Déi zougeloosse Maximalgréisst bedréit {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Den Typ vum Fichier ass ongëlteg ({{ type }}). Erlaabten Type sinn {{ types }}. + + + This value should be {{ limit }} or less. + Dëse Wäert soll méi kleng oder gläich {{ limit }} sinn. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Dës Zeecheketten ass ze laang. Se sollt héchstens {{ limit }} Zeechen hunn. + + + This value should be {{ limit }} or more. + Dëse Wäert sollt méi grouss oder gläich {{ limit }} sinn. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Dës Zeecheketten ass ze kuerz. Se sollt mindestens {{ limit }} Zeechen hunn. + + + This value should not be blank. + Dëse Wäert sollt net eidel sinn. + + + This value should not be null. + Dëst sollt keen Null-Wäert sinn. + + + This value should be null. + Dëst sollt keen Null-Wäert sinn. + + + This value is not valid. + Dëse Wäert ass net gëlteg. + + + This value is not a valid time. + Dëse Wäert entsprécht kenger gëlteger Zäitangab. + + + This value is not a valid URL. + Dëse Wäert ass keng gëlteg URL. + + + The two values should be equal. + Béid Wäerter sollten identesch sinn. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + De fichier ass ze grouss. Déi maximal Gréisst dierf {{ limit }} {{ suffix }} net depasséieren. + + + The file is too large. + De Fichier ass ze grouss. + + + The file could not be uploaded. + De Fichier konnt net eropgeluede ginn. + + + This value should be a valid number. + Dëse Wäert sollt eng gëlteg Zuel sinn. + + + This file is not a valid image. + Dëse Fichier ass kee gëltegt Bild. + + + This value is not a valid IP address. + Dëse Wäert ass keng gülteg IP-Adress. + + + This value is not a valid language. + Dëse Wäert entsprécht kenger gëlteger Sprooch. + + + This value is not a valid locale. + Dëse Wäert entsprécht kengem gëltege Gebittsschema. + + + This value is not a valid country. + Dëse Wäert entsprécht kengem gëltege Land. + + + This value is already used. + Dëse Wäert gëtt scho benotzt. + + + The size of the image could not be detected. + D'Gréisst vum Bild konnt net detektéiert ginn. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + D'Breet vum Bild ass ze grouss ({{ width }}px). Déi erlaabte maximal Breet ass {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + D'Breet vum Bild ass ze kleng ({{ width }}px). Déi minimal Breet ass {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + D'Héicht vum Bild ass ze grouss ({{ height }}px). Déi erlaabte maximal Héicht ass {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + D'Héicht vum Bild ass ze kleng ({{ height }}px). Déi minimal Héicht ass {{ min_height }}px. + + + This value should be the user's current password. + Dëse Wäert sollt dem aktuelle Benotzerpasswuert entspriechen. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Dëse Wäert sollt exakt {{ limit }} Buschtaf hunn.|Dëse Wäert sollt exakt {{ limit }} Buschtawen hunn. + + + The file was only partially uploaded. + De Fichier gouf just deelweis eropgelueden. + + + No file was uploaded. + Et gouf kee Fichier eropgelueden. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Et gouf keen temporären Dossier an der php.ini konfiguréiert oder den temporären Dossier existéiert net. + + + Cannot write temporary file to disk. + Den temporäre Fichier kann net gespäichert ginn. + + + A PHP extension caused the upload to fail. + Eng PHP-Erweiderung huet den Upload verhënnert. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Dës Sammlung sollt {{ limit }} oder méi Elementer hunn. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Dës Sammlung sollt {{ limit }} oder manner Elementer hunn. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Dës Sammlung sollt exakt {{ limit }} Element hunn.|Dës Sammlung sollt exakt {{ limit }} Elementer hunn. + + + Invalid card number. + Ongëlteg Kaartennummer. + + + Unsupported card type or invalid card number. + Net ënnerstëtzte Kaartentyp oder ongëlteg Kaartennummer. + + + This value is not a valid International Bank Account Number (IBAN). + Dëse Wäert ass keng gülteg International Bankkontonummer (IBAN). + + + This value is not a valid ISBN-10. + Dëse Wäert ass keng gëlteg ISBN-10. + + + This value is not a valid ISBN-13. + Dëse Wäert ass keng gëlteg ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Dëse Wäert ass weder eng gëlteg ISBN-10 nach eng gëlteg ISBN-13. + + + This value is not a valid ISSN. + Dëse Wäert ass keng gëlteg ISSN. + + + This value is not a valid currency. + Dëse Wäert ass keng gëlteg Währung. + + + This value should be equal to {{ compared_value }}. + Dëse Wäert sollt {{ compared_value }} sinn. + + + This value should be greater than {{ compared_value }}. + Dëse Wäert sollt méi grouss wéi {{ compared_value }} sinn. + + + This value should be greater than or equal to {{ compared_value }}. + Dëse Wäert sollt méi grouss wéi oder gläich {{ compared_value }} sinn. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Dëse Wäert sollt identesch si mat {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Dëse Wäert sollt méi kleng wéi {{ compared_value }} sinn. + + + This value should be less than or equal to {{ compared_value }}. + Dëse Wäert sollt méi kleng wéi oder gläich {{ compared_value }} sinn. + + + This value should not be equal to {{ compared_value }}. + Dëse Wäert sollt net {{ compared_value }} sinn. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Dëse Wäert sollt net identesch si mat {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + D'Säiteverhältnis vum Bild ass ze grouss ({{ ratio }}). Den erlaabte Maximalwäert ass {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + D'Säiteverhältnis vum Bild ass ze kleng ({{ ratio }}). Den erwaarte Minimalwäert ass {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + D'Bild ass quadratesch ({{ width }}x{{ height }}px). Quadratesch Biller sinn net erlaabt. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + D'Bild ass am Queeschformat ({{ width }}x{{ height }}px). Biller am Queeschformat sinn net erlaabt. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + D'Bild ass am Héichformat ({{ width }}x{{ height }}px). Biller am Héichformat sinn net erlaabt. + + + An empty file is not allowed. + En eidele Fichier ass net erlaabt. + + + The host could not be resolved. + Den Host-Numm konnt net opgeléist ginn. + + + This value does not match the expected {{ charset }} charset. + Dëse Wäert entsprécht net dem erwaarten Zeechesaz {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Dëse Wäert ass kee gültege Business Identifier Code (BIC). + + + Error + Feeler + + + This value is not a valid UUID. + Dëse Wäert ass keng gülteg UUID. + + + This value should be a multiple of {{ compared_value }}. + Dëse Wäert sollt e puer vun {{ compared_value }} sinn. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Dëse "Business Identifier Code" (BIC) ass net mat IBAN verbonnen {{ iban }}. + + + This value should be valid JSON. + Dëse Wäert sollt gëlteg JSON. + + + This collection should contain only unique elements. + Dës Sammlung sollt just eenzegaarteg Elementer enthalen. + + + This value should be positive. + Dëse Wäert sollt positiv sinn. + + + This value should be either positive or zero. + Dëse Wäert sollt entweeder positiv oder null sinn. + + + This value should be negative. + Dëse Wäert sollt negativ sinn. + + + This value should be either negative or zero. + Dëse Wäert sollt entweeder negativ oder null sinn. + + + This value is not a valid timezone. + Dëse Wäert ass keng gëlteg Zäitzon. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Dëst Passwuert war Deel vun engem Dateleck an dierf net benotzt ginn. Benotzt w.e.g. en anert Passwuert . + + + This value should be between {{ min }} and {{ max }}. + De Wäert sollt tëscht {{ min }} a(n) {{ max }} leien. + + + This value is not a valid hostname. + Dëse Wäert ass kee gëltegen Hostnumm. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + D'Unzuel un Elementer an dëser Sammlung sollt e multipel vu(n) {{ compared_value }} sinn. + + + This value should satisfy at least one of the following constraints: + Dëse Wäert sollt op d'mannst ee vun dësen Aschränkungen erfëllen: + + + Each element of this collection should satisfy its own set of constraints. + All Element aus dëser Sammlung sollt seng eegen Aschränkungen erfëllen. + + + This value is not a valid International Securities Identification Number (ISIN). + Dëse Wäert ass keng gëlteg International Wäertpabeiererkennnummer (ISIN). + + + This value should be a valid expression. + Dëse Wäert soll eng gëlteg Expression sinn. + + + This value is not a valid CSS color. + Dëse Wäert ass keng gëlteg CSS Faarf. + + + This value is not a valid CIDR notation. + Dëse Wäert ass keng gëlteg CIDR Notatioun. + + + The value of the netmask should be between {{ min }} and {{ max }}. + De Wäert vum Netmask soll tëscht {{ min }} a {{ max }} sinn. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + De Dateinimm ass ze laang. Et sollt {{ filename_max_length }} Zeechen oder manner hunn.|De Dateinimm ass ze laang. Et sollt {{ filename_max_length }} Zeechen oder manner hunn. + + + The password strength is too low. Please use a stronger password. + D'Staarf vum Passwuert ass ze schwaach. Benotzt w. e. g. e stäerker Passwuert. + + + This value contains characters that are not allowed by the current restriction-level. + Dëse Wäert enthält Zeechen, déi net erlaabt sinn no der aktueller Beschränkungsstuf. + + + Using invisible characters is not allowed. + D'Benotzen vu onsiichtbaren Zeechen ass net erlaabt. + + + Mixing numbers from different scripts is not allowed. + D'Mësche vu Nummeren aus verschiddenen Skripten ass net erlaabt. + + + Using hidden overlay characters is not allowed. + D'Benotzen vu verstoppten Iwwerlagungszeechen ass net erlaabt. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + D'Extensioun vum Fichier ass net valabel ({{ extension }}). Valabel Extensioune sinn {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Den Encodage vun de Schrëftzeechen ass net valabel ({{ detected }}). Valabel Encodage sinn {{ encodings }}. + + + This value is not a valid MAC address. + Dëse Wäert ass keng gülteg MAC-Adress. + + + This URL is missing a top-level domain. + Dësen URL feelt eng Top-Level-Domain. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Dëse Wäert ass ze kuerz. Et sollt op d'mannst ee Wuert enthalen.|Dëse Wäert ass ze kuerz. Et sollt op d'mannst {{ min }} Wierder enthalen. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Dëse Wäert ass ze laang. Et sollt nëmmen ee Wuert enthalen.|Dëse Wäert ass ze laang. Et sollt {{ max }} Wierder oder manner enthalen. + + + This value does not represent a valid week in the ISO 8601 format. + Dëse Wäert stellt keng valabel Woch am ISO 8601-Format duer. + + + This value is not a valid week. + Dëse Wäert ass keng valabel Woch. + + + This value should not be before week "{{ min }}". + Dëse Wäert sollt net virun der Woch "{{ min }}" sinn. + + + This value should not be after week "{{ max }}". + Dëse Wäert sollt net no Woch "{{ max }}" sinn. + + + This value is not a valid Twig template. + Dëse Wäert ass kee valabelen Twig-Template. + + + This file is not a valid video. + Dës Datei ass kee gëltegen Video. + + + The size of the video could not be detected. + D'Gréisst vum Video konnt net erkannt ginn. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + D'Videobreed ass ze grouss ({{ width }}px). Erlaabt maximal Breed ass {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + D'Videobreed ass ze kleng ({{ width }}px). Minimal erwaart Breed ass {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + D'Videohéicht ass ze grouss ({{ height }}px). Erlaabt maximal Héicht ass {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + D'Videohéicht ass ze kleng ({{ height }}px). Erwaart Mindesthéicht ass {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + De Video huet ze wéineg Pixel ({{ pixels }}). Erwaart Minimum ass {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + De Video huet ze vill Pixel ({{ pixels }}). Déi erwaart maximal Zuel ass {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + D'Videoproportioun ass ze grouss ({{ ratio }}). Erlaabt maximal Proportioun ass {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + D'Videoratio ass ze kleng ({{ ratio }}). Minimal erwaart Ratio ass {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + De Video ass quadratesch ({{ width }}x{{ height }}px). Quadratesch Videoe sinn net erlaabt. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + De Video ass am Landschaftsformat ({{ width }}x{{ height }} px). Landschafts-Videoe sinn net erlaabt. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + De Video ass am Portraitformat ({{ width }}x{{ height }}px). Portrait-Videoe sinn net erlaabt. + + + The video file is corrupted. + D'Videodatei ass beschiedegt. + + + The video contains multiple streams. Only one stream is allowed. + De Video enthält verschidde Stréimen. Nëmmen ee Stroum ass erlaabt. + + + Unsupported video codec "{{ codec }}". + Net ënnerstëtzte Videocodec „{{ codec }}“. + + + Unsupported video container "{{ container }}". + Net ënnerstëtzte Video-Container "{{ container }}". + + + The image file is corrupted. + D'Bilddatei ass beschiedegt. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + D'Bild huet ze wéineg Pixel ({{ pixels }}). Déi erwaart Mindestzuel ass {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + D'Bild huet ze vill Pixel ({{ pixels }}). Déi erwaart maximal Zuel ass {{ max_pixels }}. + + + This filename does not match the expected charset. + Dësen Dateinumm entsprécht net dem erwaarten Zeechesaz. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.lt.xlf b/lib/symfony/validator/Resources/translations/validators.lt.xlf new file mode 100644 index 0000000000..ab4bdc57e7 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.lt.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Reikšmė turi būti neigiama. + + + This value should be true. + Reikšmė turi būti teigiama. + + + This value should be of type {{ type }}. + Šios reikšmės tipas turi būti {{ type }}. + + + This value should be blank. + Ši reikšmė turi būti tuščia. + + + The value you selected is not a valid choice. + Neteisingas pasirinkimas. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Turite pasirinkti bent {{ limit }} variantą.|Turite pasirinkti bent {{ limit }} variantus.|Turite pasirinkti bent {{ limit }} variantų. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Turite pasirinkti ne daugiau kaip {{ limit }} variantą.|Turite pasirinkti ne daugiau kaip {{ limit }} variantus.|Turite pasirinkti ne daugiau kaip {{ limit }} variantų. + + + One or more of the given values is invalid. + Viena ar daugiau įvestų reikšmių yra netinkamos. + + + This field was not expected. + Nebuvo tikimasi šio laukelio. + + + This field is missing. + Trūkstamas laukelis. + + + This value is not a valid date. + Ši reikšmė nėra data. + + + This value is not a valid datetime. + Ši reikšmė nera data ir laikas. + + + This value is not a valid email address. + Ši reikšmė nėra tinkamas el. pašto adresas. + + + The file could not be found. + Byla nerasta. + + + The file is not readable. + Negalima nuskaityti bylos. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Byla yra per didelė ({{ size }} {{ suffix }}). Maksimalus dydis {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Netinkamas bylos tipas (mime type) ({{ type }}). Galimi bylų tipai {{ types }}. + + + This value should be {{ limit }} or less. + Reikšmė turi būti {{ limit }} arba mažiau. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Per didelis simbolių skaičius. Turi susidaryti iš {{ limit }} arba mažiau simbolių.|Per didelis simbolių skaičius. Turi susidaryti iš {{ limit }} arba mažiau simbolių.|Per didelis simbolių skaičius. Turi susidaryti iš {{ limit }} arba mažiau simbolių. + + + This value should be {{ limit }} or more. + Reikšmė turi būti {{ limit }} arba daugiau. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Per mažas simbolių skaičius. Turi susidaryti iš {{ limit }} arba daugiau simbolių.|Per mažas simbolių skaičius. Turi susidaryti iš {{ limit }} arba daugiau simbolių.|Per mažas simbolių skaičius. Turi susidaryti iš {{ limit }} arba daugiau simbolių. + + + This value should not be blank. + Ši reikšmė negali būti tuščia. + + + This value should not be null. + Ši reikšmė negali būti null. + + + This value should be null. + Ši reikšmė turi būti null. + + + This value is not valid. + Netinkama reikšmė. + + + This value is not a valid time. + Ši reikšmė nėra laikas. + + + This value is not a valid URL. + Ši reikšmė nėra tinkamas interneto adresas. + + + The two values should be equal. + Abi reikšmės turi būti identiškos. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Byla yra per didelė. Maksimalus dydis yra {{ limit }} {{ suffix }}. + + + The file is too large. + Byla per didelė. + + + The file could not be uploaded. + Byla negali būti įkelta. + + + This value should be a valid number. + Ši reikšmė turi būti skaičius. + + + This file is not a valid image. + Byla nėra paveikslėlis. + + + This value is not a valid IP address. + Ši reikšmė nėra tinkamas IP adresas. + + + This value is not a valid language. + Ši reikšmė nėra tinkama kalba. + + + This value is not a valid locale. + Ši reikšmė nėra tinkama lokalė. + + + This value is not a valid country. + Ši reikšmė nėra tinkama šalis. + + + This value is already used. + Ši reikšmė jau yra naudojama. + + + The size of the image could not be detected. + Nepavyko nustatyti nuotraukos dydžio. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Nuotraukos plotis per didelis ({{ width }}px). Maksimalus leidžiamas plotis yra {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Nuotraukos plotis per mažas ({{ width }}px). Minimalus leidžiamas plotis yra {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Nuotraukos aukštis per didelis ({{ height }}px). Maksimalus leidžiamas aukštis yra {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Nuotraukos aukštis per mažas ({{ height }}px). Minimalus leidžiamas aukštis yra {{ min_height }}px. + + + This value should be the user's current password. + Ši reikšmė turi sutapti su dabartiniu naudotojo slaptažodžiu. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ši reikšmė turi turėti lygiai {{ limit }} simbolį.|Ši reikšmė turi turėti lygiai {{ limit }} simbolius.|Ši reikšmė turi turėti lygiai {{ limit }} simbolių. + + + The file was only partially uploaded. + Failas buvo tik dalinai įkeltas. + + + No file was uploaded. + Nebuvo įkelta jokių failų. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + php.ini nesukonfigūruotas laikinas aplankas arba sukonfigūruotas aplankas neegzistuoja. + + + Cannot write temporary file to disk. + Nepavyko išsaugoti laikino failo. + + + A PHP extension caused the upload to fail. + PHP plėtinys sutrukdė failo įkėlimą ir jis nepavyko. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Sąraše turi būti {{ limit }} arba daugiau įrašų.|Sąraše turi būti {{ limit }} arba daugiau įrašų.|Sąraše turi būti {{ limit }} arba daugiau įrašų. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Sąraše turi būti {{ limit }} arba mažiau įrašų.|Sąraše turi būti {{ limit }} arba mažiau įrašų.|Sąraše turi būti {{ limit }} arba mažiau įrašų. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Sąraše turi būti lygiai {{ limit }} įrašas.|Sąraše turi būti lygiai {{ limit }} įrašai.|Sąraše turi būti lygiai {{ limit }} įrašų. + + + Invalid card number. + Klaidingas kortelės numeris. + + + Unsupported card type or invalid card number. + Kortelės tipas nepalaikomas arba klaidingas kortelės numeris. + + + This value is not a valid International Bank Account Number (IBAN). + Ši reikšmė nėra tinkamas Tarptautinis Banko Sąskaitos Numeris (IBAN). + + + This value is not a valid ISBN-10. + Ši reikšmė neatitinka ISBN-10 formato. + + + This value is not a valid ISBN-13. + Ši reikšmė neatitinka ISBN-13 formato. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ši reikšmė neatitinka nei ISBN-10, nei ISBN-13 formato. + + + This value is not a valid ISSN. + Ši reišmė neatitinka ISSN formato. + + + This value is not a valid currency. + Netinkamas valiutos formatas. + + + This value should be equal to {{ compared_value }}. + Ši reikšmė turi būti lygi {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ši reikšmė turi būti didesnė už {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ši reikšmė turi būti didesnė už arba lygi {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ši reikšmė turi būti identiška {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ši reikšmė turi būti mažesnė už {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ši reikšmė turi būti mažesnė už arba lygi {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ši reikšmė neturi būti lygi {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ši reikšmė neturi būti identiška {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Nuotraukos santykis yra per didelis ({{ ratio }}). Didžiausias leistinas santykis yra {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Nuotraukos santykis yra per mažas ({{ ratio }}). Mažiausias leistinas santykis yra {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Nuotrauka yra kvadratinė ({{ width }}x{{ height }}px). Kvadratinės nuotraukos nėra leistinos. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Nuotrauka orientuota į plotį ({{ width }}x{{ height }}px). Nuotraukos orientuotos į plotį nėra leistinos. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Nuotrauka orientuota į aukštį ({{ width }}x{{ height }}px). Nuotraukos orientuotos į aukštį nėra leistinos. + + + An empty file is not allowed. + Failas negali būti tuščias. + + + The host could not be resolved. + Serveris nepasiekiamas. + + + This value does not match the expected {{ charset }} charset. + Ši reikšmė neatitinka {{ charset }} koduotės. + + + This value is not a valid Business Identifier Code (BIC). + Ši reikšmė nėra tinkamas Verslo Identifikavimo Kodas (BIC). + + + Error + Klaida + + + This value is not a valid UUID. + Ši reikšmė nėra tinkamas UUID. + + + This value should be a multiple of {{ compared_value }}. + Ši reikšmė turi būti skaičiaus {{ compared_value }} kartotinis. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Šis bendrovės identifikavimo kodas (BIC) nesusijęs su IBAN {{ iban }}. + + + This value should be valid JSON. + Ši reikšmė turi būti tinkamo JSON formato. + + + This collection should contain only unique elements. + Sąraše turi būti tik unikalios reikšmės. + + + This value should be positive. + Reikšmė turi būti teigiama. + + + This value should be either positive or zero. + Reikšmė turi būti teigiama arba lygi nuliui. + + + This value should be negative. + Reikšmė turi būti neigiama. + + + This value should be either negative or zero. + Reikšmė turi būti neigiama arba lygi nuliui. + + + This value is not a valid timezone. + Reikšmė nėra tinkama laiko juosta. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Slaptažodis yra nutekėjęs duomenų saugumo pažeidime, jo naudoti negalima. Prašome naudoti kitą slaptažodį. + + + This value should be between {{ min }} and {{ max }}. + Ši reikšmė turi būti tarp {{ min }} ir {{ max }}. + + + This value is not a valid hostname. + Ši reikšmė nėra tinkamas svetainės adresas. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Šio sąrašo elementų skaičius turėtų būti skaičiaus {{ compared_value }} kartotinis. + + + This value should satisfy at least one of the following constraints: + Ši reikšmė turėtų atitikti bent vieną iš šių nurodymų: + + + Each element of this collection should satisfy its own set of constraints. + Kiekvienas šio sąrašo elementas turi atitikti savo nurodymų rinkinį. + + + This value is not a valid International Securities Identification Number (ISIN). + Ši reišmė neatitinka tarptautinio vertybinių popierių identifikavimo numerio formato (ISIN). + + + This value should be a valid expression. + Ši vertė turėtų būti teisinga išraiška. + + + This value is not a valid CSS color. + Ši reikšmė nėra tinkama CSS spalva. + + + This value is not a valid CIDR notation. + Ši vertė nėra tinkamas CIDR žymėjimas. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Tinklo kaukės reikšmė turi būti nuo {{ min }} iki {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Failo pavadinimas per ilgas. Jame turėtų būti {{ filename_max_length }} simbolis arba mažiau.|Failo pavadinimas per ilgas. Jame turėtų būti {{ filename_max_length }} simbolių arba mažiau. + + + The password strength is too low. Please use a stronger password. + Slaptažodis per silpnas. Naudokite stipresnį slaptažodį. + + + This value contains characters that are not allowed by the current restriction-level. + Šioje reikšmėje yra simbolių, kurių neleidžia dabartinis apribojimo lygis. + + + Using invisible characters is not allowed. + Naudoti nematomus simbolius draudžiama. + + + Mixing numbers from different scripts is not allowed. + Draudžiama maišyti skaičius iš skirtingų scenarijų. + + + Using hidden overlay characters is not allowed. + Draudžiama naudoti paslėptus perdangos simbolius. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Failo plėtinys netinkamas ({{ extension }}). Leidžiami plėtiniai yra {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Aptikta simbolių koduotė yra netinkama ({{ detected }}). Leidžiamos koduotės yra {{ encodings }}. + + + This value is not a valid MAC address. + Ši reikšmė nėra tinkamas MAC adresas. + + + This URL is missing a top-level domain. + Šiam URL trūksta aukščiausio lygio domeno. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Per mažas žodžių skaičius. Turi susidaryti bent iš 1 žodžio.|Per mažas žodžių skaičius. Turi susidaryti iš {{ min }} arba daugiau žodžių. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Per didelis žodžių skaičius. Turi susidaryti iš 1 žodžio.|Per didelis žodžių skaičius. Turi susidaryti iš {{ max }} arba mažiau žodžių. + + + This value does not represent a valid week in the ISO 8601 format. + Ši reikšmė neatitinka galiojančios savaitės ISO 8601 formatu. + + + This value is not a valid week. + Ši reikšmė nėra galiojanti savaitė. + + + This value should not be before week "{{ min }}". + Ši reikšmė neturėtų būti prieš savaitę "{{ min }}". + + + This value should not be after week "{{ max }}". + Ši reikšmė neturėtų būti po savaitės "{{ max }}". + + + This value is not a valid Twig template. + Ši reikšmė nėra tinkamas „Twig“ šablonas. + + + This file is not a valid video. + Šis failas nėra galiojantis vaizdo įrašas. + + + The size of the video could not be detected. + Nepavyko nustatyti vaizdo įrašo dydžio. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Vaizdo įrašo plotis per didelis ({{ width }}px). Leidžiamas didžiausias plotis yra {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Vaizdo įrašo plotis per mažas ({{ width }}px). Tikėtinas mažiausias plotis yra {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Vaizdo aukštis per didelis ({{ height }}px). Leidžiamas maksimalus aukštis yra {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Vaizdo aukštis per mažas ({{ height }}px). Tikėtinas minimalus aukštis yra {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Vaizdo įraše per mažai pikselių ({{ pixels }}). Tikimasi mažiausiai {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Vaizdo įraše per daug pikselių ({{ pixels }}). Tikimasi, kad didžiausias kiekis yra {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Vaizdo santykis per didelis ({{ ratio }}). Leidžiamas didžiausias santykis yra {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Vaizdo santykis per mažas ({{ ratio }}). Tikimasi mažiausias santykis yra {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Vaizdo įrašas yra kvadratinis ({{ width }}x{{ height }}px). Kvadratiniai vaizdo įrašai neleidžiami. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Vaizdo įrašas yra gulsčio formato ({{ width }}x{{ height }} px). Gulsčio formato vaizdo įrašai neleidžiami. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Vaizdo įrašas yra portreto orientacijos ({{ width }}x{{ height }}px). Portreto orientacijos vaizdo įrašai neleidžiami. + + + The video file is corrupted. + Vaizdo failas sugadintas. + + + The video contains multiple streams. Only one stream is allowed. + Vaizdo įraše yra keli srautai. Leidžiamas tik vienas srautas. + + + Unsupported video codec "{{ codec }}". + Nepalaikomas vaizdo kodekas „{{ codec }}“. + + + Unsupported video container "{{ container }}". + Nepalaikomas vaizdo konteineris "{{ container }}". + + + The image file is corrupted. + Paveikslėlio failas sugadintas. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Paveikslėlyje per mažai pikselių ({{ pixels }}). Tikimasi mažiausiai {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Paveikslėlis turi per daug pikselių ({{ pixels }}). Tikėtinas didžiausias kiekis yra {{ max_pixels }}. + + + This filename does not match the expected charset. + Šis failo pavadinimas neatitinka laukiamo ženklų rinkinio. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.lv.xlf b/lib/symfony/validator/Resources/translations/validators.lv.xlf new file mode 100644 index 0000000000..2d78bfd3eb --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.lv.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Šai vērtībai ir jābūt nepatiesai. + + + This value should be true. + Šai vērtībai ir jābūt patiesai. + + + This value should be of type {{ type }}. + Šīs vērtības tipam ir jābūt {{ type }}. + + + This value should be blank. + Šai vērtībai ir jābūt tukšai. + + + The value you selected is not a valid choice. + Vērtība, kuru jūs izvēlējāties, nav derīga izvēle. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Jums nav jāveic izvēle.|Jums ir jāveic vismaz {{ limit }} izvēle.|Jums ir jāveic vismaz {{ limit }} izvēles. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Jums nav jāveic izvēle.|Jums ir jāveic ne vairāk kā {{ limit }} izvēle.|Jums ir jāveic ne vairāk kā {{ limit }} izvēles. + + + One or more of the given values is invalid. + Viena vai vairākas no dotajām vērtībām ir nederīgas. + + + This field was not expected. + Šis lauks netika gaidīts. + + + This field is missing. + Šis lauks ir pazudis. + + + This value is not a valid date. + Šī vērtība ir nederīgs datums. + + + This value is not a valid datetime. + Šī vērtība ir nederīgs datums un laiks. + + + This value is not a valid email address. + Šī vērtība ir nederīga e-pasta adrese. + + + The file could not be found. + Fails nav atrasts. + + + The file is not readable. + Fails nav lasāms. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Fails ir pārāk liels ({{ size }} {{ suffix }}). Atļautais maksimālais izmērs ir {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Faila mime tips nav derīgs ({{ type }}). Atļautie mime tipi ir {{ types }}. + + + This value should be {{ limit }} or less. + Šai vērtībai ir jābūt ne vairāk kā {{ limit }}. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Šīs vērtības garums ir 0 rakstzīmes.|Šī vērtība ir pārāk gara. Tai būtu jābūt ne vairāk kā {{ limit }} rakstzīmi garai.|Šī vērtība ir pārāk gara. Tai būtu jābūt ne vairāk kā {{ limit }} rakstzīmes garai. + + + This value should be {{ limit }} or more. + Šai vērtībai ir jābūt ne mazāk kā {{ limit }}. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Šīs vērtības garums ir 0 rakstzīmes.|Šī vērtība ir pārāk īsa. Tai būtu jābūt ne mazāk kā {{ limit }} rakstzīmi garai.|Šī vērtība ir pārāk īsa. Tai būtu jābūt ne mazāk kā {{ limit }} rakstzīmes garai. + + + This value should not be blank. + Šai vērtībai nav jābūt tukšai. + + + This value should not be null. + Šai vērtībai nav jābūt null. + + + This value should be null. + Šai vērtībai ir jābūt null. + + + This value is not valid. + Šī vērtība ir nederīga. + + + This value is not a valid time. + Šī vērtība ir nederīgs laiks. + + + This value is not a valid URL. + Šī vērtība ir nederīgs URL. + + + The two values should be equal. + Abām vērtībām jābūt vienādām. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Fails ir pārāk liels. Atļautais maksimālais izmērs ir {{ limit }} {{ suffix }}. + + + The file is too large. + Fails ir pārāk liels. + + + The file could not be uploaded. + Failu nevarēja augšupielādēt. + + + This value should be a valid number. + Šai vērtībai ir jābūt derīgam skaitlim. + + + This file is not a valid image. + Šis fails nav derīgs attēls. + + + This value is not a valid IP address. + Šī vērtība nav derīga IP adrese. + + + This value is not a valid language. + Šī vērtība nav derīga valoda. + + + This value is not a valid locale. + Šī vērtība nav derīga lokalizācija. + + + This value is not a valid country. + Šī vērtība nav derīga valsts. + + + This value is already used. + Šī vērtība jau tiek izmantota. + + + The size of the image could not be detected. + Nevar noteikt attēla izmēru. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Attēla platums ir pārāk liels ({{ width }}px). Atļautais maksimālais platums ir {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Attēla platums ir pārāk mazs ({{ width }}px). Minimālais sagaidāmais platums ir {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Attēla augstums ir pārāk liels ({{ height }}px). Atļautais maksimālais augstums ir {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Attēla augstums ir pārāk mazs ({{ height }}px). Minimālais sagaidāmais augstums ir {{ min_height }}px. + + + This value should be the user's current password. + Šai vērtībai ir jābūt lietotāja pašreizējai parolei. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Šīs vērtības garums ir 0 rakstzīmes.|Šai vērtībai ir jābūt tieši {{ limit }} rakstzīmi garai.|Šai vērtībai ir jābūt tieši {{ limit }} rakstzīmes garai. + + + The file was only partially uploaded. + Fails bija tikai daļēji augšupielādēts. + + + No file was uploaded. + Fails netika augšupielādēts. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + php.ini nav konfigurēta pagaidu mape vai arī konfigurētā mape neeksistē. + + + Cannot write temporary file to disk. + Nevar ierakstīt pagaidu failu diskā. + + + A PHP extension caused the upload to fail. + PHP paplašinājums izraisīja augšupielādes neizdošanos. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Šis krājums satur 0 elementu.|Šim krājumam jāsatur vismaz {{ limit }} elements.|Šim krājumam jāsatur vismaz {{ limit }} elementi. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Šis krājums satur 0 elementu.|Šim krājumam jāsatur ne vairāk kā {{ limit }} elements.|Šim krājumam jāsatur ne vairāk kā {{ limit }} elementi. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Šis krājums satur 0 elementu.|Šim krājumam jāsatur tieši {{ limit }} elements.|Šim krājumam jāsatur tieši {{ limit }} elementi. + + + Invalid card number. + Nederīgs kartes numurs. + + + Unsupported card type or invalid card number. + Neatbalstīts kartes tips vai nederīgs kartes numurs. + + + This value is not a valid International Bank Account Number (IBAN). + Šī vērtība nav derīgs Starptautiskais Bankas Konta Numurs (IBAN). + + + This value is not a valid ISBN-10. + Šī vērtība nav derīgs ISBN-10 numurs. + + + This value is not a valid ISBN-13. + Šī vērtība nav derīgs ISBN-13 numurs. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Šī vērtība neatbilst ne derīgam ISBN-10 numuram, ne derīgm ISBN-13 numuram. + + + This value is not a valid ISSN. + Šī vērtība nav derīgs ISSN numurs. + + + This value is not a valid currency. + Šī vērtība nav derīga valūta. + + + This value should be equal to {{ compared_value }}. + Šai vērtībai ir jābūt vienādai ar {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Šai vērtībai ir jābūt lielākai par {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Šai vērtībai ir jābūt lielākai vai vienādai ar {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Šai vērtībai ir jābūt identiskai ar {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Šai vērtībai ir jābūt mazākai par {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Šai vērtībai ir jābūt mazākai vai vienādai ar {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Šai vērtībai ir jābūt vienādai ar {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Šai vērtībai nav jābūt identiskai ar {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Attēla attiecība ir pārāk liela ({{ ratio }}). Atļautā maksimālā attiecība ir {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Attēla attiecība ir pārāk maza ({{ ratio }}). Minimālā sagaidāmā attiecība ir {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Šis attēls ir kvadrāts ({{ width }}x{{ height }}px). Kvadrātveida attēli nav atļauti. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Attēls ir orientēts kā ainava ({{ width }}x{{ height }}px). Attēli, kas ir orientēti kā ainavas, nav atļauti. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Attēls ir orientēts kā portrets ({{ width }}x{{ height }}px). Attēli, kas ir orientēti kā portreti, nav atļauti. + + + An empty file is not allowed. + Tukšs fails nav atļauts. + + + The host could not be resolved. + Resursdatora nosaukumu nevar atrisināt. + + + This value does not match the expected {{ charset }} charset. + Šī vērtība neatbilst sagaidāmajai rakstzīmju kopai {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Šī vērtība nav derīgs Uzņēmuma Identifikācijas Kods (BIC). + + + Error + Kļūda + + + This value is not a valid UUID. + Šī vērtība nav derīgs UUID. + + + This value should be a multiple of {{ compared_value }}. + Šai vērtībai jābūt vairākas reizes atkārtotai {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Šis Biznesa Identifikācijas Kods (BIC) neatbilst {{ iban }} konta numuram (IBAN). + + + This value should be valid JSON. + Šai vērtībai jābūt derīgam JSON. + + + This collection should contain only unique elements. + Šai kolekcijai jāsatur tikai unikāli elementi. + + + This value should be positive. + Šai vērtībai jābūt pozitīvai. + + + This value should be either positive or zero. + Šai vērtībai jābūt pozitīvai vai vienādai ar nulli. + + + This value should be negative. + Šai vērtībai jābūt negatīvai. + + + This value should be either negative or zero. + Šai vērtībai jābūt negatīvai vai vienādai ar nulli. + + + This value is not a valid timezone. + Šī vērtība nav derīga laika zona. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Šī parole tika publicēta datu noplūdē, to nedrīkst izmantot. Lūdzu, izvēlieties citu paroli. + + + This value should be between {{ min }} and {{ max }}. + Šai vērtībai jābūt starp {{ min }} un {{ max }}. + + + This value is not a valid hostname. + Šī vērtība nav derīgs tīmekļa servera nosaukums. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Elementu skaitam šajā kolekcijā jābūt {{ compared_value }} reizinājumam. + + + This value should satisfy at least one of the following constraints: + Šai vērtībai jāiekļaujas vismaz vienā no sekojošiem ierobežojumiem: + + + Each element of this collection should satisfy its own set of constraints. + Šīs kolekcijas katram elementam jāiekļaujas savā ierobežojumu kopā. + + + This value is not a valid International Securities Identification Number (ISIN). + Šī vērtība nav derīgs starptautiskais vērtspapīru identifikācijas numurs (ISIN). + + + This value should be a valid expression. + Šai vērtībai jābūt korektai izteiksmei. + + + This value is not a valid CSS color. + Šī vērtība nav korekta CSS krāsa. + + + This value is not a valid CIDR notation. + Šī vērtība nav korekts CIDR apzīmējums. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Tīkla maskas (netmask) vērtībai jābūt starp {{ min }} un {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Faila nosaukums ir pārāk garš. Tas var būt {{ filename_max_length }} rakstzīmi garš vai īsāks.|Faila nosaukums ir pārāk garš. Tas var būt {{ filename_max_length }} rakstzīmes garš vai īsāks. + + + The password strength is too low. Please use a stronger password. + Paroles stiprums ir pārāk zems. Lūdzu, izmantojiet spēcīgāku paroli. + + + This value contains characters that are not allowed by the current restriction-level. + Šī vērtība satur rakstzīmes, kuras nav atļautas pašreizējā ierobežojuma līmenī. + + + Using invisible characters is not allowed. + Neredzamu rakstzīmju izmantošana nav atļauta. + + + Mixing numbers from different scripts is not allowed. + Nav atļauts sajaukt numurus no dažādiem skriptiem. + + + Using hidden overlay characters is not allowed. + Slēptu pārklājuma rakstzīmju izmantošana nav atļauta. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Faila paplašinājums nav derīgs ({{ extension }}). Atļautie paplašinājumi ir {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Noteiktais rakstzīmju kodējums nav derīgs ({{ detected }}). Atļautie kodējumi ir {{ encodings }}. + + + This value is not a valid MAC address. + Šī vērtība nav derīga MAC adrese. + + + This URL is missing a top-level domain. + Šim URL trūkst augšējā līmeņa domēna. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Šī vērtība ir pārāk īsa. Tai būtu jābūt vismaz vienu vārdu garai.|Šī vērtība ir pārāk īsa. Tai būtu jābūt ne mazāk kā {{ min }} vārdus garai. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Šī vērtība ir pārāk gara. Tai būtu jābūt vienam vārdam.|Šī vērtība ir pārāk gara. Tai būtu jābūt ne vairāk kā {{ max }} vārdus garai. + + + This value does not represent a valid week in the ISO 8601 format. + Šī vērtība neatspoguļo nedēļu ISO 8601 formatā. + + + This value is not a valid week. + Šī vērtība nav derīga nedēļa. + + + This value should not be before week "{{ min }}". + Šai vērtībai nevajadzētu būt pirms "{{ min }}" nedēļas. + + + This value should not be after week "{{ max }}". + Šai vērtībai nevajadzētu būt pēc "{{ max }}" nedēļas. + + + This value is not a valid Twig template. + Šī vērtība nav derīgs Twig šablons. + + + This file is not a valid video. + Šī datne nav derīgs video fails. + + + The size of the video could not be detected. + Neizdevās noteikt video izmēru. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Video platums ir pārāk liels ({{ width }}px). Atļautais maksimālais platums ir {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Video platums ir pārāk mazs ({{ width }}px). Sagaidāmais minimālais platums ir {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Video augstums ir pārāk liels ({{ height }}px). Atļautais maksimālais augstums ir {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Video augstums ir pārāk mazs ({{ height }}px). Sagaidāmais minimālais augstums ir {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Video ir pārāk maz pikseļu ({{ pixels }}). Sagaidāmais minimālais daudzums ir {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Video ir pārāk daudz pikseļu ({{ pixels }}). Paredzētais maksimālais daudzums ir {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Video attiecība ir pārāk liela ({{ ratio }}). Atļautā maksimālā attiecība ir {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Video attiecība ir pārāk maza ({{ ratio }}). Sagaidāmā minimālā attiecība ir {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video ir kvadrātveida ({{ width }}x{{ height }}px). Kvadrātveida video nav atļauti. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video ir ainavas orientācijā ({{ width }}x{{ height }} px). Ainavas formāta video nav atļauti. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video ir portreta orientācijā ({{ width }}x{{ height }}px). Portreta orientācijas video nav atļauti. + + + The video file is corrupted. + Video fails ir bojāts. + + + The video contains multiple streams. Only one stream is allowed. + Video satur vairākus straumējumus. Atļauta ir tikai viena straume. + + + Unsupported video codec "{{ codec }}". + Neatbalstīts video kodeks “{{ codec }}”. + + + Unsupported video container "{{ container }}". + Neatbalstīts video konteiners "{{ container }}". + + + The image file is corrupted. + Attēla fails ir bojāts. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Attēlam ir par maz pikseļu ({{ pixels }}). Sagaidāmais minimālais daudzums ir {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Attēlam ir pārāk daudz pikseļu ({{ pixels }}). Sagaidāmais maksimālais daudzums ir {{ max_pixels }}. + + + This filename does not match the expected charset. + Šis faila nosaukums neatbilst paredzētajam rakstzīmju kopumam. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.mk.xlf b/lib/symfony/validator/Resources/translations/validators.mk.xlf new file mode 100644 index 0000000000..a21621b17e --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.mk.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Оваа вредност треба да биде лажна. + + + This value should be true. + Оваа вредност треба да биде вистинита. + + + This value should be of type {{ type }}. + Оваа вредност треба да биде од типот {{ type }}. + + + This value should be blank. + Оваа вредност треба да биде празна. + + + The value you selected is not a valid choice. + Вредноста што ја одбравте не е валиден избор. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Мора да одберете најмалку {{ limit }} избор.|Мора да одберете најмалку {{ limit }} изброи. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Може да одберете најмногу {{ limit }} избор.|Мора да одберете најмногу {{ limit }} избори. + + + One or more of the given values is invalid. + Една или повеќе од дадените вредности не се валидни. + + + This field was not expected. + Ова поле не беше очекувано. + + + This field is missing. + Ова поле недостига. + + + This value is not a valid date. + Оваа вредност не е валиден датум. + + + This value is not a valid datetime. + Оваа вредност не е валиден датум и време. + + + This value is not a valid email address. + Оваа вредност не е валидна адреса за е-пошта. + + + The file could not be found. + Датотеката не е најдена. + + + The file is not readable. + Датотеката не може да биде прочитана. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Датотеката е премногу голема ({{ size }} {{ suffix }}). Максималната дозволена големина е {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Миме типот на датотеката не е валиден ({{ type }}). Дозволените миме типови се {{ types }}. + + + This value should be {{ limit }} or less. + Оваа вредност треба да биде {{ limit }} или помалку. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Оваа вредност е предолга. Треба да содржи {{ limit }} карактер или помалку.|Оваа вредност е предолга. Треба да содржи {{ limit }} карактери или помалку. + + + This value should be {{ limit }} or more. + Оваа вредност треба да е {{ limit }} или повеќе. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Оваа вредност е прекратка. Треба да содржи {{ limit }} карактер или повеќе.|Оваа вредност е прекратка. Треба да содржи {{ limit }} карактери или повеќе. + + + This value should not be blank. + Ова поле не може да биде празно. + + + This value should not be null. + Оваа вредност не може да биде ништо (null). + + + This value should be null. + Оваа вредност треба да е ништо (null). + + + This value is not valid. + Оваа вредност не е валидна. + + + This value is not a valid time. + Оваа вредност не е валидно време. + + + This value is not a valid URL. + Оваа вредност не е валиден URL. + + + The two values should be equal. + Двете вредности треба да се еднакви. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Датотеката е премногу голема. Максималната дозволена големина е {{ limit }} {{ suffix }}. + + + The file is too large. + Датотеката е премногу голема. + + + The file could not be uploaded. + Датотеката не може да биде подигната. + + + This value should be a valid number. + Оваа вредност треба да е валиден број. + + + This file is not a valid image. + Оваа датотека не е валидна слика. + + + This value is not a valid IP address. + Оваа вредност не е валидна IP адреса. + + + This value is not a valid language. + Оваа вредност не е валиден јазик. + + + This value is not a valid locale. + Оваа вредност не е валидна локализација. + + + This value is not a valid country. + Оваа вредност не е валидна земја. + + + This value is already used. + Оваа вредност веќе се користи. + + + The size of the image could not be detected. + Големината на сликата не може да се детектира. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ширината на сликата е преголема ({{ width }}px). Максималната дозволена ширина е {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ширината на сликата е премала ({{ width }}px). Минималната дозволена ширина е {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Висината на сликата е преголема ({{ height }}px). Максималната дозволена висина е {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Висината на сликата е премала ({{ height }}px). Минималната дозволена висина е {{ min_height }}px. + + + This value should be the user's current password. + Оваа вредност треба да биде сегашната лозинка на корисникот. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Оваа вредност треба да има точно {{ limit }} карактер.|Оваа вредност треба да има точно {{ limit }} карактери. + + + The file was only partially uploaded. + Датотеката е само делумно подигната. + + + No file was uploaded. + Датотеката не е подигната. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Не е конфигурирана привремена папка во php.ini, или конфигурираната папка не постои. + + + Cannot write temporary file to disk. + Не може да се напише привремена датотека на дискот. + + + A PHP extension caused the upload to fail. + PHP екстензијата предизвика подигнувањето да биде неуспешно. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Оваа колекција треба да содржи {{ limit }} елемент или повеќе.|Оваа колекција треба да содржи {{ limit }} елементи или повеќе. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Оваа колекција треба да содржи {{ limit }} елемент или помалку.|Оваа колекција треба да содржи {{ limit }} елементи или помалку. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Оваа колекција треба да содржи точно {{ limit }} елемент.|Оваа колекција треба да содржи точно {{ limit }} елементи. + + + Invalid card number. + Бројот на картичката не е валиден. + + + Unsupported card type or invalid card number. + Неподдржан тип на картичка или бројот на картичката не е валиден. + + + This value is not a valid International Bank Account Number (IBAN). + Оваа вредност не е валиден Меѓународен Банкарски Сметка Број (IBAN). + + + This value is not a valid ISBN-10. + Оваа вредност не е валиден ISBN-10. + + + This value is not a valid ISBN-13. + Оваа вредност не е валиден ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Оваа вредност не е ниту валиден ISBN-10 ниту валиден ISBN-13. + + + This value is not a valid ISSN. + Оваа вредност не е валиден ISSN. + + + This value is not a valid currency. + Оваа вредност не е валидна валута. + + + This value should be equal to {{ compared_value }}. + Оваа вредност треба да биде еднаква на {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Оваа вредност треба да е поголема од {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Оваа вредност треба да е поголема или еднаква на {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Оваа вредност треба да е идентична на {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Оваа вредност треба да е помала од {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Оваа вредност треба да е помала или еднаква на {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Оваа вредност треба да не биде еднаква на {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Оваа вредност треба да не биде идентична со {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Соодносот на сликата е преголем ({{ ratio }}).Максималниот дозволен сооднос е {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Соодносот на сликата е премал ({{ ratio }}). Минималниот дозволен сооднос е {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Сликата е квадратна ({{ width }}x{{ height }}px). Квадратни слики не се дозволени. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Сликата е ориентирана кон пејзаж ({{ width }}x{{ height }}px). Сликите ориентирани кон пејзаж не се дозволени. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Сликата е ориентирана кон портрет ({{ width }}x{{ height }}px). Сликите ориентирани кон портрет не се дозволени. + + + An empty file is not allowed. + Празна датотека не е дозволена. + + + The host could not be resolved. + Хостот е недостапен. + + + This value does not match the expected {{ charset }} charset. + Оваа вредност не се совпаѓа со очекуваниот {{ charset }} сет на карактери (charset). + + + This value is not a valid Business Identifier Code (BIC). + Оваа вредност не е валиден Бизнис Идентификациски Код (BIC). + + + Error + Грешка + + + This value is not a valid UUID. + Оваа вредност не е валиден UUID. + + + This value should be a multiple of {{ compared_value }}. + Оваа вредност треба да биде повеќекратна од {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Овој бизнис идентификациски код (BIC) не е поврзан со IBAN {{ iban }}. + + + This value should be valid JSON. + Оваа вредност треба да биде валиден JSON. + + + This collection should contain only unique elements. + Оваа колекција треба да содржи само уникатни елементи. + + + This value should be positive. + Оваа вредност треба да биде позитивна. + + + This value should be either positive or zero. + Оваа вредност треба да биде или позитивна или нула. + + + This value should be negative. + Оваа вредност треба да биде негативна. + + + This value should be either negative or zero. + Оваа вредност треба да биде или негативна или нула. + + + This value is not a valid timezone. + Оваа вредност не е валидна временска зона. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Оваа лозинка е компромитирана и не смее да биде користена. Ве молиме употребете друга лозинка. + + + This value should be between {{ min }} and {{ max }}. + Оваа вредност треба да е помеѓу {{ min }} и {{ max }}. + + + This value is not a valid hostname. + Оваа вредност не е валидно име за мрежниот сметач (hostname). + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Бројот на елементи во оваа колекција треба да биде повеќекратен од {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Оваа вредност треба да задоволува најмалку едно од следните ограничувања: + + + Each element of this collection should satisfy its own set of constraints. + Секој елемент од оваа колекција треба да задоволува сопствен сет на ограничувања. + + + This value is not a valid International Securities Identification Number (ISIN). + Оваа вредност не е важечки меѓународен идентификациски број за хартии од вредност (ISIN). + + + This value should be a valid expression. + Оваа вредност треба да биде валиден израз. + + + This value is not a valid CSS color. + Оваа вредност не е валидна CSS боја. + + + This value is not a valid CIDR notation. + Оваа вредност не е валидна CIDR ознака. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Вредноста на мрежната маска (netmask) треба да биде помеѓу {{ min }} и {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Името на датотеката е предолго. Треба да има {{ filename_max_length }} карактер има помалку.|Името на датотеката е предолго. Треба да има {{ filename_max_length }} карактери или помалку. + + + The password strength is too low. Please use a stronger password. + Оваа лозинка е премногу едноставна. Ве молиме користете посилна лозинка. + + + This value contains characters that are not allowed by the current restriction-level. + Оваа вредност содржи карактери кои не се дозволени од тековното ниво на ограничување. + + + Using invisible characters is not allowed. + Користењето на невидливи знаци не е дозволено. + + + Mixing numbers from different scripts is not allowed. + Не е дозволено мешање на броеви од различни скрипти. + + + Using hidden overlay characters is not allowed. + Не е дозволено користење на скриени знаци за преклопување. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Зголемувања на датотеката е неважечка ({{ extension }}). Дозволени зголемувања се ({{ extensions }}). + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Откриеното кодирање на знаци е неважечко ({{ detected }}). Дозволените шифрирања се {{ encodings }}. + + + This value is not a valid MAC address. + Оваа вредност не е валидна MAC адреса. + + + This URL is missing a top-level domain. + На овој URL недостасува домен од највисоко ниво. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Оваа вредност е премногу кратка. Треба да содржи барем една збор.|Оваа вредност е премногу кратка. Треба да содржи барем {{ min }} зборови. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Оваа вредност е премногу долга. Треба да содржи само еден збор.|Оваа вредност е премногу долга. Треба да содржи {{ max }} зборови или помалку. + + + This value does not represent a valid week in the ISO 8601 format. + Ова вредност не претставува валидна недела во ISO 8601 формат. + + + This value is not a valid week. + Оваа вредност не е валидна недела. + + + This value should not be before week "{{ min }}". + Ова вредност не треба да биде пред неделата "{{ min }}". + + + This value should not be after week "{{ max }}". + Ова вредност не треба да биде по недела "{{ max }}". + + + This value is not a valid Twig template. + Оваа вредност не е валиден Twig шаблон. + + + This file is not a valid video. + Оваа датотека не е валидно видео. + + + The size of the video could not be detected. + Големината на видеото не можеше да се утврди. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ширината на видеото е премногу голема ({{ width }}px). Дозволената максимална ширина е {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ширината на видеото е премала ({{ width }}px). Минималната очекувана ширина е {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Висината на видеото е премногу голема ({{ height }}px). Дозволената максимална висина е {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Висината на видеото е премала ({{ height }}px). Очекуваната минимална висина е {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Видеото има премалку пиксели ({{ pixels }}). Очекуван минимален износ е {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Видеото има премногу пиксели ({{ pixels }}). Очекуваниот максимален износ е {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Соодносот на видеото е преголем ({{ ratio }}). Дозволениот максимален сооднос е {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Односот на видеото е премал ({{ ratio }}). Очекуваниот минимален однос е {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Видеото е квадратно ({{ width }}x{{ height }}px). Квадратни видеа не се дозволени. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Видеото е во хоризонтална ориентација ({{ width }}x{{ height }} px). Хоризонтални видеа не се дозволени. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Видеото е во портретна ориентација ({{ width }}x{{ height }}px). Видеа со портретна ориентација не се дозволени. + + + The video file is corrupted. + Видео датотеката е оштетена. + + + The video contains multiple streams. Only one stream is allowed. + Видеото содржи повеќе струи. Дозволена е само една струја. + + + Unsupported video codec "{{ codec }}". + Неподдржан видео кодек „{{ codec }}“. + + + Unsupported video container "{{ container }}". + Неподдржан видео контејнер "{{ container }}". + + + The image file is corrupted. + Датотеката со слика е оштетена. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Сликата има премалку пиксели ({{ pixels }}). Очекуваниот минимален број е {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Сликата има премногу пиксели ({{ pixels }}). Очекуваната максимална количина е {{ max_pixels }}. + + + This filename does not match the expected charset. + Името на датотеката не одговара на очекуваниот збир на знаци. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.mn.xlf b/lib/symfony/validator/Resources/translations/validators.mn.xlf new file mode 100644 index 0000000000..42a841f7d0 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.mn.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Энэ утга буруу байх ёстой. + + + This value should be true. + Энэ утга үнэн байх ёстой. + + + This value should be of type {{ type }}. + Энэ утга {{ type }} -н төрөл байх ёстой. + + + This value should be blank. + Энэ утга хоосон байх ёстой. + + + The value you selected is not a valid choice. + Сонгосон утга буруу байна. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Хамгийн багадаа {{ limit }} утга сонгогдсон байх ёстой. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Хамгийн ихдээ {{ limit }} утга сонгогдох боломжтой. + + + One or more of the given values is invalid. + Өгөгдсөн нэг эсвэл нэгээс олон утга буруу байна. + + + This field was not expected. + Энэ талбар нь хүлээгдэж байсан юм. + + + This field is missing. + Энэ талбар нь алга болсон байна. + + + This value is not a valid date. + Энэ утга буруу date төрөл байна . + + + This value is not a valid datetime. + Энэ утга буруу цаг төрөл байна. + + + This value is not a valid email address. + И-майл хаяг буруу байна. + + + The file could not be found. + Файл олдсонгүй. + + + The file is not readable. + Файл уншигдахуйц биш байна. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Файл хэтэрхий том байна ({{ size }} {{ suffix }}). Зөвшөөрөгдөх дээд хэмжээ {{ limit }} {{ suffix }} байна. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Файлын MIME-төрөл нь буруу байна ({{ type }}). Зөвшөөрөгдөх MIME-төрлүүд {{ types }}. + + + This value should be {{ limit }} or less. + Энэ утга {{ limit }} юмуу эсвэл бага байна. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Энэ утга хэтэрхий урт байна. {{ limit }} тэмдэгтийн урттай юмуу эсвэл бага байна. + + + This value should be {{ limit }} or more. + Энэ утга {{ limit }} юмуу эсвэл их байна. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Энэ утга хэтэрхий богино байна. {{ limit }} тэмдэгт эсвэл их байна. + + + This value should not be blank. + Энэ утга хоосон байж болохгүй. + + + This value should not be null. + Энэ утга null байж болохгүй. + + + This value should be null. + Энэ утга null байна. + + + This value is not valid. + Энэ утга буруу байна. + + + This value is not a valid time. + Энэ утга буруу цаг төрөл байна. + + + This value is not a valid URL. + Энэ утга буруу URL байна . + + + The two values should be equal. + Хоёр утгууд ижил байх ёстой. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Файл хэтэрхий том байна. Зөвшөөрөгдөх дээд хэмжээ нь {{ limit }} {{ suffix }} байна. + + + The file is too large. + Файл хэтэрхий том байна. + + + The file could not be uploaded. + Файл upload хийгдсэнгүй. + + + This value should be a valid number. + Энэ утга зөвхөн тоо байна. + + + This file is not a valid image. + Файл зураг биш байна. + + + This value is not a valid IP address. + Энэ утга хүчинтэй IP хаяг биш юм. + + + This value is not a valid language. + Энэ утга үнэн зөв хэл биш байна. + + + This value is not a valid locale. + Энэ утга үнэн зөв байршил биш байна. + + + This value is not a valid country. + Энэ утга үнэн бодит улс биш байна. + + + This value is already used. + Энэ утга аль хэдийнээ хэрэглэгдсэн байна. + + + The size of the image could not be detected. + Зургийн хэмжээ тогтоогдож чадсангүй. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Зургийн өргөн хэтэрхий том байна ({{ width }}px). Өргөн нь хамгийн ихдээ {{ max_width }}px байх боломжтой. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Зургийн өргөн хэтэрхий жижиг байна ({{ width }}px). Өргөн нь хамгийн багадаа {{ min_width }}px байх боломжтой. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Зургийн өндөр хэтэрхий том байна ({{ height }}px). Өндөр нь хамгийн ихдээ {{ max_height }}px байх боломжтой. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Зургийн өндөр хэтэрхий жижиг байна ({{ height }}px). Өндөр нь хамгийн багадаа {{ min_height }}px байх боломжтой. + + + This value should be the user's current password. + Энэ утга хэрэглэгчийн одоогийн нууц үг байх ёстой. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Энэ утга яг {{ limit }} тэмдэгт байх ёстой.|Энэ утга яг {{ limit }} тэмдэгт байх ёстой. + + + The file was only partially uploaded. + Файлын зөвхөн хагас нь upload хийгдсэн. + + + No file was uploaded. + Ямар ч файл upload хийгдсэнгүй. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + php.ini дээр түр зуурын хавтсыг тохируулаагүй байна, эсвэл тохируулсан хавтас байхгүй байна. + + + Cannot write temporary file to disk. + Түр зуурын файлыг диск руу бичиж болохгүй байна. + + + A PHP extension caused the upload to fail. + PHP extension нь upload -г амжилтгүй болгоод байна. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Энэ коллекц {{ limit }} ба түүнээс дээш тооны элемент агуулах ёстой.|Энэ коллекц {{ limit }} ба түүнээс дээш тооны элемент агуулах ёстой. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Энэ коллекц {{ limit }} ба түүнээс доош тооны элемент агуулах ёстой.|Энэ коллекц {{ limit }} ба түүнээс доош тооны элемент агуулах ёстой. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Энэ коллекц яг {{ limit }} элемент агуулах ёстой.|Энэ коллекц яг {{ limit }} элемент агуулах ёстой. + + + Invalid card number. + Картын дугаар буруу байна. + + + Unsupported card type or invalid card number. + Дэмжигдээгүй картын төрөл эсвэл картын дугаар буруу байна. + + + This value is not a valid International Bank Account Number (IBAN). + Энэ утга хүчинтэй Олон улсын Банкны Дансны Дугаар (IBAN) биш юм. + + + This value is not a valid ISBN-10. + Энэ утга үнэн зөв ISBN-10 биш байна. + + + This value is not a valid ISBN-13. + Энэ утга үнэн зөв ISBN-13 биш байна. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Энэ утга үнэн зөв ISBN-10 юмуу ISBN-13 биш байна. + + + This value is not a valid ISSN. + Энэ утга үнэн зөв ISSN биш байна. + + + This value is not a valid currency. + Энэ утга үнэн бодит валют биш байна. + + + This value should be equal to {{ compared_value }}. + Энэ утга {{ compared_value }} -тaй тэнцүү байх ёстой. + + + This value should be greater than {{ compared_value }}. + Энэ утга {{ compared_value }} -с их байх ёстой. + + + This value should be greater than or equal to {{ compared_value }}. + Энэ утга {{ compared_value }} -тай тэнцүү юмуу эсвэл их байх ёстой. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Энэ утга {{ compared_value_type }} {{ compared_value }} -тай яг ижил байх ёстой. + + + This value should be less than {{ compared_value }}. + Энэ утга {{ compared_value }} -с бага байх ёстой. + + + This value should be less than or equal to {{ compared_value }}. + Энэ утга {{ compared_value }} -тай ижил юмуу эсвэл бага байх ёстой. + + + This value should not be equal to {{ compared_value }}. + Энэ утга {{ compared_value }} -тай тэнцүү байх ёсгүй. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Энэ утга {{ compared_value_type }} {{ compared_value }} -тай яг ижил байх ёсгүй. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Зургийн харьцаа хэтэрхий том байна ({{ ratio }}). Харьцаа нь хамгийн ихдээ {{ max_ratio }} байна. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Зургийн харьцаа хэтэрхий жижиг байна ({{ ratio }}). Харьцаа нь хамгийн багадаа {{ min_ratio }} байна. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Зураг дөрвөлжин хэлбэртэй байна ({{ width }}x{{ height }}px). Дөрвөлжин зургууд оруулах боломжгүй. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Зураг хэвтээ байрлалтай байна ({{ width }}x{{ height }}px). Хэвтээ байрлалтай зургууд оруулах боломжгүй. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Зургууд босоо байрлалтай байна ({{ width }}x{{ height }}px). Босоо байрлалтай зургууд оруулах боломжгүй. + + + An empty file is not allowed. + Хоосон файл оруулах боломжгүй. + + + The host could not be resolved. + Хост зөв тохирогдоогүй байна. + + + This value does not match the expected {{ charset }} charset. + Энэ утга тооцоолсон {{ charset }} тэмдэгттэй таарахгүй байна. + + + This value is not a valid Business Identifier Code (BIC). + Энэ утга хүчинтэй Бизнес Таних Код (BIC) биш юм. + + + Error + Алдаа + + + This value is not a valid UUID. + Энэ утга хүчинтэй UUID биш юм. + + + This value should be a multiple of {{ compared_value }}. + Энэ утга {{ compared_value }} -н үржвэр байх ёстой. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Энэ Business Identifier Code (BIC) код нь IBAN {{ iban }} -тай холбоогүй байна. + + + This value should be valid JSON. + Энэ утга JSON байх ёстой. + + + This collection should contain only unique elements. + Энэ коллекц зөвхөн давтагдахгүй элементүүд агуулах ёстой. + + + This value should be positive. + Энэ утга эерэг байх ёстой. + + + This value should be either positive or zero. + Энэ утга тэг эсвэл эерэг байх ёстой. + + + This value should be negative. + Энэ утга сөрөг байх ёстой. + + + This value should be either negative or zero. + Энэ утга сөрөг эсвэл тэг байх ёстой. + + + This value is not a valid timezone. + Энэ утга үнэн зөв цагийн бүс биш байна. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Энэ нууц үгийн мэдээлэл алдагдсан байх магадлалтай учраас дахин ашиглагдах ёсгүй. Өөр нууц үг ашиглана уу. + + + This value should be between {{ min }} and {{ max }}. + Энэ утга {{ min }} -с {{ max }} хооронд байх ёстой. + + + This value is not a valid hostname. + Энэ утга буруу hostname байна. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Энэхүү цуглуулган дахь элемэнтийн тоо, {{ compared_value }}-н үржвэр байх ёстой. + + + This value should satisfy at least one of the following constraints: + Энэ утга доорх болзолуудын ядаж нэгийг хангах ёстой: + + + Each element of this collection should satisfy its own set of constraints. + Энэхүү цуглуулган дахь элемэнтүүд өөр өөрсдийн болзолуудаа хангах ёстой. + + + This value is not a valid International Securities Identification Number (ISIN). + Энэ утга зөв International Securities Identification Number (ISIN) биш байна. + + + This value should be a valid expression. + Энэ утга нь зөв илэрхийлэл байх ёстой. + + + This value is not a valid CSS color. + Энэ утга нь хүчинтэй CSS өнгө биш байна. + + + This value is not a valid CIDR notation. + Энэ утга нь хүчинтэй CIDR тэмдэглэгээ биш байна. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Сүлжээний маскны утга нь {{ min }} ба {{ max }}-ийн хооронд байх ёстой. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Файлын нэр хэт урт байна. Энэ нь {{ filename_max_length }} тэмдэгт эсвэл түүнээс бага байх ёстой.|Файлын нэр хэт урт байна. Энэ нь {{ filename_max_length }} тэмдэгт эсвэл түүнээс бага байх ёстой. + + + The password strength is too low. Please use a stronger password. + Нууц үгийн хүч нь хэт бага байна. Хүчтэй нууц үгийг ашиглана уу. + + + This value contains characters that are not allowed by the current restriction-level. + Энэ утга нь одоогийн хязгаарлалтын түвшинд зөвшөөрөгдөөгүй тэмдэгтүүд агуулж байна. + + + Using invisible characters is not allowed. + Харагдахгүй тэмдэгтүүдийг ашиглахыг зөвшөөрөхгүй. + + + Mixing numbers from different scripts is not allowed. + Янз бүрийн скриптүүдээс тоог хольж хэрэглэхийг зөвшөөрөхгүй. + + + Using hidden overlay characters is not allowed. + Нууцлагдсан давхаргын тэмдэгтүүдийг ашиглахыг зөвшөөрөхгүй. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Файлын өргөтгөл буруу байна ({{ extension }}). Зөвшөөрөгдсөн өргөтгөлүүд нь {{ extensions }} юм. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Илрүүлсэн тэмдэгтийн кодчилол буруу байна ({{ detected }}). Зөвшөөрөгдсөн кодчилолууд нь {{ encodings }} юм. + + + This value is not a valid MAC address. + Энэ утга хүчинтэй MAC хаяг биш юм. + + + This URL is missing a top-level domain. + Энэ URL дээд түвшингийн домейн дутуу байна. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Энэ утга нь хэтэрхий богино байна. Энэ нь дор хаяж нэг үг агуулсан байх ёстой.|Энэ утга нь хэтэрхий богино байна. Энэ нь дор хаяж {{ min }} үг агуулсан байх ёстой. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Энэ утга нь хэтэрхий урт байна. Энэ нь зөвхөн нэг үг агуулсан байх ёстой.|Энэ утга нь хэтэрхий урт байна. Энэ нь {{ max }} үг эсвэл түүнээс бага байх ёстой. + + + This value does not represent a valid week in the ISO 8601 format. + Энэ утга нь ISO 8601 форматад хүчинтэй долоо хоногийг илэрхийлэхгүй байна. + + + This value is not a valid week. + Энэ утга хүчинтэй долоо хоног биш байна. + + + This value should not be before week "{{ min }}". + Энэ утга нь "{{ min }}" долоо хоногоос өмнө байх ёсгүй. + + + This value should not be after week "{{ max }}". + Энэ утга нь долоо хоног "{{ max }}" -аас хойш байх ёсгүй. + + + This value is not a valid Twig template. + Энэ утга нь Twig-ийн хүчинтэй загвар биш юм. + + + This file is not a valid video. + Энэ файл хүчинтэй видео биш байна. + + + The size of the video could not be detected. + Видеоны хэмжээг тодорхойлох боломжгүй байлаа. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Видео өргөн хэт их байна ({{ width }}px). Зөвшөөрөгдөх дээд өргөн нь {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Видео өргөн хэт бага байна ({{ width }}px). Хамгийн бага хүлээгдэж буй өргөн {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Видеоны өндөр хэт их байна ({{ height }}px). Зөвшөөрөгдсөн дээд өндөр нь {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Видео өндрийг хэт бага байна ({{ height }}px). Хамгийн бага өндрийн шаардлага {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Видео хэт цөөн пикселтэй байна ({{ pixels }}). Хүлээгдэж буй хамгийн бага хэмжээ нь {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Видео хэт олон пикселтэй байна ({{ pixels }}). Хүлээгдэж буй дээд хэмжээ нь {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Видео харьцаа хэт их байна ({{ ratio }}). Зөвшөөрөгдөх дээд харьцаа {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Видеоны харьцаа хэт жижиг байна ({{ ratio }}). Хамгийн бага хүлээгдэж буй харьцаа {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Видео дөрвөлжин байна ({{ width }}x{{ height }}px). Дөрвөлжин видеонууд зөвшөөрөгдөхгүй. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Видео хэвтээ чиглэлтэй байна ({{ width }}x{{ height }} px). Хэвтээ видеонууд зөвшөөрөгдөхгүй. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Видео босоо чиглэлтэй ({{ width }}x{{ height }}px). Босоо чиглэлийн видеонууд зөвшөөрөгдөхгүй. + + + The video file is corrupted. + Видео файл гэмтсэн байна. + + + The video contains multiple streams. Only one stream is allowed. + Видео нь олон урсгал агуулсан байна. Зөвхөн нэг урсгалыг зөвшөөрнө. + + + Unsupported video codec "{{ codec }}". + Дэмжигдээгүй видео кодек "{{ codec }}". + + + Unsupported video container "{{ container }}". + Дэмжигдээгүй видео контейнер "{{ container }}". + + + The image file is corrupted. + Зургийн файл гэмтсэн. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Зурган дээрх пикселийн тоо дэндүү цөөн байна ({{ pixels }}). Хүлээгдэж буй доод хэмжээ нь {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Зурагт хэт олон пиксел байна ({{ pixels }}). Хүлээгдэж буй дээд хэмжээ нь {{ max_pixels }}. + + + This filename does not match the expected charset. + Энэ файлын нэр хүлээгдэж буй тэмдэгтийн багцтай нийцэхгүй байна. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.my.xlf b/lib/symfony/validator/Resources/translations/validators.my.xlf new file mode 100644 index 0000000000..bf23d63635 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.my.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + ဤတန်ဖိုးသည် false ဖြစ်ရမည်။ + + + This value should be true. + ဤတန်ဖိုးသည် true ဖြစ်ရမည်။ + + + This value should be of type {{ type }}. + ဤတန်ဖိုးသည် {{ type }} အမျိုးအစားဖြစ်ရမည်။ + + + This value should be blank. + ဤတန်ဖိုးသည် ကွပ်လပ်မဖြစ်သင့်ပါ။ + + + The value you selected is not a valid choice. + သင်ရွေးချယ်သောတန်ဖိုးသည် သင့်လျှော်သော် တန်ဖိုးမဟုတ်ပါ။ + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + သင်သည် အနည်းဆုံးရွေးချယ်မှု {{ limit }} ခုရွေးချယ်ရမည်။ + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + သင်သည်အများဆုံး {{ limit }} ခုသာရွေးချယ်ခွင့်ရှိသည်။ + + + One or more of the given values is invalid. + ပေးထားသောတန်ဖိုးတစ်ခု (သို့မဟုတ်) တစ်ခုထက်ပို၍မမှန်ကန်ပါ။ + + + This field was not expected. + ဤကွက်လပ်ကိုမမျှော်လင့်ထားပါ။ + + + This field is missing. + ဤကွက်လပ်ကိုမမျှော်လင့်ထားပါ။ + + + This value is not a valid date. + ဤတန်ဖိုးသည်မှန်ကန်သော်ရက်စွဲမဟုတ်ပါ။ + + + This value is not a valid datetime. + ဤတန်ဖိုးသည် မှန်ကန်သော် ရက်စွဲ/အချိန် မဟုတ်ပါ။ + + + This value is not a valid email address. + ဤတန်ဖိုးသည် မှန်ကန်သော် အီးမေးလိပ်စာ မဟုတ်ပါ။ + + + The file could not be found. + ဖိုင်ရှာမတွေ့ပါ။ + + + The file is not readable. + ဤဖိုင်ကို ဖတ်၍မရပါ။ + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + ဖိုင်အရွယ်အစား အလွန်ကြီးနေသည် ({{ size }} {{ suffix }}). ခွင့်ပြုထားသော အများဆုံး ဖိုင်ဆိုဒ်သည် {{ limit }} {{ suffix }} ဖြစ်သည်။ + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + ဖိုင်၏ mime အမျိုးအစားမမှန်ကန်ပါ ({{ type }})။ ခွင့်ပြုထားသော mime အမျိုးအစားများမှာ {{ types }}. + + + This value should be {{ limit }} or less. + ဤတန်ဖိုးသည် {{ limit }} (သို့မဟုတ်) {{ limit }} ထက်နည်းသင့်သည်။ + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + ဤတန်ဖိုးသည် အလွန်ရှည်လွန်းသည်။ ၎င်းတွင်အက္ခရာ {{ limit }} (သို့မဟုတ်) ၎င်းထက်နည်းသင့်သည်။ | ဤတန်ဖိုးသည် အလွန်ရှည်လွန်းသည်။ ၎င်းတွင်အက္ခရာ {{limit}} ခုနှင့်အထက်ရှိသင့်သည်။ + + + This value should be {{ limit }} or more. + ဤတန်ဖိုးသည် {{limit}} (သို့မဟုတ်) ထို့ထက်ပိုသင့်သည်။ + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + ဤတန်ဖိုးသည် အလွန်တိုလွန်းသည်။ ၎င်းတွင်အက္ခရာ {{limit}} (သို့မဟုတ်) ထို့ထက်ပိုရှိသင့်သည်။ | ဤတန်ဖိုးသည်တိုလွန်းသည်။ ၎င်းတွင်အက္ခရာ {{limit}} လုံးနှင့်အထက်ရှိသင့်သည်။ + + + This value should not be blank. + ဤတန်ဖိုးသည်ကွက်လပ်မဖြစ်သင့်ပါ။ + + + This value should not be null. + ဤတန်ဖိုးသည် null မဖြစ်သင့်ပါ။ + + + This value should be null. + ဤတန်ဖိုးသည် null ဖြစ်သင့်သည်။ + + + This value is not valid. + ဤတန်ဖိုးသည်မှန်ကန်သောတန်ဖိုးမဟုတ်ပါ။ + + + This value is not a valid time. + ဤတန်ဖိုးသည်မှန်ကန်သော အချိန်တန်ဖိုးမဟုတ်ပါ။ + + + This value is not a valid URL. + ဤတန်ဖိုးသည်မှန်ကန်သော URL တန်ဖိုးမဟုတ်ပါ။ + + + The two values should be equal. + တန်ဖိုးနှစ်ခုသည် တူညီသင့်သည်။ + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + ဤဖိုင်သည် အလွန်ကြီးသည်။ ခွင့်ပြုထားသည့်အများဆုံးဖိုင်အရွယ်အစားသည် {{ limit }} {{ suffix }} ဖြစ်သည်။ + + + The file is too large. + ဤဖိုင်သည် အလွန်ကြီးသည်။ + + + The file could not be uploaded. + ဤဖိုင်ကိုတင်၍မရပါ။ + + + This value should be a valid number. + ဤတန်ဖိုးသည်မှန်ကန်သောနံပါတ်ဖြစ်သင့်သည်။ + + + This file is not a valid image. + ဤဖိုင်သည်မှန်ကန်သော ဓါတ်ပုံမဟုတ်ပါ။ + + + This value is not a valid IP address. + ဤတန်ဖိုးသည် မှန်ကန်သော IP လိပ်စာ မဟုတ်ပါ။ + + + This value is not a valid language. + ဤတန်ဖိုးသည် မှန်ကန်သောဘာသာစကားမဟုတ်ပါ။ + + + This value is not a valid locale. + ဤတန်ဖိုးသည်မှန်ကန်သောဘာသာပြန်မဟုတ်ပါ။ + + + This value is not a valid country. + ဤတန်ဖိုးသည်မှန်ကန်သောနိုင်ငံမဟုတ်ပါ။ + + + This value is already used. + ဤတန်ဖိုးသည် အသုံးပြုပြီးသားဖြစ်သည်။ + + + The size of the image could not be detected. + ဓါတ်ပုံအရွယ်အစားကိုရှာမတွေ့ပါ။ + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + ပုံ၏အလျားသည် ကြီးလွန်းသည် ({{ width }}px)။ ခွင့်ပြုထားသည့်အများဆုံးအလျားသည် {{max_width}}px ဖြစ်သည်။ + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + ပုံ၏အလျားသည် သေးလွန်းသည် ({{ width }}px)။ ခွင့်ပြုထားသည့်အနည်းဆုံးအလျားသည် {{max_width}}px ဖြစ်သည်။ + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + ပုံ၏အနံသည် ကြီးလွန်းသည် ({{ height }}px)။ ခွင့်ပြုထားသည့်အများဆုံးအနံသည် {{max_height}}px ဖြစ်သည်။ + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + ပုံ၏အနံသည် သေးလွန်းသည် ({{ height }}px)။ ခွင့်ပြုထားသည့်အနည်းဆုံးအနံသည် {{min_height}}px ဖြစ်သည်။ + + + This value should be the user's current password. + ဤတန်ဖိုးသည်အသုံးပြုသူ၏ လက်ရှိစကားဝှက်ဖြစ်သင့်သည်။ + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + ဤတန်ဖိုးသည်စာလုံး {{limit}} အတိအကျရှိသင့်သည်။ + + + The file was only partially uploaded. + ဤဖိုင်သည်တစ်စိတ်တစ်ပိုင်းသာ upload တင်ခဲ့သည်။ + + + No file was uploaded. + မည်သည့် ဖိုင်မျှ upload မလုပ်ခဲ့ပါ။ + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + php.ini တွင်ယာယီဖိုင်တွဲကိုပြင်ဆင်ထားခြင်းမရှိပါ၊ သို့မဟုတ် ပြင်ဆင်ထားသောဖိုင်တွဲမရှိပါ။ + + + Cannot write temporary file to disk. + ယာရီဖိုင်ကို disk မရေးနိုင်ပါ။ + + + A PHP extension caused the upload to fail. + PHP extension တစ်ခုကြောင့် upload တင်၍မရနိုင်ပါ။ + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + ဤ collection တွင် {{limit}} element (သို့မဟုတ်) ထို့ထက်မပိုသင့်ပါ။ + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + ဤ collection တွင် {{limit}} element (သို့မဟုတ်) ၎င်းထက်နည်းသင့်သည်။ + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + ဤစုစည်းမှုတွင် {{limit}} element အတိအကျပါသင့်သည်။ + + + Invalid card number. + ကဒ်နံပါတ်မမှန်ပါ။ + + + Unsupported card type or invalid card number. + ကဒ်အမျိုးအစားမမှန်ပါ (သို့မဟုတ်) ကဒ်နံပါတ်မမှန်ပါ။ + + + This value is not a valid International Bank Account Number (IBAN). + ဤတန်ဖိုးသည် မှန်ကန်သော နိုင်ငံတကာ ဘဏ်စာရင်းနံပါတ် (IBAN) မဟုတ်ပါ။ + + + This value is not a valid ISBN-10. + ဤတန်ဖိုးသည် မှန်ကန်သော ISBN-10 တန်ဖိုးမဟုတ်ပါ၊ + + + This value is not a valid ISBN-13. + ဤတန်ဖိုးသည် မှန်ကန်သော ISBN-13 တန်ဖိုးမဟုတ်ပါ၊ + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + ဤတန်ဖိုးသည် သင့်လျှော်သော် ISBN-10 (သို့မဟုတ်) ISBN-13 တန်ဖိုးမဟုတ်ပါ၊ + + + This value is not a valid ISSN. + ဤတန်ဖိုးသည် သင့်လျှော်သော် ISSN တန်ဖိုးမဟုတ်ပါ။ + + + This value is not a valid currency. + ဤတန်ဖိုးသည် သင့်လျှော်သော် ငွေကြေးတန်ဖိုးမဟုတ်ပါ။ + + + This value should be equal to {{ compared_value }}. + ဤတန်ဖိုးသည် {{ compared_value }} နှင့်ညီသင့်သည်။ + + + This value should be greater than {{ compared_value }}. + ဤတန်ဖိုးသည် {{ compared_value }} ထက်ကြီးသင့်သည်။ + + + This value should be greater than or equal to {{ compared_value }}. + ဤတန်ဖိုးသည် {{ compared_value }} ထက်ကြီးသင့်သည် (သို့မဟုတ်) ဤတန်ဖိုးသည် {{ compared_value }} ညီသင့်သည်။ + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + ဤတန်ဖိုးသည် {{ compared_value_type }} {{ compared_value }} နှင့်ထပ်တူညီမျှသင့်သည်။ + + + This value should be less than {{ compared_value }}. + ဤတန်ဖိုးသည် {{ compared_value }} ထက်မနဲသောတဲ့ တန်ဖိုးဖြစ်သင့်သည်။ + + + This value should be less than or equal to {{ compared_value }}. + ဤတန်ဖိုးသည် {{ compared_value }} ထက် မနည်းသောတန်ဖိုး (သို့မဟုတ်) ညီမျှသောတန်ဖိုးဖြစ်သင့်သည်။ + + + This value should not be equal to {{ compared_value }}. + ဤတန်ဖိုးသည် {{ compared_value }} နှင့်မညီသင့်ပါ။ + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + ဤတန်ဖိုးသည် {{ compared_value_type }} {{ compared_value }} နှင့်ထပ်တူမညီမျှသင့်သည်။ + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + ဤဓာတ်ပုံအချိုးအစားသည်အလွန်ကြီးလွန်းသည်။ ({{ ratio }})။ ခွင့်ပြုထားသောဓာတ်ပုံအချိုးအသားသည် {{ max_ratio }} ဖြစ်သည်။ + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + ဤဓာတ်ပုံအချိုးအစားသည်အလွန်သေးလွန်းသည်။ ({{ ratio }})။ ခွင့်ပြုထားသောဓာတ်ပုံအချိုးအသားသည် {{ min_ratio }} ဖြစ်သည်။ + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + ဤဓာတ်ပုံသည် စတုရန်းဖြစ်နေသည် ({{ width }}x{{ height }}px)။ စတုရန်းဓာတ်ပုံများကို ခွင့်မပြုပါ။ + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + ဤဓာတ်ပုံသည် အလျှားလိုက်ဖြစ်နေသည် ({{ width }}x{{ height }}px). အလျှားလိုက်ဓာတ်ပုံများခွင့်မပြုပါ။ + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + ဤဓာတ်ပုံသည် ဒေါင်လိုက်ဖြစ်နေသည် ({{ width }}x{{ height }}px). ဒေါင်လိုက်ဓာတ်ပုံများခွင့်မပြုပါ။ + + + An empty file is not allowed. + ဖိုင်အလွတ်ကိုတင်ခွင့်မပြုပါ။ + + + The host could not be resolved. + host ဖြေရှင်း၍မနိုင်ပါ။ + + + This value does not match the expected {{ charset }} charset. + ဤတန်ဖိုးသည် မျှော်မှန်းထားသော {{ charset }} စားလုံးနှင့် ကိုက်ညီမှုမရှိပါ။ + + + This value is not a valid Business Identifier Code (BIC). + ဤတန်ဖိုးသည် မှန်ကန်သော စီးပွားရေး မှတ်ပုံတင်ကုဒ် (BIC) မဟုတ်ပါ။ + + + Error + အမှား + + + This value is not a valid UUID. + ဤတန်ဖိုးသည် မှန်ကန်သော UUID မဟုတ်ပါ။ + + + This value should be a multiple of {{ compared_value }}. + ဤတန်ဖိုးသည် {{compared_value}} ၏ စတူတန်ဖိုးဖြစ်သင့်သည်။ + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + ဤ Business Identifier Code (BIC) သည် IBAN {{ iban }} နှင့်ဆက်စပ်မှုမရှိပါ။ + + + This value should be valid JSON. + ဤတန်ဖိုးသည် သင့်လျှော်သော် JSON တန်ဖိုးဖြစ်သင့်သည်။ + + + This collection should contain only unique elements. + ဤ collection ကိုယ်ပိုင် elements များ ပါသင့်သည်။ + + + This value should be positive. + ဤတန်ဖိုးသည် အပေါင်းဖြစ်သင့်သည်။ + + + This value should be either positive or zero. + ဤတန်ဖိုးသည် အပေါင်း (သို့မဟုတ်) သုည ဖြစ်သင့်သည်။ + + + This value should be negative. + ဤတန်ဖိုးသည် အနုတ် ဖြစ်သင့်သည်။ + + + This value should be either negative or zero. + ဤတန်ဖိုးသည် အနုတ် (သို့မဟုတ်) သုည ဖြစ်သင့်သည်။ + + + This value is not a valid timezone. + ဤတန်ဖိုးသည် မှန်ကန်သော အချိန်ဇုန်မဟုတ်ပါ။ + + + This password has been leaked in a data breach, it must not be used. Please use another password. + ဤစကားဝှက် သည် ဒေတာပေါက်ကြားမှုတစ်ခုဖြစ်ခဲ့သည်။ ဤစကား၀ှက်ကိုအသုံးမပြုရပါ။ ကျေးဇူးပြု၍ အခြားစကားဝှက်ကိုသုံးပါ။ + + + This value should be between {{ min }} and {{ max }}. + ဤတန်ဖိုးသည် {{ min }} နှင့် {{ max }} ကြားရှိသင့်သည်။ + + + This value is not a valid hostname. + ဤတန်ဖိုးသည် သင့်လျှော်သော် hostname မဟုတ်ပါ။ + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + ဤ collection တွင်ပါပါ၀င်သော elements အရေအတွက်သည် {{ compared_value }} ၏ စတူဖြစ်သင့်သည်။ + + + This value should satisfy at least one of the following constraints: + ဤတန်ဖိုးသည် အောက်ပါကန့်သတ်ချက်များအနက်မှအနည်းဆုံးတစ်ခု ဖြည့်ဆည်းပေးသင့်သည်။ + + + Each element of this collection should satisfy its own set of constraints. + ဤ collection ၏ element တစ်ခုစီသည်၎င်း၏ကိုယ်ပိုင်ကန့်သတ်ချက်များကိုဖြည့်ဆည်းသင့်သည်။ + + + This value is not a valid International Securities Identification Number (ISIN). + ဤတန်ဖိုးသည် သင့်လျှော်သော် အပြည်ပြည်ဆိုင်ရာငွေချေးသက်သေခံနံပါတ် ,International Securities Identification Number (ISIN) မဟုတ်ပါ။ + + + This value should be a valid expression. + ဤတန်ဖိုးသည်မှန်ကန်သောစကားရပ်ဖြစ်သင့်သည်။ + + + This value is not a valid CSS color. + ဤတန်ဖိုးသည် CSS အရောင်မှန်ကန်မှုမရှိပါ။ + + + This value is not a valid CIDR notation. + ဤတန်ဖိုးသည် CIDR မှတ်စုံမှန်ကန်မှုမရှိပါ။ + + + The value of the netmask should be between {{ min }} and {{ max }}. + ကွန်ယက်မျက်နှာဖုံး၏ တန်ဖိုးသည် {{ min }} နှင့် {{ max }} ကြားရှိရမည်။ + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + ဖိုင်နာမည်သည် အရှည်လွန်းသည်။ သင်္ကေတ {{ filename_max_length }} သို့မဟုတ် နည်းသည့်အရေအတွက်ရှိရမည်။|ဖိုင်နာမည်သည် အရှည်လွန်းသည်။ သင်္ကေတ {{ filename_max_length }} သို့မဟုတ် နည်းသည့်အရေအတွက်ရှိရမည်။ + + + The password strength is too low. Please use a stronger password. + စကားဝှက်ခိုင်မာမှုနည်းပါးသည်။ ပိုခိုင်မာသော စကားဝှက်ကို သုံးပါ။ + + + This value contains characters that are not allowed by the current restriction-level. + ဤတန်ဖိုးတွင် လက်ရှိကန့်သတ်မှုအဆင့်မှ ခွင့်မပြုထားသော ဇာတ်ကောင်များပါဝင်သည်။ + + + Using invisible characters is not allowed. + မမြင်ရသော ဇာတ်ကောင်များကို သုံးခြင်းကို ခွင့်မပြုပါ။ + + + Mixing numbers from different scripts is not allowed. + မတူညီသော ဇာတ်ကောင်များမှ နံပါတ်များကို ရောနှောစပ်ခြင်းကို ခွင့်မပြုပါ။ + + + Using hidden overlay characters is not allowed. + ပုန်းထားသော အထပ်ကောင်းဇာတ်ကောင်များကို သုံးခြင်းကို ခွင့်မပြုပါ။ + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + ဖိုင်တွင်းတိုးခြင်းသည် မမှန်ကန်ပါ ({{ extension }})။ ခွင့်ပြုထားသော တိုးခြင်းများမှာ {{ extensions }} ဖြစ်သည်။ + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + တွေ့ရှိထားသော စာလုံးကုဒ်စံနစ်သည် မမှန်ကန်ပါ ({{ detected }})။ ခွင့်ပြုထားသော ကုဒ်စံနစ်များမှာ {{ encodings }} ဖြစ်သည်။ + + + This value is not a valid MAC address. + ဤတန်ဖိုးသည် မှန်ကန်သော MAC လိပ်စာ မဟုတ်ပါ။ + + + This URL is missing a top-level domain. + ဤ URL တွင် အမြင့်ဆုံးအဆင့်ဒိုမိန်း ပါဝင်မရှိပါ။ + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + ဤတန်ဖိုးသည် အလွန်တိုတောင်းသည်။ အနည်းဆုံး စကားလုံးတစ်လုံး ပါဝင်သင့်သည်။|ဤတန်ဖိုးသည် အလွန်တိုတောင်းသည်။ အနည်းဆုံး စကားလုံး {{ min }} လုံး ပါဝင်သင့်သည်။ + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + ဤတန်ဖိုးသည် အလွန်ရှည်လျားသည်။ စကားလုံးတစ်လုံးသာ ပါဝင်သင့်သည်။|ဤတန်ဖိုးသည် အလွန်ရှည်လျားသည်။ စကားလုံး {{ max }} လုံး သို့မဟုတ် ထိုထက်နည်းသည် ပါဝင်သင့်သည်။ + + + This value does not represent a valid week in the ISO 8601 format. + ဤတန်ဖိုးသည် ISO 8601 ပုံစံအတိုင်း မသက်ဆိုင်သော သီတင်းပတ်ကို ကိုယ်စားမပြုပါ။ + + + This value is not a valid week. + ဤတန်ဖိုးသည်မှန်ကန်သည့်အပတ်မဟုတ်ပါ။ + + + This value should not be before week "{{ min }}". + ဤတန်ဖိုးသည် သီတင်းပတ် "{{ min }}" မတိုင်မီ ဖြစ်သင့်သည်မဟုတ်ပါ။ + + + This value should not be after week "{{ max }}". + ဤတန်ဖိုးသည် သီတင်းပတ် "{{ max }}" ပြီးနောက် ဖြစ်သင့်သည်မဟုတ်ပါ။ + + + This value is not a valid Twig template. + ဤတန်ဖိုးသည် မှန်ကန်သော Twig တင်းပလိတ်မဟုတ်ပါ။ + + + This file is not a valid video. + ဤဖိုင်သည် မှန်ကန်သော ဗီဒီယို မဟုတ်ပါ။ + + + The size of the video could not be detected. + ဗီဒီယို၏ အရွယ်အစားကို စိစစ်မရနိုင်ခဲ့ပါ။ + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + ဗီဒီယိုအကျယ် {{ width }}px သည် အလွန်ကြီးနေသည်။ ခွင့်ပြုထားသော အများဆုံးအကျယ်မှာ {{ max_width }}px ဖြစ်သည်။ + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + ဗီဒီယိုအကျယ်အဝန်းမှာ သေးလွန်းနေပါတယ် ({{ width }}px)။ ခန့်မှန်းထားသော အနည်းဆုံး အကျယ်မှာ {{ min_width }}px ဖြစ်ပါတယ်။ + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + ဗီဒီယိုအမြင့် ကြီးလွန်းသည် ({{ height }}px)။ ခွင့်ပြုထားသော အမြင့်အများဆုံးမှာ {{ max_height }}px ဖြစ်သည်။ + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + ဗွီဒီယိုအမြင့် သက်သက်ငယ်နေပါသည် ({{ height }}px)။ မျှော်မှန်းထားသော အနည်းဆုံးအမြင့်မှာ {{ min_height }}px ဖြစ်သည်။ + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + ဗီဒီယိုတွင် ပစ်ဆယ် အရေအတွက် နည်းလွန်းသည် ({{ pixels }})။ မျှော်လင့်ထားသည့် အနည်းဆုံး အရေအတွက်မှာ {{ min_pixels }} ဖြစ်သည်။ + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + ဗီဒီယိုတွင် pixel များ အလွန်များနေသည် ({{ pixels }})။ မျှော်မှန်းထားသော အများဆုံးပမာဏမှာ {{ max_pixels }} ဖြစ်သည်။ + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + ဗီဒီယို အချိုးအစား များလွန်းသည် ({{ ratio }})။ ခွင့်ပြုထားသော အများဆုံး အချိုးအစားမှာ {{ max_ratio }} ဖြစ်သည်။ + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + ဗီဒီယိုအချိုးအစား သောလွန်းငယ်သည် ({{ ratio }})။ ခန့်မှန်းထားသော အနည်းဆုံး အချိုးအစားမှာ {{ min_ratio }} ဖြစ်သည်။ + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + ဗီဒီယိုသည် စတုဂံဖြစ်သည် ({{ width }}x{{ height }}px)။ စတုဂံ ဗီဒီယိုများကို ခွင့်မပြုပါ။ + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + ဗီဒီယိုသည် အလျားလိုက် ({{ width }}x{{ height }} px) ဖြစ်သည်။ အလျားလိုက်ဗီဒီယိုများကို ခွင့်မပြုပါ။ + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + ဗီဒီယိုသည် ဒေါင်လိုက် ရှုထောင့်ဖြစ်သည် ({{ width }}x{{ height }}px)။ ဒေါင်လိုက် ဗီဒီယိုများကို ခွင့်မပြုပါ။ + + + The video file is corrupted. + ဗီဒီယိုဖိုင် ပျက်စီးထားသည်။ + + + The video contains multiple streams. Only one stream is allowed. + ဗီဒီယိုတွင် စီးဆင်းမှုများ များစွာ ပါရှိသည်။ စီးဆင်းမှုတစ်ခုသာ ခွင့်ပြုထားသည်။ + + + Unsupported video codec "{{ codec }}". + ပံ့ပိုးမထားသော ဗီဒီယိုကုဒက် "{{ codec }}" ။ + + + Unsupported video container "{{ container }}". + မပံ့ပိုးထားသော ဗီဒီယို ကွန်တိနာ "{{ container }}". + + + The image file is corrupted. + ပုံဖိုင် ပျက်စီးနေသည်။ + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + ပုံတွင် ပစ်ဆယ်များအလွန်နည်းပါးသည် ({{ pixels }})။ မျှော်မှန်းထားသော အနည်းဆုံး အရေအတွက်မှာ {{ min_pixels }} ဖြစ်သည်။ + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + ပုံတွင် ပစ်ကဆယ်များ အလွန်များနေသည် ({{ pixels }}). လျှောက်ထားထားသော အများဆုံး ပမာဏမှာ {{ max_pixels }} ဖြစ်သည်. + + + This filename does not match the expected charset. + ဤဖိုင်နာမည်သည် မျှော်မှန်းထားသော အက္ခရာစုနှင့် ကိုက်ညီမှုမရှိပါ။ + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.nb.xlf b/lib/symfony/validator/Resources/translations/validators.nb.xlf new file mode 100644 index 0000000000..11ce9777bb --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.nb.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Verdien må være usann. + + + This value should be true. + Verdien må være sann. + + + This value should be of type {{ type }}. + Verdien skal ha typen {{ type }}. + + + This value should be blank. + Verdien skal være blank. + + + The value you selected is not a valid choice. + Den valgte verdien er ikke gyldig. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Du må velge minst {{ limit }} valg. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Du kan maks velge {{ limit }} valg. + + + One or more of the given values is invalid. + En eller flere av de oppgitte verdiene er ugyldige. + + + This field was not expected. + Dette feltet var ikke forventet. + + + This field is missing. + Dette feltet mangler. + + + This value is not a valid date. + Verdien er ikke en gyldig dato. + + + This value is not a valid datetime. + Verdien er ikke en gyldig dato/tid. + + + This value is not a valid email address. + Verdien er ikke en gyldig e-postadresse. + + + The file could not be found. + Filen kunne ikke finnes. + + + The file is not readable. + Filen er ikke lesbar. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Filen er for stor ({{ size }} {{ suffix }}). Tilatte maksimale størrelse {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mimetypen av filen er ugyldig ({{ type }}). Tilatte mimetyper er {{ types }}. + + + This value should be {{ limit }} or less. + Verdien må være {{ limit }} tegn lang eller mindre. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Verdien er for lang. Den må ha {{ limit }} tegn eller mindre. + + + This value should be {{ limit }} or more. + Verdien må være {{ limit }} eller mer. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Verdien er for kort. Den må ha {{ limit }} tegn eller flere. + + + This value should not be blank. + Verdien kan ikke være blank. + + + This value should not be null. + Verdien kan ikke være tom (null). + + + This value should be null. + Verdien skal være tom (null). + + + This value is not valid. + Verdien er ugyldig. + + + This value is not a valid time. + Verdien er ikke en gyldig tid. + + + This value is not a valid URL. + Verdien er ikke en gyldig URL. + + + The two values should be equal. + Verdiene skal være identiske. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Filen er for stor. Den maksimale størrelsen er {{ limit }} {{ suffix }}. + + + The file is too large. + Filen er for stor. + + + The file could not be uploaded. + Filen kunne ikke lastes opp. + + + This value should be a valid number. + Verdien skal være et gyldig tall. + + + This file is not a valid image. + Denne filen er ikke et gyldig bilde. + + + This value is not a valid IP address. + Denne verdien er ikke en gyldig IP-adresse. + + + This value is not a valid language. + Verdien er ikke et gyldig språk. + + + This value is not a valid locale. + Verdien er ikke en gyldig lokalitet. + + + This value is not a valid country. + Verdien er ikke et gyldig navn på land. + + + This value is already used. + Verdien er allerede brukt. + + + The size of the image could not be detected. + Bildestørrelsen kunne ikke oppdages. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Bildebredden er for stor ({{ width }} piksler). Tillatt maksimumsbredde er {{ max_width }} piksler. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Bildebredden er for liten ({{ width }} piksler). Forventet minimumsbredde er {{ min_width }} piksler. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Bildehøyden er for stor ({{ height }} piksler). Tillatt maksimumshøyde er {{ max_height }} piksler. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Bildehøyden er for liten ({{ height }} piksler). Forventet minimumshøyde er {{ min_height }} piksler. + + + This value should be the user's current password. + Verdien skal være brukerens sitt nåværende passord. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Verdien skal være nøyaktig {{ limit }} tegn. + + + The file was only partially uploaded. + Filen var kun delvis opplastet. + + + No file was uploaded. + Ingen fil var lastet opp. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Ingen midlertidig mappe ble konfigurert i php.ini, eller den konfigurerte mappen eksisterer ikke. + + + Cannot write temporary file to disk. + Kan ikke skrive midlertidig fil til disk. + + + A PHP extension caused the upload to fail. + En PHP-utvidelse forårsaket en feil under opplasting. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Denne samlingen må inneholde {{ limit }} element eller flere.|Denne samlingen må inneholde {{ limit }} elementer eller flere. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Denne samlingen må inneholde {{ limit }} element eller færre.|Denne samlingen må inneholde {{ limit }} elementer eller færre. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Denne samlingen må inneholde nøyaktig {{ limit }} element.|Denne samlingen må inneholde nøyaktig {{ limit }} elementer. + + + Invalid card number. + Ugyldig kortnummer. + + + Unsupported card type or invalid card number. + Korttypen er ikke støttet eller kortnummeret er ugyldig. + + + This value is not a valid International Bank Account Number (IBAN). + Denne verdien er ikke et gyldig internasjonalt bankkontonummer (IBAN). + + + This value is not a valid ISBN-10. + Verdien er ikke en gyldig ISBN-10. + + + This value is not a valid ISBN-13. + Verdien er ikke en gyldig ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Verdien er hverken en gyldig ISBN-10 eller ISBN-13. + + + This value is not a valid ISSN. + Verdien er ikke en gyldig ISSN. + + + This value is not a valid currency. + Verdien er ikke gyldig valuta. + + + This value should be equal to {{ compared_value }}. + Verdien skal være lik {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Verdien skal være større enn {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Verdien skal være større enn eller lik {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Verdien skal være identisk med {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Verdien skal være mindre enn {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Verdien skal være mindre enn eller lik {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Verdien skal ikke være lik {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Verdien skal ikke være identisk med {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Bildeforholdet er for stort ({{ ratio }}). Tillatt bildeforhold er maks {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Bildeforholdet er for lite ({{ ratio }}). Forventet bildeforhold er minst {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Bildet er en kvadrat ({{ width }}x{{ height }}px). Kvadratiske bilder er ikke tillatt. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Bildet er i liggende retning ({{ width }}x{{ height }}px). Bilder i liggende retning er ikke tillatt. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Bildet er i stående retning ({{ width }}x{{ height }}px). Bilder i stående retning er ikke tillatt. + + + An empty file is not allowed. + Tomme filer er ikke tilatt. + + + The host could not be resolved. + Vertsnavn kunne ikke løses. + + + This value does not match the expected {{ charset }} charset. + Verdien samsvarer ikke med forventet tegnsett {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Denne verdien er ikke en gyldig forretningsidentifikasjonskode (BIC). + + + Error + Feil + + + This value is not a valid UUID. + Denne verdien er ikke en gyldig UUID. + + + This value should be a multiple of {{ compared_value }}. + Verdien skal være flertall av {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Business Identifier Code (BIC) er ikke tilknyttet en IBAN {{ iban }}. + + + This value should be valid JSON. + Verdien er ikke gyldig JSON. + + + This collection should contain only unique elements. + Samlingen kan kun inneholde unike elementer. + + + This value should be positive. + Denne verdien må være positiv. + + + This value should be either positive or zero. + Denne verdien må være positiv eller null. + + + This value should be negative. + Denne verdien må være negativ. + + + This value should be either negative or zero. + Denne verdien må være negativ eller null. + + + This value is not a valid timezone. + Verdien er ikke en gyldig tidssone. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Dette passordet er lekket i et datainnbrudd, det må ikke tas i bruk. Vennligst bruk et annet passord. + + + This value should be between {{ min }} and {{ max }}. + Verdien må være mellom {{ min }} og {{ max }}. + + + This value is not a valid hostname. + Denne verdien er ikke et gyldig vertsnavn. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Antall elementer i denne samlingen bør være et multiplum av {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Denne verdien skal tilfredsstille minst en av følgende begrensninger: + + + Each element of this collection should satisfy its own set of constraints. + Hvert element i denne samlingen skal tilfredsstille sitt eget sett med begrensninger. + + + This value is not a valid International Securities Identification Number (ISIN). + Denne verdien er ikke et gyldig International Securities Identification Number (ISIN). + + + This value should be a valid expression. + Denne verdien skal være et gyldig uttrykk. + + + This value is not a valid CSS color. + Denne verdien er ikke en gyldig CSS-farge. + + + This value is not a valid CIDR notation. + Denne verdien er ikke en gyldig CIDR-notasjon. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Verdien på nettmasken skal være mellom {{ min }} og {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Filnavnet er for langt. Det bør ha {{ filename_max_length }} tegn eller mindre.|Filnavnet er for langt. Det bør ha {{ filename_max_length }} tegn eller mindre. + + + The password strength is too low. Please use a stronger password. + Passordstyrken er for lav. Vennligst bruk et sterkere passord. + + + This value contains characters that are not allowed by the current restriction-level. + Denne verdien inneholder tegn som ikke er tillatt av gjeldende restriksjonsnivå. + + + Using invisible characters is not allowed. + Det er ikke tillatt å bruke usynlige tegn. + + + Mixing numbers from different scripts is not allowed. + Det er ikke tillatt å blande tall fra forskjellige skript. + + + Using hidden overlay characters is not allowed. + Det er ikke tillatt å bruke skjulte overleggskarakterer. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Filutvidelsen er ugyldig ({{ extension }}). Tillatte utvidelser er {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Den oppdagede tegnkodingen er ugyldig ({{ detected }}). Tillatte kodinger er {{ encodings }}. + + + This value is not a valid MAC address. + Denne verdien er ikke en gyldig MAC-adresse. + + + This URL is missing a top-level domain. + Denne URL-en mangler et toppnivådomene. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Denne verdien er for kort. Den bør inneholde minst ett ord.|Denne verdien er for kort. Den bør inneholde minst {{ min }} ord. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Denne verdien er for lang. Den bør inneholde kun ett ord.|Denne verdien er for lang. Den bør inneholde {{ max }} ord eller færre. + + + This value does not represent a valid week in the ISO 8601 format. + Denne verdien representerer ikke en gyldig uke i ISO 8601-formatet. + + + This value is not a valid week. + Denne verdien er ikke en gyldig uke. + + + This value should not be before week "{{ min }}". + Denne verdien bør ikke være før uke "{{ min }}". + + + This value should not be after week "{{ max }}". + Denne verdien bør ikke være etter uke "{{ max }}". + + + This value is not a valid Twig template. + Denne verdien er ikke en gyldig Twig-mal. + + + This file is not a valid video. + Denne filen er ikke en gyldig video. + + + The size of the video could not be detected. + Videostørrelsen kunne ikke oppdages. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Videobredden er for stor ({{ width }}px). Tillatt maksimal bredde er {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Videobredden er for liten ({{ width }}px). Forventet minimumsbredde er {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Videohøyden er for stor ({{ height }}px). Tillatt maksimal høyde er {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Videoens høyde er for liten ({{ height }}px). Forventet minstehøyde er {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Videoen har for få piksler ({{ pixels }}). Forventet minimum er {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Videoen har for mange piksler ({{ pixels }}). Forventet maksimalt antall er {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Video-forholdet er for stort ({{ ratio }}). Tillatt maksimalt forhold er {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Videoforholdet er for lite ({{ ratio }}). Forventet minimumsforhold er {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Videoen er kvadratisk ({{ width }}x{{ height }}px). Kvadratiske videoer er ikke tillatt. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Videoen er i liggende format ({{ width }}x{{ height }} px). Liggende videoer er ikke tillatt. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Videoen er i portrettformat ({{ width }}x{{ height }}px). Portrettvideoer er ikke tillatt. + + + The video file is corrupted. + Videofilen er ødelagt. + + + The video contains multiple streams. Only one stream is allowed. + Videoen inneholder flere strømmer. Kun én strøm er tillatt. + + + Unsupported video codec "{{ codec }}". + Ikke støttet videokodek «{{ codec }}». + + + Unsupported video container "{{ container }}". + Ikke-støttet videokontainer "{{ container }}". + + + The image file is corrupted. + Bildefilen er ødelagt. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Bildet har for få piksler ({{ pixels }}). Forventet minimum er {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Bildet har for mange piksler ({{ pixels }}). Forventet maksimalt antall er {{ max_pixels }}. + + + This filename does not match the expected charset. + Dette filnavnet samsvarer ikke med forventet tegnsett. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.nl.xlf b/lib/symfony/validator/Resources/translations/validators.nl.xlf new file mode 100644 index 0000000000..74bea6f48c --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.nl.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Deze waarde moet onwaar zijn. + + + This value should be true. + Deze waarde moet waar zijn. + + + This value should be of type {{ type }}. + Deze waarde moet van het type {{ type }} zijn. + + + This value should be blank. + Deze waarde moet leeg zijn. + + + The value you selected is not a valid choice. + De geselecteerde waarde is geen geldige optie. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Selecteer ten minste {{ limit }} optie.|Selecteer ten minste {{ limit }} opties. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Selecteer maximaal {{ limit }} optie.|Selecteer maximaal {{ limit }} opties. + + + One or more of the given values is invalid. + Eén of meer van de ingegeven waarden zijn ongeldig. + + + This field was not expected. + Dit veld werd niet verwacht. + + + This field is missing. + Dit veld ontbreekt. + + + This value is not a valid date. + Deze waarde is geen geldige datum. + + + This value is not a valid datetime. + Deze waarde is geen geldige datum en tijd. + + + This value is not a valid email address. + Deze waarde is geen geldig e-mailadres. + + + The file could not be found. + Het bestand kon niet gevonden worden. + + + The file is not readable. + Het bestand is niet leesbaar. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Het bestand is te groot ({{ size }} {{ suffix }}). De maximale grootte is {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Het mediatype van het bestand is ongeldig ({{ type }}). De toegestane mediatypes zijn {{ types }}. + + + This value should be {{ limit }} or less. + Deze waarde moet {{ limit }} of minder zijn. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Deze waarde is te lang. Deze mag maximaal één teken bevatten.|Deze waarde is te lang. Deze mag maximaal {{ limit }} tekens bevatten. + + + This value should be {{ limit }} or more. + Deze waarde moet {{ limit }} of meer zijn. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Deze waarde is te kort. Deze moet ten minste één teken bevatten.|Deze waarde is te kort. Deze moet ten minste {{ limit }} tekens bevatten. + + + This value should not be blank. + Deze waarde mag niet leeg zijn. + + + This value should not be null. + Deze waarde mag niet null zijn. + + + This value should be null. + Deze waarde moet null zijn. + + + This value is not valid. + Deze waarde is niet geldig. + + + This value is not a valid time. + Deze waarde is geen geldige tijd. + + + This value is not a valid URL. + Deze waarde is geen geldige URL. + + + The two values should be equal. + De twee waarden moeten gelijk zijn. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Het bestand is te groot. De maximale grootte is {{ limit }} {{ suffix }}. + + + The file is too large. + Het bestand is te groot. + + + The file could not be uploaded. + Het bestand kon niet worden geüpload. + + + This value should be a valid number. + Deze waarde moet een geldig getal zijn. + + + This file is not a valid image. + Dit bestand is geen geldige afbeelding. + + + This value is not a valid IP address. + Deze waarde is geen geldig IP-adres. + + + This value is not a valid language. + Deze waarde is geen geldige taal. + + + This value is not a valid locale. + Deze waarde is geen geldige landinstelling. + + + This value is not a valid country. + Deze waarde is geen geldig land. + + + This value is already used. + Deze waarde wordt al gebruikt. + + + The size of the image could not be detected. + De grootte van de afbeelding kon niet bepaald worden. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + De afbeelding is te breed ({{ width }}px). De maximale breedte is {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + De afbeelding is niet breed genoeg ({{ width }}px). De minimaal verwachte breedte is {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + De afbeelding is te hoog ({{ height }}px). De maximale hoogte is {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + De afbeelding is niet hoog genoeg ({{ height }}px). De minimaal verwachte hoogte is {{ min_height }}px. + + + This value should be the user's current password. + Deze waarde moet het huidige wachtwoord van de gebruiker zijn. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Deze waarde moet exact één teken lang zijn.|Deze waarde moet exact {{ limit }} tekens lang zijn. + + + The file was only partially uploaded. + Het bestand is slechts gedeeltelijk geüpload. + + + No file was uploaded. + Er is geen bestand geüpload. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Er is geen tijdelijke map geconfigureerd in php.ini, of de gespecificeerde map bestaat niet. + + + Cannot write temporary file to disk. + Kan het tijdelijke bestand niet wegschrijven op de schijf. + + + A PHP extension caused the upload to fail. + De upload is mislukt vanwege een PHP-extensie. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Deze collectie moet één of meer elementen bevatten.|Deze collectie moet {{ limit }} of meer elementen bevatten. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Deze collectie moet één of minder elementen bevatten.|Deze collectie moet {{ limit }} of minder elementen bevatten. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Deze collectie moet exact één element bevatten.|Deze collectie moet exact {{ limit }} elementen bevatten. + + + Invalid card number. + Ongeldig creditcardnummer. + + + Unsupported card type or invalid card number. + Niet-ondersteund type creditcard of ongeldig nummer. + + + This value is not a valid International Bank Account Number (IBAN). + Deze waarde is geen geldig internationaal bankrekeningnummer (IBAN). + + + This value is not a valid ISBN-10. + Deze waarde is geen geldige ISBN-10. + + + This value is not a valid ISBN-13. + Deze waarde is geen geldige ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Deze waarde is geen geldige ISBN-10 of ISBN-13. + + + This value is not a valid ISSN. + Deze waarde is geen geldige ISSN. + + + This value is not a valid currency. + Deze waarde is geen geldige valuta. + + + This value should be equal to {{ compared_value }}. + Deze waarde moet gelijk zijn aan {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Deze waarde moet groter zijn dan {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Deze waarde moet groter of gelijk aan {{ compared_value }} zijn. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Deze waarde moet identiek zijn aan {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Deze waarde moet minder zijn dan {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Deze waarde moet minder dan of gelijk aan {{ compared_value }} zijn. + + + This value should not be equal to {{ compared_value }}. + Deze waarde mag niet gelijk zijn aan {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Deze waarde mag niet identiek zijn aan {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + De afbeeldingsverhouding is te groot ({{ ratio }}). De maximale verhouding is {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + De afbeeldingsverhouding is te klein ({{ ratio }}). De minimale verhouding is {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + De afbeelding is vierkant ({{ width }}x{{ height }}px). Vierkante afbeeldingen zijn niet toegestaan. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + De afbeelding is liggend ({{ width }}x{{ height }}px). Liggende afbeeldingen zijn niet toegestaan. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + De afbeelding is staand ({{ width }}x{{ height }}px). Staande afbeeldingen zijn niet toegestaan. + + + An empty file is not allowed. + Lege bestanden zijn niet toegestaan. + + + The host could not be resolved. + De hostnaam kon niet worden gevonden. + + + This value does not match the expected {{ charset }} charset. + Deze waarde is niet in de verwachte tekencodering {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Deze waarde is geen geldige bankidentificatiecode (BIC). + + + Error + Fout + + + This value is not a valid UUID. + Deze waarde is geen geldige UUID. + + + This value should be a multiple of {{ compared_value }}. + Deze waarde moet een meervoud van {{ compared_value }} zijn. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Deze bankidentificatiecode (BIC) is niet gekoppeld aan IBAN {{ iban }}. + + + This value should be valid JSON. + Deze waarde moet geldige JSON zijn. + + + This collection should contain only unique elements. + Deze collectie mag alleen unieke elementen bevatten. + + + This value should be positive. + Deze waarde moet positief zijn. + + + This value should be either positive or zero. + Deze waarde moet positief of gelijk aan nul zijn. + + + This value should be negative. + Deze waarde moet negatief zijn. + + + This value should be either negative or zero. + Deze waarde moet negatief of gelijk aan nul zijn. + + + This value is not a valid timezone. + Deze waarde is geen geldige tijdzone. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Dit wachtwoord is gelekt bij een datalek en mag niet worden gebruikt. Kies een ander wachtwoord. + + + This value should be between {{ min }} and {{ max }}. + Deze waarde moet zich tussen {{ min }} en {{ max }} bevinden. + + + This value is not a valid hostname. + Deze waarde is geen geldige hostnaam. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Het aantal elementen van deze collectie moet een veelvoud zijn van {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Deze waarde moet voldoen aan tenminste een van de volgende voorwaarden: + + + Each element of this collection should satisfy its own set of constraints. + Elk element van deze collectie moet voldoen aan zijn eigen set voorwaarden. + + + This value is not a valid International Securities Identification Number (ISIN). + Deze waarde is geen geldig International Securities Identification Number (ISIN). + + + This value should be a valid expression. + Deze waarde moet een geldige expressie zijn. + + + This value is not a valid CSS color. + Deze waarde is geen geldige CSS kleur. + + + This value is not a valid CIDR notation. + Deze waarde is geen geldige CIDR-notatie. + + + The value of the netmask should be between {{ min }} and {{ max }}. + De waarde van het netmasker moet tussen {{ min }} en {{ max }} liggen. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + De bestandsnaam is te lang. Het moet {{ filename_max_length }} of minder karakters zijn.|De bestandsnaam is te lang. Het moet {{ filename_max_length }} of minder karakters zijn. + + + The password strength is too low. Please use a stronger password. + Het wachtwoord is niet sterk genoeg. Probeer een sterker wachtwoord. + + + This value contains characters that are not allowed by the current restriction-level. + Deze waarde bevat tekens die niet zijn toegestaan volgens het huidige beperkingsniveau. + + + Using invisible characters is not allowed. + Het gebruik van onzichtbare tekens is niet toegestaan. + + + Mixing numbers from different scripts is not allowed. + Het mengen van cijfers uit verschillende schriften is niet toegestaan. + + + Using hidden overlay characters is not allowed. + Het gebruik van verborgen overlay-tekens is niet toegestaan. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + De bestandsextensie is ongeldig ({{ extension }}). De toegestane extensies zijn {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + De gedetecteerde karaktercodering is ongeldig ({{ detected }}). De toegestane coderingen zijn {{ encodings }}. + + + This value is not a valid MAC address. + Deze waarde is geen geldig MAC-adres. + + + This URL is missing a top-level domain. + Deze URL mist een top-level domein. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Deze waarde is te kort. Het moet ten minste één woord bevatten.|Deze waarde is te kort. Het moet ten minste {{ min }} woorden bevatten. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Deze waarde is te lang. Het moet één woord zijn.|Deze waarde is te lang. Het mag maximaal {{ max }} woorden bevatten. + + + This value does not represent a valid week in the ISO 8601 format. + Deze waarde vertegenwoordigt geen geldige week in het ISO 8601-formaat. + + + This value is not a valid week. + Deze waarde is geen geldige week. + + + This value should not be before week "{{ min }}". + Deze waarde mag niet vóór week "{{ min }}" liggen. + + + This value should not be after week "{{ max }}". + Deze waarde mag niet na week "{{ max }}" liggen. + + + This value is not a valid Twig template. + Deze waarde is geen geldige Twig-template. + + + This file is not a valid video. + Dit bestand is geen geldige video. + + + The size of the video could not be detected. + De grootte van de video kon niet worden gedetecteerd. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + De videobreedte is te groot ({{ width }}px). Toegestane maximale breedte is {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + De videobreedte is te klein ({{ width }}px). Verwachte minimum breedte is {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + De videohoogte is te groot ({{ height }}px). Toegestane maximale hoogte is {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + De videohoogte is te klein ({{ height }}px). Verwachte minimale hoogte is {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + De video heeft te weinig pixels ({{ pixels }}). Verwachte minimumaantal is {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + De video heeft te veel pixels ({{ pixels }}). Het verwachte maximum is {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + De videoratio is te groot ({{ ratio }}). Toegestane maximale ratio is {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + De videoratio is te klein ({{ ratio }}). Verwachte minimumverhouding is {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + De video is vierkant ({{ width }}x{{ height }}px). Vierkante video's zijn niet toegestaan. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + De video is in liggende oriëntatie ({{ width }}x{{ height }} px). Liggende video's zijn niet toegestaan. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + De video is in portretstand ({{ width }}x{{ height }}px). Video's in portretstand zijn niet toegestaan. + + + The video file is corrupted. + Het videobestand is beschadigd. + + + The video contains multiple streams. Only one stream is allowed. + De video bevat meerdere streams. Slechts één stream is toegestaan. + + + Unsupported video codec "{{ codec }}". + Niet-ondersteunde videocodec ‘{{ codec }}’. + + + Unsupported video container "{{ container }}". + Niet-ondersteunde videocontainer "{{ container }}". + + + The image file is corrupted. + Het afbeeldingsbestand is beschadigd. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + De afbeelding heeft te weinig pixels ({{ pixels }}). Verwachte minimumhoeveelheid is {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + De afbeelding heeft te veel pixels ({{ pixels }}). Het verwachte maximum is {{ max_pixels }}. + + + This filename does not match the expected charset. + Deze bestandsnaam komt niet overeen met de verwachte tekencodering. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.nn.xlf b/lib/symfony/validator/Resources/translations/validators.nn.xlf new file mode 100644 index 0000000000..16dbe27272 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.nn.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Verdien skulle ha vore tom/nei. + + + This value should be true. + Verdien skulla ha vore satt/ja. + + + This value should be of type {{ type }}. + Verdien må vere av typen {{ type }}. + + + This value should be blank. + Verdien skal vere blank. + + + The value you selected is not a valid choice. + Verdien du valde er ikkje gyldig. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Du må gjere minst {{ limit }} val. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Du kan maksimalt gjere {{ limit }} val. + + + One or more of the given values is invalid. + Ein eller fleire av dei opplyste verdiane er ugyldige. + + + This field was not expected. + Dette feltet var ikkje forventa. + + + This field is missing. + Dette feltet mangler. + + + This value is not a valid date. + Verdien er ikkje ein gyldig dato. + + + This value is not a valid datetime. + Verdien er ikkje ein gyldig dato og tid. + + + This value is not a valid email address. + Verdien er ikkje ei gyldig e-postadresse. + + + The file could not be found. + Fila er ikkje funnen. + + + The file is not readable. + Fila kan ikkje lesast. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Fila er for stor ({{ size }} {{ suffix }}). Maksimal storleik er {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mime-typen av fila er ugyldig ({{ type }}). Tillatne mime-typar er {{ types }}. + + + This value should be {{ limit }} or less. + Verdien må vere {{ limit }} eller mindre. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Verdien er for lang. Den må vere {{ limit }} bokstavar eller mindre. + + + This value should be {{ limit }} or more. + Verdien må vere {{ limit }} eller meir. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Verdien er for kort. Den må ha {{ limit }} teikn eller fleire. + + + This value should not be blank. + Verdien kan ikkje vere blank. + + + This value should not be null. + Verdien kan ikkje vere tom (null). + + + This value should be null. + Verdien må vere tom (null). + + + This value is not valid. + Verdien er ikkje gyldig. + + + This value is not a valid time. + Verdien er ikkje ei gyldig tidseining. + + + This value is not a valid URL. + Verdien er ikkje ein gyldig URL. + + + The two values should be equal. + Dei to verdiane må vere like. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Fila er for stor. Den maksimale storleiken er {{ limit }} {{ suffix }}. + + + The file is too large. + Fila er for stor. + + + The file could not be uploaded. + Fila kunne ikkje bli lasta opp. + + + This value should be a valid number. + Verdien må vere eit gyldig tal. + + + This file is not a valid image. + Fila er ikkje eit gyldig bilete. + + + This value is not a valid IP address. + Denne verdien er ikkje ein gyldig IP-adresse. + + + This value is not a valid language. + Verdien er ikkje eit gyldig språk. + + + This value is not a valid locale. + Verdien er ikkje ein gyldig lokalitet (språk/region). + + + This value is not a valid country. + Verdien er ikkje eit gyldig land. + + + This value is already used. + Verdien er allereie i bruk. + + + The size of the image could not be detected. + Storleiken på biletet kunne ikkje oppdagast. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Biletbreidda er for stor, ({{ width }} pikslar). Tillaten maksimumsbreidde er {{ max_width }} pikslar. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Biletbreidda er for liten, ({{ width }} pikslar). Forventa minimumsbreidde er {{ min_width }} pikslar. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Bilethøgda er for stor, ({{ height }} pikslar). Tillaten maksimumshøgde er {{ max_height }} pikslar. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Billethøgda er for låg, ({{ height }} pikslar). Forventa minimumshøgde er {{ min_height }} pikslar. + + + This value should be the user's current password. + Verdien må vere brukaren sitt noverande passord. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Verdien må vere nøyaktig {{ limit }} teikn. + + + The file was only partially uploaded. + Fila vart berre delvis lasta opp. + + + No file was uploaded. + Inga fil vart lasta opp. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Ingen midlertidig mappe var konfigurert i php.ini, eller den konfigurerte mappa eksisterer ikkje. + + + Cannot write temporary file to disk. + Kan ikkje skrive førebels fil til disk. + + + A PHP extension caused the upload to fail. + Ei PHP-udviding forårsaka feil under opplasting. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Denne samlinga må innehalde {{ limit }} element eller meir.|Denne samlinga må innehalde {{ limit }} element eller meir. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Denne samlinga må innehalde {{ limit }} element eller færre.|Denne samlinga må innehalde {{ limit }} element eller færre. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Denne samlinga må innehalde nøyaktig {{ limit }} element.|Denne samlinga må innehalde nøyaktig {{ limit }} element. + + + Invalid card number. + Ugyldig kortnummer. + + + Unsupported card type or invalid card number. + Korttypen er ikkje støtta, eller kortnummeret er ugyldig. + + + This value is not a valid International Bank Account Number (IBAN). + Denne verdien er ikkje eit gyldig internasjonalt bankkontonummer (IBAN). + + + This value is not a valid ISBN-10. + Verdien er ikkje eit gyldig ISBN-10. + + + This value is not a valid ISBN-13. + Verdien er ikkje eit gyldig ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Verdien er verken eit gyldig ISBN-10 eller eit gyldig ISBN-13. + + + This value is not a valid ISSN. + Verdien er ikkje eit gyldig ISSN. + + + This value is not a valid currency. + Verdien er ikkje ein gyldig valuta. + + + This value should be equal to {{ compared_value }}. + Verdien bør vera eins med {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Verdien bør vera større enn {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Verdien bør vera større enn eller eins med {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Verdien bør vera eins med {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Verdien bør vera mindre enn {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Verdi bør vera mindre enn eller eins med {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Verdi bør ikkje vera eins med {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Denne verdien bør ikkje vera eins med {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Sideforholdet til biletet er for stort ({{ ratio }}). Sideforholdet kan ikkje vere større enn {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Sideforholdet til biletet er for lite ({{ ratio }}). Sideforholdet kan ikkje vere mindre enn {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Biletet er kvadratisk ({{ width }}x{{ height }}px). Kvadratiske bilete er ikkje tillatne. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Biletet er landskapsorientert ({{ width }}x{{ height }}px). Landskapsorienterte bilete er ikkje tillatne. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Biletet er portrettorientert ({{ width }}x{{ height }}px). Portrettorienterte bilete er ikkje tillatne. + + + An empty file is not allowed. + Ei tom fil er ikkje tillate. + + + The host could not be resolved. + Verten kunne ikkje finnast. + + + This value does not match the expected {{ charset }} charset. + Verdien stemmer ikkje med forventa {{ charset }} charset. + + + This value is not a valid Business Identifier Code (BIC). + Denne verdien er ikkje ein gyldig forretningsidentifikasjonskode (BIC). + + + Error + Feil + + + This value is not a valid UUID. + Denne verdien er ikkje ein gyldig UUID. + + + This value should be a multiple of {{ compared_value }}. + Verdien bør vera eit multipel av {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Denne Business Identifier Code (BIC) er ikkje kopla til IBAN {{ iban }}. + + + This value should be valid JSON. + Verdien bør vera gyldig JSON. + + + This collection should contain only unique elements. + Denne samlinga bør berre innehalda unike element. + + + This value should be positive. + Verdien bør vera positiv. + + + This value should be either positive or zero. + Verdien bør vera anten positiv eller null. + + + This value should be negative. + Verdien bør vera negativ. + + + This value should be either negative or zero. + Verdien bør vera negativ eller null. + + + This value is not a valid timezone. + Verdien er ikkje ei gyldig tidssone. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Dette passordet har lekt ut ved eit datainnbrot, det får ikkje nyttast. Gje opp eit anna passord. + + + This value should be between {{ min }} and {{ max }}. + Denne verdien bør liggje mellom {{ min }} og {{ max }}. + + + This value is not a valid hostname. + Verdien er ikkje eit gyldig vertsnamn. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Talet på element i denne samlinga bør vera eit multippel av {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Verdien burde oppfylla minst ein av følgjande avgrensingar: + + + Each element of this collection should satisfy its own set of constraints. + Kvart element i denne samlinga bør oppfylla sine eigne avgrensingar. + + + This value is not a valid International Securities Identification Number (ISIN). + Verdien er ikkje eit gyldig International Securities Identification Number (ISIN). + + + This value should be a valid expression. + Denne verdien skal være et gyldig uttrykk. + + + This value is not a valid CSS color. + Denne verdien er ikke en gyldig CSS-farge. + + + This value is not a valid CIDR notation. + Denne verdien er ikke en gyldig CIDR-notasjon. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Verdien av nettmasken skal være mellom {{ min }} og {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Filnamnet er for langt. Det bør ha {{ filename_max_length }} teikn eller færre.|Filnamnet er for langt. Det bør ha {{ filename_max_length }} teikn eller færre. + + + The password strength is too low. Please use a stronger password. + Passordstyrken er for låg. Vennligst bruk eit sterkare passord. + + + This value contains characters that are not allowed by the current restriction-level. + Denne verdien inneheld teikn som ikkje er tillatne av det gjeldande restriksjonsnivået. + + + Using invisible characters is not allowed. + Det er ikkje tillate å bruke usynlege teikn. + + + Mixing numbers from different scripts is not allowed. + Det er ikkje tillate å blande tal frå forskjellige skript. + + + Using hidden overlay characters is not allowed. + Det er ikkje tillate å bruke skjulte overleggsteikn. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Filutvidinga er ugyldig ({{ extension }}). Tillatne utvidingar er {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Den oppdaga teiknkodinga er ugyldig ({{ detected }}). Tillatne kodingar er {{ encodings }}. + + + This value is not a valid MAC address. + Denne verdien er ikkje ein gyldig MAC-adresse. + + + This URL is missing a top-level domain. + Denne URL-en manglar eit toppnivådomene. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Denne verdien er for kort. Han bør innehalde minst eitt ord.|Denne verdien er for kort. Han bør innehalde minst {{ min }} ord. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Denne verdien er for lang. Han bør innehalde berre eitt ord.|Denne verdien er for lang. Han bør innehalde {{ max }} ord eller færre. + + + This value does not represent a valid week in the ISO 8601 format. + Denne verdien representerer ikkje ein gyldig veke i ISO 8601-formatet. + + + This value is not a valid week. + Denne verdien er ikkje ei gyldig veke. + + + This value should not be before week "{{ min }}". + Denne verdien bør ikkje vere før veke "{{ min }}". + + + This value should not be after week "{{ max }}". + Denne verdien bør ikkje vere etter veke "{{ max }}". + + + This value is not a valid Twig template. + Denne verdien er ikkje ein gyldig Twig-mal. + + + This file is not a valid video. + Denne fila er ikkje ein gyldig video. + + + The size of the video could not be detected. + Storleiken på videoen kunne ikkje oppdagast. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Videobreidda er for stor ({{ width }}px). Tillaten maksimal breidde er {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Videobreidda er for lita ({{ width }}px). Forventa minimumsbreidde er {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Videoen si høgd er for stor ({{ height }}px). Tillaten maksimal høgd er {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Videohøgda er for lita ({{ height }}px). Forventa minstehøgd er {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Videoen har for få pikslar ({{ pixels }}). Forventa minimum er {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Videoen har for mange pikslar ({{ pixels }}). Forventa maksimalt tal er {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Videoforholdet er for stort ({{ ratio }}). Tillaten maksimal forhold er {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Videoforholdet er for lite ({{ ratio }}). Forventa minimumsforhold er {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Videoen er kvadratisk ({{ width }}x{{ height }}px). Kvadratiske videoar er ikkje tillatne. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Videoen er i liggjande format ({{ width }}x{{ height }} px). Liggjande videoar er ikkje tillatne. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Videoen er i portrettformat ({{ width }}x{{ height }}px). Portrettvideoar er ikkje tillatne. + + + The video file is corrupted. + Videofila er skadd. + + + The video contains multiple streams. Only one stream is allowed. + Videoen inneheld fleire straumar. Berre éin straum er tillaten. + + + Unsupported video codec "{{ codec }}". + Ikkje støtta videokodek «{{ codec }}». + + + Unsupported video container "{{ container }}". + Ikkje-støtta videokontainer "{{ container }}". + + + The image file is corrupted. + Bildefila er skadd. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Biletet har for få pikslar ({{ pixels }}). Forventa minimum er {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Biletet har for mange pikslar ({{ pixels }}). Forventa maksimalt tal er {{ max_pixels }}. + + + This filename does not match the expected charset. + Dette filnamnet samsvarar ikkje med forventa teiknsett. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.no.xlf b/lib/symfony/validator/Resources/translations/validators.no.xlf new file mode 100644 index 0000000000..11ce9777bb --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.no.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Verdien må være usann. + + + This value should be true. + Verdien må være sann. + + + This value should be of type {{ type }}. + Verdien skal ha typen {{ type }}. + + + This value should be blank. + Verdien skal være blank. + + + The value you selected is not a valid choice. + Den valgte verdien er ikke gyldig. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Du må velge minst {{ limit }} valg. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Du kan maks velge {{ limit }} valg. + + + One or more of the given values is invalid. + En eller flere av de oppgitte verdiene er ugyldige. + + + This field was not expected. + Dette feltet var ikke forventet. + + + This field is missing. + Dette feltet mangler. + + + This value is not a valid date. + Verdien er ikke en gyldig dato. + + + This value is not a valid datetime. + Verdien er ikke en gyldig dato/tid. + + + This value is not a valid email address. + Verdien er ikke en gyldig e-postadresse. + + + The file could not be found. + Filen kunne ikke finnes. + + + The file is not readable. + Filen er ikke lesbar. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Filen er for stor ({{ size }} {{ suffix }}). Tilatte maksimale størrelse {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mimetypen av filen er ugyldig ({{ type }}). Tilatte mimetyper er {{ types }}. + + + This value should be {{ limit }} or less. + Verdien må være {{ limit }} tegn lang eller mindre. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Verdien er for lang. Den må ha {{ limit }} tegn eller mindre. + + + This value should be {{ limit }} or more. + Verdien må være {{ limit }} eller mer. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Verdien er for kort. Den må ha {{ limit }} tegn eller flere. + + + This value should not be blank. + Verdien kan ikke være blank. + + + This value should not be null. + Verdien kan ikke være tom (null). + + + This value should be null. + Verdien skal være tom (null). + + + This value is not valid. + Verdien er ugyldig. + + + This value is not a valid time. + Verdien er ikke en gyldig tid. + + + This value is not a valid URL. + Verdien er ikke en gyldig URL. + + + The two values should be equal. + Verdiene skal være identiske. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Filen er for stor. Den maksimale størrelsen er {{ limit }} {{ suffix }}. + + + The file is too large. + Filen er for stor. + + + The file could not be uploaded. + Filen kunne ikke lastes opp. + + + This value should be a valid number. + Verdien skal være et gyldig tall. + + + This file is not a valid image. + Denne filen er ikke et gyldig bilde. + + + This value is not a valid IP address. + Denne verdien er ikke en gyldig IP-adresse. + + + This value is not a valid language. + Verdien er ikke et gyldig språk. + + + This value is not a valid locale. + Verdien er ikke en gyldig lokalitet. + + + This value is not a valid country. + Verdien er ikke et gyldig navn på land. + + + This value is already used. + Verdien er allerede brukt. + + + The size of the image could not be detected. + Bildestørrelsen kunne ikke oppdages. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Bildebredden er for stor ({{ width }} piksler). Tillatt maksimumsbredde er {{ max_width }} piksler. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Bildebredden er for liten ({{ width }} piksler). Forventet minimumsbredde er {{ min_width }} piksler. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Bildehøyden er for stor ({{ height }} piksler). Tillatt maksimumshøyde er {{ max_height }} piksler. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Bildehøyden er for liten ({{ height }} piksler). Forventet minimumshøyde er {{ min_height }} piksler. + + + This value should be the user's current password. + Verdien skal være brukerens sitt nåværende passord. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Verdien skal være nøyaktig {{ limit }} tegn. + + + The file was only partially uploaded. + Filen var kun delvis opplastet. + + + No file was uploaded. + Ingen fil var lastet opp. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Ingen midlertidig mappe ble konfigurert i php.ini, eller den konfigurerte mappen eksisterer ikke. + + + Cannot write temporary file to disk. + Kan ikke skrive midlertidig fil til disk. + + + A PHP extension caused the upload to fail. + En PHP-utvidelse forårsaket en feil under opplasting. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Denne samlingen må inneholde {{ limit }} element eller flere.|Denne samlingen må inneholde {{ limit }} elementer eller flere. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Denne samlingen må inneholde {{ limit }} element eller færre.|Denne samlingen må inneholde {{ limit }} elementer eller færre. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Denne samlingen må inneholde nøyaktig {{ limit }} element.|Denne samlingen må inneholde nøyaktig {{ limit }} elementer. + + + Invalid card number. + Ugyldig kortnummer. + + + Unsupported card type or invalid card number. + Korttypen er ikke støttet eller kortnummeret er ugyldig. + + + This value is not a valid International Bank Account Number (IBAN). + Denne verdien er ikke et gyldig internasjonalt bankkontonummer (IBAN). + + + This value is not a valid ISBN-10. + Verdien er ikke en gyldig ISBN-10. + + + This value is not a valid ISBN-13. + Verdien er ikke en gyldig ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Verdien er hverken en gyldig ISBN-10 eller ISBN-13. + + + This value is not a valid ISSN. + Verdien er ikke en gyldig ISSN. + + + This value is not a valid currency. + Verdien er ikke gyldig valuta. + + + This value should be equal to {{ compared_value }}. + Verdien skal være lik {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Verdien skal være større enn {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Verdien skal være større enn eller lik {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Verdien skal være identisk med {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Verdien skal være mindre enn {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Verdien skal være mindre enn eller lik {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Verdien skal ikke være lik {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Verdien skal ikke være identisk med {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Bildeforholdet er for stort ({{ ratio }}). Tillatt bildeforhold er maks {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Bildeforholdet er for lite ({{ ratio }}). Forventet bildeforhold er minst {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Bildet er en kvadrat ({{ width }}x{{ height }}px). Kvadratiske bilder er ikke tillatt. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Bildet er i liggende retning ({{ width }}x{{ height }}px). Bilder i liggende retning er ikke tillatt. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Bildet er i stående retning ({{ width }}x{{ height }}px). Bilder i stående retning er ikke tillatt. + + + An empty file is not allowed. + Tomme filer er ikke tilatt. + + + The host could not be resolved. + Vertsnavn kunne ikke løses. + + + This value does not match the expected {{ charset }} charset. + Verdien samsvarer ikke med forventet tegnsett {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Denne verdien er ikke en gyldig forretningsidentifikasjonskode (BIC). + + + Error + Feil + + + This value is not a valid UUID. + Denne verdien er ikke en gyldig UUID. + + + This value should be a multiple of {{ compared_value }}. + Verdien skal være flertall av {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Business Identifier Code (BIC) er ikke tilknyttet en IBAN {{ iban }}. + + + This value should be valid JSON. + Verdien er ikke gyldig JSON. + + + This collection should contain only unique elements. + Samlingen kan kun inneholde unike elementer. + + + This value should be positive. + Denne verdien må være positiv. + + + This value should be either positive or zero. + Denne verdien må være positiv eller null. + + + This value should be negative. + Denne verdien må være negativ. + + + This value should be either negative or zero. + Denne verdien må være negativ eller null. + + + This value is not a valid timezone. + Verdien er ikke en gyldig tidssone. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Dette passordet er lekket i et datainnbrudd, det må ikke tas i bruk. Vennligst bruk et annet passord. + + + This value should be between {{ min }} and {{ max }}. + Verdien må være mellom {{ min }} og {{ max }}. + + + This value is not a valid hostname. + Denne verdien er ikke et gyldig vertsnavn. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Antall elementer i denne samlingen bør være et multiplum av {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Denne verdien skal tilfredsstille minst en av følgende begrensninger: + + + Each element of this collection should satisfy its own set of constraints. + Hvert element i denne samlingen skal tilfredsstille sitt eget sett med begrensninger. + + + This value is not a valid International Securities Identification Number (ISIN). + Denne verdien er ikke et gyldig International Securities Identification Number (ISIN). + + + This value should be a valid expression. + Denne verdien skal være et gyldig uttrykk. + + + This value is not a valid CSS color. + Denne verdien er ikke en gyldig CSS-farge. + + + This value is not a valid CIDR notation. + Denne verdien er ikke en gyldig CIDR-notasjon. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Verdien på nettmasken skal være mellom {{ min }} og {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Filnavnet er for langt. Det bør ha {{ filename_max_length }} tegn eller mindre.|Filnavnet er for langt. Det bør ha {{ filename_max_length }} tegn eller mindre. + + + The password strength is too low. Please use a stronger password. + Passordstyrken er for lav. Vennligst bruk et sterkere passord. + + + This value contains characters that are not allowed by the current restriction-level. + Denne verdien inneholder tegn som ikke er tillatt av gjeldende restriksjonsnivå. + + + Using invisible characters is not allowed. + Det er ikke tillatt å bruke usynlige tegn. + + + Mixing numbers from different scripts is not allowed. + Det er ikke tillatt å blande tall fra forskjellige skript. + + + Using hidden overlay characters is not allowed. + Det er ikke tillatt å bruke skjulte overleggskarakterer. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Filutvidelsen er ugyldig ({{ extension }}). Tillatte utvidelser er {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Den oppdagede tegnkodingen er ugyldig ({{ detected }}). Tillatte kodinger er {{ encodings }}. + + + This value is not a valid MAC address. + Denne verdien er ikke en gyldig MAC-adresse. + + + This URL is missing a top-level domain. + Denne URL-en mangler et toppnivådomene. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Denne verdien er for kort. Den bør inneholde minst ett ord.|Denne verdien er for kort. Den bør inneholde minst {{ min }} ord. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Denne verdien er for lang. Den bør inneholde kun ett ord.|Denne verdien er for lang. Den bør inneholde {{ max }} ord eller færre. + + + This value does not represent a valid week in the ISO 8601 format. + Denne verdien representerer ikke en gyldig uke i ISO 8601-formatet. + + + This value is not a valid week. + Denne verdien er ikke en gyldig uke. + + + This value should not be before week "{{ min }}". + Denne verdien bør ikke være før uke "{{ min }}". + + + This value should not be after week "{{ max }}". + Denne verdien bør ikke være etter uke "{{ max }}". + + + This value is not a valid Twig template. + Denne verdien er ikke en gyldig Twig-mal. + + + This file is not a valid video. + Denne filen er ikke en gyldig video. + + + The size of the video could not be detected. + Videostørrelsen kunne ikke oppdages. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Videobredden er for stor ({{ width }}px). Tillatt maksimal bredde er {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Videobredden er for liten ({{ width }}px). Forventet minimumsbredde er {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Videohøyden er for stor ({{ height }}px). Tillatt maksimal høyde er {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Videoens høyde er for liten ({{ height }}px). Forventet minstehøyde er {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Videoen har for få piksler ({{ pixels }}). Forventet minimum er {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Videoen har for mange piksler ({{ pixels }}). Forventet maksimalt antall er {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Video-forholdet er for stort ({{ ratio }}). Tillatt maksimalt forhold er {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Videoforholdet er for lite ({{ ratio }}). Forventet minimumsforhold er {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Videoen er kvadratisk ({{ width }}x{{ height }}px). Kvadratiske videoer er ikke tillatt. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Videoen er i liggende format ({{ width }}x{{ height }} px). Liggende videoer er ikke tillatt. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Videoen er i portrettformat ({{ width }}x{{ height }}px). Portrettvideoer er ikke tillatt. + + + The video file is corrupted. + Videofilen er ødelagt. + + + The video contains multiple streams. Only one stream is allowed. + Videoen inneholder flere strømmer. Kun én strøm er tillatt. + + + Unsupported video codec "{{ codec }}". + Ikke støttet videokodek «{{ codec }}». + + + Unsupported video container "{{ container }}". + Ikke-støttet videokontainer "{{ container }}". + + + The image file is corrupted. + Bildefilen er ødelagt. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Bildet har for få piksler ({{ pixels }}). Forventet minimum er {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Bildet har for mange piksler ({{ pixels }}). Forventet maksimalt antall er {{ max_pixels }}. + + + This filename does not match the expected charset. + Dette filnavnet samsvarer ikke med forventet tegnsett. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.pl.xlf b/lib/symfony/validator/Resources/translations/validators.pl.xlf new file mode 100644 index 0000000000..8f329dcd43 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.pl.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Ta wartość powinna być fałszem. + + + This value should be true. + Ta wartość powinna być prawdą. + + + This value should be of type {{ type }}. + Ta wartość powinna być typu {{ type }}. + + + This value should be blank. + Ta wartość powinna być pusta. + + + The value you selected is not a valid choice. + Ta wartość powinna być jedną z podanych opcji. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Powinieneś wybrać co najmniej {{ limit }} opcję.|Powinieneś wybrać co najmniej {{ limit }} opcje.|Powinieneś wybrać co najmniej {{ limit }} opcji. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Powinieneś wybrać maksymalnie {{ limit }} opcję.|Powinieneś wybrać maksymalnie {{ limit }} opcje.|Powinieneś wybrać maksymalnie {{ limit }} opcji. + + + One or more of the given values is invalid. + Jedna lub więcej z podanych wartości jest nieprawidłowa. + + + This field was not expected. + Tego pola się nie spodziewano. + + + This field is missing. + Tego pola brakuje. + + + This value is not a valid date. + Ta wartość nie jest prawidłową datą. + + + This value is not a valid datetime. + Ta wartość nie jest prawidłową datą i czasem. + + + This value is not a valid email address. + Ta wartość nie jest prawidłowym adresem email. + + + The file could not be found. + Plik nie mógł zostać odnaleziony. + + + The file is not readable. + Nie można odczytać pliku. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Plik jest za duży ({{ size }} {{ suffix }}). Maksymalny dozwolony rozmiar to {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Nieprawidłowy typ mime pliku ({{ type }}). Dozwolone typy mime to {{ types }}. + + + This value should be {{ limit }} or less. + Ta wartość powinna wynosić {{ limit }} lub mniej. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Ta wartość jest zbyt długa. Powinna mieć {{ limit }} lub mniej znaków.|Ta wartość jest zbyt długa. Powinna mieć {{ limit }} lub mniej znaków.|Ta wartość jest zbyt długa. Powinna mieć {{ limit }} lub mniej znaków. + + + This value should be {{ limit }} or more. + Ta wartość powinna wynosić {{ limit }} lub więcej. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Ta wartość jest zbyt krótka. Powinna mieć {{ limit }} lub więcej znaków.|Ta wartość jest zbyt krótka. Powinna mieć {{ limit }} lub więcej znaków.|Ta wartość jest zbyt krótka. Powinna mieć {{ limit }} lub więcej znaków. + + + This value should not be blank. + Ta wartość nie powinna być pusta. + + + This value should not be null. + Ta wartość nie powinna być nullem. + + + This value should be null. + Ta wartość powinna być nullem. + + + This value is not valid. + Ta wartość jest nieprawidłowa. + + + This value is not a valid time. + Ta wartość nie jest prawidłowym czasem. + + + This value is not a valid URL. + Ta wartość nie jest prawidłowym adresem URL. + + + The two values should be equal. + Obie wartości powinny być równe. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Plik jest za duży. Maksymalny dozwolony rozmiar to {{ limit }} {{ suffix }}. + + + The file is too large. + Plik jest za duży. + + + The file could not be uploaded. + Plik nie mógł być wgrany. + + + This value should be a valid number. + Ta wartość powinna być prawidłową liczbą. + + + This file is not a valid image. + Ten plik nie jest obrazem. + + + This value is not a valid IP address. + Ta wartość nie jest prawidłowym adresem IP. + + + This value is not a valid language. + Ta wartość nie jest prawidłowym językiem. + + + This value is not a valid locale. + Ta wartość nie jest prawidłową lokalizacją. + + + This value is not a valid country. + Ta wartość nie jest prawidłową nazwą kraju. + + + This value is already used. + Ta wartość jest już wykorzystywana. + + + The size of the image could not be detected. + Nie można wykryć rozmiaru obrazka. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Szerokość obrazka jest zbyt duża ({{ width }}px). Maksymalna dopuszczalna szerokość to {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Szerokość obrazka jest zbyt mała ({{ width }}px). Oczekiwana minimalna szerokość to {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Wysokość obrazka jest zbyt duża ({{ height }}px). Maksymalna dopuszczalna wysokość to {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Wysokość obrazka jest zbyt mała ({{ height }}px). Oczekiwana minimalna wysokość to {{ min_height }}px. + + + This value should be the user's current password. + Ta wartość powinna być aktualnym hasłem użytkownika. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ta wartość powinna mieć dokładnie {{ limit }} znak.|Ta wartość powinna mieć dokładnie {{ limit }} znaki.|Ta wartość powinna mieć dokładnie {{ limit }} znaków. + + + The file was only partially uploaded. + Plik został wgrany tylko częściowo. + + + No file was uploaded. + Żaden plik nie został wgrany. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Nie skonfigurowano folderu tymczasowego w php.ini lub skonfigurowany folder nie istnieje. + + + Cannot write temporary file to disk. + Nie można zapisać pliku tymczasowego na dysku. + + + A PHP extension caused the upload to fail. + Rozszerzenie PHP spowodowało błąd podczas wgrywania. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ten zbiór powinien zawierać {{ limit }} lub więcej elementów. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ten zbiór powinien zawierać {{ limit }} lub mniej elementów. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ten zbiór powinien zawierać dokładnie {{ limit }} element.|Ten zbiór powinien zawierać dokładnie {{ limit }} elementy.|Ten zbiór powinien zawierać dokładnie {{ limit }} elementów. + + + Invalid card number. + Nieprawidłowy numer karty. + + + Unsupported card type or invalid card number. + Nieobsługiwany rodzaj karty lub nieprawidłowy numer karty. + + + This value is not a valid International Bank Account Number (IBAN). + Ta wartość nie jest prawidłowym Międzynarodowym Numerem Rachunku Bankowego (IBAN). + + + This value is not a valid ISBN-10. + Ta wartość nie jest prawidłowym numerem ISBN-10. + + + This value is not a valid ISBN-13. + Ta wartość nie jest prawidłowym numerem ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ta wartość nie jest prawidłowym numerem ISBN-10 ani ISBN-13. + + + This value is not a valid ISSN. + Ta wartość nie jest prawidłowym numerem ISSN. + + + This value is not a valid currency. + Ta wartość nie jest prawidłową walutą. + + + This value should be equal to {{ compared_value }}. + Ta wartość powinna być równa {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ta wartość powinna być większa niż {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ta wartość powinna być większa bądź równa {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ta wartość powinna być identycznego typu {{ compared_value_type }} oraz wartości {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ta wartość powinna być mniejsza niż {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ta wartość powinna być mniejsza bądź równa {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ta wartość nie powinna być równa {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ta wartość nie powinna być identycznego typu {{ compared_value_type }} oraz wartości {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Proporcje obrazu są zbyt duże ({{ ratio }}). Maksymalne proporcje to {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Proporcje obrazu są zbyt małe ({{ ratio }}). Minimalne proporcje to {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Obraz jest kwadratem ({{ width }}x{{ height }}px). Kwadratowe obrazy nie są akceptowane. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Obraz jest panoramiczny ({{ width }}x{{ height }}px). Panoramiczne zdjęcia nie są akceptowane. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Obraz jest portretowy ({{ width }}x{{ height }}px). Portretowe zdjęcia nie są akceptowane. + + + An empty file is not allowed. + Plik nie może być pusty. + + + The host could not be resolved. + Nazwa hosta nie została rozpoznana. + + + This value does not match the expected {{ charset }} charset. + Ta wartość nie pasuje do oczekiwanego zestawu znaków {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Ta wartość nie jest prawidłowym Kodem Identyfikującym Bank (BIC). + + + Error + Błąd + + + This value is not a valid UUID. + Ta wartość nie jest prawidłowym UUID. + + + This value should be a multiple of {{ compared_value }}. + Ta wartość powinna być wielokrotnością {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Ten kod BIC (Business Identifier Code) nie jest powiązany z międzynarodowym numerem rachunku bankowego (IBAN) {{ iban }}. + + + This value should be valid JSON. + Ta wartość powinna być prawidłowym formatem JSON. + + + This collection should contain only unique elements. + Ten zbiór powinien zawierać tylko unikalne elementy. + + + This value should be positive. + Ta wartość powinna być dodatnia. + + + This value should be either positive or zero. + Ta wartość powinna być dodatnia lub równa zero. + + + This value should be negative. + Ta wartość powinna być ujemna. + + + This value should be either negative or zero. + Ta wartość powinna być ujemna lub równa zero. + + + This value is not a valid timezone. + Ta wartość nie jest prawidłową strefą czasową. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + To hasło wyciekło w wyniku naruszenia danych i nie może być użyte. Proszę użyć innego hasła. + + + This value should be between {{ min }} and {{ max }}. + Ta wartość powinna być pomiędzy {{ min }} a {{ max }}. + + + This value is not a valid hostname. + Ta wartość nie jest prawidłową nazwą hosta. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Liczba elementów w tym zbiorze powinna być wielokrotnością {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Ta wartość powinna spełniać co najmniej jedną z następujących reguł: + + + Each element of this collection should satisfy its own set of constraints. + Każdy element w tym zbiorze powinien spełniać własny zestaw reguł. + + + This value is not a valid International Securities Identification Number (ISIN). + Ta wartość nie jest prawidłowym Międzynarodowym Numerem Identyfikacyjnym Papierów Wartościowych (ISIN). + + + This value should be a valid expression. + Ta wartość powinna być prawidłowym wyrażeniem. + + + This value is not a valid CSS color. + Ta wartość nie jest prawidłowym kolorem CSS. + + + This value is not a valid CIDR notation. + Ta wartość nie jest prawidłową notacją CIDR. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Wartość maski podsieci powinna być pomiędzy {{ min }} i {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Nazwa pliku jest za długa. Powinna mieć {{ filename_max_length }} znak lub mniej.|Nazwa pliku jest za długa. Powinna mieć {{ filename_max_length }} znaki lub mniej.|Nazwa pliku jest za długa. Powinna mieć {{ filename_max_length }} znaków lub mniej. + + + The password strength is too low. Please use a stronger password. + Siła hasła jest zbyt niska. Użyj mocniejszego hasła. + + + This value contains characters that are not allowed by the current restriction-level. + Ta wartość zawiera znaki, które nie są dozwolone przez aktualny poziom ograniczeń. + + + Using invisible characters is not allowed. + Używanie niewidzialnych znaków jest niedozwolone. + + + Mixing numbers from different scripts is not allowed. + Mieszanie liczb z różnych skryptów jest niedozwolone. + + + Using hidden overlay characters is not allowed. + Używanie ukrytych znaków nakładki jest niedozwolone. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Rozszerzenie pliku jest nieprawidłowe ({{ extension }}). Dozwolone rozszerzenia to {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Wykryte kodowanie znaków ({{ detected }}) jest nieprawidłowe. Dozwolone kodowania to {{ encodings }}. + + + This value is not a valid MAC address. + Ta wartość nie jest prawidłowym adresem MAC. + + + This URL is missing a top-level domain. + Ten URL nie zawiera domeny najwyższego poziomu. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Ta wartość jest zbyt krótka. Powinna zawierać co najmniej jedno słowo.|Ta wartość jest zbyt krótka. Powinna zawierać co najmniej {{ min }} słów. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Ta wartość jest zbyt długa. Powinna zawierać jedno słowo.|Ta wartość jest zbyt długa. Powinna zawierać {{ max }} słowa lub mniej.|Ta wartość jest zbyt długa. Powinna zawierać {{ max }} słów lub mniej. + + + This value does not represent a valid week in the ISO 8601 format. + Ta wartość nie jest poprawnym oznaczeniem tygodnia w formacie ISO 8601. + + + This value is not a valid week. + Ta wartość nie jest poprawnym oznaczeniem tygodnia. + + + This value should not be before week "{{ min }}". + Ta wartość nie powinna być przed tygodniem "{{ min }}". + + + This value should not be after week "{{ max }}". + Ta wartość nie powinna być po tygodniu "{{ max }}". + + + This value is not a valid Twig template. + Ta wartość nie jest prawidłowym szablonem Twig. + + + This file is not a valid video. + Ten plik nie jest prawidłowym plikiem wideo. + + + The size of the video could not be detected. + Nie można wykryć rozmiaru wideo. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Szerokość wideo jest zbyt duża ({{ width }}px). Maksymalna dopuszczalna szerokość to {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Szerokość wideo jest zbyt mała ({{ width }}px). Oczekiwana minimalna szerokość to {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Wysokość wideo jest zbyt duża ({{ height }}px). Maksymalna dopuszczalna wysokość to {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Wysokość wideo jest zbyt mała ({{ height }}px). Oczekiwana minimalna wysokość to {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Wideo ma zbyt mało ({{ pixels }} pikseli). Oczekiwana minimalna liczba to {{ min_pixels }} pikseli. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Wideo ma zbyt wiele ({{ pixels }} pikseli). Oczekiwana maksymalna liczba to {{ max_pixels }} pikseli. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Współczynnik proporcji wideo jest zbyt duży ({{ ratio }}). Maksymalny dopuszczalny współczynnik to {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Współczynnik proporcji wideo jest zbyt mały ({{ ratio }}). Oczekiwany minimalny współczynnik to {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Wideo jest w formacie kwadratowym ({{ width }}x{{ height }}px). Filmy w tym formacie są niedozwolone. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Wideo ma orientację poziomą ({{ width }}x{{ height }}px). Filmy w orientacji poziomej są niedozwolone. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Wideo ma orientację pionową ({{ width }}x{{ height }}px). Filmy w orientacji pionowej są niedozwolone. + + + The video file is corrupted. + Plik wideo jest uszkodzony. + + + The video contains multiple streams. Only one stream is allowed. + Wideo zawiera wiele strumieni. Dozwolony jest tylko jeden strumień. + + + Unsupported video codec "{{ codec }}". + Nieobsługiwany kodek wideo "{{ codec }}". + + + Unsupported video container "{{ container }}". + Nieobsługiwany kontener wideo "{{ container }}". + + + The image file is corrupted. + Plik obrazu jest uszkodzony. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Obraz ma zbyt mało ({{ pixels }} pikseli). Oczekiwana minimalna liczba to {{ min_pixels }} pikseli. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Obraz ma zbyt wiele ({{ pixels }} pikseli). Oczekiwana maksymalna liczba to {{ max_pixels }} pikseli. + + + This filename does not match the expected charset. + Ta nazwa pliku nie odpowiada oczekiwanemu zestawowi znaków. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.pt.xlf b/lib/symfony/validator/Resources/translations/validators.pt.xlf new file mode 100644 index 0000000000..62c3c5fc2a --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.pt.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Este valor deveria ser falso. + + + This value should be true. + Este valor deveria ser verdadeiro. + + + This value should be of type {{ type }}. + Este valor deveria ser do tipo {{ type }}. + + + This value should be blank. + Este valor deveria ser vazio. + + + The value you selected is not a valid choice. + O valor selecionado não é uma opção válida. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Você deveria selecionar {{ limit }} opção no mínimo.|Você deveria selecionar {{ limit }} opções no mínimo. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Você deve selecionar, no máximo {{ limit }} opção.|Você deve selecionar, no máximo {{ limit }} opções. + + + One or more of the given values is invalid. + Um ou mais dos valores introduzidos não são válidos. + + + This field was not expected. + Este campo não era esperado. + + + This field is missing. + Este campo está faltando. + + + This value is not a valid date. + Este valor não é uma data válida. + + + This value is not a valid datetime. + Este valor não é uma data-hora válida. + + + This value is not a valid email address. + Este valor não é um endereço de e-mail válido. + + + The file could not be found. + O arquivo não pôde ser encontrado. + + + The file is not readable. + O arquivo não pôde ser lido. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + O arquivo é muito grande ({{ size }} {{ suffix }}). O tamanho máximo permitido é de {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + O tipo mime do arquivo é inválido ({{ type }}). Os tipos mime permitidos são {{ types }}. + + + This value should be {{ limit }} or less. + Este valor deveria ser {{ limit }} ou menor. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + O valor é muito longo. Deveria ter {{ limit }} caracteres ou menos. + + + This value should be {{ limit }} or more. + Este valor deveria ser {{ limit }} ou mais. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + O valor é muito curto. Deveria de ter {{ limit }} caractere ou mais.|O valor é muito curto. Deveria de ter {{ limit }} caracteres ou mais. + + + This value should not be blank. + Este valor não deveria ser vazio. + + + This value should not be null. + Este valor não deveria ser nulo. + + + This value should be null. + Este valor deveria ser nulo. + + + This value is not valid. + Este valor não é válido. + + + This value is not a valid time. + Este valor não é uma hora válida. + + + This value is not a valid URL. + Este valor não é uma URL válida. + + + The two values should be equal. + Os dois valores deveriam ser iguais. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + O arquivo é muito grande. O tamanho máximo permitido é de {{ limit }} {{ suffix }}. + + + The file is too large. + O arquivo é muito grande. + + + The file could not be uploaded. + Não foi possível enviar o arquivo. + + + This value should be a valid number. + Este valor deveria ser um número válido. + + + This file is not a valid image. + Este arquivo não é uma imagem. + + + This value is not a valid IP address. + Este valor não é um endereço IP válido. + + + This value is not a valid language. + Este valor não é uma linguagem válida. + + + This value is not a valid locale. + Este valor não é uma localidade válida. + + + This value is not a valid country. + Este valor não é um país válido. + + + This value is already used. + Este valor já está a ser usado. + + + The size of the image could not be detected. + O tamanho da imagem não foi detectado. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + A largura da imagem ({{ width }}px) é muito grande. A largura máxima da imagem é: {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + A largura da imagem ({{ width }}px) é muito pequena. A largura mínima da imagem é de: {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + A altura da imagem ({{ height }}px) é muito grande. A altura máxima da imagem é de: {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + A altura da imagem ({{ height }}px) é muito pequena. A altura mínima da imagem é de: {{ min_height }}px. + + + This value should be the user's current password. + Este valor deveria ser a senha atual do usuário. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Este valor deve possuir exatamente {{ limit }} caractere.|Este valor deve possuir exatamente {{ limit }} caracteres. + + + The file was only partially uploaded. + Só foi enviada uma parte do arquivo. + + + No file was uploaded. + Nenhum arquivo foi enviado. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Nenhuma pasta temporária foi configurada no php.ini, ou a pasta configurada não existe. + + + Cannot write temporary file to disk. + Não foi possível escrever os arquivos temporários no disco. + + + A PHP extension caused the upload to fail. + Uma extensão PHP causou a falha no envio. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Esta coleção deve conter {{ limit }} elemento ou mais.|Esta coleção deve conter {{ limit }} elementos ou mais. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Esta coleção deve conter {{ limit }} elemento ou menos.|Esta coleção deve conter {{ limit }} elementos ou menos. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Esta coleção deve conter exatamente {{ limit }} elemento.|Esta coleção deve conter exatamente {{ limit }} elementos. + + + Invalid card number. + Número de cartão inválido. + + + Unsupported card type or invalid card number. + Tipo de cartão não suportado ou número de cartão inválido. + + + This value is not a valid International Bank Account Number (IBAN). + Este valor não é um Número de Conta Bancária Internacional (IBAN) válido. + + + This value is not a valid ISBN-10. + Este valor não é um ISBN-10 válido. + + + This value is not a valid ISBN-13. + Este valor não é um ISBN-13 válido. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Este valor não é um ISBN-10 ou ISBN-13 válido. + + + This value is not a valid ISSN. + Este valor não é um ISSN válido. + + + This value is not a valid currency. + Este não é um valor monetário válido. + + + This value should be equal to {{ compared_value }}. + Este valor deve ser igual a {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Este valor deve ser superior a {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Este valor deve ser igual ou superior a {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor deve ser idêntico a {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Este valor deve ser inferior a {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Este valor deve ser igual ou inferior a {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Este valor não deve ser igual a {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor não deve ser idêntico a {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + O formato da imagem é muito grande ({{ ratio }}). O formato máximo é {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + O formato da imagem é muito pequeno ({{ ratio }}). O formato mínimo esperado é {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + A imagem é um quadrado ({{ width }}x{{ height }}px). Imagens quadradas não são permitidas. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + A imagem está em orientação de paisagem ({{ width }}x{{ height }}px). Imagens orientadas em paisagem não são permitidas. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + A imagem está em orientação de retrato ({{ width }}x{{ height }}px). Imagens orientadas em retrato não são permitidas. + + + An empty file is not allowed. + Um arquivo vazio não é permitido. + + + The host could not be resolved. + O host não pode ser resolvido. + + + This value does not match the expected {{ charset }} charset. + Este valor não corresponde ao conjunto de caracteres {{ charset }} esperado. + + + This value is not a valid Business Identifier Code (BIC). + Este valor não é um Código de Identificação de Negócio (BIC) válido. + + + Error + Erro + + + This value is not a valid UUID. + Este valor não é um UUID válido. + + + This value should be a multiple of {{ compared_value }}. + Este valor deve ser um múltiplo de {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + O Código de Identificação de Empresa (BIC) não está associado ao IBAN {{ iban }}. + + + This value should be valid JSON. + Este valor deve ser um JSON válido. + + + This collection should contain only unique elements. + Esta coleção deve conter só elementos únicos. + + + This value should be positive. + Este valor deve ser positivo. + + + This value should be either positive or zero. + Este valor deve ser superior ou igual a zero. + + + This value should be negative. + Este valor deve ser negativo. + + + This value should be either negative or zero. + Este valor deve ser inferior ou igual a zero. + + + This value is not a valid timezone. + Este valor não é um fuso horário válido. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Esta senha foi divulgada durante um vazamento de dados, não deve ser usada de novamente. Por favor usar uma senha outra. + + + This value should be between {{ min }} and {{ max }}. + Este valor deve estar entre {{ min }} e {{ max }}. + + + This value is not a valid hostname. + Este valor não é um nome de host válido. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + O número de elementos desta coleção deve ser um múltiplo de {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Este valor deve satisfazer pelo menos uma das seguintes restrições: + + + Each element of this collection should satisfy its own set of constraints. + Cada elemento desta coleção deve satisfazer o seu próprio conjunto de restrições. + + + This value is not a valid International Securities Identification Number (ISIN). + Este valor não é um Número Internacional de Identificação de Segurança (ISIN) válido. + + + This value should be a valid expression. + Este valor deve ser uma expressão válida. + + + This value is not a valid CSS color. + Este valor não é uma cor de CSS válida. + + + This value is not a valid CIDR notation. + Este valor não é uma notação CIDR válida. + + + The value of the netmask should be between {{ min }} and {{ max }}. + O valor da máscara de rede deve estar entre {{ min }} e {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + O nome do arquivo é muito grande. Deveria ter {{ filename_max_length }} caractere ou menos.|O nome do arquivo é muito grande. Deveria ter {{ filename_max_length }} caracteres ou menos. + + + The password strength is too low. Please use a stronger password. + A força da senha é muito baixa. Por favor utilize uma senha mais forte. + + + This value contains characters that are not allowed by the current restriction-level. + Este valor contém caracteres que não são permitidos pelo nível de restrição atual. + + + Using invisible characters is not allowed. + Não é permitido usar caracteres invisíveis. + + + Mixing numbers from different scripts is not allowed. + Não é permitido misturar números de scripts diferentes. + + + Using hidden overlay characters is not allowed. + Não é permitido usar caracteres de sobreposição ocultos. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + A extensão do arquivo é inválida ({{ extension }}). As extensões permitidas são {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + A codificação de carateres detectada é inválida ({{ detected }}). As codificações permitidas são {{ encodings }}. + + + This value is not a valid MAC address. + Este valor não é um endereço MAC válido. + + + This URL is missing a top-level domain. + Esta URL está faltando o domínio de nível superior. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Este valor é muito curto. Deve conter pelo menos uma palavra.|Este valor é muito curto. Deve conter pelo menos {{ min }} palavras. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Este valor é muito longo. Deve conter apenas uma palavra.|Este valor é muito longo. Deve conter {{ max }} palavras ou menos. + + + This value does not represent a valid week in the ISO 8601 format. + Este valor não representa uma semana válida no formato ISO 8601. + + + This value is not a valid week. + Este valor não é uma semana válida. + + + This value should not be before week "{{ min }}". + Este valor não deve ser anterior à semana "{{ min }}". + + + This value should not be after week "{{ max }}". + Este valor não deve estar após a semana "{{ max }}". + + + This value is not a valid Twig template. + Este valor não é um modelo Twig válido. + + + This file is not a valid video. + Este ficheiro não é um vídeo válido. + + + The size of the video could not be detected. + Não foi possível detetar o tamanho do vídeo. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + A largura do vídeo é demasiado grande ({{ width }}px). A largura máxima permitida é {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + A largura do vídeo é muito pequena ({{ width }}px). A largura mínima esperada é {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + A altura do vídeo é demasiado grande ({{ height }}px). A altura máxima permitida é {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + A altura do vídeo é muito pequena ({{ height }}px). A altura mínima esperada é {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + O vídeo tem poucos píxeis ({{ pixels }}). A quantidade mínima esperada é {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + O vídeo tem píxeis a mais ({{ pixels }}). A quantidade máxima esperada é {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + A proporção do vídeo é muito grande ({{ ratio }}). A proporção máxima permitida é {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + A proporção do vídeo é muito pequena ({{ ratio }}). A proporção mínima esperada é {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + O vídeo é quadrado ({{ width }}x{{ height }}px). Vídeos quadrados não são permitidos. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + O vídeo está em modo paisagem ({{ width }}x{{ height }} px). Vídeos em paisagem não são permitidos. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + O vídeo está em orientação vertical ({{ width }}x{{ height }}px). Vídeos em orientação vertical não são permitidos. + + + The video file is corrupted. + O ficheiro de vídeo está corrompido. + + + The video contains multiple streams. Only one stream is allowed. + O vídeo contém vários fluxos. É permitido apenas um fluxo. + + + Unsupported video codec "{{ codec }}". + Codec de vídeo não suportado «{{ codec }}». + + + Unsupported video container "{{ container }}". + Contentor de vídeo não suportado "{{ container }}". + + + The image file is corrupted. + O ficheiro de imagem está corrompido. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + A imagem tem píxeis a menos ({{ pixels }}). A quantidade mínima esperada é {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + A imagem tem píxeis a mais ({{ pixels }}). A quantidade máxima esperada é {{ max_pixels }}. + + + This filename does not match the expected charset. + Este nome de ficheiro não corresponde ao conjunto de caracteres esperado. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.pt_BR.xlf b/lib/symfony/validator/Resources/translations/validators.pt_BR.xlf new file mode 100644 index 0000000000..0d3a30c6c4 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.pt_BR.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Este valor deve ser falso. + + + This value should be true. + Este valor deve ser verdadeiro. + + + This value should be of type {{ type }}. + Este valor deve ser do tipo {{ type }}. + + + This value should be blank. + Este valor deve ser vazio. + + + The value you selected is not a valid choice. + O valor selecionado não é uma opção válida. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Você deve selecionar, no mínimo, {{ limit }} opção.|Você deve selecionar, no mínimo, {{ limit }} opções. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Você deve selecionar, no máximo, {{ limit }} opção.|Você deve selecionar, no máximo, {{ limit }} opções. + + + One or more of the given values is invalid. + Um ou mais valores informados são inválidos. + + + This field was not expected. + Este campo não era esperado. + + + This field is missing. + Este campo está ausente. + + + This value is not a valid date. + Este valor não é uma data válida. + + + This value is not a valid datetime. + Este valor não é uma data e hora válida. + + + This value is not a valid email address. + Este valor não é um endereço de e-mail válido. + + + The file could not be found. + O arquivo não foi encontrado. + + + The file is not readable. + O arquivo não pode ser lido. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + O arquivo é muito grande ({{ size }} {{ suffix }}). O tamanho máximo permitido é {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + O tipo mime do arquivo é inválido ({{ type }}). Os tipos mime permitidos são {{ types }}. + + + This value should be {{ limit }} or less. + Este valor deve ser {{ limit }} ou menos. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Este valor é muito longo. Deve ter {{ limit }} caractere ou menos.|Este valor é muito longo. Deve ter {{ limit }} caracteres ou menos. + + + This value should be {{ limit }} or more. + Este valor deve ser {{ limit }} ou mais. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Este valor é muito curto. Deve ter {{ limit }} caractere ou mais.|Este valor é muito curto. Deve ter {{ limit }} caracteres ou mais. + + + This value should not be blank. + Este valor não deve ser vazio. + + + This value should not be null. + Este valor não deve ser nulo. + + + This value should be null. + Este valor deve ser nulo. + + + This value is not valid. + Este valor não é válido. + + + This value is not a valid time. + Este valor não é uma hora válida. + + + This value is not a valid URL. + Este valor não é uma URL válida. + + + The two values should be equal. + Os dois valores devem ser iguais. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + O arquivo é muito grande. O tamanho máximo permitido é de {{ limit }} {{ suffix }}. + + + The file is too large. + O arquivo é muito grande. + + + The file could not be uploaded. + O arquivo não pode ser enviado. + + + This value should be a valid number. + Este valor deve ser um número válido. + + + This file is not a valid image. + Este arquivo não é uma imagem válida. + + + This value is not a valid IP address. + Este valor não é um endereço IP válido. + + + This value is not a valid language. + Este valor não é um idioma válido. + + + This value is not a valid locale. + Este valor não é uma localidade válida. + + + This value is not a valid country. + Este valor não é um país válido. + + + This value is already used. + Este valor já está sendo usado. + + + The size of the image could not be detected. + O tamanho da imagem não pode ser detectado. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + A largura da imagem é muito grande ({{ width }}px). A largura máxima permitida é de {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + A largura da imagem é muito pequena ({{ width }}px). A largura mínima esperada é de {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + A altura da imagem é muito grande ({{ height }}px). A altura máxima permitida é de {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + A altura da imagem é muito pequena ({{ height }}px). A altura mínima esperada é de {{ min_height }}px. + + + This value should be the user's current password. + Este valor deve ser a senha atual do usuário. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Este valor deve ter exatamente {{ limit }} caractere.|Este valor deve ter exatamente {{ limit }} caracteres. + + + The file was only partially uploaded. + O arquivo foi enviado apenas parcialmente. + + + No file was uploaded. + Nenhum arquivo foi enviado. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Nenhum diretório temporário foi configurado no php.ini, ou o diretório configurado não existe. + + + Cannot write temporary file to disk. + Não foi possível escrever o arquivo temporário no disco. + + + A PHP extension caused the upload to fail. + Uma extensão PHP fez com que o envio falhasse. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Esta coleção deve conter {{ limit }} elemento ou mais.|Esta coleção deve conter {{ limit }} elementos ou mais. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Esta coleção deve conter {{ limit }} elemento ou menos.|Esta coleção deve conter {{ limit }} elementos ou menos. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Esta coleção deve conter exatamente {{ limit }} elemento.|Esta coleção deve conter exatamente {{ limit }} elementos. + + + Invalid card number. + Número de cartão inválido. + + + Unsupported card type or invalid card number. + Tipo de cartão não suportado ou número de cartão inválido. + + + This value is not a valid International Bank Account Number (IBAN). + Este valor não é um Número de Conta Bancária Internacional (IBAN) válido. + + + This value is not a valid ISBN-10. + Este valor não é um ISBN-10 válido. + + + This value is not a valid ISBN-13. + Este valor não é um ISBN-13 válido. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Este valor não é um ISBN-10 e nem um ISBN-13 válido. + + + This value is not a valid ISSN. + Este valor não é um ISSN válido. + + + This value is not a valid currency. + Este não é um valor monetário válido. + + + This value should be equal to {{ compared_value }}. + Este valor deve ser igual a {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Este valor deve ser maior que {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Este valor deve ser maior ou igual a {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor deve ser idêntico a {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Este valor deve ser menor que {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Este valor deve ser menor ou igual a {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Este valor não deve ser igual a {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Este valor não deve ser idêntico a {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + A proporção da imagem é muito grande ({{ ratio }}). A proporção máxima permitida é {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + A proporção da imagem é muito pequena ({{ ratio }}). A proporção mínima esperada é {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + A imagem está num formato quadrado ({{ width }}x{{ height }}px). Imagens com formato quadrado não são permitidas. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + A imagem está orientada à paisagem ({{ width }}x{{ height }}px). Imagens orientadas à paisagem não são permitidas. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + A imagem está orientada ao retrato ({{ width }}x{{ height }}px). Imagens orientadas ao retrato não são permitidas. + + + An empty file is not allowed. + Arquivo vazio não é permitido. + + + The host could not be resolved. + O host não pôde ser resolvido. + + + This value does not match the expected {{ charset }} charset. + Este valor não corresponde ao charset {{ charset }} esperado. + + + This value is not a valid Business Identifier Code (BIC). + Este valor não é um Código de Identificação de Negócios (BIC) válido. + + + Error + Erro + + + This value is not a valid UUID. + Este valor não é um UUID válido. + + + This value should be a multiple of {{ compared_value }}. + Este valor deve ser múltiplo de {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Este Código Identificador Bancário (BIC) não está associado ao IBAN {{ iban }}. + + + This value should be valid JSON. + Este valor deve ser um JSON válido. + + + This collection should contain only unique elements. + Esta coleção deve conter somente elementos únicos. + + + This value should be positive. + Este valor deve ser positivo. + + + This value should be either positive or zero. + Este valor deve ser positivo ou zero. + + + This value should be negative. + Este valor deve ser negativo. + + + This value should be either negative or zero. + Este valor deve ser negativo ou zero. + + + This value is not a valid timezone. + Este valor não representa um fuso horário válido. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Esta senha foi divulgada num vazamento de dados e não deve ser utilizada. Por favor, utilize outra senha. + + + This value should be between {{ min }} and {{ max }}. + Este valor deve estar entre {{ min }} e {{ max }}. + + + This value is not a valid hostname. + Este valor não é um nome de host válido. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + O número de elementos desta coleção deve ser um múltiplo de {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Este valor deve satisfazer pelo menos uma das seguintes restrições: + + + Each element of this collection should satisfy its own set of constraints. + Cada elemento desta coleção deve satisfazer seu próprio grupo de restrições. + + + This value is not a valid International Securities Identification Number (ISIN). + Este valor não é um Número de Identificação de Títulos Internacionais (ISIN) válido. + + + This value should be a valid expression. + Este valor deve ser uma expressão válida. + + + This value is not a valid CSS color. + Este valor não é uma cor CSS válida. + + + This value is not a valid CIDR notation. + Este valor não é uma notação CIDR válida. + + + The value of the netmask should be between {{ min }} and {{ max }}. + O valor da máscara de rede deve estar entre {{ min }} e {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + O nome do arquivo é muito longo. Deve ter {{ filename_max_length }} caractere ou menos.|O nome do arquivo é muito longo. Deve ter {{ filename_max_length }} caracteres ou menos. + + + The password strength is too low. Please use a stronger password. + A força da senha é muito baixa. Por favor, use uma senha mais forte. + + + This value contains characters that are not allowed by the current restriction-level. + Este valor contém caracteres que não são permitidos pelo nível de restrição atual. + + + Using invisible characters is not allowed. + O uso de caracteres invisíveis não é permitido. + + + Mixing numbers from different scripts is not allowed. + Misturar números de scripts diferentes não é permitido. + + + Using hidden overlay characters is not allowed. + O uso de caracteres de sobreposição ocultos não é permitido. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + A extensão do arquivo é inválida ({{ extension }}). As extensões permitidas são {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + A codificação de caracteres detectada é inválida ({{ detected }}). As codificações permitidas são {{ encodings }}. + + + This value is not a valid MAC address. + Este valor não é um endereço MAC válido. + + + This URL is missing a top-level domain. + Esta URL está faltando o domínio de nível superior. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Este valor é muito curto. Deve conter pelo menos uma palavra.|Este valor é muito curto. Deve conter pelo menos {{ min }} palavras. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Este valor é muito longo. Deve conter apenas uma palavra.|Este valor é muito longo. Deve conter {{ max }} palavras ou menos. + + + This value does not represent a valid week in the ISO 8601 format. + Este valor não representa uma semana válida no formato ISO 8601. + + + This value is not a valid week. + Este valor não é uma semana válida. + + + This value should not be before week "{{ min }}". + Este valor não deve ser anterior à semana "{{ min }}". + + + This value should not be after week "{{ max }}". + Este valor não deve estar após a semana "{{ max }}". + + + This value is not a valid Twig template. + Este valor não é um modelo Twig válido. + + + This file is not a valid video. + Este arquivo não é um vídeo válido. + + + The size of the video could not be detected. + Não foi possível detectar o tamanho do vídeo. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + A largura do vídeo é muito grande ({{ width }}px). A largura máxima permitida é {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + A largura do vídeo é muito pequena ({{ width }}px). A largura mínima esperada é {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + A altura do vídeo é muito grande ({{ height }}px). A altura máxima permitida é {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + A altura do vídeo é muito pequena ({{ height }}px). A altura mínima esperada é {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + O vídeo tem poucos pixels ({{ pixels }}). A quantidade mínima esperada é {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + O vídeo tem pixels demais ({{ pixels }}). A quantidade máxima esperada é {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + A proporção do vídeo é muito grande ({{ ratio }}). A proporção máxima permitida é {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + A proporção do vídeo é muito pequena ({{ ratio }}). A proporção mínima esperada é {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + O vídeo é quadrado ({{ width }}x{{ height }}px). Vídeos quadrados não são permitidos. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + O vídeo está no modo paisagem ({{ width }}x{{ height }} px). Vídeos em paisagem não são permitidos. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + O vídeo está em orientação vertical ({{ width }}x{{ height }}px). Vídeos em orientação vertical não são permitidos. + + + The video file is corrupted. + O arquivo de vídeo está corrompido. + + + The video contains multiple streams. Only one stream is allowed. + O vídeo contém múltiplos fluxos. Apenas um fluxo é permitido. + + + Unsupported video codec "{{ codec }}". + Codec de vídeo não suportado «{{ codec }}». + + + Unsupported video container "{{ container }}". + Contêiner de vídeo não suportado "{{ container }}". + + + The image file is corrupted. + O arquivo de imagem está corrompido. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + A imagem tem pixels de menos ({{ pixels }}). A quantidade mínima esperada é {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + A imagem tem pixels demais ({{ pixels }}). A quantidade máxima esperada é {{ max_pixels }}. + + + This filename does not match the expected charset. + Este nome de arquivo não corresponde ao conjunto de caracteres esperado. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.ro.xlf b/lib/symfony/validator/Resources/translations/validators.ro.xlf new file mode 100644 index 0000000000..e4e27570a8 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.ro.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Această valoare ar trebui să fie falsă. + + + This value should be true. + Această valoare ar trebui să fie adevărată. + + + This value should be of type {{ type }}. + Această valoare ar trebui să fie de tipul {{ type }}. + + + This value should be blank. + Această valoare ar trebui să fie necompletată. + + + The value you selected is not a valid choice. + Valoarea selectată nu este o opțiune validă. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Trebuie să selectați cel puțin {{ limit }} opțiune.|Trebuie să selectați cel puțin {{ limit }} opțiuni. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Trebuie să selectați cel mult {{ limit }} opțiune.|Trebuie să selectați cel mult {{ limit }} opțiuni. + + + One or more of the given values is invalid. + Una sau mai multe dintre valorile furnizate sunt invalide. + + + This field was not expected. + Acest câmp nu era prevăzut. + + + This field is missing. + Acest câmp lipsește. + + + This value is not a valid date. + Această valoare nu reprezintă o dată validă. + + + This value is not a valid datetime. + Această valoare nu reprezintă o dată și oră validă. + + + This value is not a valid email address. + Această valoare nu reprezintă o adresă de e-mail validă. + + + The file could not be found. + Fișierul nu a putut fi găsit. + + + The file is not readable. + Fișierul nu poate fi citit. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Fișierul este prea mare ({{ size }} {{ suffix }}). Dimensiunea maximă permisă este {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Tipul fișierului este invalid ({{ type }}). Tipurile de fișiere permise sunt {{ types }}. + + + This value should be {{ limit }} or less. + Această valoare ar trebui să fie cel mult {{ limit }}. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Această valoare este prea lungă. Ar trebui să aibă maxim {{ limit }} caracter.|Această valoare este prea lungă. Ar trebui să aibă maxim {{ limit }} caractere. + + + This value should be {{ limit }} or more. + Această valoare ar trebui să fie cel puțin {{ limit }}. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Această valoare este prea scurtă. Ar trebui să aibă minim {{ limit }} caracter.|Această valoare este prea scurtă. Ar trebui să aibă minim {{ limit }} caractere. + + + This value should not be blank. + Această valoare nu ar trebui să fie necompletată. + + + This value should not be null. + Această valoare nu ar trebui să fie nulă. + + + This value should be null. + Această valoare ar trebui să fie nulă. + + + This value is not valid. + Această valoare nu este validă. + + + This value is not a valid time. + Această valoare nu reprezintă o oră validă. + + + This value is not a valid URL. + Această valoare nu reprezintă un URL valid. + + + The two values should be equal. + Cele două valori ar trebui să fie egale. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Fișierul este prea mare. Mărimea maximă permisă este de {{ limit }} {{ suffix }}. + + + The file is too large. + Fișierul este prea mare. + + + The file could not be uploaded. + Fișierul nu a putut fi încărcat. + + + This value should be a valid number. + Această valoare nu reprezintă un număr valid. + + + This file is not a valid image. + Acest fișier nu este o imagine validă. + + + This value is not a valid IP address. + Această valoare nu este o adresă de IP validă. + + + This value is not a valid language. + Această valoare nu reprezintă o limbă corectă. + + + This value is not a valid locale. + Această valoare nu este o localizare validă. + + + This value is not a valid country. + Această valoare nu este o țară validă. + + + This value is already used. + Această valoare este folosită deja. + + + The size of the image could not be detected. + Mărimea imaginii nu a putut fi detectată. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Lățimea imaginii este prea mare ({{ width }}px). Lățimea maximă permisă este de {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Lățimea imaginii este prea mică ({{ width }}px). Lățimea minimă permisă este de {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Înălțimea imaginii este prea mare ({{ height }}px). Înălțimea maximă permisă este de {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Înălțimea imaginii este prea mică ({{ height }}px). Înălțimea minimă permisă este de {{ min_height }}px. + + + This value should be the user's current password. + Această valoare trebuie să fie parola curentă a utilizatorului. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Această valoare trebuie să conțină exact {{ limit }} caracter.|Această valoare trebuie să conțină exact {{ limit }} caractere. + + + The file was only partially uploaded. + Fișierul a fost încărcat parțial. + + + No file was uploaded. + Nu a fost încărcat niciun fișier. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Nu a fost configurat niciun folder temporar în php.ini, sau folderul configurat nu există. + + + Cannot write temporary file to disk. + Nu a fost posibilă scrierea fișierului temporar pe disk. + + + A PHP extension caused the upload to fail. + O extensie PHP a cauzat eșecul încărcării. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Această colecție trebuie să conțină cel puțin {{ limit }} element.|Această colecție trebuie să conțină cel puțin {{ limit }} elemente. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Această colecție trebuie să conțină cel mult {{ limit }} element.|Această colecție trebuie să conțină cel mult {{ limit }} elemente. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Această colecție trebuie să conțină exact {{ limit }} element.|Această colecție trebuie să conțină exact {{ limit }} elemente. + + + Invalid card number. + Numărul cardului este invalid. + + + Unsupported card type or invalid card number. + Tipul sau numărul cardului sunt invalide. + + + This value is not a valid International Bank Account Number (IBAN). + Această valoare nu este un Număr de Cont Bancar Internațional (IBAN) valid. + + + This value is not a valid ISBN-10. + Această valoare nu este un cod ISBN-10 valid. + + + This value is not a valid ISBN-13. + Această valoare nu este un cod ISBN-13 valid. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Această valoare nu este un cod ISBN-10 sau ISBN-13 valid. + + + This value is not a valid ISSN. + Această valoare nu este un cod ISSN valid. + + + This value is not a valid currency. + Această valoare nu este o monedă validă. + + + This value should be equal to {{ compared_value }}. + Această valoare trebuie să fie egală cu {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Această valoare trebuie să fie mai mare decât {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Această valoare trebuie să fie mai mare sau egală cu {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Această valoare trebuie să fie identică cu {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Această valoare trebuie să fie mai mică decât {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Această valoare trebuie să fie mai mică sau egală cu {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Această valoare nu trebuie să fie egală cu {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Această valoare nu trebuie să fie identică cu {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Raportul imaginii este prea mare ({{ ratio }}). Raportul maxim permis este {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Raportul imaginii este prea mic ({{ ratio }}). Raportul minim permis este {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Imaginea este pătrată ({{ width }}x{{ height }}px). Imaginile pătrate nu sunt permise. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Imaginea are orientarea orizontală ({{ width }}x{{ height }}px). Imaginile cu orientare orizontală nu sunt permise. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Imaginea are orientarea portret ({{ width }}x{{ height }}px). Imaginile cu orientare portret nu sunt permise. + + + An empty file is not allowed. + Nu se permite un fișier gol. + + + The host could not be resolved. + Host-ul nu a putut fi rezolvat. + + + This value does not match the expected {{ charset }} charset. + Această valoare nu corespunde setului de caractere {{ charset }} așteptat. + + + This value is not a valid Business Identifier Code (BIC). + Această valoare nu este un Cod de Identificare a Afacerilor (BIC) valid. + + + Error + Eroare + + + This value is not a valid UUID. + Această valoare nu este un UUID valid. + + + This value should be a multiple of {{ compared_value }}. + Această valoare trebuie să fie un multiplu de {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Codul BIC (Business Identifier Code) nu este asociat cu codul IBAN {{ iban }}. + + + This value should be valid JSON. + Această valoare trebuie să fie un JSON valid. + + + This collection should contain only unique elements. + Această colecție ar trebui să conțină numai elemente unice. + + + This value should be positive. + Această valoare ar trebui să fie pozitivă. + + + This value should be either positive or zero. + Această valoare trebuie să fie pozitivă sau zero. + + + This value should be negative. + Această valoare ar trebui să fie negativă. + + + This value should be either negative or zero. + Această valoare trebuie să fie negativă sau zero. + + + This value is not a valid timezone. + Această valoare nu este un fus orar valid. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Această parolă a fost compromisă și nu poate fi utilizată. Vă rugăm să utilizați o altă parolă. + + + This value should be between {{ min }} and {{ max }}. + Această valoare trebuie să fie între {{ min }} și {{ max }}. + + + This value is not a valid hostname. + Această valoare nu este un hostname valid. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Numărul de elemente din această colecție ar trebui să fie un multiplu de {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Această valoare trebuie să îndeplinească cel puțin una dintre următoarele condiții: + + + Each element of this collection should satisfy its own set of constraints. + Fiecare element din acest set ar trebui să îndeplinească propriul set de condiții. + + + This value is not a valid International Securities Identification Number (ISIN). + Această valoare nu este un număr internațional de identificare (ISIN) valabil. + + + This value should be a valid expression. + Această valoare ar trebui să fie o expresie validă. + + + This value is not a valid CSS color. + Această valoare nu este o culoare CSS validă. + + + This value is not a valid CIDR notation. + Această valoare nu este o notație CIDR validă. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Valoarea măștii de rețea trebuie să fie între {{ min }} și {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Denumirea fișierului este prea lungă. Trebuie să conțină {{ filename_max_length }} caracter sau mai puțin.|Denumirea fișierului este prea lungă. Trebuie să conțină {{ filename_max_length }} caractere sau mai puține. + + + The password strength is too low. Please use a stronger password. + Complexitatea parolei este prea mică. Vă rugăm să folosiți o parolă mai puternică. + + + This value contains characters that are not allowed by the current restriction-level. + Această valoare conține caractere care nu sunt premise de nivelul de restricționare curent. + + + Using invisible characters is not allowed. + Folosirea caracterelor invizibile nu este permisă. + + + Mixing numbers from different scripts is not allowed. + Combinarea numerelor din diferite script-uri nu este permisă. + + + Using hidden overlay characters is not allowed. + Folosirea caracterelor ascunse nu este permisă. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Extensia fișierului este invalidă ({{ extension }}). Extensiile permise sunt {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Codificarea caracterelor detectate este invalidă ({{ detected }}). Codificările permise sunt {{ encodings }}. + + + This value is not a valid MAC address. + Această valoare nu este o adresă MAC validă. + + + This URL is missing a top-level domain. + Acestui URL îi lipsește un domeniu de nivel superior. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Această valoare este prea scurtă. Trebuie să conțină cel puțin un cuvânt.|Această valoare este prea scurtă. Trebuie să conțină cel puțin {{ min }} cuvinte. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Această valoare este prea lungă. Trebuie să conțină un singur cuvânt.|Această valoare este prea lungă. Trebuie să conțină cel mult {{ max }} cuvinte. + + + This value does not represent a valid week in the ISO 8601 format. + Această valoare nu reprezintă o săptămână validă în formatul ISO 8601. + + + This value is not a valid week. + Această valoare nu este o săptămână validă. + + + This value should not be before week "{{ min }}". + Această valoare nu trebuie să fie înainte de săptămâna "{{ min }}". + + + This value should not be after week "{{ max }}". + Această valoare nu trebuie să fie după săptămâna "{{ max }}". + + + This value is not a valid Twig template. + Această valoare nu este un șablon Twig valid. + + + This file is not a valid video. + Acest fișier nu este un videoclip valid. + + + The size of the video could not be detected. + Dimensiunea videoclipului nu a putut fi detectată. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Lățimea videoclipului este prea mare ({{ width }}px). Lățimea maximă permisă este {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Lățimea videoclipului este prea mică ({{ width }}px). Lățimea minimă așteptată este {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Înălțimea videoclipului este prea mare ({{ height }}px). Înălțimea maximă permisă este {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Înălțimea videoclipului este prea mică ({{ height }}px). Înălțimea minimă așteptată este {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Videoclipul are prea puțini pixeli ({{ pixels }}). Cantitatea minimă așteptată este {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Videoclipul are prea mulți pixeli ({{ pixels }}). Cantitatea maximă așteptată este {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Raportul video este prea mare ({{ ratio }}). Raportul maxim permis este {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Raportul video este prea mic ({{ ratio }}). Raportul minim așteptat este {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Videoclipul este pătrat ({{ width }}x{{ height }}px). Videoclipurile pătrate nu sunt permise. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Videoclipul are orientare peisaj ({{ width }}x{{ height }} px). Videoclipurile în orientare peisaj nu sunt permise. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Videoclipul este în orientare portret ({{ width }}x{{ height }}px). Videoclipurile cu orientare portret nu sunt permise. + + + The video file is corrupted. + Fișierul video este corupt. + + + The video contains multiple streams. Only one stream is allowed. + Videoclipul conține mai multe fluxuri. Doar un singur flux este permis. + + + Unsupported video codec "{{ codec }}". + Codec video nesuportat „{{ codec }}”. + + + Unsupported video container "{{ container }}". + Container video nesuportat "{{ container }}". + + + The image file is corrupted. + Fișierul imagine este corupt. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Imaginea are prea puțini pixeli ({{ pixels }}). Cantitatea minimă așteptată este {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Imaginea are prea mulți pixeli ({{ pixels }}). Cantitatea maximă așteptată este {{ max_pixels }}. + + + This filename does not match the expected charset. + Acest nume de fișier nu corespunde setului de caractere așteptat. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.ru.xlf b/lib/symfony/validator/Resources/translations/validators.ru.xlf new file mode 100644 index 0000000000..5392515def --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.ru.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Значение должно быть ложным. + + + This value should be true. + Значение должно быть истинным. + + + This value should be of type {{ type }}. + Тип значения должен быть {{ type }}. + + + This value should be blank. + Значение должно быть пустым. + + + The value you selected is not a valid choice. + Выбранное Вами значение недопустимо. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Вы должны выбрать хотя бы {{ limit }} вариант.|Вы должны выбрать хотя бы {{ limit }} варианта.|Вы должны выбрать хотя бы {{ limit }} вариантов. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Вы должны выбрать не более чем {{ limit }} вариант.|Вы должны выбрать не более чем {{ limit }} варианта.|Вы должны выбрать не более чем {{ limit }} вариантов. + + + One or more of the given values is invalid. + Одно или несколько заданных значений недопустимо. + + + This field was not expected. + Это поле не ожидалось. + + + This field is missing. + Это поле отсутствует. + + + This value is not a valid date. + Значение не является правильной датой. + + + This value is not a valid datetime. + Значение даты и времени недопустимо. + + + This value is not a valid email address. + Значение адреса электронной почты недопустимо. + + + The file could not be found. + Файл не может быть найден. + + + The file is not readable. + Файл не может быть прочитан. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Файл слишком большой ({{ size }} {{ suffix }}). Максимально допустимый размер {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + MIME-тип файла недопустим ({{ type }}). Допустимы MIME-типы файлов {{ types }}. + + + This value should be {{ limit }} or less. + Значение должно быть {{ limit }} или меньше. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Значение слишком длинное. Должно быть равно {{ limit }} символу или меньше.|Значение слишком длинное. Должно быть равно {{ limit }} символам или меньше.|Значение слишком длинное. Должно быть равно {{ limit }} символам или меньше. + + + This value should be {{ limit }} or more. + Значение должно быть {{ limit }} или больше. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Значение слишком короткое. Должно быть равно {{ limit }} символу или больше.|Значение слишком короткое. Должно быть равно {{ limit }} символам или больше.|Значение слишком короткое. Должно быть равно {{ limit }} символам или больше. + + + This value should not be blank. + Значение не должно быть пустым. + + + This value should not be null. + Значение не должно быть null. + + + This value should be null. + Значение должно быть null. + + + This value is not valid. + Значение недопустимо. + + + This value is not a valid time. + Значение времени недопустимо. + + + This value is not a valid URL. + Значение не является допустимым URL. + + + The two values should be equal. + Оба значения должны быть одинаковыми. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Файл слишком большой. Максимально допустимый размер {{ limit }} {{ suffix }}. + + + The file is too large. + Файл слишком большой. + + + The file could not be uploaded. + Файл не может быть загружен. + + + This value should be a valid number. + Значение должно быть числом. + + + This file is not a valid image. + Файл не является допустимым форматом изображения. + + + This value is not a valid IP address. + Это значение не является действительным IP-адресом. + + + This value is not a valid language. + Значение не является допустимым языком. + + + This value is not a valid locale. + Значение не является допустимой локалью. + + + This value is not a valid country. + Значение не является допустимой страной. + + + This value is already used. + Это значение уже используется. + + + The size of the image could not be detected. + Не удалось определить размер изображения. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ширина изображения слишком велика ({{ width }}px). Максимально допустимая ширина {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ширина изображения слишком мала ({{ width }}px). Минимально допустимая ширина {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Высота изображения слишком велика ({{ height }}px). Максимально допустимая высота {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Высота изображения слишком мала ({{ height }}px). Минимально допустимая высота {{ min_height }}px. + + + This value should be the user's current password. + Значение должно быть текущим паролем пользователя. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Значение должно быть равно {{ limit }} символу.|Значение должно быть равно {{ limit }} символам.|Значение должно быть равно {{ limit }} символам. + + + The file was only partially uploaded. + Файл был загружен только частично. + + + No file was uploaded. + Файл не был загружен. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + В php.ini не была настроена временная папка, или настроенная папка не существует. + + + Cannot write temporary file to disk. + Невозможно записать временный файл на диск. + + + A PHP extension caused the upload to fail. + Расширение PHP вызвало ошибку при загрузке. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Эта коллекция должна содержать {{ limit }} элемент или больше.|Эта коллекция должна содержать {{ limit }} элемента или больше.|Эта коллекция должна содержать {{ limit }} элементов или больше. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Эта коллекция должна содержать {{ limit }} элемент или меньше.|Эта коллекция должна содержать {{ limit }} элемента или меньше.|Эта коллекция должна содержать {{ limit }} элементов или меньше. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Эта коллекция должна содержать ровно {{ limit }} элемент.|Эта коллекция должна содержать ровно {{ limit }} элемента.|Эта коллекция должна содержать ровно {{ limit }} элементов. + + + Invalid card number. + Неверный номер карты. + + + Unsupported card type or invalid card number. + Неподдерживаемый тип или неверный номер карты. + + + This value is not a valid International Bank Account Number (IBAN). + Это значение не является действительным Международным банковским счетом (IBAN). + + + This value is not a valid ISBN-10. + Значение имеет неверный формат ISBN-10. + + + This value is not a valid ISBN-13. + Значение имеет неверный формат ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Значение не соответствует форматам ISBN-10 и ISBN-13. + + + This value is not a valid ISSN. + Значение не соответствует формату ISSN. + + + This value is not a valid currency. + Некорректный формат валюты. + + + This value should be equal to {{ compared_value }}. + Значение должно быть равно {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Значение должно быть больше чем {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Значение должно быть больше или равно {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Значение должно быть идентичным {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Значение должно быть меньше чем {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Значение должно быть меньше или равно {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Значение не должно быть равно {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Значение не должно быть идентичным {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Соотношение сторон изображения слишком велико ({{ ratio }}). Максимальное соотношение сторон {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Соотношение сторон изображения слишком мало ({{ ratio }}). Минимальное соотношение сторон {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Изображение квадратное ({{ width }}x{{ height }}px). Квадратные изображения не разрешены. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Изображение в альбомной ориентации ({{ width }}x{{ height }}px). Изображения в альбомной ориентации не разрешены. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Изображение в портретной ориентации ({{ width }}x{{ height }}px). Изображения в портретной ориентации не разрешены. + + + An empty file is not allowed. + Пустые файлы не разрешены. + + + The host could not be resolved. + Имя хоста не может быть разрешено. + + + This value does not match the expected {{ charset }} charset. + Значение не совпадает с ожидаемой {{ charset }} кодировкой. + + + This value is not a valid Business Identifier Code (BIC). + Это значение не является действительным Бизнес-идентификатором (BIC). + + + Error + Ошибка + + + This value is not a valid UUID. + Это значение не является действительным UUID. + + + This value should be a multiple of {{ compared_value }}. + Значение должно быть кратно {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Данный BIC не связан с IBAN {{ iban }}. + + + This value should be valid JSON. + Значение должно быть корректным JSON. + + + This collection should contain only unique elements. + Эта коллекция должна содержать только уникальные элементы. + + + This value should be positive. + Значение должно быть положительным. + + + This value should be either positive or zero. + Значение должно быть положительным или равным нулю. + + + This value should be negative. + Значение должно быть отрицательным. + + + This value should be either negative or zero. + Значение должно быть отрицательным или равным нулю. + + + This value is not a valid timezone. + Значение не является корректным часовым поясом. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Данный пароль был скомпрометирован в результате утечки данных и не должен быть использован. Пожалуйста, используйте другой пароль. + + + This value should be between {{ min }} and {{ max }}. + Значение должно быть между {{ min }} и {{ max }}. + + + This value is not a valid hostname. + Значение не является корректным именем хоста. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Количество элементов в этой коллекции должно быть кратным {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Значение должно удовлетворять как минимум одному из следующих ограничений: + + + Each element of this collection should satisfy its own set of constraints. + Каждый элемент этой коллекции должен удовлетворять своему собственному набору ограничений. + + + This value is not a valid International Securities Identification Number (ISIN). + Значение не является корректным международным идентификационным номером ценных бумаг (ISIN). + + + This value should be a valid expression. + Это значение должно быть корректным выражением. + + + This value is not a valid CSS color. + Значение не является корректным CSS цветом. + + + This value is not a valid CIDR notation. + Значение не соответствует нотации CIDR. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Значение маски подсети должно быть от {{ min }} до {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Имя файла слишком длинное. Оно должно содержать {{ filename_max_length }} символ или меньше.|Имя файла слишком длинное. Оно должно содержать {{ filename_max_length }} символа или меньше.|Имя файла слишком длинное. Оно должно содержать {{ filename_max_length }} символов или меньше. + + + The password strength is too low. Please use a stronger password. + Слишком низкая надёжность пароля. Пожалуйста, используйте более надёжный пароль. + + + This value contains characters that are not allowed by the current restriction-level. + Значение содержит символы, запрещённые на текущем уровне ограничений. + + + Using invisible characters is not allowed. + Использование невидимых символов запрещено. + + + Mixing numbers from different scripts is not allowed. + Смешивание номеров из разных сценариев запрещено. + + + Using hidden overlay characters is not allowed. + Использование невидимых символов наложения запрещено. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Недопустимое расширение файла ({{ extension }}). Разрешенные расширения: {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Обнаруженная кодировка символов недопустима ({{ detected }}). Разрешенные кодировки: {{ encodings }}. + + + This value is not a valid MAC address. + Это значение не является действительным MAC-адресом. + + + This URL is missing a top-level domain. + В этом URL отсутствует домен верхнего уровня. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Это значение слишком короткое. Оно должно содержать как минимум одно слово.|Это значение слишком короткое. Оно должно содержать как минимум {{ min }} слова.|Это значение слишком короткое. Оно должно содержать как минимум {{ min }} слов. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Это значение слишком длинное. Оно должно содержать только одно слово.|Это значение слишком длинное. Оно должно содержать {{ max }} слова или меньше.|Это значение слишком длинное. Оно должно содержать {{ max }} слов или меньше. + + + This value does not represent a valid week in the ISO 8601 format. + Это значение не представляет допустимую неделю в формате ISO 8601. + + + This value is not a valid week. + Это значение не является допустимой неделей. + + + This value should not be before week "{{ min }}". + Это значение не должно быть раньше недели "{{ min }}". + + + This value should not be after week "{{ max }}". + Это значение не должно быть после недели "{{ max }}". + + + This value is not a valid Twig template. + Это значение не является корректным шаблоном Twig. + + + This file is not a valid video. + Этот файл не является корректным видео. + + + The size of the video could not be detected. + Не удалось определить размер видео. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ширина видео слишком велика ({{ width }}px). Максимально допустимая ширина {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ширина видео слишком мала ({{ width }}px). Минимально допустимая ширина {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Высота видео слишком велика ({{ height }}px). Максимально допустимая высота {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Высота видео слишком мала ({{ height }}px). Минимально допустимая высота {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + В видео слишком мало пикселей ({{ pixels }} пикселей). Минимально допустимое количество {{ min_pixels }} пикселей. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + В видео слишком много пикселей ({{ pixels }} пикселей). Максимально допустимое количество {{ max_pixels }} пикселей. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Соотношение сторон видео слишком велико ({{ ratio }}). Максимально допустимое соотношение {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Соотношение сторон видео слишком мало ({{ ratio }}). Минимально допустимое соотношение {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Видео квадратное ({{ width }}x{{ height }}px). Квадратные видео не разрешены. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Видео в альбомной ориентации ({{ width }}x{{ height }}px). Видео в альбомной ориентации не разрешены. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Видео в портретной ориентации ({{ width }}x{{ height }}px). Видео в портретной ориентации не разрешены. + + + The video file is corrupted. + Видеофайл повреждён. + + + The video contains multiple streams. Only one stream is allowed. + Видео содержит несколько потоков. Разрешён только один поток. + + + Unsupported video codec "{{ codec }}". + Неподдерживаемый видеокодек «{{ codec }}». + + + Unsupported video container "{{ container }}". + Неподдерживаемый видеоконтейнер «{{ container }}». + + + The image file is corrupted. + Файл изображения повреждён. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + В изображении слишком мало пикселей ({{ pixels }} пикселей). Минимально допустимое количество {{ min_pixels }} пикселей. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + В изображении слишком много пикселей ({{ pixels }} пикселей). Максимально допустимое количество {{ max_pixels }} пикселей. + + + This filename does not match the expected charset. + Это имя файла не соответствует ожидаемой кодировке. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.sk.xlf b/lib/symfony/validator/Resources/translations/validators.sk.xlf new file mode 100644 index 0000000000..e795213213 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.sk.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Táto hodnota by mala byť nastavená na false. + + + This value should be true. + Táto hodnota by mala byť nastavená na true. + + + This value should be of type {{ type }}. + Táto hodnota by mala byť typu {{ type }}. + + + This value should be blank. + Táto hodnota by mala byť prázdna. + + + The value you selected is not a valid choice. + Táto hodnota by mala byť jednou z poskytnutých možností. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Mali by ste vybrať minimálne {{ limit }} možnosť.|Mali by ste vybrať minimálne {{ limit }} možnosti.|Mali by ste vybrať minimálne {{ limit }} možností. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Mali by ste vybrať najviac {{ limit }} možnosť.|Mali by ste vybrať najviac {{ limit }} možnosti.|Mali by ste vybrať najviac {{ limit }} možností. + + + One or more of the given values is invalid. + Niektoré z uvedených hodnôt sú neplatné. + + + This field was not expected. + Toto pole sa neočakáva. + + + This field is missing. + Toto pole chýba. + + + This value is not a valid date. + Tato hodnota nemá platný formát dátumu. + + + This value is not a valid datetime. + Táto hodnota nemá platný formát dátumu a času. + + + This value is not a valid email address. + Táto hodnota nie je platná emailová adresa. + + + The file could not be found. + Súbor sa nenašiel. + + + The file is not readable. + Súbor nie je čitateľný. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Súbor je príliš veľký ({{ size }} {{ suffix }}). Maximálna povolená veľkosť je {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Súbor typu ({{ type }}) nie je podporovaný. Podporované typy sú {{ types }}. + + + This value should be {{ limit }} or less. + Táto hodnota by mala byť {{ limit }} alebo menej. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Táto hodnota obsahuje viac znakov ako je povolené. Mala by obsahovať najviac {{ limit }} znak.|Táto hodnota obsahuje viac znakov ako je povolené. Mala by obsahovať najviac {{ limit }} znaky.|Táto hodnota obsahuje viac znakov ako je povolené. Mala by obsahovať najviac {{ limit }} znakov. + + + This value should be {{ limit }} or more. + Táto hodnota by mala byť viac ako {{ limit }}. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Táto hodnota je príliš krátka. Musí obsahovať minimálne {{ limit }} znak.|Táto hodnota je príliš krátka. Musí obsahovať minimálne {{ limit }} znaky.|Táto hodnota je príliš krátka. Minimálny počet znakov je {{ limit }}. + + + This value should not be blank. + Táto hodnota by mala byť vyplnená. + + + This value should not be null. + Táto hodnota by nemala byť null. + + + This value should be null. + Táto hodnota by mala byť null. + + + This value is not valid. + Táto hodnota nie je platná. + + + This value is not a valid time. + Tato hodnota nemá správny formát času. + + + This value is not a valid URL. + Táto hodnota nie je platnou URL adresou. + + + The two values should be equal. + Tieto dve hodnoty by mali byť rovnaké. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Súbor je príliš veľký. Maximálna povolená veľkosť je {{ limit }} {{ suffix }}. + + + The file is too large. + Súbor je príliš veľký. + + + The file could not be uploaded. + Súbor sa nepodarilo nahrať. + + + This value should be a valid number. + Táto hodnota by mala byť číslo. + + + This file is not a valid image. + Tento súbor nie je obrázok. + + + This value is not a valid IP address. + Táto hodnota nie je platná IP adresa. + + + This value is not a valid language. + Tento jazyk neexistuje. + + + This value is not a valid locale. + Táto lokalizácia neexistuje. + + + This value is not a valid country. + Táto krajina neexistuje. + + + This value is already used. + Táto hodnota sa už používa. + + + The size of the image could not be detected. + Nepodarilo sa zistiť rozmery obrázku. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Obrázok je príliš široký ({{ width }}px). Maximálna povolená šírka obrázku je {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Obrázok je príliš úzky ({{ width }}px). Minimálna šírka obrázku by mala byť {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Obrázok je príliš vysoký ({{ height }}px). Maximálna povolená výška obrázku je {{ max_height }}px.]]> + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Obrázok je príliš nízky ({{ height }}px). Minimálna výška obrázku by mala byť {{ min_height }}px. + + + This value should be the user's current password. + Táto hodnota by mala byť aktuálne heslo používateľa. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Táto hodnota by mala mať presne {{ limit }} znak.|Táto hodnota by mala mať presne {{ limit }} znaky.|Táto hodnota by mala mať presne {{ limit }} znakov. + + + The file was only partially uploaded. + Bola nahraná len časť súboru. + + + No file was uploaded. + Žiadny súbor nebol nahraný. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + V php.ini nie je nastavený žiadny dočasný adresár, alebo nastavený adresár neexistuje. + + + Cannot write temporary file to disk. + Dočasný súbor sa nepodarilo zapísať na disk. + + + A PHP extension caused the upload to fail. + Rozšírenie PHP zabránilo nahraniu súboru. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Táto kolekcia by mala obsahovať aspoň {{ limit }} prvok alebo viac.|Táto kolekcia by mala obsahovať aspoň {{ limit }} prvky alebo viac.|Táto kolekcia by mala obsahovať aspoň {{ limit }} prvkov alebo viac. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Táto kolekcia by mala maximálne {{ limit }} prvok.|Táto kolekcia by mala obsahovať maximálne {{ limit }} prvky.|Táto kolekcia by mala obsahovať maximálne {{ limit }} prvkov. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Táto kolekcia by mala obsahovať presne {{ limit }} prvok.|Táto kolekcia by mala obsahovať presne {{ limit }} prvky.|Táto kolekcia by mala obsahovať presne {{ limit }} prvkov. + + + Invalid card number. + Neplatné číslo karty. + + + Unsupported card type or invalid card number. + Nepodporovaný typ karty alebo neplatné číslo karty. + + + This value is not a valid International Bank Account Number (IBAN). + Táto hodnota nie je platným Medzinárodným bankovým číslom účtu (IBAN). + + + This value is not a valid ISBN-10. + Táto hodnota je neplatné ISBN-10. + + + This value is not a valid ISBN-13. + Táto hodnota je neplatné ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Táto hodnota nie je platné ISBN-10 ani ISBN-13. + + + This value is not a valid ISSN. + Táto hodnota nie je platné ISSN. + + + This value is not a valid currency. + Táto hodnota nie je platná mena. + + + This value should be equal to {{ compared_value }}. + Táto hodnota by mala byť rovná {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Táto hodnota by mala byť väčšia ako {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Táto hodnota by mala byť väčšia alebo rovná {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Táto hodnota by mala byť typu {{ compared_value_type }} a zároveň by mala byť rovná {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Táto hodnota by mala byť menšia ako {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Táto hodnota by mala byť menšia alebo rovná {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Táto hodnota by nemala byť rovná {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Táto hodnota by nemala byť typu {{ compared_value_type }} a zároveň by nemala byť rovná {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Pomer strán obrázku je príliš veľký ({{ ratio }}). Maximálny povolený pomer strán obrázku je {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Pomer strán obrázku je príliš malý ({{ ratio }}). Minimálny povolený pomer strán obrázku je {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Strany obrázku sú štvorcové ({{ width }}x{{ height }}px). Štvorcové obrázky nie sú povolené. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Obrázok je orientovaný na šírku ({{ width }}x{{ height }}px). Obrázky orientované na šírku nie sú povolené. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Obrázok je orientovaný na výšku ({{ width }}x{{ height }}px). Obrázky orientované na výšku nie sú povolené. + + + An empty file is not allowed. + Súbor nesmie byť prázdny. + + + The host could not be resolved. + Hostiteľa nebolo možné rozpoznať. + + + This value does not match the expected {{ charset }} charset. + Táto hodnota nezodpovedá očakávanej znakovej sade {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Táto hodnota nie je platným Obchodným identifikačným kódom (BIC). + + + Error + Chyba + + + This value is not a valid UUID. + Táto hodnota nie je platné UUID. + + + This value should be a multiple of {{ compared_value }}. + Táto hodnota by mala byť násobkom {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Tento identifikačný kód podniku (BIC) nie je spojený s IBAN {{ iban }}. + + + This value should be valid JSON. + Táto hodnota by mala byť platný JSON. + + + This collection should contain only unique elements. + Táto kolekcia by mala obsahovať len unikátne prvky. + + + This value should be positive. + Táto hodnota by mala byť kladná. + + + This value should be either positive or zero. + Táto hodnota by mala byť kladná alebo nulová. + + + This value should be negative. + Táto hodnota by mala byť záporná. + + + This value should be either negative or zero. + Táto hodnota by mala byť záporná alebo nulová. + + + This value is not a valid timezone. + Táto hodnota nie je platné časové pásmo. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Toto heslo uniklo pri narušení ochrany dát, nie je možné ho použiť. Prosím, použite iné heslo. + + + This value should be between {{ min }} and {{ max }}. + Táto hodnota by mala byť medzi {{ min }} a {{ max }}. + + + This value is not a valid hostname. + Táto hodnota nie je platný hostname. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Počet prvkov v tejto kolekcii musí byť násobok {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Táto hodnota musí spĺňať aspoň jedno z nasledujúcich obmedzení: + + + Each element of this collection should satisfy its own set of constraints. + Každý prvok v tejto kolekcii musí spĺňať svoje vlastné obmedzenia. + + + This value is not a valid International Securities Identification Number (ISIN). + Táto hodnota nie je platné medzinárodné označenie cenného papiera (ISIN). + + + This value should be a valid expression. + Táto hodnota by mala byť platným výrazom. + + + This value is not a valid CSS color. + Táto hodnota nie je platná CSS farba. + + + This value is not a valid CIDR notation. + Táto hodnota nie je platnou notáciou CIDR. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Hodnota masky siete by mala byť medzi {{ min }} a {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Názov súboru je príliš dlhý. Mal by mať {{ filename_max_length }} znak alebo menej.|Názov súboru je príliš dlhý. Mal by mať {{ filename_max_length }} znaky alebo menej.|Názov súboru je príliš dlhý. Mal by mať {{ filename_max_length }} znakov alebo menej. + + + The password strength is too low. Please use a stronger password. + Sila hesla je príliš nízka. Použite silnejšie heslo. + + + This value contains characters that are not allowed by the current restriction-level. + Táto hodnota obsahuje znaky, ktoré nie sú povolené aktuálnou úrovňou obmedzenia. + + + Using invisible characters is not allowed. + Používanie neviditeľných znakov nie je povolené. + + + Mixing numbers from different scripts is not allowed. + Miešanie čísel z rôznych skriptov nie je povolené. + + + Using hidden overlay characters is not allowed. + Používanie skrytých prekryvných znakov nie je povolené. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Prípona súboru je neplatná ({{ extension }}). Povolené prípony sú {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Zistené kódovanie znakov je neplatné ({{ detected }}). Povolené kódovania sú {{ encodings }}. + + + This value is not a valid MAC address. + Táto hodnota nie je platnou MAC adresou. + + + This URL is missing a top-level domain. + Tejto URL chýba doména najvyššej úrovne. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Táto hodnota je príliš krátka. Mala by obsahovať aspoň jedno slovo.|Táto hodnota je príliš krátka. Mala by obsahovať aspoň {{ min }} slov. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Táto hodnota je príliš dlhá. Mala by obsahovať len jedno slovo.|Táto hodnota je príliš dlhá. Mala by obsahovať {{ max }} slov alebo menej. + + + This value does not represent a valid week in the ISO 8601 format. + Táto hodnota nepredstavuje platný týždeň vo formáte ISO 8601. + + + This value is not a valid week. + Táto hodnota nie je platný týždeň. + + + This value should not be before week "{{ min }}". + Táto hodnota by nemala byť pred týždňom "{{ min }}". + + + This value should not be after week "{{ max }}". + Táto hodnota by nemala byť po týždni "{{ max }}". + + + This value is not a valid Twig template. + Táto hodnota nie je platnou Twig šablónou. + + + This file is not a valid video. + Tento súbor nie je platné video. + + + The size of the video could not be detected. + Veľkosť videa sa nepodarilo zistiť. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Šírka videa je príliš veľká ({{ width }}px). Povolená maximálna šírka je {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Šírka videa je príliš malá ({{ width }}px). Očakávaná minimálna šírka je {{ min_width }} px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Výška videa je príliš veľká ({{ height }}px). Povolená maximálna výška je {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Výška videa je príliš malá ({{ height }}px). Očakávaná minimálna výška je {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Video má príliš málo pixelov ({{ pixels }}). Očakávané minimálne množstvo je {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Video má príliš veľa pixelov ({{ pixels }}). Očakávané maximálne množstvo je {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Pomer strán videa je príliš veľký ({{ ratio }}). Povolený maximálny pomer strán je {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Pomer strán videa je príliš malý ({{ ratio }}). Očakávaný minimálny pomer strán je {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video je štvorcové ({{ width }}x{{ height }}px). Štvorcové videá nie sú povolené. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video je orientované na šírku ({{ width }}x{{ height }} px). Videá orientované na šírku nie sú povolené. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video je orientované na výšku ({{ width }}x{{ height }}px). Videá orientované na výšku nie sú povolené. + + + The video file is corrupted. + Videosúbor je poškodený. + + + The video contains multiple streams. Only one stream is allowed. + Video obsahuje viacero tokov. Povolený je len jeden tok. + + + Unsupported video codec "{{ codec }}". + Nepodporovaný videokodek "{{ codec }}". + + + Unsupported video container "{{ container }}". + Nepodporovaný kontajner videa "{{ container }}". + + + The image file is corrupted. + Súbor obrázka je poškodený. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Obrázok má príliš málo pixelov ({{ pixels }}). Očakávané minimálne množstvo je {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Obrázok má príliš veľa pixelov ({{ pixels }}). Očakávané maximálne množstvo je {{ max_pixels }}. + + + This filename does not match the expected charset. + Tento názov súboru nezodpovedá očakávanej znakovej sade. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.sl.xlf b/lib/symfony/validator/Resources/translations/validators.sl.xlf new file mode 100644 index 0000000000..515e5d0aaf --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.sl.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Vrednost bi morala biti nepravilna (false). + + + This value should be true. + Vrednost bi morala biti pravilna (true). + + + This value should be of type {{ type }}. + Vrednost mora biti naslednjega tipa {{ type }}. + + + This value should be blank. + Vrednost mora biti prazna. + + + The value you selected is not a valid choice. + Vrednost, ki ste jo izbrali, ni veljavna možnost. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Izbrati morate vsaj {{ limit }} možnost.|Izbrati morate vsaj {{ limit }} možnosti.|Izbrati morate vsaj {{ limit }} možnosti.|Izbrati morate vsaj {{ limit }} možnosti. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Izberete lahko največ {{ limit }} možnost.|Izberete lahko največ {{ limit }} možnosti.|Izberete lahko največ {{ limit }} možnosti.|Izberete lahko največ {{ limit }} možnosti. + + + One or more of the given values is invalid. + Ena ali več podanih vrednosti ni veljavnih. + + + This field was not expected. + To polje ni bilo pričakovati. + + + This field is missing. + To polje manjka. + + + This value is not a valid date. + Ta vrednost ni veljaven datum. + + + This value is not a valid datetime. + Ta vrednost ni veljaven datum in čas. + + + This value is not a valid email address. + Ta vrednost ni veljaven e-poštni naslov. + + + The file could not be found. + Datoteke ni mogoče najti. + + + The file is not readable. + Datoteke ni mogoče prebrati. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Datoteka je prevelika ({{ size }} {{ suffix }}). Največja dovoljena velikost je {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mime tip datoteke je neveljaven ({{ type }}). Dovoljeni mime tipi so {{ types }}. + + + This value should be {{ limit }} or less. + Ta vrednost bi morala biti {{ limit }} ali manj. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Ta vrednost je predolga. Morala bi imeti {{ limit }} znak ali manj.|Ta vrednost je predolga. Morala bi imeti {{ limit }} znaka ali manj.|Ta vrednost je predolga. Morala bi imeti {{ limit }} znake ali manj.|Ta vrednost je predolga. Morala bi imeti {{ limit }} znakov ali manj. + + + This value should be {{ limit }} or more. + Ta vrednost bi morala biti {{ limit }} ali več. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Ta vrednost je prekratka. Morala bi imeti {{ limit }} znak ali več.|Ta vrednost je prekratka. Morala bi imeti {{ limit }} znaka ali več.|Ta vrednost je prekratka. Morala bi imeti {{ limit }} znake ali več.|Ta vrednost je prekratka. Morala bi imeti {{ limit }} znakov ali več. + + + This value should not be blank. + Ta vrednost ne bi smela biti prazna. + + + This value should not be null. + Ta vrednost ne bi smela biti nedefinirana (null). + + + This value should be null. + Ta vrednost bi morala biti nedefinirana (null). + + + This value is not valid. + Ta vrednost ni veljavna. + + + This value is not a valid time. + Ta vrednost ni veljaven čas. + + + This value is not a valid URL. + Ta vrednost ni veljaven URL. + + + The two values should be equal. + Ti dve vrednosti bi morali biti enaki. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Datoteka je prevelika. Največja dovoljena velikost je {{ limit }} {{ suffix }}. + + + The file is too large. + Datoteka je prevelika. + + + The file could not be uploaded. + Datoteke ni bilo mogoče naložiti. + + + This value should be a valid number. + Ta vrednost bi morala biti veljavna številka. + + + This file is not a valid image. + Ta datoteka ni veljavna slika. + + + This value is not a valid IP address. + Ta vrednost ni veljaven IP naslov. + + + This value is not a valid language. + Ta vrednost ni veljaven jezik. + + + This value is not a valid locale. + Ta vrednost ni veljavna lokalnost. + + + This value is not a valid country. + Ta vrednost ni veljavna država. + + + This value is already used. + Ta vrednost je že uporabljena. + + + The size of the image could not be detected. + Velikosti slike ni bilo mogoče zaznati. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Širina slike je preširoka ({{ width }}px). Največja dovoljena širina je {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Širina slike je premajhna ({{ width }}px). Najmanjša predvidena širina je {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Višina slike je prevelika ({{ height }}px). Največja dovoljena višina je {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Višina slike je premajhna ({{ height }}px). Najmanjša predvidena višina je {{ min_height }}px. + + + This value should be the user's current password. + Ta vrednost bi morala biti trenutno uporabnikovo geslo. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ta vrednost bi morala imeti točno {{ limit }} znak.|Ta vrednost bi morala imeti točno {{ limit }} znaka.|Ta vrednost bi morala imeti točno {{ limit }} znake.|Ta vrednost bi morala imeti točno {{ limit }} znakov. + + + The file was only partially uploaded. + Datoteka je bila le delno naložena. + + + No file was uploaded. + Nobena datoteka ni bila naložena. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + V php.ini ni bila nastavljena začasna mapa, ali pa nastavljena mapa ne obstaja. + + + Cannot write temporary file to disk. + Začasne datoteke ni bilo mogoče zapisati na disk. + + + A PHP extension caused the upload to fail. + PHP razširitev je vzrok, da nalaganje ni uspelo. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ta zbirka bi morala vsebovati {{ limit }} element ali več.|Ta zbirka bi morala vsebovati {{ limit }} elementa ali več.|Ta zbirka bi morala vsebovati {{ limit }} elemente ali več.|Ta zbirka bi morala vsebovati {{ limit }} elementov ali več. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ta zbirka bi morala vsebovati {{ limit }} element ali manj.|Ta zbirka bi morala vsebovati {{ limit }} elementa ali manj.|Ta zbirka bi morala vsebovati {{ limit }} elemente ali manj.|Ta zbirka bi morala vsebovati {{ limit }} elementov ali manj. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ta zbirka bi morala vsebovati točno {{ limit }} element.|Ta zbirka bi morala vsebovati točno {{ limit }} elementa.|Ta zbirka bi morala vsebovati točno {{ limit }} elemente.|Ta zbirka bi morala vsebovati točno {{ limit }} elementov. + + + Invalid card number. + Neveljavna številka kartice. + + + Unsupported card type or invalid card number. + Nepodprti tip kartice ali neveljavna številka kartice. + + + This value is not a valid International Bank Account Number (IBAN). + Ta vrednost ni veljavna mednarodna številka bančnega računa (IBAN). + + + This value is not a valid ISBN-10. + Neveljavna vrednost po ISBN-10. + + + This value is not a valid ISBN-13. + Neveljavna vrednost po ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Neveljavna vrednost po ISBN-10 ali po ISBN-13. + + + This value is not a valid ISSN. + Neveljavna vrednost ISSN. + + + This value is not a valid currency. + Ta vrednost ni veljavna valuta. + + + This value should be equal to {{ compared_value }}. + Ta vrednost bi morala biti enaka {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ta vrednost bi morala biti večja od {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ta vrednost bi morala biti večja ali enaka {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ta vrednost bi morala biti identična {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ta vrednost bi morala biti manjša od {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ta vrednost bi morala biti manjša ali enaka {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ta vrednost ne bi smela biti enaka {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ta vrednost ne bi smela biti identična {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Razmerje slike je preveliko ({{ ratio }}). Največje dovoljeno razmerje je {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Razmerje slike je premajhno ({{ ratio }}). Najmanjše pričakovano razmerje je {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Slika je kvadrat ({{ width }}x{{ height }}px). Kvadratne slike niso dovoljene. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Slika je ležeče usmerjena ({{ width }}x{{ height }}px). Ležeče usmerjene slike niso dovoljene. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Slika je pokončno usmerjena ({{ width }}x{{ height }}px). Pokončno usmerjene slike niso dovoljene. + + + An empty file is not allowed. + Prazna datoteka ni dovoljena. + + + The host could not be resolved. + Gostitelja ni bilo mogoče prepoznati. + + + This value does not match the expected {{ charset }} charset. + Ta vrednost se ne ujema s pričakovanim naborom znakov {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Ta vrednost ni veljavna poslovna identifikacijska koda (BIC). + + + Error + Napaka + + + This value is not a valid UUID. + Ta vrednost ni veljaven UUID. + + + This value should be a multiple of {{ compared_value }}. + Ta vrednost bi morala biti večkratnik od {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Ta poslovna identifikacijska koda (BIC) ni povezana z IBAN {{ iban }}. + + + This value should be valid JSON. + Ta vrednost bi morala biti veljaven JSON. + + + This collection should contain only unique elements. + Ta zbirka bi morala vsebovati samo edinstvene elemente. + + + This value should be positive. + Ta vrednost bi morala biti pozitivna. + + + This value should be either positive or zero. + Ta vrednost bi morala biti pozitivna ali enaka nič. + + + This value should be negative. + Ta vrednost bi morala biti negativna. + + + This value should be either negative or zero. + Ta vrednost bi morala biti negativna ali enaka nič. + + + This value is not a valid timezone. + Ta vrednost ni veljaven časovni pas. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + To geslo je ušlo pri kršitvi varnosti podatkov in ga ne smete uporabljati. Prosimo, uporabite drugo geslo. + + + This value should be between {{ min }} and {{ max }}. + Ta vrednost bi morala biti med {{ min }} in {{ max }}. + + + This value is not a valid hostname. + Ta vrednost ni veljavno ime gostitelja. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Število elementov v tej zbirki bi moralo biti mnogokratnik {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Ta vrednost bi morala zadostiti vsaj eni izmed sledečih omejitev: + + + Each element of this collection should satisfy its own set of constraints. + Vsak element te zbirke bi moral zadostiti svojemu lastnemu naboru omejitev. + + + This value is not a valid International Securities Identification Number (ISIN). + Ta vrednost ni veljavna mednarodna identifikacijska koda vrednostnih papirjev (ISIN). + + + This value should be a valid expression. + Ta vrednost bi morala biti veljaven izraz. + + + This value is not a valid CSS color. + Ta vrednost ni veljavna barva CSS. + + + This value is not a valid CIDR notation. + Ta vrednost ni veljaven zapis CIDR. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Vrednost omrežne maske mora biti med {{ min }} in {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Ime datoteke je predolgo. Imeti mora {{ filename_max_length }} znak ali manj.|Ime datoteke je predolgo. Imeti mora {{ filename_max_length }} znaka ali manj.|Ime datoteke je predolgo. Imeti mora {{ filename_max_length }} znake ali manj.|Ime datoteke je predolgo. Imeti mora {{ filename_max_length }} znakov ali manj. + + + The password strength is too low. Please use a stronger password. + Moč gesla je prenizka. Uporabite močnejše geslo. + + + This value contains characters that are not allowed by the current restriction-level. + Ta vrednost vsebuje znake, ki jih trenutna raven omejitve ne dovoljuje. + + + Using invisible characters is not allowed. + Uporaba nevidnih znakov ni dovoljena. + + + Mixing numbers from different scripts is not allowed. + Mešanje številk iz različnih skript ni dovoljeno. + + + Using hidden overlay characters is not allowed. + Uporaba skritih prekrivnih znakov ni dovoljena. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Končnica datoteke ni veljavna ({{ extension }}). Dovoljene so naslednje končnice: {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Zaznano kodiranje znakov ni veljavno ({{ detected }}). Dovoljene so naslednje vrste kodiranja {{ encodings }}. + + + This value is not a valid MAC address. + Ta vrednost ni veljaven MAC naslov. + + + This URL is missing a top-level domain. + URL-ju manjka vrhnja domena. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Ta vrednost je prekratka. Vsebovati mora vsaj eno besedo.|Ta vrednost je prekratka. Vsebovati mora vsaj {{ min }} besedi.|Ta vrednost je prekratka. Vsebovati mora vsaj {{ min }} besede.|Ta vrednost je prekratka. Vsebovati mora vsaj {{ min }} besed. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Ta vrednost je predolga. Vsebovati mora največ eno besedo.|Ta vrednost je predolga. Vsebovati mora največ {{ max }}.|Ta vrednost je predolga. Vsebovati mora največ {{ max }} besede.|Ta vrednost je predolga. Vsebovati mora največ {{ max }} besed. + + + This value does not represent a valid week in the ISO 8601 format. + Ta vrednost ne predstavlja veljavnega tedna v ISO 8601 formatu. + + + This value is not a valid week. + Ta vrednost ni veljaven teden. + + + This value should not be before week "{{ min }}". + Ta vrednost ne sme biti pred tednom "{{ min }}". + + + This value should not be after week "{{ max }}". + Ta vrednost ne sme biti po tednu "{{ max }}". + + + This value is not a valid Twig template. + Ta vrednost ni veljavna predloga Twig. + + + This file is not a valid video. + Ta datoteka ni veljaven video. + + + The size of the video could not be detected. + Velikosti videoposnetka ni bilo mogoče zaznati. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Širina videoposnetka je prevelika ({{ width }}px). Dovoljena največja širina je {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Širina videa je premajhna ({{ width }}px). Pričakovana minimalna širina je {{ min_width }} px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Višina videa je prevelika ({{ height }}px). Dovoljena največja višina je {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Višina videa je premajhna ({{ height }}px). Pričakovana najmanjša višina je {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Video ima premalo slikovnih pik ({{ pixels }}). Pričakovana minimalna količina je {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Video ima preveč slikovnih pik ({{ pixels }}). Pričakovano največje število je {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Razmerje videa je preveliko ({{ ratio }}). Dovoljeno največje razmerje je {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Razmerje videa je premajhno ({{ ratio }}). Pričakovano minimalno razmerje je {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video je kvadratno ({{ width }}x{{ height }}px). Kvadratni videoposnetki niso dovoljeni. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video je vodoravno orientiran ({{ width }}x{{ height }} px). Vodoravni videi niso dovoljeni. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video je usmerjeno pokonci ({{ width }}x{{ height }}px). Videi v pokončni usmeritvi niso dovoljeni. + + + The video file is corrupted. + Videodatoteka je poškodovana. + + + The video contains multiple streams. Only one stream is allowed. + Video vsebuje več tokov. Dovoljen je le en tok. + + + Unsupported video codec "{{ codec }}". + Nepodprti video kodek »{{ codec }}«. + + + Unsupported video container "{{ container }}". + Nepodprt videokontejner "{{ container }}". + + + The image file is corrupted. + Slikovna datoteka je poškodovana. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Slika ima premalo slikovnih točk ({{ pixels }}). Pričakovana minimalna količina je {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Slika ima preveč slikovnih pik ({{ pixels }}). Pričakovano največje število je {{ max_pixels }}. + + + This filename does not match the expected charset. + To ime datoteke ne ustreza pričakovanemu naboru znakov. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.sq.xlf b/lib/symfony/validator/Resources/translations/validators.sq.xlf new file mode 100644 index 0000000000..0561705a6b --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.sq.xlf @@ -0,0 +1,568 @@ + + + +
+ + Për fjalët e huaja, të cilat nuk kanë përkthim të drejtpërdrejtë, ju lutemi të ndiqni rregullat e mëposhtme: + a) në rast se emri është akronim i përdorur gjerësisht si i përveçëm, atëherë, emri lakohet pa thonjëza dhe mbaresa shkruhet me vizë ndarëse. Gjinia gjykohet sipas rastit. Shembull: JSON (mashkullore) + b) në rast se emri është akronim i papërdorur gjerësisht si i përveçëm, atëherë, emri lakohet pa thonjëza dhe mbaresa shkruhet me vizë ndarëse. Gjinia është femërore. Shembull: URL (femërore) + c) në rast se emri duhet lakuar për shkak të rasës në fjali, atëherë, emri lakohet pa thonjëza dhe mbaresa shkruhet me vizë ndarëse. Shembull: host-i, prej host-it + d) në rast se emri nuk duhet lakuar për shkak të trajtës në fjali, atëherë, emri rrethote me thonjëzat “”. Shembull: “locale” + +
+ + + This value should be false. + Kjo vlerë duhet të jetë e pavërtetë (false). + + + This value should be true. + Kjo vlerë duhet të jetë e vërtetë (true). + + + This value should be of type {{ type }}. + Kjo vlerë duhet të jetë e llojit {{ type }}. + + + This value should be blank. + Kjo vlerë duhet të jetë e zbrazët. + + + The value you selected is not a valid choice. + Vlera që keni zgjedhur nuk është alternativë e vlefshme. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Duhet të zgjidhni së paku {{ limit }} alternativë.|Duhet të zgjidhni së paku {{ limit }} alternativa. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Duhet të zgjidhni së shumti {{ limit }} alternativë.|Duhet të zgjidhni së shumti {{ limit }} alternativa. + + + One or more of the given values is invalid. + Një apo më shumë nga vlerat e dhëna janë të pavlefshme. + + + This field was not expected. + Kjo fushë nuk pritej. + + + This field is missing. + Kjo fushë mungon. + + + This value is not a valid date. + Kjo vlerë nuk është datë e vlefshme. + + + This value is not a valid datetime. + Kjo vlerë nuk është datë dhe orë e vlefshme. + + + This value is not a valid email address. + Kjo vlerë nuk është email adresë e vlefshme. + + + The file could not be found. + Fajli nuk u gjet. + + + The file is not readable. + Fajli nuk është e lexueshme. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Fajli është shumë e madhe ({{ size }} {{ suffix }}). Madhësia maksimale e lejuar është {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Lloji “mime” i fajlit është i pavlefshëm ({{ type }}). Llojet “mime” të lejuara janë {{ types }}. + + + This value should be {{ limit }} or less. + Kjo vlerë duhet të jetë {{ limit }} ose më pak. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + 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. + + + This value should be {{ limit }} or more. + Kjo vlerë duhet të jetë {{ limit }} ose më shumë. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + 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ë. + + + This value should not be blank. + Kjo vlerë nuk duhet të jetë e zbrazët. + + + This value should not be null. + Kjo vlerë nuk duhet të jetë “null”. + + + This value should be null. + Kjo vlerë duhet të jetë “null”. + + + This value is not valid. + Kjo vlerë nuk është e vlefshme. + + + This value is not a valid time. + Kjo vlerë nuk është një orë e vlefshme. + + + This value is not a valid URL. + Kjo vlerë nuk është URL e vlefshme. + + + The two values should be equal. + Këto dy vlera duhet të jenë të barabarta. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Ky fajl është shumë i madhë. Madhësia maksimale e lejuar është {{ limit }} {{ suffix }}. + + + The file is too large. + Ky fajl është shumë i madhë. + + + The file could not be uploaded. + Ky fajl nuk mund të ngarkohet. + + + This value should be a valid number. + Kjo vlerë duhet të jetë një numër i vlefshëm. + + + This file is not a valid image. + Ky fajl nuk është një imazh i vlefshëm. + + + This value is not a valid IP address. + Kjo vlerë nuk është një adresë IP e vlefshme. + + + This value is not a valid language. + Kjo vlerë nuk është një gjuhë e vlefshme. + + + This value is not a valid locale. + Kjo vlerë nuk është nje “locale” e vlefshme. + + + This value is not a valid country. + Kjo vlerë nuk është një shtet i vlefshëm. + + + This value is already used. + Kjo vlerë është tashmë në përdorim. + + + The size of the image could not be detected. + Madhësia e imazhit nuk mund të zbulohet. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Gjerësia e imazhit është shumë e madhe ({{ width }}px). Gjerësia maksimale e lejuar është {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Gjerësia e imazhit është shumë e vogël ({{ width }}px). Gjerësia minimale e pritur është {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Gjatësia e imazhit është shumë e madhe ({{ height }}px). Gjatësia maksimale e lejuar është {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Gjatësia e imazhit është shumë e vogël ({{ height }}px). Gjatësia minimale e pritur është {{ min_height }}px. + + + This value should be the user's current password. + Kjo vlerë duhet të jetë fjalëkalimi i tanishëm i përdoruesit. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Kjo vlerë duhet të ketë saktësisht {{ limit }} karakter.|Kjo vlerë duhet të ketë saktësisht {{ limit }} karaktere. + + + The file was only partially uploaded. + Ky fajl është ngarkuar pjesërisht. + + + No file was uploaded. + Nuk është ngarkuar ndonjë fajl. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Nuk është konfiguruar asnjë dosje e përkohshëm në php.ini, ose dosja e konfiguruar nuk ekziston. + + + Cannot write temporary file to disk. + Nuk mund të shkruhet fajli e përkohshme në disk. + + + A PHP extension caused the upload to fail. + Një shtojcë PHP shkaktoi dështimin e ngarkimit. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ky koleksion duhet të përmbajë {{ limit }} element ose më shumë.|Ky koleksion duhet të përmbajë {{ limit }} elemente ose më shumë. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ky koleksion duhet të përmbajë {{ limit }} element ose më pak.|Ky koleksion duhet të përmbajë {{ limit }} elemente ose më pak. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ky koleksion duhet të përmbajë saktësisht {{ limit }} element.|Ky koleksion duhet të përmbajë saktësisht {{ limit }} elemente. + + + Invalid card number. + Numër karte i pavlefshëm. + + + Unsupported card type or invalid card number. + Lloji i kartës i papërkrahur ose numër kartës i pavlefshëm. + + + This value is not a valid International Bank Account Number (IBAN). + Kjo vlerë nuk është një Numër Llogarie Bankare Ndërkombëtare (IBAN) i vlefshëm. + + + This value is not a valid ISBN-10. + Kjo vlerë nuk është një ISBN-10 e vlefshme. + + + This value is not a valid ISBN-13. + Kjo vlerë nuk është një ISBN-13 e vlefshme. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Kjo vlerë nuk është as ISBN-10 e vlefshme as ISBN-13 e vlefshme. + + + This value is not a valid ISSN. + Kjo vlerë nuk është një ISSN e vlefshme. + + + This value is not a valid currency. + Kjo vlerë nuk është një valutë e vlefshme. + + + This value should be equal to {{ compared_value }}. + Kjo vlerë duhet të jetë e barabartë me {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Kjo vlerë duhet të jetë më e madhe se {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Kjo vlerë duhet të jetë më e madhe ose e barabartë me {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Kjo vlerë duhet të jetë identike me {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Kjo vlerë duhet të jetë më vogël se {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Kjo vlerë duhet të jetë më e vogël ose e barabartë me {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Kjo vlerë nuk duhet të jetë e barabartë me {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Kjo vlerë nuk duhet të jetë identike me {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Raporti i imazhit është shumë i madh ({{ ratio }}). Raporti maksimal i lejuar është {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Raporti i imazhit është shumë i vogël ({{ ratio }}). Raporti minimal pritet të jetë {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Imazhi është katror ({{ width }}x{{ height }}px). Imazhet katrore nuk janë të lejuara. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Imazhi është i orientuar horizontalisht ({{ width }}x{{ height }}px). Imazhet e orientuara horizontalisht nuk lejohen. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Imazhi është i orientuar vertikalisht ({{ width }}x{{ height }}px). Imazhet orientuara vertikalisht nuk lejohen. + + + An empty file is not allowed. + Një fajl i zbrazët nuk lejohet. + + + The host could not be resolved. + Host-i nuk mund te zbulohej. + + + This value does not match the expected {{ charset }} charset. + Kjo vlerë nuk përputhet me kodifikimin e karaktereve {{ charset }} që pritej. + + + This value is not a valid Business Identifier Code (BIC). + Kjo vlerë nuk është një Kod Identifikues Biznesi (BIC) i vlefshëm. + + + Error + Gabim + + + This value is not a valid UUID. + Kjo vlerë nuk është një UUID e vlefshme. + + + This value should be a multiple of {{ compared_value }}. + Kjo vlerë duhet të jetë një shumëfish i {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Ky Kod Identifikues Biznesi (BIC) nuk është i lidhur me IBAN {{ iban }}. + + + This value should be valid JSON. + Kjo vlerë duhet të jetë JSON i vlefshëm. + + + This collection should contain only unique elements. + Ky koleksion duhet të përmbajë vetëm elementë unikë. + + + This value should be positive. + Kjo vlerë duhet të jetë pozitive. + + + This value should be either positive or zero. + Kjo vlerë duhet të jetë pozitive ose zero. + + + This value should be negative. + Kjo vlerë duhet të jetë negative. + + + This value should be either negative or zero. + Kjo vlerë duhet të jetë negative ose zero. + + + This value is not a valid timezone. + Kjo vlerë nuk është një zonë e vlefshme kohore. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Ky fjalëkalim është zbuluar në një shkelje të të dhënave, nuk duhet të përdoret. Ju lutemi përdorni një fjalëkalim tjetër. + + + This value should be between {{ min }} and {{ max }}. + Kjo vlerë duhet të jetë ndërmjet {{ min }} dhe {{ max }}. + + + This value is not a valid hostname. + Kjo vlerë nuk është një emër i vlefshëm host-i. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Numri i elementeve në këtë koleksion duhet të jetë një shumëfish i {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Kjo vlerë duhet të plotësojë të paktën njërën nga kufizimet e mëposhtme: + + + Each element of this collection should satisfy its own set of constraints. + Secili element i këtij koleksioni duhet të përmbushë kufizimet e veta. + + + This value is not a valid International Securities Identification Number (ISIN). + Kjo vlerë nuk është një numër i vlefshëm identifikues ndërkombëtar i sigurisë (ISIN). + + + This value should be a valid expression. + Kjo vlerë duhet të jetë një shprehje e vlefshme. + + + This value is not a valid CSS color. + Kjo vlerë nuk është një ngjyrë e vlefshme CSS. + + + This value is not a valid CIDR notation. + Kjo vlerë nuk është një shënim i vlefshëm CIDR. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Vlera e maskës së rrjetit duhet të jetë ndërmjet {{ min }} dhe {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Emri i fajlit është shumë i gjatë. Duhet të ketë maksimumi {{ filename_max_length }} karakter ose më pak.|Emri i fajlit është shumë i gjatë. Duhet të ketë maksimumi {{ filename_max_length }} karaktere ose më pak. + + + The password strength is too low. Please use a stronger password. + Fuqia e fjalëkalimit është shumë e ulët. Ju lutemi përdorni një fjalëkalim më të fortë. + + + This value contains characters that are not allowed by the current restriction-level. + Kjo vlerë përmban karaktere që nuk lejohen nga niveli aktual i kufizimit. + + + Using invisible characters is not allowed. + Përdorimi i karaktereve të padukshme nuk lejohet. + + + Mixing numbers from different scripts is not allowed. + Përzierja e numrave nga shkrimet e ndryshme nuk lejohet. + + + Using hidden overlay characters is not allowed. + Përdorimi i karaktereve të mbivendosura të fshehura nuk lejohet. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Shtesa e fajlit është e pavlefshme ({{ extension }}). Shtesat e lejuara janë {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Kodimi i karakterit të identifikuar është i pavlefshëm ({{ detected }}). Kodimet e lejuara janë {{ encodings }}. + + + This value is not a valid MAC address. + Kjo nuk është një adresë e vlefshme e Kontrollit të Qasjes në Media (MAC). + + + This URL is missing a top-level domain. + Kësaj URL-je i mungon një domain i nivelit të sipërm. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Kjo vlerë është shumë e shkurtër. Duhet të përmbajë të paktën një fjalë.|Kjo vlerë është shumë e shkurtër. Duhet të përmbajë të paktën {{ min }} fjalë. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Kjo vlerë është shumë e gjatë. Duhet të përmbajë një fjalë.|Kjo vlerë është shumë e gjatë. Duhet të përmbajë {{ max }} fjalë ose më pak. + + + This value does not represent a valid week in the ISO 8601 format. + Kjo vlerë nuk përfaqëson një javë të vlefshme në formatin ISO 8601. + + + This value is not a valid week. + Kjo vlerë nuk është një javë e vlefshme. + + + This value should not be before week "{{ min }}". + Kjo vlerë nuk duhet të jetë para javës "{{ min }}". + + + This value should not be after week "{{ max }}". + Kjo vlerë nuk duhet të jetë pas javës "{{ max }}". + + + This value is not a valid Twig template. + Kjo vlerë nuk është një shabllon Twig i vlefshëm. + + + This file is not a valid video. + Ky fajl nuk është video e vlefshme. + + + The size of the video could not be detected. + Madhësia e videos nuk mund të zbulohej. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Gjerësia e videos është shumë e madhe ({{ width }}px). Gjerësia maksimale e lejuar është {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Gjerësia e videos është shumë e vogël ({{ width }}px). Gjerësia minimale e pritur është {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Lartësia e videos është shumë e madhe ({{ height }}px). Lartësia maksimale e lejuar është {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Lartësia e videos është shumë e vogël ({{ height }}px). Lartësia minimale e pritur është {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Video ka shumë pak pikselë ({{ pixels }}). Sasia minimale e pritur është {{ min_pixels }}px. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Videoja ka tepër piksele ({{ pixels }}). Sasia maksimale e pritur është {{ max_pixels }}px. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Raporti i videos është shumë i madh ({{ ratio }}). Raporti maksimal i lejuar është {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Raporti i videos është shumë i vogël ({{ ratio }}). Raporti minimal i pritur është {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Videoja është katrore ({{ width }}x{{ height }}px). Videot katrore nuk lejohen. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Videoja është me orientim horizontal ({{ width }}x{{ height }}px). Videot horizontale nuk lejohen. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Videoja është me orientim portret ({{ width }}x{{ height }}px). Videot me orientim portret nuk lejohen. + + + The video file is corrupted. + Fajli i videos është i korruptuar. + + + The video contains multiple streams. Only one stream is allowed. + Videoja përmban disa rrjedha. Lejohet vetëm një rrjedhë. + + + Unsupported video codec "{{ codec }}". + Kodeku videos është i pambështetur „{{ codec }}“. + + + Unsupported video container "{{ container }}". + Kontejneri videos është i pambështetur "{{ container }}". + + + The image file is corrupted. + Fajli i imazhit është korruptuar. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Imazhi ka shumë pak pikselë ({{ pixels }}). Sasia minimale e pritur është {{ min_pixels }}px. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Imazhi ka shumë pikselë ({{ pixels }}). Shuma maksimale e pritur është {{ max_pixels }}px. + + + This filename does not match the expected charset. + Ky emër fajlit nuk përputhet me grupin e pritur të karaktereve. + + +
+
diff --git a/lib/symfony/validator/Resources/translations/validators.sr_Cyrl.xlf b/lib/symfony/validator/Resources/translations/validators.sr_Cyrl.xlf new file mode 100644 index 0000000000..9874740636 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.sr_Cyrl.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Вредност треба да буде нетачна. + + + This value should be true. + Вредност треба да буде тачна. + + + This value should be of type {{ type }}. + Вредност треба да буде типа {{ type }}. + + + This value should be blank. + Вредност треба да буде празна. + + + The value you selected is not a valid choice. + Вредност треба да буде једна од понуђених. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Изаберите бар {{ limit }} могућност.|Изаберите бар {{ limit }} могућности.|Изаберите бар {{ limit }} могућности. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Изаберите највише {{ limit }} могућност.|Изаберите највише {{ limit }} могућности.|Изаберите највише {{ limit }} могућности. + + + One or more of the given values is invalid. + Једна или више вредности је невалидна. + + + This field was not expected. + Ово поље није било очекивано. + + + This field is missing. + Ово поље недостаје. + + + This value is not a valid date. + Вредност није валидан датум. + + + This value is not a valid datetime. + Вредност није валидан датум-време. + + + This value is not a valid email address. + Вредност није валидна адреса електронске поште. + + + The file could not be found. + Датотека не може бити пронађена. + + + The file is not readable. + Датотека није читљива. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Датотека је превелика ({{ size }} {{ suffix }}). Највећа дозвољена величина је {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Миме тип датотеке није валидан ({{ type }}). Дозвољени миме типови су {{ types }}. + + + This value should be {{ limit }} or less. + Вредност треба да буде {{ limit }} или мање. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Вредност је предугачка. Треба да има {{ limit }} карактер или мање.|Вредност је предугачка. Треба да има {{ limit }} карактера или мање.|Вредност је предугачка. Треба да има {{ limit }} карактера или мање. + + + This value should be {{ limit }} or more. + Вредност треба да буде {{ limit }} или више. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Вредност је прекратка. Треба да има {{ limit }} карактер или више.|Вредност је прекратка. Треба да има {{ limit }} карактера или више.|Вредност је прекратка. Треба да има {{ limit }} карактера или више. + + + This value should not be blank. + Вредност не треба да буде празна. + + + This value should not be null. + Вредност не треба да буде null. + + + This value should be null. + Вредност треба да буде null. + + + This value is not valid. + Вредност није валидна. + + + This value is not a valid time. + Вредност није валидно време. + + + This value is not a valid URL. + Вредност није валидан URL. + + + The two values should be equal. + Обе вредности треба да буду једнаке. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Датотека је превелика. Највећа дозвољена величина је {{ limit }} {{ suffix }}. + + + The file is too large. + Датотека је превелика. + + + The file could not be uploaded. + Датотека не може бити отпремљена. + + + This value should be a valid number. + Вредност треба да буде валидан број. + + + This file is not a valid image. + Ова датотека није валидна слика. + + + This value is not a valid IP address. + Ова вредност није валидна IP адреса. + + + This value is not a valid language. + Вредност није валидан језик. + + + This value is not a valid locale. + Вредност није валидна међународна ознака језика. + + + This value is not a valid country. + Вредност није валидна држава. + + + This value is already used. + Вредност је већ искоришћена. + + + The size of the image could not be detected. + Величина слике не може бити одређена. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ширина слике је превелика ({{ width }} пиксела). Најећа дозвољена ширина је {{ max_width }} пиксела. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ширина слике је премала ({{ width }} пиксела). Најмања дозвољена ширина је {{ min_width }} пиксела. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Висина слике је превелика ({{ height }} пиксела). Најећа дозвољена висина је {{ max_height }} пиксела. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Висина слике је премала ({{ height }} пиксела). Најмања дозвољена висина је {{ min_height }} пиксела. + + + This value should be the user's current password. + Вредност треба да буде тренутна корисничка лозинка. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Вредност треба да има тачно {{ limit }} карактер.|Вредност треба да има тачно {{ limit }} карактера.|Вредност треба да има тачно {{ limit }} карактера. + + + The file was only partially uploaded. + Датотека је само делимично отпремљена. + + + No file was uploaded. + Датотека није отпремљена. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Привремени директоријум није конфигурисан у php.ini, или конфигурисани директоријум не постоји. + + + Cannot write temporary file to disk. + Немогуће писање привремене датотеке на диск. + + + A PHP extension caused the upload to fail. + PHP екстензија је проузроковала неуспех отпремања датотеке. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ова колекција треба да садржи {{ limit }} или више елемената.|Ова колекција треба да садржи {{ limit }} или више елемената.|Ова колекција треба да садржи {{ limit }} или више елемената. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ова колекција треба да садржи {{ limit }} или мање елемената.|Ова колекција треба да садржи {{ limit }} или мање елемената.|Ова колекција треба да садржи {{ limit }} или мање елемената. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ова колекција треба да садржи тачно {{ limit }} елемент.|Ова колекција треба да садржи тачно {{ limit }} елемента.|Ова колекција треба да садржи тачно {{ limit }} елемената. + + + Invalid card number. + Невалидан број картице. + + + Unsupported card type or invalid card number. + Невалидан број картице или тип картице није подржан. + + + This value is not a valid International Bank Account Number (IBAN). + Ова вредност није валидан Међународни број банковног рачуна (IBAN). + + + This value is not a valid ISBN-10. + Ова вредност није валидан ISBN-10. + + + This value is not a valid ISBN-13. + Ова вредност није валидан ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Овa вредност није ни валидан ISBN-10 ни валидан ISBN-13. + + + This value is not a valid ISSN. + Ова вредност није валидан ISSN. + + + This value is not a valid currency. + Ово вредност није валидна валута. + + + This value should be equal to {{ compared_value }}. + Ова вредност треба да буде {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ова вредност треба да буде већа од {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ова вредност треба да буде већа или једнака {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ова вредност треба да буде идентична са {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ова вредност треба да буде мања од {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ова вредност треба да буде мања или једнака {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ова вредност не треба да буде једнака {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ова вредност не треба да буде идентична са {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Размера ове слике је превелика ({{ ratio }}). Максимална дозвољена размера је {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Размера ове слике је премала ({{ ratio }}). Минимална очекивана размера је {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Слика је квадратна ({{ width }}x{{ height }} пиксела). Квадратне слике нису дозвољене. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Слика је оријентације пејзажа ({{ width }}x{{ height }} пиксела). Пејзажна оријентација слика није дозвољена. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Слика је оријантације портрета ({{ width }}x{{ height }} пиксела). Портретна оријентација слика није дозвољена. + + + An empty file is not allowed. + Празна датотека није дозвољена. + + + The host could not be resolved. + Име хоста не може бити разрешено. + + + This value does not match the expected {{ charset }} charset. + Вредност се не поклапа са очекиваним {{ charset }} сетом карактера. + + + This value is not a valid Business Identifier Code (BIC). + Ова вредност није валидан Код за идентификацију бизниса (BIC). + + + Error + Грешка + + + This value is not a valid UUID. + Ова вредност није валидан UUID. + + + This value should be a multiple of {{ compared_value }}. + Ова вредност треба да буде дељива са {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + BIC код није повезан са IBAN {{ iban }}. + + + This value should be valid JSON. + Ова вредност треба да буде валидан JSON. + + + This collection should contain only unique elements. + Ова колекција треба да садржи само јединствене елементе. + + + This value should be positive. + Ова вредност треба да буде позитивна. + + + This value should be either positive or zero. + Ова вредност треба да буде или позитивна или нула. + + + This value should be negative. + Ова вредност треба да буде негативна. + + + This value should be either negative or zero. + Ова вредност треба да буде или негативна или нула. + + + This value is not a valid timezone. + Ова вредност није валидна временска зона. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Ова лозинка је компромитована приликом претходних напада, немојте је користити. Користите другу лозинку. + + + This value should be between {{ min }} and {{ max }}. + Ова вредност треба да буде између {{ min }} и {{ max }}. + + + This value is not a valid hostname. + Ова вредност није исправно име хоста. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Број елемената у овој колекцији треба да буде дељив са {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Ова вредност треба да задовољава најмање једно од наредних ограничења: + + + Each element of this collection should satisfy its own set of constraints. + Сваки елемент ове колекције треба да задовољи сопствени скуп ограничења. + + + This value is not a valid International Securities Identification Number (ISIN). + Ова вредност није валидна међународна идентификациона ознака хартија од вредности (ISIN). + + + This value should be a valid expression. + Ова вредност треба да буде валидан израз. + + + This value is not a valid CSS color. + Ова вредност није валидна CSS боја. + + + This value is not a valid CIDR notation. + Ова вредност није валидна CIDR нотација. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Вредност мрежне маске треба да буде између {{ min }} и {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Назив датотеке је сувише дугачак. Треба да има {{ filename_max_length }} карактер или мање.|Назив датотеке је сувише дугачак. Треба да има {{ filename_max_length }} карактера или мање.|Назив датотеке је сувише дугачак. Треба да има {{ filename_max_length }} карактера или мање. + + + The password strength is too low. Please use a stronger password. + Лозинка није довољно јака. Молимо користите јачу лозинку. + + + This value contains characters that are not allowed by the current restriction-level. + Ова вредност садржи карактере који нису дозвољени од стране важећег нивоа рестрикције. + + + Using invisible characters is not allowed. + Коришћење невидљивих карактера није дозвољено. + + + Mixing numbers from different scripts is not allowed. + Мешање бројева из различитих скрипти није дозвољено. + + + Using hidden overlay characters is not allowed. + Коришћење скривених преклопних карактера није дозвољено. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Екстензија фајла није валидна ({{ extension }}). Дозвољене екстензије су {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Детектовано кодирање знакова није валидно ({{ detected }}). Дозвољена кодирања су {{ encodings }}. + + + This value is not a valid MAC address. + Ова вредност није валидна MAC адреса. + + + This URL is missing a top-level domain. + Овом URL-у недостаје домен највишег нивоа. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Ова вредност је прекратка. Треба да садржи макар једну реч.|Ова вредност је прекратка. Треба да садржи макар {{ min }} речи.|Ова вредност је прекратка. Треба да садржи макар {{ min }} речи. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Ова вредност је предугачка. Треба да садржи само једну реч.|Ова вредност је предугачка. Треба да садржи највише {{ max }} речи.|Ова вредност је предугачка. Треба да садржи највише {{ max }} речи. + + + This value does not represent a valid week in the ISO 8601 format. + Ова вредност не представља валидну недељу у ISO 8601 формату. + + + This value is not a valid week. + Ова вредност није валидна недеља. + + + This value should not be before week "{{ min }}". + Ова вредност не треба да буде пре недеље "{{ min }}". + + + This value should not be after week "{{ max }}". + Ова вредност не треба да буде после недеље "{{ max }}". + + + This value is not a valid Twig template. + Ова вредност није важећи Twig шаблон. + + + This file is not a valid video. + Ова датотека није важећи видео. + + + The size of the video could not be detected. + Није било могуће утврдити величину видео снимка. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ширина видеа је превелика ({{ width }}px). Дозвољена максимална ширина је {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ширина видеа је превише мала ({{ width }}px). Очекивана минимална ширина је {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Висина видеа је превелика ({{ height }}px). Дозвољена максимална висина је {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Висина видеа је превише мала ({{ height }}px). Очекивана минимална висина је {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Видео има премало пиксела ({{ pixels }}). Очекивана минимална количина је {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Видео има превише пиксела ({{ pixels }}). Очекивана максимална количина је {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Однос слике видеа је превелик ({{ ratio }}). Дозвољени максимални однос је {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Однос стране видеа је превише мали ({{ ratio }}). Очекивани минимални однос је {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Видео је квадратног облика ({{ width }}x{{ height }}px). Квадратни видео записи нису дозвољени. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Видео је у водоравној оријентацији ({{ width }}x{{ height }} px). Водоравни видео записи нису дозвољени. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Видео је у портрет оријентацији ({{ width }}x{{ height }}px). Видео снимци у портрет оријентацији нису дозвољени. + + + The video file is corrupted. + Видео датотека је оштећена. + + + The video contains multiple streams. Only one stream is allowed. + Видео садржи више токова. Дозвољен је само један ток. + + + Unsupported video codec "{{ codec }}". + Неподржан видео кодек „{{ codec }}“. + + + Unsupported video container "{{ container }}". + Неподржан видео контејнер "{{ container }}". + + + The image file is corrupted. + Датотека слике је оштећена. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Слика има премало пиксела ({{ pixels }}). Очекивани минимални број је {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Слика има превише пиксела ({{ pixels }}). Очекивани максимални број је {{ max_pixels }}. + + + This filename does not match the expected charset. + Ово име датотеке не одговара очекиваном скупу знакова. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.sr_Latn.xlf b/lib/symfony/validator/Resources/translations/validators.sr_Latn.xlf new file mode 100644 index 0000000000..9fac3a2610 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.sr_Latn.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Vrednost treba da bude netačna. + + + This value should be true. + Vrednost treba da bude tačna. + + + This value should be of type {{ type }}. + Vrednost treba da bude tipa {{ type }}. + + + This value should be blank. + Vrednost treba da bude prazna. + + + The value you selected is not a valid choice. + Vrednost treba da bude jedna od ponuđenih. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Izaberite bar {{ limit }} mogućnost.|Izaberite bar {{ limit }} mogućnosti.|Izaberite bar {{ limit }} mogućnosti. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Izaberite najviše {{ limit }} mogućnost.|Izaberite najviše {{ limit }} mogućnosti.|Izaberite najviše {{ limit }} mogućnosti. + + + One or more of the given values is invalid. + Jedna ili više vrednosti je nevalidna. + + + This field was not expected. + Ovo polje nije bilo očekivano. + + + This field is missing. + Ovo polje nedostaje. + + + This value is not a valid date. + Vrednost nije validan datum. + + + This value is not a valid datetime. + Vrednost nije validan datum-vreme. + + + This value is not a valid email address. + Vrednost nije validna adresa elektronske pošte. + + + The file could not be found. + Datoteka ne može biti pronađena. + + + The file is not readable. + Datoteka nije čitljiva. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Datoteka je prevelika ({{ size }} {{ suffix }}). Najveća dozvoljena veličina je {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + MIME tip datoteke nije validan ({{ type }}). Dozvoljeni MIME tipovi su {{ types }}. + + + This value should be {{ limit }} or less. + Vrednost treba da bude {{ limit }} ili manje. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Vrednost je predugačka. Treba da ima {{ limit }} karakter ili manje.|Vrednost je predugačka. Treba da ima {{ limit }} karaktera ili manje.|Vrednost je predugačka. Treba da ima {{ limit }} karaktera ili manje. + + + This value should be {{ limit }} or more. + Vrednost treba da bude {{ limit }} ili više. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Vrednost je prekratka. Treba da ima {{ limit }} karakter ili više.|Vrednost je prekratka. Treba da ima {{ limit }} karaktera ili više.|Vrednost je prekratka. Treba da ima {{ limit }} karaktera ili više. + + + This value should not be blank. + Vrednost ne treba da bude prazna. + + + This value should not be null. + Vrednost ne treba da bude null. + + + This value should be null. + Vrednost treba da bude null. + + + This value is not valid. + Vrednost nije validna. + + + This value is not a valid time. + Vrednost nije validno vreme. + + + This value is not a valid URL. + Vrednost nije validan URL. + + + The two values should be equal. + Obe vrednosti treba da budu jednake. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Datoteka je prevelika. Najveća dozvoljena veličina je {{ limit }} {{ suffix }}. + + + The file is too large. + Datoteka je prevelikia. + + + The file could not be uploaded. + Datoteka ne može biti otpremljena. + + + This value should be a valid number. + Vrednost treba da bude validan broj. + + + This file is not a valid image. + Ova datoteka nije validna slika. + + + This value is not a valid IP address. + Ova vrednost nije validna IP adresa. + + + This value is not a valid language. + Vrednost nije validan jezik. + + + This value is not a valid locale. + Vrednost nije validna međunarodna oznaka jezika. + + + This value is not a valid country. + Vrednost nije validna država. + + + This value is already used. + Vrednost je već iskorišćena. + + + The size of the image could not be detected. + Veličina slike ne može biti određena. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Širina slike je prevelika ({{ width }} piksela). Najveća dozvoljena širina je {{ max_width }} piksela. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Širina slike je premala ({{ width }} piksela). Najmanja dozvoljena širina je {{ min_width }} piksela. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Visina slike je prevelika ({{ height }} piksela). Najveća dozvoljena visina je {{ max_height }} piksela. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Visina slike je preniska ({{ height }} piksela). Najmanja dozvoljena visina je {{ min_height }} piksela. + + + This value should be the user's current password. + Vrednost treba da bude trenutna korisnička lozinka. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Vrednost treba da ima tačno {{ limit }} karakter.|Vrednost treba da ima tačno {{ limit }} karaktera.|Vrednost treba da ima tačno {{ limit }} karaktera. + + + The file was only partially uploaded. + Datoteka je samo delimično otpremljena. + + + No file was uploaded. + Datoteka nije otpremljena. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Privremeni direktorijum nije konfigurisan u php.ini, ili konfigurisani direktorijum ne postoji. + + + Cannot write temporary file to disk. + Nemoguće pisanje privremene datoteke na disk. + + + A PHP extension caused the upload to fail. + PHP ekstenzija je prouzrokovala neuspeh otpremanja datoteke. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ova kolekcija treba da sadrži {{ limit }} ili više elemenata.|Ova kolekcija treba da sadrži {{ limit }} ili više elemenata.|Ova kolekcija treba da sadrži {{ limit }} ili više elemenata. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ova kolekcija treba da sadrži {{ limit }} ili manje elemenata.|Ova kolekcija treba da sadrži {{ limit }} ili manje elemenata.|Ova kolekcija treba da sadrži {{ limit }} ili manje elemenata. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ova kolekcija treba da sadrži tačno {{ limit }} element.|Ova kolekcija treba da sadrži tačno {{ limit }} elementa.|Ova kolekcija treba da sadrži tačno {{ limit }} elemenata. + + + Invalid card number. + Nevalidan broj kartice. + + + Unsupported card type or invalid card number. + Nevalidan broj kartice ili tip kartice nije podržan. + + + This value is not a valid International Bank Account Number (IBAN). + Ova vrednost nije validan Međunarodni broj bankovnog računa (IBAN). + + + This value is not a valid ISBN-10. + Ova vrednost nije validan ISBN-10. + + + This value is not a valid ISBN-13. + Ova vrednost nije validan ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ova vrednost nije ni validan ISBN-10 ni validan ISBN-13. + + + This value is not a valid ISSN. + Ova vrednost nije validan ISSN. + + + This value is not a valid currency. + Ova vrednost nije validna valuta. + + + This value should be equal to {{ compared_value }}. + Ova vrednost treba da bude {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ova vrednost treba da bude veća od {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ova vrednost treba da bude veća ili jednaka {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ova vrednost treba da bude identična sa {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ova vrednost treba da bude manja od {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ova vrednost treba da bude manja ili jednaka {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ova vrednost ne treba da bude jednaka {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ova vrednost ne treba da bude identična sa {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Razmera ove slike je prevelika ({{ ratio }}). Maksimalna dozvoljena razmera je {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Razmera ove slike je premala ({{ ratio }}). Minimalna očekivana razmera je {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Slika je kvadratna ({{ width }}x{{ height }} piksela). Kvadratne slike nisu dozvoljene. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Slika je orijentacije pejzaža ({{ width }}x{{ height }} piksela). Pejzažna orijentacija slika nije dozvoljena. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Slika je orijentacije portreta ({{ width }}x{{ height }} piksela). Portretna orijentacija slika nije dozvoljena. + + + An empty file is not allowed. + Prazna datoteka nije dozvoljena. + + + The host could not be resolved. + Ime hosta ne može biti razrešeno. + + + This value does not match the expected {{ charset }} charset. + Vrednost se ne poklapa sa očekivanim {{ charset }} setom karaktera. + + + This value is not a valid Business Identifier Code (BIC). + Ova vrednost nije validan Kod za identifikaciju biznisa (BIC). + + + Error + Greška + + + This value is not a valid UUID. + Ova vrednost nije validan UUID. + + + This value should be a multiple of {{ compared_value }}. + Ova vrednost treba da bude deljiva sa {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + BIC kod nije povezan sa IBAN {{ iban }}. + + + This value should be valid JSON. + Ova vrednost treba da bude validan JSON. + + + This collection should contain only unique elements. + Ova kolekcija treba da sadrži samo jedinstvene elemente. + + + This value should be positive. + Ova vrednost treba da bude pozitivna. + + + This value should be either positive or zero. + Ova vrednost treba da bude ili pozitivna ili nula. + + + This value should be negative. + Ova vrednost treba da bude negativna. + + + This value should be either negative or zero. + Ova vrednost treba da bude ili negativna ili nula. + + + This value is not a valid timezone. + Ova vrednost nije validna vremenska zona. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Ova lozinka je kompromitovana prilikom prethodnih napada, nemojte je koristiti. Koristite drugu lozinku. + + + This value should be between {{ min }} and {{ max }}. + Ova vrednost treba da bude između {{ min }} i {{ max }}. + + + This value is not a valid hostname. + Ova vrednost nije ispravno ime hosta. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Broj elemenata u ovoj kolekciji treba da bude deljiv sa {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Ova vrednost treba da zadovoljava namjanje jedno od narednih ograničenja: + + + Each element of this collection should satisfy its own set of constraints. + Svaki element ove kolekcije treba da zadovolji sopstveni skup ograničenja. + + + This value is not a valid International Securities Identification Number (ISIN). + Ova vrednost nije validna međunarodna identifikaciona oznaka hartija od vrednosti (ISIN). + + + This value should be a valid expression. + Ova vrednost treba da bude validan izraz. + + + This value is not a valid CSS color. + Ova vrednost nije validna CSS boja. + + + This value is not a valid CIDR notation. + Ova vrednost nije validna CIDR notacija. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Vrednost mrežne maske treba da bude između {{ min }} i {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Naziv datoteke je suviše dugačak. Treba da ima {{ filename_max_length }} karakter ili manje.|Naziv datoteke je suviše dugačak. Treba da ima {{ filename_max_length }} karaktera ili manje.|Naziv datoteke je suviše dugačak. Treba da ima {{ filename_max_length }} karaktera ili manje. + + + The password strength is too low. Please use a stronger password. + Lozinka nije dovoljno jaka. Molimo koristite jaču lozinku. + + + This value contains characters that are not allowed by the current restriction-level. + Ova vrednost sadrži karaktere koji nisu dozvoljeni od strane važećeg nivoa restrikcije. + + + Using invisible characters is not allowed. + Korišćenje nevidljivih karaktera nije dozvoljeno. + + + Mixing numbers from different scripts is not allowed. + Mešanje brojeva iz različitih skripti nije dozvoljeno. + + + Using hidden overlay characters is not allowed. + Korišćenje skrivenih preklopnih karaktera nije dozvoljeno. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Ekstenzija fajla nije validna ({{ extension }}). Dozvoljene ekstenzije su {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Detektovano kodiranje znakova nije validno ({{ detected }}). Dozvoljena kodiranja su {{ encodings }}. + + + This value is not a valid MAC address. + Ova vrednost nije validna MAC adresa. + + + This URL is missing a top-level domain. + Ovom URL nedostaje domen najvišeg nivoa. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Ova vrednost je prekratka. Treba da sadrži makar jednu reč.|Ova vrednost je prekratka. Treba da sadrži makar {{ min }} reči.|Ova vrednost je prekratka. Treba da sadrži makar {{ min }} reči. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Ova vrednost je predugačka. Treba da sadrži samo jednu reč.|Ova vrednost je predugačka. Treba da sadrži najviše {{ max }} reči.|Ova vrednost je predugačka. Treba da sadrži najviše {{ max }} reči. + + + This value does not represent a valid week in the ISO 8601 format. + Ova vrednost ne predstavlja validnu nedelju u ISO 8601 formatu. + + + This value is not a valid week. + Ova vrednost nije validna nedelja + + + This value should not be before week "{{ min }}". + Ova vrednost ne treba da bude pre nedelje "{{ min }}". + + + This value should not be after week "{{ max }}". + Ova vrednost ne treba da bude posle nedelje "{{ max }}". + + + This value is not a valid Twig template. + Ova vrednost nije važeći Twig šablon. + + + This file is not a valid video. + Ova datoteka nije važeći video. + + + The size of the video could not be detected. + Nije bilo moguće utvrditi veličinu video snimka. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Širina videa je prevelika ({{ width }}px). Dozvoljena maksimalna širina je {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Širina videa je previše mala ({{ width }}px). Očekivana minimalna širina je {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Visina videa je prevelika ({{ height }}px). Dozvoljena maksimalna visina je {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Visina videa je premala ({{ height }}px). Očekivana minimalna visina je {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Video ima premalo piksela ({{ pixels }}). Očekivana minimalna količina je {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Video ima previše piksela ({{ pixels }}). Očekivana maksimalna količina je {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Odnos slike videa je prevelik ({{ ratio }}). Dozvoljeni maksimalni odnos je {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Odnos stranica videa je previše mali ({{ ratio }}). Očekivani minimalni odnos je {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video je kvadratnog oblika ({{ width }}x{{ height }}px). Kvadratni video zapisi nisu dozvoljeni. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video je u vodoravnoj orijentaciji ({{ width }}x{{ height }} px). Vodoravni video zapisi nisu dozvoljeni. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video je u portret orijentaciji ({{ width }}x{{ height }}px). Video zapisi u portret orijentaciji nisu dozvoljeni. + + + The video file is corrupted. + Video datoteka je oštećena. + + + The video contains multiple streams. Only one stream is allowed. + Video sadrži više tokova. Dozvoljen je samo jedan tok. + + + Unsupported video codec "{{ codec }}". + Nepodržan video kodek „{{ codec }}“. + + + Unsupported video container "{{ container }}". + Nepodržan video kontejner "{{ container }}". + + + The image file is corrupted. + Datoteka slike je oštećena. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Slika ima premalo piksela ({{ pixels }}). Očekivani minimalni broj je {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Slika ima previše piksela ({{ pixels }}). Očekivani maksimalni broj je {{ max_pixels }}. + + + This filename does not match the expected charset. + Ovo ime datoteke ne odgovara očekivanom skupu znakova. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.sv.xlf b/lib/symfony/validator/Resources/translations/validators.sv.xlf new file mode 100644 index 0000000000..1c18cf1082 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.sv.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Värdet ska vara falskt. + + + This value should be true. + Värdet ska vara sant. + + + This value should be of type {{ type }}. + Värdet ska vara av typen {{ type }}. + + + This value should be blank. + Värdet ska vara tomt. + + + The value you selected is not a valid choice. + Värdet ska vara ett av de givna valen. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Du måste välja minst {{ limit }} val.|Du måste välja minst {{ limit }} val. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Du kan som mest välja {{ limit }} val.|Du kan som mest välja {{ limit }} val. + + + One or more of the given values is invalid. + Ett eller fler av de angivna värdena är ogiltigt. + + + This field was not expected. + Det här fältet förväntades inte. + + + This field is missing. + Det här fältet saknas. + + + This value is not a valid date. + Värdet är inte ett giltigt datum. + + + This value is not a valid datetime. + Värdet är inte ett giltigt datum med tid. + + + This value is not a valid email address. + Värdet är inte en giltig e-postadress. + + + The file could not be found. + Filen kunde inte hittas. + + + The file is not readable. + Filen är inte läsbar. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Filen är för stor ({{ size }} {{ suffix }}). Största tillåtna storlek är {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Filens MIME-typ ({{ type }}) är ogiltig. De tillåtna typerna är {{ types }}. + + + This value should be {{ limit }} or less. + Värdet ska vara {{ limit }} eller mindre. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Värdet är för långt. Det ska ha {{ limit }} tecken eller färre.|Värdet är för långt. Det ska ha {{ limit }} tecken eller färre. + + + This value should be {{ limit }} or more. + Värdet ska vara {{ limit }} eller mer. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Värdet är för kort. Det ska ha {{ limit }} tecken eller mer.|Värdet är för kort. Det ska ha {{ limit }} tecken eller mer. + + + This value should not be blank. + Värdet kan inte vara tomt. + + + This value should not be null. + Värdet kan inte vara null. + + + This value should be null. + Värdet ska vara null. + + + This value is not valid. + Värdet är inte giltigt. + + + This value is not a valid time. + Värdet är inte en giltig tid. + + + This value is not a valid URL. + Värdet är inte en giltig URL. + + + The two values should be equal. + De två värdena måste vara lika. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Filen är för stor. Tillåten maximal storlek är {{ limit }} {{ suffix }}. + + + The file is too large. + Filen är för stor. + + + The file could not be uploaded. + Filen kunde inte laddas upp. + + + This value should be a valid number. + Värdet ska vara ett giltigt nummer. + + + This file is not a valid image. + Filen är ingen giltig bild. + + + This value is not a valid IP address. + Värdet är inte en giltig IP-adress. + + + This value is not a valid language. + Värdet är inte ett giltigt språk. + + + This value is not a valid locale. + Värdet är inte en giltig plats. + + + This value is not a valid country. + Värdet är inte ett giltigt land. + + + This value is already used. + Värdet används redan. + + + The size of the image could not be detected. + Det gick inte att fastställa storleken på bilden. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Bildens bredd är för stor ({{ width }}px). Tillåten maximal bredd är {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Bildens bredd är för liten ({{ width }}px). Minsta förväntade bredd är {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Bildens höjd är för stor ({{ height }}px). Tillåten maximal bredd är {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Bildens höjd är för liten ({{ height }}px). Minsta förväntade höjd är {{ min_height }}px. + + + This value should be the user's current password. + Värdet ska vara användarens nuvarande lösenord. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Värdet ska ha exakt {{ limit }} tecken.|Värdet ska ha exakt {{ limit }} tecken. + + + The file was only partially uploaded. + Filen laddades bara upp delvis. + + + No file was uploaded. + Ingen fil laddades upp. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Ingen tillfällig mapp konfigurerades i php.ini, eller den konfigurerade mappen finns inte. + + + Cannot write temporary file to disk. + Kan inte skriva temporär fil till disken. + + + A PHP extension caused the upload to fail. + En PHP extension gjorde att uppladdningen misslyckades. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Den här samlingen ska innehålla {{ limit }} element eller mer.|Den här samlingen ska innehålla {{ limit }} element eller mer. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Den här samlingen ska innehålla {{ limit }} element eller mindre.|Den här samlingen ska innehålla {{ limit }} element eller mindre. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Den här samlingen ska innehålla exakt {{ limit }} element.|Den här samlingen ska innehålla exakt {{ limit }} element. + + + Invalid card number. + Ogiltigt kortnummer. + + + Unsupported card type or invalid card number. + Okänd korttyp eller ogiltigt kortnummer. + + + This value is not a valid International Bank Account Number (IBAN). + Värdet är inte ett giltigt internationellt bankkontonummer (IBAN). + + + This value is not a valid ISBN-10. + Värdet är inte en giltig ISBN-10. + + + This value is not a valid ISBN-13. + Värdet är inte en giltig ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Värdet är varken en giltig ISBN-10 eller en giltig ISBN-13. + + + This value is not a valid ISSN. + Värdet är inte en giltig ISSN. + + + This value is not a valid currency. + Värdet är inte en giltig valuta. + + + This value should be equal to {{ compared_value }}. + Värdet ska vara detsamma som {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Värdet ska vara större än {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Värdet ska bara större än eller detsamma som {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Värdet ska vara identiskt till {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Värdet ska vara mindre än {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Värdet ska vara mindre än eller detsamma som {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Värdet ska inte vara detsamma som {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Värdet ska inte vara identiskt med {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Förhållandet mellan bildens bredd och höjd är för stort ({{ ratio }}). Högsta tillåtna förhållande är {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Förhållandet mellan bildens bredd och höjd är för litet ({{ ratio }}). Minsta tillåtna förhållande är {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Bilden är kvadratisk ({{ width }}x{{ height }}px). Kvadratiska bilder tillåts inte. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Bilden är landskapsorienterad ({{ width }}x{{ height }}px). Landskapsorienterade bilder tillåts inte. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Bilden är porträttsorienterad ({{ width }}x{{ height }}px). Porträttsorienterade bilder tillåts inte. + + + An empty file is not allowed. + En tom fil är inte tillåten. + + + The host could not be resolved. + Värddatorn kunde inte hittas. + + + This value does not match the expected {{ charset }} charset. + Värdet har inte den förväntade teckenkodningen {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Värdet är inte en giltig BIC-kod. + + + Error + Fel + + + This value is not a valid UUID. + Värdet är inte en giltig UUID. + + + This value should be a multiple of {{ compared_value }}. + Värdet ska vara en multipel av {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Denna BIC-koden är inte associerad med IBAN {{ iban }}. + + + This value should be valid JSON. + Värdet ska vara giltig JSON. + + + This collection should contain only unique elements. + Denna samling bör endast innehålla unika element. + + + This value should be positive. + Värdet ska vara positivt. + + + This value should be either positive or zero. + Värdet ska vara antingen positivt eller noll. + + + This value should be negative. + Värdet ska vara negativt. + + + This value should be either negative or zero. + Värdet ska vara antingen negativt eller noll. + + + This value is not a valid timezone. + Värdet är inte en giltig tidszon. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Det här lösenordet har läckt ut vid ett dataintrång, det får inte användas. Använd ett annat lösenord. + + + This value should be between {{ min }} and {{ max }}. + Värdet bör ligga mellan {{ min }} och {{ max }}. + + + This value is not a valid hostname. + Värdet är inte ett giltigt servernamn. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Antalet element i samlingen ska vara en multipel av {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Värdet ska uppfylla minst ett av följande krav: + + + Each element of this collection should satisfy its own set of constraints. + Varje element i samlingen skall uppfylla sin egen uppsättning av krav. + + + This value is not a valid International Securities Identification Number (ISIN). + Värdet är inte ett giltigt "International Securities Identification Number" (ISIN). + + + This value should be a valid expression. + Värdet ska vara ett giltigt uttryck. + + + This value is not a valid CSS color. + Värdet är inte en giltig CSS-färg. + + + This value is not a valid CIDR notation. + Värdet är inte en giltig CIDR-notation. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Värdet på nätmasken bör vara mellan {{ min }} och {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Filnamnet är för långt. Det måste vara {{ filename_max_length }} tecken eller färre.|Filnamnet är för långt. Det måste vara {{ filename_max_length }} tecken eller färre. + + + The password strength is too low. Please use a stronger password. + Detta lösenord är för svagt. Använd ett starkare lösenord. + + + This value contains characters that are not allowed by the current restriction-level. + Värdet innehåller tecken som inte är tillåtna. + + + Using invisible characters is not allowed. + Användning av osynliga tecken är inte tillåtet. + + + Mixing numbers from different scripts is not allowed. + Blandning av siffror från olika skript är inte tillåtet. + + + Using hidden overlay characters is not allowed. + Användning av dolda överlagringstecken är inte tillåtet. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Filtillägget är ogiltigt ({{ extension }}). Tillåtna filtillägg är {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Den upptäckta teckenkodningen är ogiltig ({{ detected }}). Tillåtna kodningar är {{ encodings }}. + + + This value is not a valid MAC address. + Värdet är inte en giltig MAC-adress. + + + This URL is missing a top-level domain. + Denna URL saknar en toppdomän. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Det här värdet är för kort. Det ska innehålla minst ett ord.|Det här värdet är för kort. Det ska innehålla minst {{ min }} ord. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Det här värdet är för långt. Det ska innehålla endast ett ord.|Det här värdet är för långt. Det ska innehålla {{ max }} ord eller färre. + + + This value does not represent a valid week in the ISO 8601 format. + Det här värdet representerar inte en giltig vecka i ISO 8601-formatet. + + + This value is not a valid week. + Det här värdet är inte en giltig vecka. + + + This value should not be before week "{{ min }}". + Det här värdet bör inte vara före vecka "{{ min }}". + + + This value should not be after week "{{ max }}". + Det här värdet bör inte vara efter vecka "{{ max }}". + + + This value is not a valid Twig template. + Det här värdet är inte en giltig Twig-mall. + + + This file is not a valid video. + Den här filen är inte en giltig video. + + + The size of the video could not be detected. + Videons storlek kunde inte upptäckas. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Videobredden är för stor ({{ width }}px). Tillåten maximal bredd är {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Videobredden är för liten ({{ width }}px). Förväntad minsta bredd är {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Videons höjd är för stor ({{ height }}px). Tillåten maximal höjd är {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Videohöjden är för liten ({{ height }}px). Förväntad minimihöjd är {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Videon har för få pixlar ({{ pixels }}). Förväntad miniminivå är {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Videon har för många pixlar ({{ pixels }}). Förväntat maxantal är {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Videons förhållande är för stort ({{ ratio }}). Tillåtet maxförhållande är {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Videoförhållandet är för litet ({{ ratio }}). Förväntat minimiförhållande är {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Videon är kvadratisk ({{ width }}x{{ height }}px). Kvadratiska videor är inte tillåtna. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Videon är i liggande läge ({{ width }}x{{ height }}px). Liggande videor är inte tillåtna. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Videon är i porträttläge ({{ width }}x{{ height }}px). Videor i porträttläge är inte tillåtna. + + + The video file is corrupted. + Videofilen är skadad. + + + The video contains multiple streams. Only one stream is allowed. + Videon innehåller flera strömmar. Endast en ström är tillåten. + + + Unsupported video codec "{{ codec }}". + Videokodek stöds inte "{{ codec }}". + + + Unsupported video container "{{ container }}". + Videokontainer stöds inte "{{ container }}". + + + The image file is corrupted. + Bildfilen är skadad. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Bilden har för få pixlar ({{ pixels }}). Förväntat minimiantal är {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Bilden har för många pixlar ({{ pixels }}). Förväntat maxantal är {{ max_pixels }}. + + + This filename does not match the expected charset. + Detta filnamn stämmer inte med förväntad teckenuppsättning. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.th.xlf b/lib/symfony/validator/Resources/translations/validators.th.xlf new file mode 100644 index 0000000000..f9db27cb72 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.th.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + ค่านี้ควรเป็น false + + + This value should be true. + ค่านี้ควรเป็น true + + + This value should be of type {{ type }}. + ค่านี้ควรเป็น {{ type }} + + + This value should be blank. + ควรเป็นค่าว่าง + + + The value you selected is not a valid choice. + คุณเลือกค่าที่ไม่ตรงกับตัวเลือก + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + คุณต้องเลือกอย่างน้อย {{ limit }} ตัวเลือก + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + คุณเลือกได้มากที่สุด {{ limit }} ตัวเลือก + + + One or more of the given values is invalid. + มีบางค่าที่ส่งมาไม่ถูกต้อง + + + This field was not expected. + ไม่ควรมีฟิลด์นี้ + + + This field is missing. + ฟิลด์นี้หายไป + + + This value is not a valid date. + ค่าของวันที่ไม่ถูกต้อง + + + This value is not a valid datetime. + ค่าของวันที่และเวลาไม่ถูกต้อง + + + This value is not a valid email address. + ค่าของอีเมล์ไม่ถูกต้อง + + + The file could not be found. + ไม่พบไฟล์ + + + The file is not readable. + ไฟล์ไม่อยู่ในสถานะที่สามารถอ่านได้ + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + ไฟล์ใหญ่เกิน ({{ size }} {{ suffix }}) อนุญาตให้ใหญ่ที่สุดได้ไม่เกิน {{ limit }} {{ suffix }} + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Mime type ของไฟล์ไม่ถูกต้อง ({{ type }}) Mime types ที่อนุญาตคือ {{ types }} + + + This value should be {{ limit }} or less. + ค่านี้ควรจะเป็น {{ limit }} หรือน้อยกว่านั้น + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + ค่านี้ยาวเกินไป ควรจะมีแค่ {{ limit }} ตัวอักษรหรือน้อยกว่านั้น + + + This value should be {{ limit }} or more. + ค่านี้ควรจะมี {{ limit }} หรือมากกว่านั้น + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + ค่านี้สั้นเกินไป ควรจะมี {{ limit }} ตัวอักษรหรือมากกว่านั้น + + + This value should not be blank. + ค่านี้ไม่ควรเป็นค่าว่าง + + + This value should not be null. + ค่านี้ไม่ควรเป็นค่า null + + + This value should be null. + ค่านี้ควรเป็นค่า null + + + This value is not valid. + ค่านี้ไม่ถูกต้อง + + + This value is not a valid time. + ค่าของเวลาไม่ถูกต้อง + + + This value is not a valid URL. + ค่าของ URL ไม่ถูกต้อง + + + The two values should be equal. + ค่าทั้งสองค่าควรจะเหมือนกัน + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + ขนาดไฟล์ใหญ่เกินไป อนุญาตให้ไฟล์ขนาดใหญ่ได้ไม่เกิน {{ limit }} {{ suffix }} + + + The file is too large. + ขนาดไฟล์ใหญ่เกินไป + + + The file could not be uploaded. + ไม่สามารถอัปโหลดไฟล์ได้ + + + This value should be a valid number. + ค่าของตัวเลขไม่ถูกต้อง + + + This file is not a valid image. + ไฟล์นี้ไม่ใช่ไฟล์รูปภาพ + + + This value is not a valid IP address. + ค่านี้ไม่ใช่ที่อยู่ IP ที่ถูกต้อง + + + This value is not a valid language. + ค่าของภาษาไม่ถูกต้อง + + + This value is not a valid locale. + ค่าของภูมิภาค (Locale) ไม่ถูกต้อง + + + This value is not a valid country. + ค่าของประเทศไม่ถูกต้อง + + + This value is already used. + ค่านี้ถูกใช้งานไปแล้ว + + + The size of the image could not be detected. + ไม่สามารถตรวจสอบขนาดไฟล์ของภาพได้ + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + ความกว้างของภาพเกินขนาด ({{ width }}px) อนุญาตให้กว้างได้มากที่สุด {{ max_width }}px + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + ความกว้างของภาพต่ำเกินไป ({{ width }}px) อนุญาตให้ความกว้างไม่ต่ำกว่า {{ min_width }}px + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + ความสูงของภาพเกินขนาด ({{ height }}px) อนุญาตให้สูงได้มากที่สุด {{ max_height }}px + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + ความสูงของภาพเล็กเกินไป ({{ height }}px) อนุญาตให้ความสูงไม่ควรต่ำกว่า {{ min_height }}px + + + This value should be the user's current password. + ค่านี้ควรจะเป็นรหัสผ่านปัจจุบันของผู้ใช้ + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + ค่านี้ควรจะมีความยาว {{ limit }} ตัวอักษร + + + The file was only partially uploaded. + อัปโหลดไฟล์ได้เพียงบางส่วนเท่านั้น + + + No file was uploaded. + ไม่มีไฟล์ใดถูกอัปโหลด + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + ไม่มีการกำหนดโฟลเดอร์ชั่วคราวใน php.ini หรือโฟลเดอร์ที่กำหนดไม่มีอยู่จริง + + + Cannot write temporary file to disk. + ไม่สามารถเขียนไฟล์ชั่วคราว (temporary file) ลงดิสก์ได้ + + + A PHP extension caused the upload to fail. + PHP extension ทำให้การอัปโหลดมีปัญหา + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + คอเล็กชั่นนี้ควรจะประกอบไปด้วยอย่างน้อย {{ limit }} สมาชิก + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + คอเล็กชั่นนี้ไม่ควรมีสมาชิกเกิน {{ limit }} + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + คอเล็กชั่นนี้ควรจะมี {{ limit }} สมาชิกเท่านั้น + + + Invalid card number. + หมายเลขบัตรไม่ถูกต้อง + + + Unsupported card type or invalid card number. + ไม่รู้จักประเภทของบัตร หรือหมายเลขบัตรไม่ถูกต้อง + + + This value is not a valid International Bank Account Number (IBAN). + ค่านี้ไม่ใช่หมายเลขบัญชีธนาคารระหว่างประเทศ (IBAN) ที่ถูกต้อง + + + This value is not a valid ISBN-10. + ค่านี้ไม่ใช่ ISBN-10 ที่ถูกต้อง + + + This value is not a valid ISBN-13. + ค่านี้ไม่ใช่ ISBN-13 ที่ถูกต้อง + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + ค่านี้ไม่ใช่ ISBN-10 หรือ ISBN-13 ที่ถูกต้อง + + + This value is not a valid ISSN. + ค่านี้ไม่ใช่ ISSN ที่ถูกต้อง + + + This value is not a valid currency. + ค่านี้ไม่ใช่สกุลเงินที่ถูกต้อง + + + This value should be equal to {{ compared_value }}. + ค่านี้ควรตรงกับ {{ compared_value }} + + + This value should be greater than {{ compared_value }}. + ค่านี้ควรจะมากกว่า {{ compared_value }} + + + This value should be greater than or equal to {{ compared_value }}. + ค่านี้ควรจะมากกว่าหรือตรงกับ {{ compared_value }} + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + ค่านี้ควรจะเหมือนกันกับ {{ compared_value_type }} {{ compared_value }} + + + This value should be less than {{ compared_value }}. + ค่านี้ควรจะน้อยกว่า {{ compared_value }} + + + This value should be less than or equal to {{ compared_value }}. + ค่านี้ควรจะน้อยกว่าหรือเท่ากับ {{ compared_value }} + + + This value should not be equal to {{ compared_value }}. + ค่านี้ไม่ควรเท่ากันกับ {{ compared_value }} + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + ค่านี้ไม่ควรเหมือนกันกับ {{ compared_value_type }} {{ compared_value }} + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + สัดส่วนของภาพใหญ่เกิน ({{ ratio }}) สัดส่วนใหญ่ที่สุดที่ใช้ได้คือ {{ max_ratio }} + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + สัดส่วนของภาพเล็กเกิน ({{ ratio }}) สัดส่วนเล็กที่สุดที่ใช้ได้คือ {{ min_ratio }} + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + รูปภาพเป็นจุตรัส ({{ width }}x{{ height }}px) ไม่อนุญาตภาพที่เป็นสี่เหลี่ยมจตุรัส + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + ภาพนี้เป็นแนวนอน ({{ width }}x{{ height }}px) ไม่อนุญาตภาพที่เป็นแนวนอน + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + ภาพนี้เป็นแนวตั้ง ({{ width }}x{{ height }}px) ไม่อนุญาตภาพที่เป็นแนวตั้ง + + + An empty file is not allowed. + ไม่อนุญาตให้ใช้ไฟล์ว่าง + + + The host could not be resolved. + ไม่สามารถแก้ไขชื่อโฮสต์ + + + This value does not match the expected {{ charset }} charset. + ค่านี้ไม่ตรงกับการเข้ารหัส {{ charset }} + + + This value is not a valid Business Identifier Code (BIC). + ค่านี้ไม่ใช่รหัสประจำตัวธุรกิจ (BIC) ที่ถูกต้อง + + + Error + เกิดข้อผิดพลาด + + + This value is not a valid UUID. + ค่านี้ไม่ใช่ UUID ที่ถูกต้อง + + + This value should be a multiple of {{ compared_value }}. + ค่านี้ควรเป็น {{ compared_value }} หลายตัว + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + รหัสสำหรับระบุธุรกิจนี้ (BIC) ไม่เกี่ยวข้องกับ IBAN {{ iban }} + + + This value should be valid JSON. + ค่านี้ควรอยู่ในรูปแบบ JSON ที่ถูกต้อง + + + This collection should contain only unique elements. + คอเล็กชั่นนี้ควรมีเฉพาะสมาชิกที่ไม่ซ้ำกันเท่านั้น + + + This value should be positive. + ค่านี้ควรเป็นค่าบวก + + + This value should be either positive or zero. + ค่านี้ควรเป็นค่าบวกหรือค่าศูนย์ + + + This value should be negative. + ค่านี้ควรเป็นค่าลบ + + + This value should be either negative or zero. + ค่านี้ควรเป็นค่าลบหรือค่าศูนย์ + + + This value is not a valid timezone. + ค่าเขตเวลาไม่ถูกต้อง + + + This password has been leaked in a data breach, it must not be used. Please use another password. + รหัสผ่านนี้ได้เคยรั่วไหลออกไปโดยถูกการละเมิดข้อมูล ซึ่งไม่ควรนำกลับมาใช้ กรุณาใช้รหัสผ่านอื่น + + + This value should be between {{ min }} and {{ max }}. + ค่านี้ควรอยู่ระหว่าง {{ min }} ถึง {{ max }} + + + This value is not a valid hostname. + ค่าโฮสต์เนมไม่ถูกต้อง + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + จำนวนของสมาชิกในคอเล็กชั่นควรเป็นพหุคูณของ {{ compared_value }} + + + This value should satisfy at least one of the following constraints: + ค่านี้ควรเป็นไปตามข้อจำกัดอย่างน้อยหนึ่งข้อจากข้อจำกัดเหล่านี้: + + + Each element of this collection should satisfy its own set of constraints. + สมาชิกแต่ละตัวในคอเล็กชั่นควรเป็นไปตามข้อจำกัดของคอเล็กชั่นนั้นๆ + + + This value is not a valid International Securities Identification Number (ISIN). + ค่ารหัสหลักทรัพย์สากล (ISIN) ไม่ถูกต้อง + + + This value should be a valid expression. + ค่านี้ควรเป็นนิพจน์ที่ถูกต้อง + + + This value is not a valid CSS color. + ค่านี้ไม่ใช่สี CSS ที่ถูกต้อง + + + This value is not a valid CIDR notation. + ค่านี้ไม่ใช่รูปแบบ CIDR ที่ถูกต้อง + + + The value of the netmask should be between {{ min }} and {{ max }}. + ค่าของ netmask ควรมีค่าระหว่าง {{ min }} ถึง {{ max }} + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + ชื่อไฟล์ยาวเกินไป ควรจะมีแค่ {{ filename_max_length }} ตัวอักษรหรือน้อยกว่านั้น + + + The password strength is too low. Please use a stronger password. + รหัสผ่านมีความปลอดภัยต่ำ กรุณาใช้รหัสผ่านที่มีความปลอดภัยสูง + + + This value contains characters that are not allowed by the current restriction-level. + ค่านี้ประกอบด้วยตัวอักษรที่ไม่รับอนุญาตจากระดับข้อบังคับปัจจุบัน + + + Using invisible characters is not allowed. + ไม่อนุญาตให้ใช้ตัวอักษรที่มองไม่เห็น + + + Mixing numbers from different scripts is not allowed. + ไม่อนุญาตให้ผสมตัวเลขจากสคริปต์ที่แตกต่างกัน + + + Using hidden overlay characters is not allowed. + ไม่อนุญาตให้ใช้ตัวอักษรซ้อนทับที่ซ่อนอยู่ + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + นามสกุลไฟล์ไม่ถูกต้อง ({{ extension }}). นามสกุลที่อนุญาตคือ {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + การเข้ารหัสอักขระที่ตรวจพบไม่ถูกต้อง ({{ detected }}). การเข้ารหัสที่อนุญาตคือ {{ encodings }}. + + + This value is not a valid MAC address. + ค่านี้ไม่ใช่ที่อยู่ MAC ที่ถูกต้อง + + + This URL is missing a top-level domain. + URL นี้ขาดโดเมนระดับสูงสุด. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + ค่านี้สั้นเกินไป ควรมีอย่างน้อยหนึ่งคำ|ค่านี้สั้นเกินไป ควรมีอย่างน้อย {{ min }} คำ + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + ค่านี้ยาวเกินไป ควรมีเพียงคำเดียว|ค่านี้ยาวเกินไป ควรมี {{ max }} คำ หรือต่ำกว่า + + + This value does not represent a valid week in the ISO 8601 format. + ค่านี้ไม่แสดงถึงสัปดาห์ที่ถูกต้องตามรูปแบบ ISO 8601 + + + This value is not a valid week. + ค่านี้ไม่ใช่สัปดาห์ที่ถูกต้อง + + + This value should not be before week "{{ min }}". + ค่านี้ไม่ควรจะก่อนสัปดาห์ "{{ min }}" + + + This value should not be after week "{{ max }}". + ค่านี้ไม่ควรจะอยู่หลังสัปดาห์ "{{ max }}" + + + This value is not a valid Twig template. + ค่านี้ไม่ใช่เทมเพลต Twig ที่ถูกต้อง + + + This file is not a valid video. + ไฟล์นี้ไม่ใช่วิดีโอที่ถูกต้อง + + + The size of the video could not be detected. + ไม่สามารถตรวจพบขนาดของวิดีโอได้ + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + ความกว้างของวิดีโอใหญ่เกินไป ({{ width }}px). ความกว้างสูงสุดที่อนุญาตคือ {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + ความกว้างของวิดีโอเล็กเกินไป ({{ width }}px) ความกว้างขั้นต่ำที่คาดหวังคือ {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + ความสูงของวิดีโอสูงเกินไป ({{ height }}px). ความสูงสูงสุดที่อนุญาตคือ {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + ความสูงของวิดีโอมีขนาดเล็กเกินไป ({{ height }}px). ความสูงขั้นต่ำที่คาดไว้คือ {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + วิดีโอนี้มีพิกเซลน้อยเกินไป ({{ pixels }}). ปริมาณขั้นต่ำที่คาดไว้คือ {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + วิดีโอนี้มีพิกเซลมากเกินไป ({{ pixels }}). จำนวนสูงสุดที่คาดไว้คือ {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + อัตราส่วนวิดีโอใหญ่เกินไป ({{ ratio }}) อัตราส่วนสูงสุดที่อนุญาตคือ {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + อัตราส่วนวิดีโอเล็กเกินไป ({{ ratio }}). อัตราส่วนขั้นต่ำที่คาดหวังคือ {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + วิดีโอเป็นสี่เหลี่ยมจัตุรัส ({{ width }}x{{ height }}px). ไม่อนุญาตให้ใช้วิดีโอสี่เหลี่ยมจัตุรัส. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + วิดีโออยู่ในแนวนอน ({{ width }}x{{ height }} พิกเซล). ไม่อนุญาตวิดีโอแนวนอน + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + วิดีโอเป็นแนวตั้ง ({{ width }}x{{ height }}px) วิดีโอแนวตั้งไม่ได้รับอนุญาต + + + The video file is corrupted. + ไฟล์วิดีโอเสียหาย. + + + The video contains multiple streams. Only one stream is allowed. + วิดีโอนี้มีสตรีมหลายสตรีม อนุญาตเฉพาะสตรีมเดียวเท่านั้น + + + Unsupported video codec "{{ codec }}". + ไม่รองรับตัวแปลงสัญญาณวิดีโอ "{{ codec }}". + + + Unsupported video container "{{ container }}". + ไม่รองรับคอนเทนเนอร์วิดีโอ "{{ container }}". + + + The image file is corrupted. + ไฟล์รูปภาพเสียหาย + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + รูปภาพมีพิกเซลน้อยเกินไป ({{ pixels }}). จำนวนขั้นต่ำที่คาดไว้คือ {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + ภาพมีพิกเซลมากเกินไป ({{ pixels }}). จำนวนสูงสุดที่คาดไว้คือ {{ max_pixels }}. + + + This filename does not match the expected charset. + ชื่อไฟล์นี้ไม่ตรงกับชุดอักขระที่คาดไว้. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.tl.xlf b/lib/symfony/validator/Resources/translations/validators.tl.xlf new file mode 100644 index 0000000000..7a25e79eac --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.tl.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Ang halaga nito ay dapat na huwad. + + + This value should be true. + Ang halaga nito ay dapat totoo. + + + This value should be of type {{ type }}. + Ang halaga nito ay dapat sa uri {{ type }}. + + + This value should be blank. + Ang halaga nito ay dapat walang laman. + + + The value you selected is not a valid choice. + Ang halaga ng iyong pinili ay hindi balidong pagpili. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Kailangan mong pumili ng pinakamababang {{ limit }} ng pagpilian.|Kailangan mong pumili ng pinakamababang {{ limit }} ng mga pagpipilian. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Kailangan mong pumili ng pinakamataas {{ limit }} ng pagpipilian.|Kailangan mong pumili ng pinakamataas {{ limit }} ng mga pagpipilian. + + + One or more of the given values is invalid. + Isa o higit pang mga halaga na binigay ay hindi balido. + + + This field was not expected. + Ang larangang ito ay hindi inaasahan. + + + This field is missing. + Ang patlang na ito ay nawawala. + + + This value is not a valid date. + Ang halagang ito ay hindi balidong petsa. + + + This value is not a valid datetime. + Ang halagang ito ay hindi wastong petsa/oras. + + + This value is not a valid email address. + Ang halagang ito ay hindi balidong address ng email. + + + The file could not be found. + Ang file na ito ay hindi makita. + + + The file is not readable. + Ang file na ito ay hindi mabasa. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Ang file na ito ay masyadong malaki ({{ size }} {{ suffix }}). Ang pinakamalaking sukat {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Ang uri ng file ng mime ay hindi balido ({{ type }}). Ang mga pinapayagang uri ng mime ay ang {{ types }}. + + + This value should be {{ limit }} or less. + Ang halaga nito ay dapat na {{ limit }} or maliit pa. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Ang halaga nito ay masyadong mahaba. Ito ay dapat na {{ limit }} karakter o maliit pa.|Ang halaga nito ay masyadong mahaba. Ito ay dapat na {{ limit }} mga karakter o maliit pa. + + + This value should be {{ limit }} or more. + Ang halaga nito ay dapat na {{ limit }} o mas marami pa. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Ang halaga nito ay masyadong maliit. Ito ay dapat na {{ limit }} karakter o marami pa.|Ang halaga nito ay masyadong maliit. Ito ay dapat na {{ limit }} mga karakter o marami pa. + + + This value should not be blank. + Ang halaga na ito ay dapat na may laman. + + + This value should not be null. + Meron dapt itong halaga. + + + This value should be null. + Wala dapat itong halaga. + + + This value is not valid. + Hindi balido ang halagang ito. + + + This value is not a valid time. + Ang halagang ito ay hindi wastong oras. + + + This value is not a valid URL. + Hindi ito isang balidong URL. + + + The two values should be equal. + Ang dalwang halaga ay dapat magkapareha. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Ang file ay masyadong malaki. Ang pinapayagan halaga lamang ay {{ limit}} {{ suffix }}. + + + The file is too large. + Ang file na ito ay masyadong malaki. + + + The file could not be uploaded. + Ang file na ito ay hindi ma-upload. + + + This value should be a valid number. + Ang halaga nito ay dapat na wastong numero. + + + This file is not a valid image. + Ang file na ito ay hindi wastong imahe. + + + This value is not a valid IP address. + Ang halagang ito ay hindi isang wastong IP address. + + + This value is not a valid language. + Ang halaga na ito ay hindi balidong wika. + + + This value is not a valid locale. + Ito ay isang hindi wastong locale na halaga. + + + This value is not a valid country. + ng halaga na ito ay hindi wastong bansa. + + + This value is already used. + Ang halaga na ito ay ginamit na. + + + The size of the image could not be detected. + Ang sukat ng imahe ay hindi madetect. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ang lapad ng imahe ay masyadong malaki ({{ width }}px). Ang pinapayagang lapay ay {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ang lapad ng imahe ay masyadong maliit ({{ width }}px). Ang pinakamaliit na pinapayagang lapad ay {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Ang haba ng imahe ay masyadong mataas ({{ height }}px). Ang pinakmataas na haba ay {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Ang haba ng imahe ay masyadong maliit ({{ height }}px). Ang inaasahang haba ay {{ min_height }}px. + + + This value should be the user's current password. + Ang halagang ito ay dapat na password ng kasalukuyang gumagamit. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ang halagang ito ay dapat na eksakto sa {{ limit}} karakter.|Ang halagang ito ay dapat na eksakto sa {{ limit }} mga karakter. + + + The file was only partially uploaded. + Ang file na ito ay kahalating na upload lamang. + + + No file was uploaded. + Walang na upload na file. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Walang pansamantalang folder na na-configure sa php.ini, o ang naka-configure na folder ay hindi naroroon. + + + Cannot write temporary file to disk. + Temporaryong hindi makasulat ng file sa disk. + + + A PHP extension caused the upload to fail. + Ang dahilan ng pagkabigo ng pagupload ng files ay isang extension ng PHP. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ang koleksyon na ito ay dapat magkaroon ng {{ limit }} elemento o marami pa.|Ang koleksyon na ito ay dapat magkaroon ng {{ limit }} mga elemento o marami pa. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ang koleksyon na ito ay dapat magkaroon ng {{ limit }} elemento o maliit pa.|Ang koleksyon na ito ay dapat magkaroon ng {{ limit }} mga elemento o maliit pa. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ang koleksyong ito ay magkaroon ng eksaktong {{ limit }} elemento.|Ang koleksyong ito ay magkaroon ng eksaktong {{ limit }} mga elemento. + + + Invalid card number. + Hindi wastong numero ng kard. + + + Unsupported card type or invalid card number. + Hindi supportadong uri ng kard o hindi wastong numero ng kard. + + + This value is not a valid International Bank Account Number (IBAN). + Ang halagang ito ay hindi isang wastong International Bank Account Number (IBAN). + + + This value is not a valid ISBN-10. + Ang halagang ito ay hindi balidong SBN-10. + + + This value is not a valid ISBN-13. + Ang halagang ito ay hindi balidong ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ang halagang ito ay pwdeng isang balidong ISBN-10 o isang balidong ISBN-13. + + + This value is not a valid ISSN. + Ang halangang ito ay hindi isang balidong ISSN. + + + This value is not a valid currency. + Ang halagang ito ay hindi balidong pera. + + + This value should be equal to {{ compared_value }}. + Ito ay hindi dapat magkapareho sa {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ang halagang ito ay dapat tataas sa {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ang halagang ito ay dapat mas mataas o magkapareha sa {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ang halagang ito ay dapat kapareha ng {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ang halagang ito ay dapat mas maliit sa {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ang halagang ito ay dapat mas maliit o magkapareha sa {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ang halagang ito ay hindi dapat magkapareha sa {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ang halagang ito ay hindi dapat magkapareha sa {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Ang ratio ng imahe ay masyadong malaki ({{ ratio }}). Ang pinakamalaking ratio ay {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Ang ratio ng imahe ay masyadong maliit ({{ ratio }}). Ang pinakamaliit na ratio ay {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Ang imahe ay kwadrado ({{ width }}x{{ height }}px). Ang mga kwadradong imahe ay hindi pwede. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Ang orientasyon ng imahe ay nakalandscape ({{ width }}x{{ height }}px). Ang mga imaheng nakalandscape ang orientasyon ay hindi pwede. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Ang orientasyon ng imahe ay nakaportrait ({{ width }}x{{ height }}px). Ang mga imaheng nakaportrait ang orientasyon ay hindi pwede. + + + An empty file is not allowed. + Ang file na walang laman ay hindi pwede. + + + The host could not be resolved. + Hindi maresolba ang host. + + + This value does not match the expected {{ charset }} charset. + Ang halaga ay hindi kapareha sa inaasahang {{ charset }} set ng karater. + + + This value is not a valid Business Identifier Code (BIC). + Ang halagang ito ay hindi isang wastong Business Identifier Code (BIC). + + + Error + Error + + + This value is not a valid UUID. + Ang halagang ito ay hindi isang wastong UUID. + + + This value should be a multiple of {{ compared_value }}. + Ang halagang ito ay dapat multiple ng {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Ang Business Identifier Code (BIC) na ito ay walang kaugnayan sa IBAN {{ iban }}. + + + This value should be valid JSON. + Ang halagang ito ay dapat naka wastong JSON. + + + This collection should contain only unique elements. + Ang mga elemento ng koleksyong ito ay dapat magkakaiba. + + + This value should be positive. + Ang halagang ito ay dapat positibo. + + + This value should be either positive or zero. + Ang halagang ito ay dapat positibo o zero. + + + This value should be negative. + Ang halagang ito ay dapat negatibo. + + + This value should be either negative or zero. + Ang halagang ito ay dapat negatibo o zero. + + + This value is not a valid timezone. + Ang halagang ito ay hindi wastong timezone. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Naikalat ang password na ito sa isang data breach at hindi na dapat gamitin. Mangyaring gumamit ng ibang pang password. + + + This value should be between {{ min }} and {{ max }}. + Ang halagang ito ay dapat nasa pagitan ng {{ min }} at {{ max }}. + + + This value is not a valid hostname. + Ang halagang ito ay hindi wastong hostname. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Ang bilang ng mga elemento sa koleksyon na ito ay dapat multiple ng {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Ang halagang ito ay dapat masunod ang kahit na isang sumusunod na batayan. + + + Each element of this collection should satisfy its own set of constraints. + Ang bawat elemento sa koleksyon na ito ay dapat masunod ang nararapat na batayan. + + + This value is not a valid International Securities Identification Number (ISIN). + Ang halagang ito ay hindi wastong International Securities Identification Number (ISIN). + + + This value should be a valid expression. + Ang halagang ito ay dapat wastong ekspresyon. + + + This value is not a valid CSS color. + Ang halagang ito ay hindi wastong kulay ng CSS. + + + This value is not a valid CIDR notation. + Ang halagang ito ay hindi wastong notasyon ng CIDR. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Ang halaga ng netmask ay dapat nasa pagitan ng {{ min }} at {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Ang pangalan ng file ay masyadong mahaba. Dapat itong magkaroon ng {{ filename_max_length }} karakter o mas kaunti.|Ang pangalan ng file ay masyadong mahaba. Dapat itong magkaroon ng {{ filename_max_length }} mga karakter o mas kaunti. + + + The password strength is too low. Please use a stronger password. + Ang lakas ng password ay masyadong mababa. Mangyaring gumamit ng mas malakas na password. + + + This value contains characters that are not allowed by the current restriction-level. + Ang halagang ito ay naglalaman ng mga karakter na hindi pinapayagan ng kasalukuyang antas ng paghihigpit. + + + Using invisible characters is not allowed. + Hindi pinapayagan ang paggamit ng mga hindi nakikitang karakter. + + + Mixing numbers from different scripts is not allowed. + Hindi pinapayagan ang paghahalo ng mga numero mula sa iba't ibang script. + + + Using hidden overlay characters is not allowed. + Hindi pinapayagan ang paggamit ng mga nakatagong overlay na karakter. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Ang extension ng file ay hindi wasto ({{ extension }}). Ang mga pinapayagang extension ay {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Ang nakitang encoding ng karakter ay hindi wasto ({{ detected }}). Ang mga pinapayagang encoding ay {{ encodings }}. + + + This value is not a valid MAC address. + Ang halagang ito ay hindi isang wastong MAC address. + + + This URL is missing a top-level domain. + Ang URL na ito ay kulang ng top-level domain. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Masyadong maikli ang halagang ito. Dapat itong maglaman ng hindi bababa sa isang salita.|Masyadong maikli ang halagang ito. Dapat itong maglaman ng hindi bababa sa {{ min }} salita. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Masyadong mahaba ang halagang ito. Dapat itong maglaman lamang ng isang salita.|Masyadong mahaba ang halagang ito. Dapat itong maglaman ng {{ max }} salita o mas kaunti. + + + This value does not represent a valid week in the ISO 8601 format. + Ang halagang ito ay hindi kumakatawan sa isang wastong linggo sa format ng ISO 8601. + + + This value is not a valid week. + Ang halagang ito ay hindi isang wastong linggo. + + + This value should not be before week "{{ min }}". + Ang halagang ito ay hindi dapat bago sa linggo "{{ min }}". + + + This value should not be after week "{{ max }}". + Ang halagang ito ay hindi dapat pagkatapos ng linggo "{{ max }}". + + + This value is not a valid Twig template. + Ang halagang ito ay hindi isang balidong Twig template. + + + This file is not a valid video. + Ang file na ito ay hindi isang wastong video. + + + The size of the video could not be detected. + Hindi matukoy ang laki ng video. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Masyadong malaki ang lapad ng video ({{ width }}px). Ang pinahihintulutang pinakamaksimum na lapad ay {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Masyadong maliit ang lapad ng video ({{ width }}px). Inaasahang minimum na lapad ay {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Sobrang taas ng video ({{ height }}px). Ang pinapahintulutang pinakamataas na taas ay {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Masyadong maliit ang taas ng video ({{ height }}px). Inaasahang pinakamababang taas ay {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Ang video ay may masyadong kaunting pixel ({{ pixels }}). Ang inaasahang pinakamababang dami ay {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Ang video ay may masyadong maraming pixel ({{ pixels }}). Ang inaasahang pinakamataas na bilang ay {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Masyadong malaki ang ratio ng video ({{ ratio }}). Ang pinahihintulutang pinakamataas na ratio ay {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Masyadong maliit ang ratio ng video ({{ ratio }}). Ang inaasahang minimum na ratio ay {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Ang video ay parisukat ({{ width }}x{{ height }}px). Hindi pinapayagan ang mga parisukat na video. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Ang video ay nasa landscape na oryentasyon ({{ width }}x{{ height }} px). Hindi pinapayagan ang mga landscape na video. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Ang video ay naka-portrait ({{ width }}x{{ height }}px). Hindi pinapayagan ang mga video na naka-portrait. + + + The video file is corrupted. + Sira ang file ng video. + + + The video contains multiple streams. Only one stream is allowed. + May ilang stream ang video. Isa lamang na stream ang pinapayagan. + + + Unsupported video codec "{{ codec }}". + Hindi suportadong video codec "{{ codec }}". + + + Unsupported video container "{{ container }}". + Hindi suportadong lalagyan ng video "{{ container }}". + + + The image file is corrupted. + Ang file ng larawan ay sira. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Masyadong kaunti ang pixel ng larawan ({{ pixels }}). Ang inaasahang pinakamababang dami ay {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Ang larawan ay may sobrang daming pixel ({{ pixels }}). Ang inaasahang pinakamataas na dami ay {{ max_pixels }}. + + + This filename does not match the expected charset. + Ang pangalan ng file na ito ay hindi tumutugma sa inaasahang hanay ng mga character. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.tr.xlf b/lib/symfony/validator/Resources/translations/validators.tr.xlf new file mode 100644 index 0000000000..95c1bbbea9 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.tr.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Bu değer olumsuz olmalıdır. + + + This value should be true. + Bu değer olumlu olmalıdır. + + + This value should be of type {{ type }}. + Bu değerin tipi {{ type }} olmalıdır. + + + This value should be blank. + Bu değer boş olmalıdır. + + + The value you selected is not a valid choice. + Seçtiğiniz değer geçerli bir seçenek değildir. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + En az {{ limit }} seçenek belirtmelisiniz. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + En çok {{ limit }} seçenek belirtmelisiniz. + + + One or more of the given values is invalid. + Verilen değerlerden bir veya daha fazlası geçersiz. + + + This field was not expected. + Bu alan beklenen olmadı. + + + This field is missing. + Bu alan, eksiktir + + + This value is not a valid date. + Bu değer doğru bir tarih biçimi değildir. + + + This value is not a valid datetime. + Bu değer doğru bir tarihsaat biçimi değildir. + + + This value is not a valid email address. + Bu değer doğru bir e-mail adresi değildir. + + + The file could not be found. + Dosya bulunamadı. + + + The file is not readable. + Dosya okunabilir değildir. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Dosya çok büyük ({{ size }} {{ suffix }}). İzin verilen en büyük dosya boyutu {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Dosyanın mime tipi geçersiz ({{ type }}). İzin verilen mime tipleri {{ types }}. + + + This value should be {{ limit }} or less. + Bu değer {{ limit }} ve altında olmalıdır. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Bu değer çok uzun. {{ limit }} karakter veya daha az olmalıdır. + + + This value should be {{ limit }} or more. + Bu değer {{ limit }} veya daha fazla olmalıdır. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Bu değer çok kısa. {{ limit }} karakter veya daha fazla olmalıdır. + + + This value should not be blank. + Bu değer boş bırakılmamalıdır. + + + This value should not be null. + Bu değer boş bırakılmamalıdır. + + + This value should be null. + Bu değer boş bırakılmalıdır. + + + This value is not valid. + Bu değer geçerli değildir. + + + This value is not a valid time. + Bu değer doğru bir saat değildir. + + + This value is not a valid URL. + Bu değer doğru bir URL değildir. + + + The two values should be equal. + İki değer eşit olmalıdır. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Dosya çok büyük. İzin verilen en büyük dosya boyutu {{ limit }} {{ suffix }}. + + + The file is too large. + Dosya çok büyük. + + + The file could not be uploaded. + Dosya yüklenemiyor. + + + This value should be a valid number. + Bu değer geçerli bir rakam olmalıdır. + + + This file is not a valid image. + Bu dosya geçerli bir resim değildir. + + + This value is not a valid IP address. + Bu değer geçerli bir IP adresi değildir. + + + This value is not a valid language. + Bu değer geçerli bir lisan değildir. + + + This value is not a valid locale. + Bu değer geçerli bir yer değildir. + + + This value is not a valid country. + Bu değer geçerli bir ülke değildir. + + + This value is already used. + Bu değer şu anda kullanımda. + + + The size of the image could not be detected. + Resmin boyutu saptanamıyor. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Resmin genişliği çok büyük ({{ width }}px). İzin verilen en büyük genişlik {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Resmin genişliği çok küçük ({{ width }}px). En az {{ min_width }}px olmalıdır. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Resmin yüksekliği çok büyük ({{ height }}px). İzin verilen en büyük yükseklik {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Resmin yüksekliği çok küçük ({{ height }}px). En az {{ min_height }}px olmalıdır. + + + This value should be the user's current password. + Bu değer kullanıcının şu anki şifresi olmalıdır. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Bu değer tam olarak {{ limit }} karakter olmaldır. + + + The file was only partially uploaded. + Dosya sadece kısmen yüklendi. + + + No file was uploaded. + Hiçbir dosya yüklenmedi. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + php.ini'de geçici bir klasör yapılandırılmadı veya yapılandırılan klasör mevcut değildir. + + + Cannot write temporary file to disk. + Geçici dosya diske yazılamıyor. + + + A PHP extension caused the upload to fail. + Bir PHP eklentisi dosyanın yüklemesini başarısız kıldı. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Bu derlem {{ limit }} veya daha çok eleman içermelidir. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Bu derlem {{ limit }} veya daha az eleman içermelidir. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Bu derlem {{ limit }} eleman içermelidir. + + + Invalid card number. + Geçersiz kart numarası. + + + Unsupported card type or invalid card number. + Desteklenmeyen kart tipi veya geçersiz kart numarası. + + + This value is not a valid International Bank Account Number (IBAN). + Bu değer geçerli bir Uluslararası Banka Hesap Numarası (IBAN) değildir. + + + This value is not a valid ISBN-10. + Bu değer geçerli bir ISBN-10 değildir. + + + This value is not a valid ISBN-13. + Bu değer geçerli bir ISBN-13 değildir. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Bu değer geçerli bir ISBN-10 veya ISBN-13 değildir. + + + This value is not a valid ISSN. + Bu değer geçerli bir ISSN değildir. + + + This value is not a valid currency. + Bu değer geçerli bir para birimi değildir. + + + This value should be equal to {{ compared_value }}. + Bu değer {{ compared_value }} ile eşit olmalıdır. + + + This value should be greater than {{ compared_value }}. + Bu değer {{ compared_value }} değerinden büyük olmalıdır. + + + This value should be greater than or equal to {{ compared_value }}. + Bu değer {{ compared_value }} ile eşit veya büyük olmalıdır. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Bu değer {{ compared_value_type }} {{ compared_value }} ile aynı olmalıdır. + + + This value should be less than {{ compared_value }}. + Bu değer {{ compared_value }} değerinden düşük olmalıdır. + + + This value should be less than or equal to {{ compared_value }}. + .Bu değer {{ compared_value }} ile eşit veya düşük olmalıdır. + + + This value should not be equal to {{ compared_value }}. + Bu değer {{ compared_value }} ile eşit olmamalıdır. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Bu değer {{ compared_value_type }} {{ compared_value }} ile aynı olmamalıdır. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Resim oranı çok büyük ({{ ratio }}). İzin verilen maksimum oran: {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Resim oranı çok ufak ({{ ratio }}). Beklenen minimum oran {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Resim karesi ({{ width }}x{{ height }}px). Kare resimlerine izin verilmiyor. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Resim manzara odaklı ({{ width }}x{{ height }}px). Manzara odaklı resimlere izin verilmiyor. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Resim portre odaklı ({{ width }}x{{ height }}px). Portre odaklı resimlere izin verilmiyor. + + + An empty file is not allowed. + Boş bir dosyaya izin verilmiyor. + + + The host could not be resolved. + Sunucu çözülemedi. + + + This value does not match the expected {{ charset }} charset. + Bu değer beklenen {{ charset }} karakter kümesiyle eşleşmiyor. + + + This value is not a valid Business Identifier Code (BIC). + Bu değer geçerli bir İşletme Tanımlama Kodu (BIC) değildir. + + + Error + Hata + + + This value is not a valid UUID. + Bu değer geçerli bir UUID değildir. + + + This value should be a multiple of {{ compared_value }}. + Bu değer {{ compare_value }} değerinin katlarından biri olmalıdır. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Bu İşletme Tanımlayıcı Kodu (BIC), IBAN {{ iban }} ile ilişkili değildir. + + + This value should be valid JSON. + Bu değer için geçerli olmalıdır JSON. + + + This collection should contain only unique elements. + Bu grup yalnızca benzersiz öğeler içermelidir. + + + This value should be positive. + Bu değer pozitif olmalıdır. + + + This value should be either positive or zero. + Bu değer pozitif veya sıfır olmalıdır. + + + This value should be negative. + Bu değer negatif olmalıdır. + + + This value should be either negative or zero. + Bu değer, negatif veya sıfır olmalıdır. + + + This value is not a valid timezone. + Bu değer, geçerli bir saat dilimi değildir. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Bu parola, bir veri ihlali nedeniyle sızdırılmıştır ve kullanılmamalıdır. Lütfen başka bir şifre kullanın. + + + This value should be between {{ min }} and {{ max }}. + Bu değer {{ min }} ve {{ max }} arasında olmalıdır. + + + This value is not a valid hostname. + Bu değer, geçerli bir ana bilgisayar adı değildir. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Bu gruptaki öğe sayısı birden fazla olmalıdır {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Bu değer aşağıdaki kısıtlamalardan birini karşılamalıdır: + + + Each element of this collection should satisfy its own set of constraints. + Bu gruptaki her öğe kendi kısıtlamalarını karşılamalıdır. + + + This value is not a valid International Securities Identification Number (ISIN). + Bu değer geçerli bir Uluslararası Menkul Kıymetler Kimlik Numarası (ISIN) değildir. + + + This value should be a valid expression. + Bu değer geçerli bir ifade olmalıdır. + + + This value is not a valid CSS color. + Bu değer geçerli bir CSS rengi değildir. + + + This value is not a valid CIDR notation. + Bu değer geçerli bir CIDR yazımı değildir. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Netmask'in değeri {{ min }} ve {{ max }} arasında olmaldır. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Dosya adı çok uzun. {{ filename_max_length }} karakter veya daha az olmalıdır. + + + The password strength is too low. Please use a stronger password. + Şifre gücü çok düşük. Lütfen daha güçlü bir şifre kullanın. + + + This value contains characters that are not allowed by the current restriction-level. + Bu değer, mevcut kısıtlama seviyesi tarafından izin verilmeyen karakterler içeriyor. + + + Using invisible characters is not allowed. + Görünmez karakterlerin kullanılması izin verilmez. + + + Mixing numbers from different scripts is not allowed. + Farklı yazı türlerinden sayıların karıştırılması izin verilmez. + + + Using hidden overlay characters is not allowed. + Gizli üstü kaplama karakterlerinin kullanılması izin verilmez. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Dosya uzantısı geçersiz ({{ extension }}). İzin verilen uzantılar {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Tespit edilen karakter kodlaması geçersiz ({{ detected }}). İzin verilen kodlamalar: {{ encodings }}. + + + This value is not a valid MAC address. + Bu değer geçerli bir MAC adresi değildir. + + + This URL is missing a top-level domain. + Bu URL bir üst seviye alan adı eksik. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Bu değer çok kısa. En az bir kelime içermelidir.|Bu değer çok kısa. En az {{ min }} kelime içermelidir. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Bu değer çok uzun. Tek bir kelime içermelidir.|Bu değer çok uzun. {{ max }} veya daha az kelime içermelidir. + + + This value does not represent a valid week in the ISO 8601 format. + Bu değer ISO 8601 formatında geçerli bir haftayı temsil etmezdir. + + + This value is not a valid week. + Bu değer geçerli hafta değildir. + + + This value should not be before week "{{ min }}". + Bu değer “{{ min }}” haftasından önce olmamalıdır. + + + This value should not be after week "{{ max }}". + Bu değer “{{ max }}” haftasından sonra olmamalıdır + + + This value is not a valid Twig template. + Bu değer geçerli bir Twig şablonu olarak kabul edilmiyor. + + + This file is not a valid video. + Bu dosya geçerli bir video dosyası değil. + + + The size of the video could not be detected. + Videonun boyutu tespit edilemedi. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Video genişliği çok büyük ({{ width }}px). İzin verilen maksimum genişlik {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Video genişliği çok küçük ({{ width }}px). Beklenen minimum genişlik {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Video yüksekliği çok büyük ({{ height }}px). İzin verilen maksimum yükseklik {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Video yüksekliği çok küçük ({{ height }}px). Beklenen minimum yükseklik {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Videodaki piksel sayısı çok az ({{ pixels }} piksel). Beklenen minimum miktar {{ min_pixels }} pikseldir. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Videodaki piksel sayısı çok fazla ({{ pixels }} piksel). Beklenen maksimum miktar {{ max_pixels }} pikseldir. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Video oranı çok büyük ({{ ratio }}). İzin verilen maksimum oran {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Video oranı çok küçük ({{ ratio }}). Beklenen minimum oran {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video kare biçimde ({{ width }}x{{ height }}px). Kare videolara izin verilmez. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video yatay biçimde ({{ width }}x{{ height }}px). Yatay videolara izin verilmez. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video dikey biçimde ({{ width }}x{{ height }}px). Dikey videolara izin verilmez. + + + The video file is corrupted. + Video dosyası bozuk. + + + The video contains multiple streams. Only one stream is allowed. + Video birden fazla akış içeriyor. Yalnızca tek akışa izin verilir. + + + Unsupported video codec "{{ codec }}". + Desteklenmeyen video codec'i "{{ codec }}". + + + Unsupported video container "{{ container }}". + Desteklenmeyen video kapsayıcısı "{{ container }}". + + + The image file is corrupted. + Görüntü dosyası bozulmuş. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Görüntüdeki piksel sayısı çok az ({{ pixels }}). Beklenen minimum miktar {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Görüntüdeki piksel sayısı çok fazla ({{ pixels }}). Beklenen maksimum miktar {{ max_pixels }}. + + + This filename does not match the expected charset. + Bu dosya adı beklenen karakter kümesiyle eşleşmiyor. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.uk.xlf b/lib/symfony/validator/Resources/translations/validators.uk.xlf new file mode 100644 index 0000000000..587301575f --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.uk.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Значення повинно бути Ні. + + + This value should be true. + Значення повинно бути Так. + + + This value should be of type {{ type }}. + Тип значення повинен бути {{ type }}. + + + This value should be blank. + Значення повинно бути пустим. + + + The value you selected is not a valid choice. + Обране вами значення недопустиме. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Ви повинні обрати хоча б {{ limit }} варіант.|Ви повинні обрати хоча б {{ limit }} варіанти.|Ви повинні обрати хоча б {{ limit }} варіантів. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Ви повинні обрати не більше ніж {{ limit }} варіантів. + + + One or more of the given values is invalid. + Одне або кілька заданих значень є недопустимі. + + + This field was not expected. + Це поле не очікується. + + + This field is missing. + Це поле не вистачає. + + + This value is not a valid date. + Дане значення не є вірною датою. + + + This value is not a valid datetime. + Дане значення дати та часу недопустиме. + + + This value is not a valid email address. + Значення адреси электронної пошти недопустиме. + + + The file could not be found. + Файл не знайдено. + + + The file is not readable. + Файл не читається. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Файл занадто великий ({{ size }} {{ suffix }}). Дозволений максимальний розмір {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + MIME-тип файлу недопустимий ({{ type }}). Допустимі MIME-типи файлів {{ types }}. + + + This value should be {{ limit }} or less. + Значення повинно бути {{ limit }} або менше. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Значення занадто довге. Повинно бути рівне {{ limit }} символу або менше.|Значення занадто довге. Повинно бути рівне {{ limit }} символам або менше.|Значення занадто довге. Повинно бути рівне {{ limit }} символам або менше. + + + This value should be {{ limit }} or more. + Значення повинно бути {{ limit }} або більше. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Значення занадто коротке. Повинно бути рівне {{ limit }} символу або більше.|Значення занадто коротке. Повинно бути рівне {{ limit }} символам або більше.|Значення занадто коротке. Повинно бути рівне {{ limit }} символам або більше. + + + This value should not be blank. + Значення не повинно бути пустим. + + + This value should not be null. + Значення не повинно бути null. + + + This value should be null. + Значення повинно бути null. + + + This value is not valid. + Значення недопустиме. + + + This value is not a valid time. + Значення часу недопустиме. + + + This value is not a valid URL. + Значення URL недопустиме. + + + The two values should be equal. + Обидва занчення повинні бути одинаковими. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Файл занадто великий. Максимальний допустимий розмір {{ limit }} {{ suffix }}. + + + The file is too large. + Файл занадто великий. + + + The file could not be uploaded. + Файл не можливо завантажити. + + + This value should be a valid number. + Значення має бути допустимим числом. + + + This file is not a valid image. + Цей файл не є допустимим форматом зображення. + + + This value is not a valid IP address. + Це значення не є дійсною IP-адресою. + + + This value is not a valid language. + Це некоректна мова. + + + This value is not a valid locale. + Це некоректна локалізація. + + + This value is not a valid country. + Це некоректна країна. + + + This value is already used. + Це значення вже використовується. + + + The size of the image could not be detected. + Не вдалося визначити розмір зображення. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ширина зображення занадто велика ({{ width }}px). Максимально допустима ширина {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ширина зображення занадто мала ({{ width }}px). Мінімально допустима ширина {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Висота зображення занадто велика ({{ height }}px). Максимально допустима висота {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Висота зображення занадто мала ({{ height }}px). Мінімально допустима висота {{ min_height }}px. + + + This value should be the user's current password. + Значення має бути поточним паролем користувача. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Значення повинно бути рівним {{ limit }} символу.|Значення повинно бути рівним {{ limit }} символам.|Значення повинно бути рівним {{ limit }} символам. + + + The file was only partially uploaded. + Файл був завантажений лише частково. + + + No file was uploaded. + Файл не був завантажений. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + У php.ini не було налаштовано тимчасової теки, або налаштована тека не існує. + + + Cannot write temporary file to disk. + Неможливо записати тимчасовий файл на диск. + + + A PHP extension caused the upload to fail. + Розширення PHP викликало помилку при завантаженні. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ця колекція повинна містити {{ limit }} елемент чи більше.|Ця колекція повинна містити {{ limit }} елемента чи більше.|Ця колекція повинна містити {{ limit }} елементів чи більше. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ця колекція повинна містити {{ limit }} елемент чи менше.|Ця колекція повинна містити {{ limit }} елемента чи менше.|Ця колекція повинна містити {{ limit }} елементов чи менше. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ця колекція повинна містити рівно {{ limit }} елемент.|Ця колекція повинна містити рівно {{ limit }} елемента.|Ця колекція повинна містити рівно {{ limit }} елементів. + + + Invalid card number. + Невірний номер карти. + + + Unsupported card type or invalid card number. + Непідтримуваний тип карти або невірний номер карти. + + + This value is not a valid International Bank Account Number (IBAN). + Це значення не є дійсним міжнародним номером банківського рахунку (IBAN). + + + This value is not a valid ISBN-10. + Значення не у форматі ISBN-10. + + + This value is not a valid ISBN-13. + Значення не у форматі ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Значення не відповідає форматам ISBN-10 та ISBN-13. + + + This value is not a valid ISSN. + Значення має невірний формат ISSN. + + + This value is not a valid currency. + Значення має невірний формат валюти. + + + This value should be equal to {{ compared_value }}. + Значення повинно дорівнювати {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Значення має бути більше ніж {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Значення має бути більше або дорівнювати {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Значення має бути ідентичним {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Значення повинно бути менше ніж {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Значення повинно бути менше або дорівнювати {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Значення не повинно дорівнювати {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Значення не повинно бути ідентичним {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Співвідношення сторін зображення занадто велике ({{ ratio }}). Максимальне співвідношення сторін {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Співвідношення сторін зображення занадто мало ({{ ratio }}). Мінімальне співвідношення сторін {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Зображення квадратне ({{ width }}x{{ height }}px). Квадратні зображення не дозволені. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Зображення альбомної орієнтації ({{ width }}x{{ height }}px). Зображення альбомної орієнтації не дозволені. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Зображення в портретній орієнтації ({{ width }}x{{ height }}px). Зображення в портретної орієнтації не дозволені. + + + An empty file is not allowed. + Порожні файли не дозволені. + + + The host could not be resolved. + Ім'я хоста не знайдено. + + + This value does not match the expected {{ charset }} charset. + Значення не збігається з очікуваним {{ charset }} кодуванням. + + + This value is not a valid Business Identifier Code (BIC). + Це значення не є дійсним банківським кодом (BIC). + + + Error + Помилка + + + This value is not a valid UUID. + Це значення не є дійсним UUID. + + + This value should be a multiple of {{ compared_value }}. + Це значення повинне бути кратним {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Банківський код (BIC) не пов’язаний із міжнародним номером банківського рахунку (IBAN) {{ iban }}. + + + This value should be valid JSON. + Значення має бути корректним JSON. + + + This collection should contain only unique elements. + Ця колекція повинна мати тільки унікальни значення. + + + This value should be positive. + Значення має бути позитивним. + + + This value should be either positive or zero. + Значення має бути позитивним або дорівнювати нулю. + + + This value should be negative. + Значення має бути негативним. + + + This value should be either negative or zero. + Значення має бути негативним або дорівнювати нулю. + + + This value is not a valid timezone. + Значення не є дійсним часовим поясом. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Цей пароль був скомпрометований в результаті витоку даних та не повинен використовуватися. Будь ласка, використовуйте інший пароль. + + + This value should be between {{ min }} and {{ max }}. + Значення має бути між {{ min }} та {{ max }}. + + + This value is not a valid hostname. + Значення не є дійсним іменем хоста. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Кількість елементів у цій колекції повинна бути кратною {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Значення повинно задовольняти хоча б одному з наступних обмежень: + + + Each element of this collection should satisfy its own set of constraints. + Кожен елемент цієї колекції повинен задовольняти власному набору обмежень. + + + This value is not a valid International Securities Identification Number (ISIN). + Це значення не є дійсним міжнародним ідентифікаційним номером цінних паперів (ISIN). + + + This value should be a valid expression. + Це значення має бути дійсним виразом. + + + This value is not a valid CSS color. + Це значення не є дійсним CSS кольором. + + + This value is not a valid CIDR notation. + Це значення не є дійсною CIDR нотаціею. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Значення в мережевій масці має бути між {{ min }} та {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Назва файлу занадто довга. Вона має містити {{ filename_max_length }} символів або менше.|Назва файлу занадто довга. Вона має містити {{ filename_max_length }} символів або менше. + + + The password strength is too low. Please use a stronger password. + Надійність пароля занадто низька. Будь ласка, створіть складніший пароль. + + + This value contains characters that are not allowed by the current restriction-level. + Це значення містить символи, які не дозволяються поточним рівнем обмежень. + + + Using invisible characters is not allowed. + Використання невидимих ​​символів не допускається. + + + Mixing numbers from different scripts is not allowed. + Змішувати числа з різних скриптів не допускається. + + + Using hidden overlay characters is not allowed. + Використання прихованих накладених символів не допускається. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Розширення файлу недопустиме ({{ extension }}). Дозволені розширення {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Недопустиме кодування символів ({{ detected }}). Допустимі кодування: {{ encodings }}. + + + This value is not a valid MAC address. + Це значення не є дійсною MAC-адресою. + + + This URL is missing a top-level domain. + Цьому URL не вистачає домену верхнього рівня. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Це значення занадто коротке. Воно має містити принаймні одне слово.|Це значення занадто коротке. Мінімальна кількість слів — {{ min }}. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Це значення занадто довге. Воно має містити лише одне слово.|Це значення занадто довге. Максимальна кількість слів — {{ max }}. + + + This value does not represent a valid week in the ISO 8601 format. + Це значення не представляє дійсний тиждень у форматі ISO 8601. + + + This value is not a valid week. + Це значення не є дійсним тижнем. + + + This value should not be before week "{{ min }}". + Це значення не повинно бути раніше тижня "{{ min }}". + + + This value should not be after week "{{ max }}". + Це значення не повинно бути після тижня "{{ max }}". + + + This value is not a valid Twig template. + Це значення не є дійсним шаблоном Twig. + + + This file is not a valid video. + Цей файл не є допустимим відеофайлом. + + + The size of the video could not be detected. + Не вдалося визначити розмір відеофайлу. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ширина відеофайлу занадто велика ({{ width }}px). Максимально допустима ширина {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ширина відеофайлу занадто мала ({{ width }}px). Мінімально допустима ширина {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Висота відеофайлу занадто велика ({{ height }}px). Максимально допустима висота {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Висота відеофайлу занадто мала ({{ height }}px). Мінімально допустима висота {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Кількість пікселів у відеофайлі занадто мала ({{ pixels }} пікселів). Мінімально допустима кількість {{ min_pixels }} пікселів. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Кількість пікселів у відеофайлі занадто велика ({{ pixels }} пікселів). Максимально допустима кількість {{ max_pixels }} пікселів. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Співвідношення сторін відеофайлу занадто велике ({{ ratio }}). Максимально допустиме співвідношення сторін {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Співвідношення сторін відеофайлу занадто мале ({{ ratio }}). Мінімально допустиме співвідношення сторін {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Відеофайл має квадратні пропорції ({{ width }}x{{ height }}px). Квадратні відеофайли не дозволені. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Відеофайл в альбомній орієнтації ({{ width }}x{{ height }}px). Відеофайли в альбомній орієнтації не дозволені. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Відеофайл у портретній орієнтації ({{ width }}x{{ height }}px). Відеофайли у портретній орієнтації не дозволені. + + + The video file is corrupted. + Відеофайл пошкоджено. + + + The video contains multiple streams. Only one stream is allowed. + Відеофайл містить кілька потоків. Дозволено лише один потік. + + + Unsupported video codec "{{ codec }}". + Непідтримуваний відеокодек «{{ codec }}». + + + Unsupported video container "{{ container }}". + Непідтримуваний відеоконтейнер "{{ container }}". + + + The image file is corrupted. + Файл зображення пошкоджено. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Кількість пікселів у зображенні занадто мала ({{ pixels }} пікселів). Мінімально допустима кількість {{ min_pixels }} пікселів. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Кількість пікселів у зображенні занадто велика ({{ pixels }} пікселів). Максимально допустима кількість {{ max_pixels }} пікселів. + + + This filename does not match the expected charset. + Назва файлу не відповідає очікуваному набору символів. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.ur.xlf b/lib/symfony/validator/Resources/translations/validators.ur.xlf new file mode 100644 index 0000000000..18e5a0efdd --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.ur.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + یہ ويليو غلط ہونی چاہیے + + + This value should be true. + یہ ويليو درست ہونی چاہیے + + + This value should be of type {{ type }}. + قسم کی ہونی چاہیے {{type}} يھ ويليو + + + This value should be blank. + یہ ويليو خالی ہونی چاہیے + + + The value you selected is not a valid choice. + آپ نے جو ويليو منتخب کی ہے وہ درست انتخاب نہیں ہے + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + کا انتخاب کرنا چاہیے {{limit}} کا انتخاب کرنا چاہیے ۔آّپ کو کم اذ کم {{limit}} آپ کو کم از کم + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + کا انتخاب کرنا چاہیے {{limit}} کا انتخاب کرنا چاہیے ۔آّپ کو ذيادھ سے ذيادھ {{limit}} آپ کو ذيادھ سے ذيادھ + + + One or more of the given values is invalid. + دی گئی ويليوذ میں سے ایک یا زیادھ ويليوذ غلط ہیں + + + This field was not expected. + اس فیلڈ کی توقع نہیں تھی + + + This field is missing. + یہ فیلڈ غائب ہے + + + This value is not a valid date. + یہ ويليو درست تاریخ نہیں ہے + + + This value is not a valid datetime. + یہ ويليو درست تاریخ وقت نہیں ہے + + + This value is not a valid email address. + یہ ويليو درست ای میل ایڈریس نہیں ہے + + + The file could not be found. + فائل نہیں مل سکی + + + The file is not readable. + فائل پڑھنے کے قابل نہیں ہے + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + {{ suffix }} {{ limit }} زیادہ سے زیادہ سائز کی اجازت ہے {{ suffix }}) ({{ size }} فائل بہت بڑی ہے + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + ہیں {{ types }} مائیم کی قسمیں ({{ type }}) فائل کی ماۂيم قسم غلط ہے + + + This value should be {{ limit }} or less. + یا اس سے کم ہونی چاہیے {{ limit }} یہ ويليو + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + حروف یا اس سے کم ہونے چاہئیں {{ limit }} حرف یا اس سے کم ہونا چاہیے۔|یہ ويليو بہت لمبی ہے۔ اس میں{{ limit }} یہ ويليو بہت لمبی ہے۔ اس میں + + + This value should be {{ limit }} or more. + یا اس سے زیادہ ہونی چاہیے {{ limit }} یہ ويليو + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + حروف یا اس سے زیادہ ہونے چاہئیں {{ limit }} حرف یا اس سے زیادہ ہونا چاہیے۔|یہ ويليو بہت چھوٹی ہے۔ اس میں{{ limit }} یہ ويليو بہت مختصر ہے۔ اس میں + + + This value should not be blank. + یہ ويليو خالی نہیں ہونی چاہیے + + + This value should not be null. + یہ ويليو خالی نہیں ہونی چاہیے + + + This value should be null. + یہ ويليو خالی ہونی چاہیے + + + This value is not valid. + یہ ويليو درست نہیں ہے + + + This value is not a valid time. + یہ ويليو درست وقت نہیں ہے + + + This value is not a valid URL. + نہیں ہے URL یہ ويليو درست + + + The two values should be equal. + دونوں ويليوذ برابر ہونی چاہئیں + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + {{ suffix }} {{ limit }} فائل بہت بڑی ہے۔ زیادہ سے زیادہ سائز کی اجازت ہے + + + The file is too large. + فائل بہت بڑی ہے + + + The file could not be uploaded. + فائل اپ لوڈ نہیں ہو سکی + + + This value should be a valid number. + یہ ويليو ایک درست نمبر ہونی چاہیے + + + This file is not a valid image. + یہ فائل درست تصویر نہیں ہے + + + This value is not a valid IP address. + یہ قیمت کوئی درست IP پتہ نہیں ہے۔ + + + This value is not a valid language. + یہ ويليو درست زبان نہیں ہے + + + This value is not a valid locale. + یہ ويليو درست مقام نہیں ہے + + + This value is not a valid country. + یہ ويليو ایک درست ملک نہیں ہے + + + This value is already used. + یہ ويليو پہلے ہی استعمال ہو چکی ہے + + + The size of the image could not be detected. + تصویر کے سائز کا پتہ نہیں چل سکا + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + ہے {{ max_width }}px اجازت دی گئی زیادہ سے زیاد چوڑائی ({{ width }}px) تصویر کی چوڑائی بہت بڑی ہے + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + ہے {{ min_width }}px کم از کم چوڑائی متوقع({{ width }}px) تصویر کی چوڑائی بہت چھوٹی ہے + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + ہے {{ max_height }}px اجازت دی گئی زیادہ سے زیاد اونچائی ({{ height }}px) تصویر کی اونچائی بہت بڑی ہے + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + ہے {{ min_height }}px متوقع کم از کم اونچائی ({{ height }}px) تصویر کی اونچائی بہت چھوٹی ہے + + + This value should be the user's current password. + یہ ويليو صارف کا موجودہ پاس ورڈ ہونا چاہیے + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + حروف ہونے چاہئیں {{ limit }} حرف ہونا چاہیے۔|اس ويليو میں بالکل {{ limit }} اس ويليو میں بالکل + + + The file was only partially uploaded. + فائل صرف جزوی طور پر اپ لوڈ کی گئی تھی + + + No file was uploaded. + کوئی فائل اپ لوڈ نہیں کی گئی + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + php.ini میں کوئی عارضی فولڈر ترتیب نہیں دیا گیا تھا، یا ترتیب دیا گیا فولڈر موجود نہیں ہے۔ + + + Cannot write temporary file to disk. + عارضی فائل کو ڈسک پر نہیں لکھا جا سکتا + + + A PHP extension caused the upload to fail. + پی ایچ پی کی توسیع کی وجہ سے اپ لوڈ ناکام ہو گیا + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + عناصر یا اس سے زیادہ ہونا چاہیے {{ limit } عنصر یا اس سے زیادہ ہونا چاہیے۔|اس مجموعہ میں {{ limit }} اس مجموعہ میں + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + عناصر یا اس سے کم ہونا چاہیے {{ limit } عنصر یا اس سے کم ہونا چاہیے۔|اس مجموعہ میں {{ limit }} اس مجموعہ میں + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + عنصر ہونا چاہیے {{ limit }} عنصر ہونا چاہیے۔|اس مجموعے میں بالکل {{ limit }} اس مجموعہ میں بالکل + + + Invalid card number. + غلط کارڈ نمبر + + + Unsupported card type or invalid card number. + غیر تعاون یافتہ کارڈ کی قسم یا غلط کارڈ نمبر + + + This value is not a valid International Bank Account Number (IBAN). + یہ قیمت کوئی درست بین الاقوامی بینک اکاؤنٹ نمبر (IBAN) نہیں ہے۔ + + + This value is not a valid ISBN-10. + نہیں ہے ISBN-10 یھ ويليو درست۔ + + + This value is not a valid ISBN-13. + نہیں ہے ISBN-13 یھ ويليو درست۔ + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + ISBN-13 ے اور نہ ہی درست ISBN-10 یہ ويليو نہ تو درست + + + This value is not a valid ISSN. + نہیں ہے ISSNیھ ويليو درست۔ + + + This value is not a valid currency. + یہ ويليو درست کرنسی نہیں ہے + + + This value should be equal to {{ compared_value }}. + کے برابر ہونا چاہیے {{ compared_value }} یھ ويليو + + + This value should be greater than {{ compared_value }}. + سے بڈي ہوني چاہیے {{ compared_value }} یھ ويليو + + + This value should be greater than or equal to {{ compared_value }}. + سے بڈي یا برابر ہوني چاہیے {{ compared_value }} یھ ويليو + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + {{ compared_value }} {{ compared_value_type }} یہ ويليو ایک جیسی ہونی چاہیے۔ + + + This value should be less than {{ compared_value }}. + سے کم ہوني چاہیے {{ compared_value }} یھ ويليو + + + This value should be less than or equal to {{ compared_value }}. + سے کم یا برابر ہوني چاہیے {{ compared_value }} یھ ويليو + + + This value should not be equal to {{ compared_value }}. + کے برابر نھيں ہوني چاہیے {{ compared_value }} یھ ويليو + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + ایک جیسی نیيں ہونی چاہیے {{ compared_value }} {{ compared_value_type }} یہ ويليو + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + ہے {{ max_ratio }} اجازت شدہ زیادہ سے زیادہ تناسب ({{ ratio }}) تصویر کا تناسب بہت بڑا ہے + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + ہے{{ min_ratio }} ratio متوقع کم از کم ({{ ratio }}) بہت چھوٹا ہے ratio تصویر کا + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + مربع تصاویر کی اجازت نہیں ہے (px{{ height }}x{{ width }}) تصویر مربع ہے + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + زمین کی تزئین پر مبنی تصاویر کی اجازت نہیں ہے ({{ width }}x{{ height }}px) تصویر زمین کی تزئین پر مبنی ہے + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + پورٹریٹ پر مبنی تصاویر کی اجازت نہیں ہے ({{ width }}x{{ height }}px) تصویر پورٹریٹ پر مبنی ہے + + + An empty file is not allowed. + خالی فائل کی اجازت نہیں ہے + + + The host could not be resolved. + میزبان حل نہیں ہو سکا + + + This value does not match the expected {{ charset }} charset. + کے جيسي نہیں ہے charset {{ charset }} یہ ويليو متوقع + + + This value is not a valid Business Identifier Code (BIC). + یہ قیمت کوئی درست بزنس شناختی کوڈ (BIC) نہیں ہے۔ + + + Error + خرابی + + + This value is not a valid UUID. + یہ قیمت کوئی درست UUID نہیں ہے۔ + + + This value should be a multiple of {{ compared_value }}. + کا ضرب ہوني چاہیے {{ compared_value }} یہ ويليو + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + سے وابستہ نہیں ہے IBAN {{ iban }} (BIC) یہ کاروباری شناختی کوڈ + + + This value should be valid JSON. + ہونی چاہیے JSON یہ ويليو درست + + + This collection should contain only unique elements. + یہ مجموعہ صرف منفرد عناصر پر مشتمل ہونا چاہیے + + + This value should be positive. + یہ ويليو مثبت ہونی چاہیے + + + This value should be either positive or zero. + یہ ويليو یا تو مثبت یا صفر ہونی چاہیے + + + This value should be negative. + یہ ويليو منفی ہونی چاہیے + + + This value should be either negative or zero. + یہ ويليو یا تو منفی یا صفر ہونی چاہیے + + + This value is not a valid timezone. + یہ ويليو درست ٹائم زون نہیں ہے + + + This password has been leaked in a data breach, it must not be used. Please use another password. + یہ پاس ورڈ ڈیٹا کی خلاف ورزی میں لیک ہو گیا ہے، اسے استعمال نہیں کرنا چاہیے۔ براۓ کرم دوسرا پاس ورڈ استعمال کریں + + + This value should be between {{ min }} and {{ max }}. + کے درمیان ہونی چاہیے {{ max }} اور {{ min }} یہ ويليو + + + This value is not a valid hostname. + نہیں ہے hostname یہ ويليو درست + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + کی ضرب ہونی چاہیے {{ compared_value }} اس مجموعہ میں عناصر کی تعداد + + + This value should satisfy at least one of the following constraints: + اس ويليو کو درج ذیل رکاوٹوں میں سے کم از کم ایک کو پورا کرنا چاہیے + + + Each element of this collection should satisfy its own set of constraints. + اس مجموعے کے ہر عنصر کو اپنی پابندیوں کے سیٹ کو پورا کرنا چاہیے + + + This value is not a valid International Securities Identification Number (ISIN). + نہیں ہے (ISIN) یہ ويليو درست بین الاقوامی سیکیورٹیز شناختی نمبر + + + This value should be a valid expression. + یہ ويليو ایک درست اظہار ہوني چاہیے + + + This value is not a valid CSS color. + رنگ نہیں ہے CSS یہ ويليو درست + + + This value is not a valid CIDR notation. + نوٹیشن نہیں ہے CIDR یہ ويليو ایک درست + + + The value of the netmask should be between {{ min }} and {{ max }}. + کے درمیان ہونی چاہیے {{ max }} اور {{ min }} نیٹ ماسک کی ويليو + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + فائل کا نام بہت لمبا ہے۔ اس میں {{ filename_max_length }} حرف یا اس سے کم ہونے چاہئیں۔|فائل کا نام بہت لمبا ہے۔ اس میں {{ filename_max_length }} حروف یا اس سے کم ہونے چاہئیں۔ + + + The password strength is too low. Please use a stronger password. + پاس ورڈ کی طاقت بہت کم ہے۔ براہ کرم مضبوط پاس ورڈ استعمال کریں۔ + + + This value contains characters that are not allowed by the current restriction-level. + اس قدر میں ایسے حروف موجود ہیں جو موجودہ پابندی کی سطح کی طرف سے اجازت نہیں ہیں۔ + + + Using invisible characters is not allowed. + نادیدہ حروف استعمال کرنے کی اجازت نہیں ہے۔ + + + Mixing numbers from different scripts is not allowed. + مختلف اسکرپٹس سے نمبروں کو ملا کر استعمال کرنے کی اجازت نہیں ہے۔ + + + Using hidden overlay characters is not allowed. + چھپے ہوئے اوورلے کریکٹرز کا استعمال کرنے کی اجازت نہیں ہے۔ + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + فائل کی توسیع نامناسب ہے ({{ extension }})۔ اجازت شدہ توسیعات {{ extensions }} ہیں۔ + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + پتہ چلنے والی کریکٹر انکوڈنگ نامناسب ہے ({{ detected }})۔ اجازت شدہ انکوڈنگز {{ encodings }} ہیں۔ + + + This value is not a valid MAC address. + یہ قیمت کوئی درست MAC پتہ نہیں ہے۔ + + + This URL is missing a top-level domain. + اس URL میں ٹاپ لیول ڈومین موجود نہیں ہے۔ + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + یہ قدر بہت مختصر ہے۔ اس میں کم از کم ایک لفظ ہونا چاہیے۔|یہ قدر بہت مختصر ہے۔ اس میں کم از کم {{ min }} الفاظ ہونے چاہئیں۔ + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + یہ قدر بہت طویل ہے۔ اس میں صرف ایک لفظ ہونا چاہیے۔|یہ قدر بہت طویل ہے۔ اس میں {{ max }} الفاظ یا اس سے کم ہونے چاہئیں۔ + + + This value does not represent a valid week in the ISO 8601 format. + یہ قدر آئی ایس او 8601 فارمیٹ میں ایک درست ہفتے کی نمائندگی نہیں کرتی ہے۔ + + + This value is not a valid week. + یہ قدر ایک درست ہفتہ نہیں ہے۔ + + + This value should not be before week "{{ min }}". + یہ قدر ہفتہ "{{ min }}" سے پہلے نہیں ہونا چاہیے۔ + + + This value should not be after week "{{ max }}". + یہ قدر ہفتہ "{{ max }}" کے بعد نہیں ہونا چاہیے۔ + + + This value is not a valid Twig template. + یہ قدر ایک درست Twig سانچہ نہیں ہے۔ + + + This file is not a valid video. + یہ فائل ایک درست ویڈیو نہیں ہے۔ + + + The size of the video could not be detected. + ویڈیو کا سائز معلوم نہیں کیا جا سکا۔ + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + ویڈیو کی چوڑائی بہت زیادہ ہے ({{ width }}px)۔ اجازت شدہ زیادہ سے زیادہ چوڑائی {{ max_width }}px ہے۔ + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + ویڈیو کی چوڑائی بہت کم ہے ({{ width }}px)۔ متوقع کم از کم چوڑائی {{ min_width }} پکسل ہے۔ + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + ویڈیو کی اونچائی بہت زیادہ ہے ({{ height }}px)۔ مجاز زیادہ سے زیادہ اونچائی {{ max_height }}px ہے۔ + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + ویڈیو کی اونچائی بہت کم ہے ({{ height }}px)۔ متوقع کم از کم اونچائی {{ min_height }}px ہے۔ + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + ویڈیو میں پکسل بہت کم ہیں ({{ pixels }}). متوقع کم از کم مقدار {{ min_pixels }} ہے۔ + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + ویڈیو میں پکسلز بہت زیادہ ہیں ({{ pixels }}). متوقع زیادہ سے زیادہ مقدار {{ max_pixels }} ہے۔ + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + ویڈیو کا تناسب بہت بڑا ہے ({{ ratio }}). اجازت شدہ زیادہ سے زیادہ تناسب {{ max_ratio }} ہے۔ + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + ویڈیو کا تناسب بہت چھوٹا ہے ({{ ratio }}). متوقع کم از کم تناسب {{ min_ratio }} ہے۔ + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + ویڈیو مربع ہے ({{ width }}x{{ height }}px). مربع ویڈیوز کی اجازت نہیں ہے۔ + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + ویڈیو افقی سمت میں ہے ({{ width }}x{{ height }} پکسل). افقی ویڈیوز کی اجازت نہیں ہے۔ + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + ویڈیو عمودی رخ پر ہے ({{ width }}x{{ height }}px). عمودی رخ والی ویڈیوز کی اجازت نہیں ہے۔ + + + The video file is corrupted. + ویڈیو فائل خراب ہے۔ + + + The video contains multiple streams. Only one stream is allowed. + ویڈیو میں متعدد اسٹریمز ہیں۔ صرف ایک اسٹریم کی اجازت ہے۔ + + + Unsupported video codec "{{ codec }}". + غیر معاون ویڈیو کوڈیک "{{ codec }}"۔ + + + Unsupported video container "{{ container }}". + غیر معاونت یافتہ ویڈیو کنٹینر "{{ container }}". + + + The image file is corrupted. + تصویری فائل خراب ہے۔ + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + تصویر میں پکسلز بہت کم ہیں ({{ pixels }})۔ متوقع کم سے کم مقدار {{ min_pixels }} ہے۔ + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + تصویر میں پکسلز بہت زیادہ ہیں ({{ pixels }}). متوقع زیادہ سے زیادہ مقدار {{ max_pixels }} ہے. + + + This filename does not match the expected charset. + اس فائل کا نام متوقع حرفوں کے مجموعے سے مطابقت نہیں رکھتا۔ + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.uz.xlf b/lib/symfony/validator/Resources/translations/validators.uz.xlf new file mode 100644 index 0000000000..f86216abb6 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.uz.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Qiymat false bo'lishi kerak. + + + This value should be true. + Qiymat true bo'lishi kerak. + + + This value should be of type {{ type }}. + Qiymat turi {{ type }} bo'lishi kerak. + + + This value should be blank. + Qiymat bo'sh bo'lishi kerak. + + + The value you selected is not a valid choice. + Tanlangan qiymat yaroqli emas. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Siz hech bo'lmaganda {{ limit }} ta qiymat tanlashingiz kerak.|Siz kamida {{ limit }} ta qiymat tanlashingiz kerak. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Siz {{ limit }} ta qiymatni tanlashingiz kerak.|Siz {{ limit }} dan ortiq qiymat tanlashingiz kerak. + + + One or more of the given values is invalid. + Belgilangan qiymatlarning bir yoki bir nechtasi yaroqsiz. + + + This field was not expected. + Ushbu maydon kutilmagan edi. + + + This field is missing. + Bu maydon majvud emas. + + + This value is not a valid date. + Ushbu sana noto'g'ri. + + + This value is not a valid datetime. + Sana va vaqt qiymati noto'g'ri. + + + This value is not a valid email address. + Elektron pochta manzili noto'g'ri. + + + The file could not be found. + Fayl topilmadi. + + + The file is not readable. + Faylni o'qib bo'lmadi. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Fayl hajmi katta ({{ size }} {{ suffix }}). Maksimal ruxsat etilgan hajim {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Faylning MIME turi noto'g'ri ({{ type }}). Ruxsat etilgan MIME turlar {{ types }}. + + + This value should be {{ limit }} or less. + Qiymat {{ limit }} ga teng yoki kam bo'lishi kerak. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Qiymat juda uzun. {{ limit }} ga teng yoki kam bo'lishi kerak.|Qiymat juda uzun. {{ limit }} yoki undan kam belgidan iborat bo'lishi kerak. + + + This value should be {{ limit }} or more. + Qiymat {{ limit }} yoki undan ortiq bo'lishi kerak. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Qiymat juda qisqa. {{ limit }} ta yoki undan ortiq belgidan iborat bo'lishi kerak.|Qiymat juda qisqa. {{ limit }} yoki undan ko'p belgidan iborat bo'lishi kerak + + + This value should not be blank. + Qiymatni bo'sh kirtish mumkin emas. + + + This value should not be null. + Qiymat null bo'lmasligi kerak. + + + This value should be null. + Qiymat null bo'lishi kerak. + + + This value is not valid. + Qiymat noto'g'ri. + + + This value is not a valid time. + Vaqt noto'g'ri. + + + This value is not a valid URL. + URL noto'g'ri + + + The two values should be equal. + Ikkala qiymat ham bir xil bo'lishi kerak. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Fayl hajmi katta. Maksimal ruxsat berilgan hajim {{ limit }} {{ suffix }}. + + + The file is too large. + Fayl hajmi katta. + + + The file could not be uploaded. + Faylni yuklab bo'lmadi. + + + This value should be a valid number. + Qiymat raqam bo'lishi kerak. + + + This file is not a valid image. + Fayl yaroqli rasm formati emas. + + + This value is not a valid IP address. + Bu qiymat haqiqiy IP manzil emas. + + + This value is not a valid language. + Noto'g'ri til. + + + This value is not a valid locale. + Ushbu qiymat mahalliy qiymat emas. + + + This value is not a valid country. + Mamlakat qiymati noto'g'ri. + + + This value is already used. + Ushbu qiymat allaqachon ishlatilgan. + + + The size of the image could not be detected. + Rasm o'lchamini aniqlab bo'lmadi. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Rasm kengligi juda katta ({{ width }}px). Maksimal ruxsat etilgan kenglik {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Rasm kengligi juda kichkina ({{ width }}px). Minimal ruxsat etilgan kenglik {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Rasm bo'yi juda katta ({{ height }}px). Maksimal ruxsat etilgan balandlik {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Rasm bo'yi juda kichkina ({{ height }}px). Minimal ruxsat etilgan balandlik {{ min_height }}px. + + + This value should be the user's current password. + Qiymat joriy foydalanuvchi paroli bo'lishi kerak. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Qiymat {{ limit }} ta belgidan iborat bo'lishi kerak.|Qiymat {{ limit }} belgidan iborat bo'lishi kerak. + + + The file was only partially uploaded. + Fayl faqat qisman yuklangan. + + + No file was uploaded. + Fayl yuklanmagan. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + php.ini da vaqtinchalik katalog sozlanmagan, yoki sozlangan katalog mavjud emas. + + + Cannot write temporary file to disk. + Diskka vaqtinchalik faylni yozib bo'lmadi. + + + A PHP extension caused the upload to fail. + PHP kengaytmasi yuklash paytida xatolik yuz berdi. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ushbu to'plam {{ limit }} ta yoki undan ko'p narsalarni o'z ichiga olishi kerak.|Ushbu to'plam {{ limit }} yoki undan ortiq narsalarni o'z ichiga olishi kerak. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ushbu to'plam {{ limit }} ta yoki undan kam narsalarni o'z ichiga olishi kerak.|Ushbu to'plamda {{ limit }} yoki undan kam element bo'lishi kerak. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ushbu to'plam to'liq {{ limit }} narsani o'z ichiga olishi kerak.|Ushbu to'plamda to'liq {{ limit }} ta ma'lumotlar bo'lishi kerak. + + + Invalid card number. + Kata raqami noto'g'ri. + + + Unsupported card type or invalid card number. + Qo'llab-quvvatlanmaydigan karta turi yoki yaroqsiz karta raqami. + + + This value is not a valid International Bank Account Number (IBAN). + Bu qiymat haqiqiy Xalqaro Bank Hisob Raqami (IBAN) emas. + + + This value is not a valid ISBN-10. + Qiymat to'g'ri ISBN-10 formatida emas. + + + This value is not a valid ISBN-13. + Qiymat to'g'ri ISBN-13 formatida emas. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Qiymat ISBN-10 va ISBN-13 formatlariga mos kelmaydi. + + + This value is not a valid ISSN. + Qiymat ISSN formatiga mos kelmaydi. + + + This value is not a valid currency. + Noto'g'ri valyuta formati. + + + This value should be equal to {{ compared_value }}. + Qiymat {{ compared_value }} ga teng bo'lishi shart. + + + This value should be greater than {{ compared_value }}. + Qiymat {{ compared_value }} dan katta bo'lishi shart. + + + This value should be greater than or equal to {{ compared_value }}. + Qiymat {{ compared_value }} dan katta yoki teng bo'lishi shart. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Значение должно быть идентичным {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Qiymat bir xil bo'lishi kerak {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Qiymat {{ compared_value }} dan kichik yoki teng bo'lishi shart. + + + This value should not be equal to {{ compared_value }}. + Qiymat {{ compared_value }} ga teng bo'lmasligi kerak. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Qiymat bir xil bo'lishi kerak emas {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Rasmning tomonlari nisbati juda katta ({{ ratio }}). Maksimal tomonlar nisbati {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Rasmning format nisbati juda kichik ({{ ratio }}). Minimal tomonlar nisbati {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Rasm kvadrat shaklida ({{ width }}x{{ height }}px). Kvadrat shaklida tasvirlarga ruxsat berilmaydi. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Landshaft tasvir ({{ width }}x{{ height }}px). Landshaft rasmlarga ruxsat berilmaydi. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Portret rasm ({{ width }}x{{ height }}px). Portretlarga ruxsat berilmaydi. + + + An empty file is not allowed. + Bo'sh fayllarga ruxsat berilmagan. + + + The host could not be resolved. + Xost nomini nomiga ruxsat berilmagan. + + + This value does not match the expected {{ charset }} charset. + Qiymat kutilgan {{ charset }} kodlashiga mos kelmaydi. + + + This value is not a valid Business Identifier Code (BIC). + Bu qiymat haqiqiy Biznes Identifikatsiya Kodi (BIC) emas. + + + Error + Xatolik + + + This value is not a valid UUID. + Bu qiymat haqiqiy UUID emas. + + + This value should be a multiple of {{ compared_value }}. + Qiymat {{ compared_value }} ning ko'paytmasi bo'lishi kerak. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Ushbu BIC IBAN {{ iban }} bilan bog'liq emas.. + + + This value should be valid JSON. + Qiymat to'g'ri JSON bo'lishi kerak. + + + This collection should contain only unique elements. + Ushbu kolleksiyada takroriy elementlar bo'lmasligi kerak. + + + This value should be positive. + Qiymat musbat bo'lishi kerak. + + + This value should be either positive or zero. + Qiymat musbat yoki 0 ga teng bo'lishi kerak. + + + This value should be negative. + Qiymat manfiy bo'lishi kerak. + + + This value should be either negative or zero. + Qiymat manfiy yoki 0 ga teng bo'lishi kerak. + + + This value is not a valid timezone. + Qiymat to'g'ri vaqt zonasi emas. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Ushbu parol ma'lumotlarning tarqalishi tufayli buzilgan va uni ishlatmaslik kerak. Boshqa paroldan foydalaning. + + + This value should be between {{ min }} and {{ max }}. + Qiymat {{ min }} va {{ max }} oralig'ida bo'lishi shart. + + + This value is not a valid hostname. + Qiymat to'g'ri xost nomi emas. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Ushbu to'plamdagi narsalar soni {{ compared_value }} dan ko'p bo'lishi kerak. + + + This value should satisfy at least one of the following constraints: + Qiymat quyidagi cheklovlardan kamida bittasiga javob berishi kerak: + + + Each element of this collection should satisfy its own set of constraints. + Ushbu to'plamdagi har bir narsa o'ziga xos cheklovlarni qondirishi kerak. + + + This value is not a valid International Securities Identification Number (ISIN). + Qiymat Qimmatli qog'ozlarning xalqaro identifikatsiya raqami (ISIN) ga mos emas. + + + This value should be a valid expression. + Ushbu qiymat to'g'ri ifoda bo'lishi kerak. + + + This value is not a valid CSS color. + Bu qiymat haqiqiy CSS rangi emas. + + + This value is not a valid CIDR notation. + Qiymat CIDR belgisiga mos kelmaydi. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Tarmoq niqobining qiymati {{ min }} va {{ max }} oralig'ida bo'lishi kerak. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Fayl nomi juda uzun. U {{ filename_max_length }} belgidan iborat boʻlishi kerak.|Fayl nomi juda uzun. U {{ filename_max_length }} ta belgidan iborat boʻlishi kerak. + + + The password strength is too low. Please use a stronger password. + Parol kuchi juda past. Iltimos, kuchliroq paroldan foydalaning. + + + This value contains characters that are not allowed by the current restriction-level. + Bu qiymat joriy cheklov darajasida ruxsat etilmagan belgilarni o'z ichiga oladi. + + + Using invisible characters is not allowed. + Ko'rinmas belgilardan foydalanish taqiqlangan. + + + Mixing numbers from different scripts is not allowed. + Turli skriptlardagi raqamlarni aralashtirish taqiqlangan. + + + Using hidden overlay characters is not allowed. + Yashirin qoplamali belgilardan foydalanish taqiqlangan. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Fayl kengaytmasi yaroqsiz ({{ extension }}). Ruxsat berilgan kengaytmalar {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Aniqlangan belgi kodlamasi yaroqsiz ({{ detected }}). Ruxsat etilgan kodlamalar {{ encodings }}. + + + This value is not a valid MAC address. + Bu qiymat haqiqiy MAC manzil emas. + + + This URL is missing a top-level domain. + Bu URL yuqori darajali domenni o'z ichiga olmaydi. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Bu qiymat juda qisqa. U kamida bitta so'z bo'lishi kerak.|Bu qiymat juda qisqa. U kamida {{ min }} so'z bo'lishi kerak. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Bu qiymat juda uzun. U faqat bitta so'z bo'lishi kerak.|Bu qiymat juda uzun. U {{ max }} so'z yoki undan kam bo'lishi kerak. + + + This value does not represent a valid week in the ISO 8601 format. + Bu qiymat ISO 8601 formatida haqiqiy haftaga mos kelmaydi. + + + This value is not a valid week. + Bu qiymat haqiqiy hafta emas. + + + This value should not be before week "{{ min }}". + Bu qiymat "{{ min }}" haftadan oldin bo'lmasligi kerak. + + + This value should not be after week "{{ max }}". + Bu qiymat "{{ max }}" haftadan keyin bo'lmasligi kerak. + + + This value is not a valid Twig template. + Bu qiymat yaroqli Twig shabloni emas. + + + This file is not a valid video. + Ushbu fayl yaroqli video emas. + + + The size of the video could not be detected. + Videoning hajmini aniqlab bo‘lmadi. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Video kengligi juda katta ({{ width }}px). Ruxsat etilgan maksimal kenglik {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Video kengligi juda kichik ({{ width }}px). Kutilayotgan minimal kenglik {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Video balandligi juda katta ({{ height }}px). Ruxsat etilgan maksimal balandlik {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Video balandligi juda kichik ({{ height }}px). Kutilayotgan minimal balandlik {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Videoda piksellar soni juda kam ({{ pixels }}). Kutilgan minimal miqdor {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Videoda juda ko‘p piksellar bor ({{ pixels }}). Kutilayotgan maksimal miqdor {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Video nisbati juda katta ({{ ratio }}). Ruxsat etilgan maksimal nisbat {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Video nisbati juda kichik ({{ ratio }}). Kutilayotgan minimal nisbat {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video kvadrat ({{ width }}x{{ height }}px). Kvadrat videolarga ruxsat berilmaydi. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video gorizontal yo‘nalishda ({{ width }}x{{ height }} px). Gorizontal videolarga ruxsat berilmaydi. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video portret yoʻnalishda ({{ width }}x{{ height }}px). Portret yoʻnalishidagi videolarga ruxsat berilmaydi. + + + The video file is corrupted. + Video fayli buzilgan. + + + The video contains multiple streams. Only one stream is allowed. + Videoda bir nechta oqim mavjud. Faqat bitta oqimga ruxsat beriladi. + + + Unsupported video codec "{{ codec }}". + Qo‘llab-quvvatlanmaydigan video kodek "{{ codec }}". + + + Unsupported video container "{{ container }}". + Qo'llab-quvvatlanmaydigan video konteyner "{{ container }}". + + + The image file is corrupted. + Rasm fayli buzilgan. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Tasvirda piksellar juda kam ({{ pixels }}). Kutilayotgan minimal miqdor {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Tasvirda juda ko‘p piksel bor ({{ pixels }}). Kutilayotgan maksimal miqdor {{ max_pixels }}. + + + This filename does not match the expected charset. + Bu fayl nomi kutilgan belgi to‘plamiga mos kelmaydi. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.vi.xlf b/lib/symfony/validator/Resources/translations/validators.vi.xlf new file mode 100644 index 0000000000..a7ac211a72 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.vi.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + Giá trị này phải là sai. + + + This value should be true. + Giá trị này phải là đúng. + + + This value should be of type {{ type }}. + Giá trị này phải là kiểu {{ type }}. + + + This value should be blank. + Giá trị này phải rỗng. + + + The value you selected is not a valid choice. + Giá trị bạn vừa chọn không hợp lệ. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Bạn phải chọn ít nhất {{ limit }} lựa chọn.|Bạn phải chọn ít nhất {{ limit }} lựa chọn. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Bạn phải chọn nhiều nhất {{ limit }} lựa chọn.|Bạn phải chọn nhiều nhất {{ limit }} lựa chọn. + + + One or more of the given values is invalid. + Một hoặc nhiều giá trị được chọn không hợp lệ. + + + This field was not expected. + Lĩnh vực này không được dự kiến. + + + This field is missing. + Lĩnh vực này bị thiếu. + + + This value is not a valid date. + Giá trị không phải là ngày hợp lệ. + + + This value is not a valid datetime. + Giá trị không phải là ngày tháng hợp lệ. + + + This value is not a valid email address. + Giá trị này không phải là email hợp lệ. + + + The file could not be found. + Tập tin không tìm thấy. + + + The file is not readable. + Tập tin không thể đọc được. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Tập tin quá lớn ({{ size }} {{ suffix }}). Kích thước tối đa cho phép {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Kiểu mime của tập tin không hợp lệ ({{ type }}). Kiểu hợp lệ là {{ types }}. + + + This value should be {{ limit }} or less. + Giá trị phải bằng hoặc nhỏ hơn {{ limit }}. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Giá trị quá dài. Phải bằng hoặc ít hơn {{ limit }} kí tự.|Giá trị quá dài. Phải bằng hoặc ít hơn {{ limit }} kí tự. + + + This value should be {{ limit }} or more. + Giá trị phải lớn hơn hoặc bằng {{ limit }}. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Giá trị quá ngắn. Phải hơn hoặc bằng {{ limit }} kí tự.|Giá trị quá ngắn. Phải hơn hoặc bằng {{ limit }} kí tự. + + + This value should not be blank. + Giá trị không được phép để trống. + + + This value should not be null. + Giá trị không được phép rỗng. + + + This value should be null. + Giá trị phải rỗng. + + + This value is not valid. + Giá trị không hợp lệ. + + + This value is not a valid time. + Giá trị không phải là thời gian hợp lệ. + + + This value is not a valid URL. + Giá trị không phải là địa chỉ URL hợp lệ. + + + The two values should be equal. + Hai giá trị phải bằng nhau. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Tập tin quá lớn. Kích thước tối đa cho phép là {{ limit }} {{ suffix }}. + + + The file is too large. + Tập tin quá lớn. + + + The file could not be uploaded. + Tập tin không thể tải lên. + + + This value should be a valid number. + Giá trị phải là con số. + + + This file is not a valid image. + Tập tin không phải là hình ảnh hợp lệ. + + + This value is not a valid IP address. + Giá trị này không phải là địa chỉ IP hợp lệ. + + + This value is not a valid language. + Giá trị không phải là ngôn ngữ hợp lệ. + + + This value is not a valid locale. + Giá trị không phải là một bản địa địa phương hợp lệ. + + + This value is not a valid country. + Giá trị không phải là quốc gia hợp lệ. + + + This value is already used. + Giá trị đã được sử dụng. + + + The size of the image could not be detected. + Kích thước của hình ảnh không thể xác định. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Chiều rộng của hình quá lớn ({{ width }}px). Chiều rộng tối đa phải là {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Chiều rộng của hình quá thấp ({{ width }}px). Chiều rộng tối thiểu phải là {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Chiều cao của hình quá cao ({{ height }}px). Chiều cao tối đa phải là {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Chiều cao của hình quá thấp ({{ height }}px). Chiều cao tối thiểu phải là {{ min_height }}px. + + + This value should be the user's current password. + Giá trị này phải là mật khẩu hiện tại của người dùng. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Giá trị này phải có chính xác {{ limit }} kí tự.|Giá trị này phải có chính xác {{ limit }} kí tự. + + + The file was only partially uploaded. + Tập tin chỉ được tải lên một phần. + + + No file was uploaded. + Tập tin không được tải lên. + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + Không có thư mục tạm được cấu hình trong php.ini, hoặc thư mục đã cấu hình không tồn tại. + + + Cannot write temporary file to disk. + Không thể ghi tập tin tạm ra đĩa. + + + A PHP extension caused the upload to fail. + Một PHP extension đã phá hỏng quá trình tải lên của tập tin. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Danh sách phải chứa {{ limit }} thành phần hoặc nhiều hơn.|Danh sách phải chứa {{ limit }} thành phần hoặc nhiều hơn. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Danh sách phải chứa {{ limit }} thành phần hoặc ít hơn.|Danh sách phải chứa {{ limit }} thành phần hoặc ít hơn. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Danh sách phải chứa chính xác {{ limit }} thành phần.|Danh sách phải chứa chính xác {{ limit }} thành phần. + + + Invalid card number. + Số thẻ không hợp lệ. + + + Unsupported card type or invalid card number. + Thẻ không được hỗ trợ hoặc số thẻ không hợp lệ. + + + This value is not a valid International Bank Account Number (IBAN). + Giá trị này không phải là Số Tài Khoản Ngân Hàng Quốc Tế (IBAN) hợp lệ. + + + This value is not a valid ISBN-10. + Giá trị không phải là ISBN-10 hợp lệ. + + + This value is not a valid ISBN-13. + Giá trị không phải là ISBN-13 hợp lệ. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Giá trị không phải là ISBN-10 hoặc ISBN-13 hợp lệ. + + + This value is not a valid ISSN. + Giá trị không phải là ISSN hợp lệ. + + + This value is not a valid currency. + Giá trị không phải là đơn vị tiền tệ hợp lệ. + + + This value should be equal to {{ compared_value }}. + Giá trị phải bằng {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Giá trị phải lớn hơn {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Giá trị phải lớn hơn hoặc bằng {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Giá trị phải giống {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Giá trị phải bé hơn {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Giá trị phải nhỏ hơn hoặc bằng {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Giá trị không được phép bằng {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Giá trị không được phép giống như {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Tỷ lệ bức ảnh quá lớn ({{ ratio }}). Tỷ lệ tối đa cho phép là {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Tỷ lệ bức ảnh quá nhỏ ({{ ratio }}). Tỷ lệ tối thiểu mong muốn là {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Bức ảnh là hình vuông ({{ width }}x{{ height }}px). Ảnh hình vuông không được phép. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Bức ảnh theo chiều ngang ({{ width }}x{{ height }}px). Ảnh chiều ngang không được phép. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Bức ảnh theo chiều dọc ({{ width }}x{{ height }}px). Ảnh chiều dọc không được phép. + + + An empty file is not allowed. + Một file rỗng không được phép. + + + The host could not be resolved. + Máy chủ không thể được tìm thấy. + + + This value does not match the expected {{ charset }} charset. + Giá trị này không đúng định dạng bộ ký tự mong muốn {{ charset }}. + + + This value is not a valid Business Identifier Code (BIC). + Giá trị này không phải là Mã Định Danh Doanh Nghiệp (BIC) hợp lệ. + + + Error + Lỗi + + + This value is not a valid UUID. + Giá trị này không phải là UUID hợp lệ. + + + This value should be a multiple of {{ compared_value }}. + Giá trị này nên là bội số của {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Mã định danh doanh nghiệp (BIC) này không liên kết với IBAN {{ iban }}. + + + This value should be valid JSON. + Giá trị này nên đúng định dạng JSON. + + + This collection should contain only unique elements. + Danh sách này chỉ nên chứa các phần tử khác nhau. + + + This value should be positive. + Giá trị này có thể thực hiện được. + + + This value should be either positive or zero. + Giá trị này có thể thực hiện được hoặc bằng không. + + + This value should be negative. + Giá trị này nên bị từ chối. + + + This value should be either negative or zero. + Giá trị này nên bị từ chối hoặc bằng không. + + + This value is not a valid timezone. + Giá trị này không phải là múi giờ hợp lệ. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Mật khẩu này đã bị rò rỉ dữ liệu, không được sử dụng nữa. Xin vui lòng sử dụng mật khẩu khác. + + + This value should be between {{ min }} and {{ max }}. + Giá trị này nên thuộc giữa {{ min }} và {{ max }}. + + + This value is not a valid hostname. + Giá trị này không phải là tên máy chủ hợp lệ. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Số lượng các phần tử trong bộ sưu tập này nên là bội số của {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Giá trị này nên thỏa mãn ít nhất một trong những ràng buộc sau: + + + Each element of this collection should satisfy its own set of constraints. + Mỗi phần tử trong bộ sưu tập này nên thỏa mãn những ràng buộc của nó. + + + This value is not a valid International Securities Identification Number (ISIN). + Giá trị này không phải là mã số chứng khoán quốc tế (ISIN) hợp lệ. + + + This value should be a valid expression. + Giá trị này phải là một biểu thức hợp lệ. + + + This value is not a valid CSS color. + Giá trị này không phải là màu CSS hợp lệ. + + + This value is not a valid CIDR notation. + Giá trị này không phải là ký hiệu CIDR hợp lệ. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Giá trị của mặt nạ mạng phải nằm trong khoảng từ {{ min }} đến {{ max }}. + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Tên tệp quá dài. Phải bằng {{ filename_max_length }} ký tự hoặc ít hơn.|Tên tệp quá dài. Phải bằng {{ filename_max_length }} ký tự hoặc ít hơn. + + + The password strength is too low. Please use a stronger password. + Sức mạnh mật khẩu quá thấp. Vui lòng sử dụng mật khẩu mạnh hơn. + + + This value contains characters that are not allowed by the current restriction-level. + Giá trị này chứa các ký tự không được phép bởi mức độ hạn chế hiện tại. + + + Using invisible characters is not allowed. + Sử dụng ký tự vô hình không được phép. + + + Mixing numbers from different scripts is not allowed. + Không được phép trộn các số từ các tập lệnh khác nhau. + + + Using hidden overlay characters is not allowed. + Sử dụng các ký tự lớp phủ ẩn không được phép. + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + Phần mở rộng của tệp không hợp lệ ({{ extension }}). Phần mở rộng cho phép là {{ extensions }}. + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + Mã hóa ký tự được phát hiện là không hợp lệ ({{ detected }}). Các mã hóa được phép là {{ encodings }}. + + + This value is not a valid MAC address. + Giá trị này không phải là địa chỉ MAC hợp lệ. + + + This URL is missing a top-level domain. + URL này thiếu miền cấp cao. + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + Giá trị này quá ngắn. Nó phải chứa ít nhất một từ.|Giá trị này quá ngắn. Nó phải chứa ít nhất {{ min }} từ. + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + Giá trị này quá dài. Nó chỉ nên chứa một từ.|Giá trị này quá dài. Nó chỉ nên chứa {{ max }} từ hoặc ít hơn. + + + This value does not represent a valid week in the ISO 8601 format. + Giá trị này không đại diện cho một tuần hợp lệ theo định dạng ISO 8601. + + + This value is not a valid week. + Giá trị này không phải là một tuần hợp lệ. + + + This value should not be before week "{{ min }}". + Giá trị này không nên trước tuần "{{ min }}". + + + This value should not be after week "{{ max }}". + Giá trị này không nên sau tuần "{{ max }}". + + + This value is not a valid Twig template. + Giá trị này không phải là một mẫu Twig hợp lệ. + + + This file is not a valid video. + Tệp này không phải là video hợp lệ. + + + The size of the video could not be detected. + Không thể phát hiện kích thước của video. + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Chiều rộng video quá lớn ({{ width }}px). Chiều rộng tối đa cho phép là {{ max_width }}px. + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Chiều rộng video quá nhỏ ({{ width }}px). Chiều rộng tối thiểu mong đợi là {{ min_width }}px. + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Chiều cao video quá lớn ({{ height }}px). Chiều cao tối đa cho phép là {{ max_height }}px. + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Chiều cao video quá nhỏ ({{ height }}px). Chiều cao tối thiểu dự kiến là {{ min_height }}px. + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Video có quá ít điểm ảnh ({{ pixels }}). Lượng tối thiểu mong đợi là {{ min_pixels }}. + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Video có quá nhiều điểm ảnh ({{ pixels }}). Số lượng tối đa dự kiến là {{ max_pixels }}. + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Tỉ lệ video quá lớn ({{ ratio }}). Tỉ lệ tối đa được phép là {{ max_ratio }}. + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Tỉ lệ video quá nhỏ ({{ ratio }}). Tỉ lệ tối thiểu dự kiến là {{ min_ratio }}. + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + Video có dạng hình vuông ({{ width }}x{{ height }}px). Không cho phép video hình vuông. + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + Video có hướng ngang ({{ width }}x{{ height }} px). Không cho phép video ngang. + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + Video có hướng dọc ({{ width }}x{{ height }}px). Không cho phép video hướng dọc. + + + The video file is corrupted. + Tệp video bị hỏng. + + + The video contains multiple streams. Only one stream is allowed. + Video chứa nhiều luồng. Chỉ cho phép một luồng. + + + Unsupported video codec "{{ codec }}". + Bộ mã hóa video không được hỗ trợ "{{ codec }}". + + + Unsupported video container "{{ container }}". + Bộ chứa video không được hỗ trợ "{{ container }}". + + + The image file is corrupted. + Tệp hình ảnh bị hỏng. + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + Hình ảnh có quá ít điểm ảnh ({{ pixels }}). Số lượng tối thiểu dự kiến là {{ min_pixels }}. + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + Hình ảnh có quá nhiều điểm ảnh ({{ pixels }}). Lượng tối đa dự kiến là {{ max_pixels }}. + + + This filename does not match the expected charset. + Tên tệp này không khớp với bộ ký tự mong đợi. + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.zh_CN.xlf b/lib/symfony/validator/Resources/translations/validators.zh_CN.xlf new file mode 100644 index 0000000000..70f2a34c07 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.zh_CN.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + 该值应为 false 。 + + + This value should be true. + 该值应为 true 。 + + + This value should be of type {{ type }}. + 该值的类型应为 {{ type }} 。 + + + This value should be blank. + 该值应为空。 + + + The value you selected is not a valid choice. + 该值不是有效的选项。 + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + 您至少要选择 {{ limit }} 个选项。 + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + 您最多能选择 {{ limit }} 个选项。 + + + One or more of the given values is invalid. + 一个或者多个给定的值无效。 + + + This field was not expected. + 该字段是多余的。 + + + This field is missing. + 该字段缺失。 + + + This value is not a valid date. + 该值不是一个有效的日期(date)。 + + + This value is not a valid datetime. + 该值不是一个有效的日期时间(datetime)。 + + + This value is not a valid email address. + 该值不是一个有效的邮件地址。 + + + The file could not be found. + 文件未找到。 + + + The file is not readable. + 文件不可读。 + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + 文件太大 ({{ size }} {{ suffix }}),文件大小不应超过 {{ limit }} {{ suffix }} 。 + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + 无效的文件类型 ({{ type }}) ,允许的文件类型有 {{ types }} 。 + + + This value should be {{ limit }} or less. + 该值应小于或等于 {{ limit }} 。 + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + 该值太长,长度不应超过 {{ limit }} 个字符。 + + + This value should be {{ limit }} or more. + 该值应大于或等于 {{ limit }} 。 + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + 该值太短,长度不应少于 {{ limit }} 个字符。 + + + This value should not be blank. + 该值不应为空。 + + + This value should not be null. + 该值不应为 null 。 + + + This value should be null. + 该值应为 null 。 + + + This value is not valid. + 该值无效。 + + + This value is not a valid time. + 该值不是一个有效的时间。 + + + This value is not a valid URL. + 该值不是一个有效的 URL 。 + + + The two values should be equal. + 该两个变量值应相等。 + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + 文件太大,文件大小不可以超过 {{ limit }} {{ suffix }} 。 + + + The file is too large. + 文件太大。 + + + The file could not be uploaded. + 无法上传此文件。 + + + This value should be a valid number. + 该值应为有效的数字。 + + + This file is not a valid image. + 该文件不是有效的图片。 + + + This value is not a valid IP address. + 该值不是有效的 IP 地址。 + + + This value is not a valid language. + 该值不是有效的语言名称(language)。 + + + This value is not a valid locale. + 该值不是有效的区域名称(locale)。 + + + This value is not a valid country. + 该值不是有效的国家名称(country)。 + + + This value is already used. + 该值已经被使用。 + + + The size of the image could not be detected. + 不能解析图片大小。 + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + 图片太宽 ({{ width }}px),最大宽度为 {{ max_width }}px 。 + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + 图片宽度不够 ({{ width }}px),最小宽度为 {{ min_width }}px 。 + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + 图片太高 ({{ height }}px),最大高度为 {{ max_height }}px 。 + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + 图片高度不够 ({{ height }}px),最小高度为 {{ min_height }}px 。 + + + This value should be the user's current password. + 该值应为用户当前的密码。 + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + 该值应为 {{ limit }} 个字符。 + + + The file was only partially uploaded. + 文件的上传不完整。 + + + No file was uploaded. + 没有上传任何文件。 + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + php.ini 中未配置临时文件夹,或配置的文件夹不存在。 + + + Cannot write temporary file to disk. + 临时文件写入磁盘失败。 + + + A PHP extension caused the upload to fail. + 某个 PHP 扩展造成上传失败。 + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + 该集合不应少于 {{ limit }} 个元素。 + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + 该集合不应超过 {{ limit }} 个元素。 + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + 该集合应为 {{ limit }} 个元素。 + + + Invalid card number. + 无效的信用卡号。 + + + Unsupported card type or invalid card number. + 不支持的信用卡类型或无效的信用卡号。 + + + This value is not a valid International Bank Account Number (IBAN). + 该值不是有效的国际银行账号(IBAN)。 + + + This value is not a valid ISBN-10. + 该值不是有效的 10 位国际标准书号(ISBN-10)。 + + + This value is not a valid ISBN-13. + 该值不是有效的 13 位国际标准书号(ISBN-13)。 + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + 该值不是有效的国际标准书号(ISBN-10 或 ISBN-13)。 + + + This value is not a valid ISSN. + 该值不是有效的国际标准期刊号(ISSN)。 + + + This value is not a valid currency. + 该值不是有效的货币名称(currency)。 + + + This value should be equal to {{ compared_value }}. + 该值应等于 {{ compared_value }} 。 + + + This value should be greater than {{ compared_value }}. + 该值应大于 {{ compared_value }} 。 + + + This value should be greater than or equal to {{ compared_value }}. + 该值应大于或等于 {{ compared_value }} 。 + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + 该值应与 {{ compared_value_type }} {{ compared_value }} 相同。 + + + This value should be less than {{ compared_value }}. + 该值应小于 {{ compared_value }} 。 + + + This value should be less than or equal to {{ compared_value }}. + 该值应小于或等于 {{ compared_value }} 。 + + + This value should not be equal to {{ compared_value }}. + 该值不应等于 {{ compared_value }} 。 + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + 该值不应与 {{ compared_value_type }} {{ compared_value }} 相同。 + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + 图片宽高比太大 ({{ ratio }})。允许的最大宽高比为 {{ max_ratio }} 。 + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + 图片宽高比太小 ({{ ratio }})。允许的最大宽高比为 {{ min_ratio }} 。 + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + 图片是方形的 ({{ width }}x{{ height }}px)。不允许使用方形的图片。 + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + 图片是横向的 ({{ width }}x{{ height }}px)。不允许使用横向的图片。 + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + 图片是纵向的 ({{ width }}x{{ height }}px)。不允许使用纵向的图片。 + + + An empty file is not allowed. + 不允许使用空文件。 + + + The host could not be resolved. + 主机名无法解析。 + + + This value does not match the expected {{ charset }} charset. + 该值不符合 {{ charset }} 编码。 + + + This value is not a valid Business Identifier Code (BIC). + 该值不是有效的银行识别代码(BIC)。 + + + Error + 错误 + + + This value is not a valid UUID. + 该值不是有效的 UUID 。 + + + This value should be a multiple of {{ compared_value }}. + 该值应为 {{ compared_value }} 的倍数。 + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + 该业务标识符代码(BIC)与 IBAN {{ iban }} 无关。 + + + This value should be valid JSON. + 该值应为有效的 JSON 。 + + + This collection should contain only unique elements. + 该集合不能包含重复项。 + + + This value should be positive. + 该值应为正数。 + + + This value should be either positive or zero. + 该值应为正数或零。 + + + This value should be negative. + 该值应为负数。 + + + This value should be either negative or zero. + 该值应为负数或零。 + + + This value is not a valid timezone. + 该值不是有效的时区。 + + + This password has been leaked in a data breach, it must not be used. Please use another password. + 此密码已被泄露,切勿使用。请更换密码。 + + + This value should be between {{ min }} and {{ max }}. + 该值应在 {{ min }} 和 {{ max }} 之间。 + + + This value is not a valid hostname. + 该值不是有效的主机名称。 + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + 该集合的元素数量应为 {{ compared_value }} 的倍数。 + + + This value should satisfy at least one of the following constraints: + 该值应符合以下其中一个约束: + + + Each element of this collection should satisfy its own set of constraints. + 该集合的每个元素应符合元素本身规定的约束。 + + + This value is not a valid International Securities Identification Number (ISIN). + 该值不是有效的国际证券识别码(ISIN)。 + + + This value should be a valid expression. + 该值应为一个有效的表达式。 + + + This value is not a valid CSS color. + 该值不是有效的 CSS 颜色。 + + + This value is not a valid CIDR notation. + 该值不是一个有效的 CIDR 表示。 + + + The value of the netmask should be between {{ min }} and {{ max }}. + 网络掩码的值应当在 {{ min }} 和 {{ max }} 之间。 + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + 文件名过长,最长不应超过{{ filename_max_length }} 个字符。 + + + The password strength is too low. Please use a stronger password. + 密码强度太低。请使用更复杂的密码。 + + + This value contains characters that are not allowed by the current restriction-level. + 该值包含了当前限制级别不允许的字符。 + + + Using invisible characters is not allowed. + 不允许使用隐藏字符。 + + + Mixing numbers from different scripts is not allowed. + 不可混合使用不同语系的数字。 + + + Using hidden overlay characters is not allowed. + 不允许使用隐藏的覆盖字符。 + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + 文件的扩展名无效 ({{ extension }})。允许的扩展名为 {{ extensions }} 。 + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + 检测到的字符编码无效 ({{ detected }})。允许的编码为 {{ encodings }} 。 + + + This value is not a valid MAC address. + 该值不是有效的 MAC 地址。 + + + This URL is missing a top-level domain. + 该 URL 缺少顶级域名。 + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + 该值太短,应至少包含一个词。|该值太短,应至少包含 {{ min }} 个词。 + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + 该值太长,应只包含一个词。|该值太长,应只包含 {{ max }} 个或更少个词。 + + + This value does not represent a valid week in the ISO 8601 format. + 该值不代表 ISO 8601 格式中的有效周。 + + + This value is not a valid week. + 该值不是一个有效周。 + + + This value should not be before week "{{ min }}". + 该值不应位于 "{{ min }}" 周之前。 + + + This value should not be after week "{{ max }}". + 该值不应位于 "{{ max }}"周之后。 + + + This value is not a valid Twig template. + 该值不是有效的 Twig 模板。 + + + This file is not a valid video. + 此文件不是有效的视频。 + + + The size of the video could not be detected. + 无法检测到视频的大小。 + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + 视频宽度过大({{ width }}px)。允许的最大宽度为 {{ max_width }}px。 + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + 视频宽度太小({{ width }}px)。预期的最小宽度为 {{ min_width }} 像素。 + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + 视频高度过大({{ height }}px)。允许的最大高度为 {{ max_height }}px。 + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + 视频高度太小({{ height }}px)。期望的最小高度为 {{ min_height }}px。 + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + 该视频像素过少 ({{ pixels }}). 期望的最小值为 {{ min_pixels }}。 + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + 该视频的像素过多({{ pixels }})。预期的最大数量为 {{ max_pixels }}。 + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + 视频纵横比过大({{ ratio }})。允许的最大纵横比为 {{ max_ratio }}。 + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + 视频纵横比过小({{ ratio }})。预期的最低比例为 {{ min_ratio }}。 + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + 视频为正方形 ({{ width }}x{{ height }}px)。不允许正方形视频。 + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + 视频为横向({{ width }}x{{ height }} 像素)。不允许横向视频。 + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + 该视频为竖屏方向({{ width }}x{{ height }}px)。不允许竖屏视频。 + + + The video file is corrupted. + 视频文件已损坏。 + + + The video contains multiple streams. Only one stream is allowed. + 该视频包含多个流。只允许一个流。 + + + Unsupported video codec "{{ codec }}". + 不支持的视频编解码器“{{ codec }}”。 + + + Unsupported video container "{{ container }}". + 不支持的视频容器 "{{ container }}". + + + The image file is corrupted. + 图像文件已损坏。 + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + 图像的像素太少({{ pixels }})。预期的最小数量为 {{ min_pixels }}。 + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + 图像的像素过多 ({{ pixels }}). 预期的最大数量为 {{ max_pixels }}. + + + This filename does not match the expected charset. + 该文件名与预期的字符集不匹配。 + + + + diff --git a/lib/symfony/validator/Resources/translations/validators.zh_TW.xlf b/lib/symfony/validator/Resources/translations/validators.zh_TW.xlf new file mode 100644 index 0000000000..63103187c9 --- /dev/null +++ b/lib/symfony/validator/Resources/translations/validators.zh_TW.xlf @@ -0,0 +1,559 @@ + + + + + + This value should be false. + 這個數值應為 false。 + + + This value should be true. + 這個數值應為 true。 + + + This value should be of type {{ type }}. + 這個數值的類型應為 {{ type }}。 + + + This value should be blank. + 這個數值應該留白。 + + + The value you selected is not a valid choice. + 選取的值不是有效的選項。 + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + 至少需要選 {{ limit }} 項。|至少需要選 {{ limit }} 項。 + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + 至多只能選 {{ limit }} 項。|至多只能選 {{ limit }} 項。 + + + One or more of the given values is invalid. + 一或多個填入的數值無效。 + + + This field was not expected. + 這個欄位不在預期之內。 + + + This field is missing. + 缺少這個欄位。 + + + This value is not a valid date. + 這個數值不是有效的日期。 + + + This value is not a valid datetime. + 這個數值不是有效的日期時間組合。 + + + This value is not a valid email address. + 這個數值不是有效的電子郵件格式。 + + + The file could not be found. + 找不到這個檔案。 + + + The file is not readable. + 無法讀取這個檔案。 + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + 這個檔案過大({{ size }} {{ suffix }})。允許的大小上限是 {{ limit }} {{ suffix }}。 + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + 這個檔案的 MIME 類型無效({{ type }})。允許的 MIME 類型有 {{ types }}。 + + + This value should be {{ limit }} or less. + 這個數值必須小於等於 {{ limit }}。 + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + 這個數值過長。最多只能有 {{ limit }} 個字元。|這個數值過長。最多只能有 {{ limit }} 個字元。 + + + This value should be {{ limit }} or more. + 這個數值必須大於等於 {{ limit }}。 + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + 這個數值過短。最少要有 {{ limit }} 個字元。|這個數值過短。最少要有 {{ limit }} 個字元。 + + + This value should not be blank. + 這個數值不允許留白。 + + + This value should not be null. + 這個數值不能為空值(null)。 + + + This value should be null. + 這個數值應為空值(null)。 + + + This value is not valid. + 這個數值無效。 + + + This value is not a valid time. + 這個數值不是有效的時間。 + + + This value is not a valid URL. + 這個數值不是 URL 格式。 + + + The two values should be equal. + 這兩個數值應該相同。 + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + 這個檔案過大。允許的大小上限為 {{ limit }} {{ suffix }}。 + + + The file is too large. + 這個檔案過大。 + + + The file could not be uploaded. + 無法上傳檔案。 + + + This value should be a valid number. + 這個數值不是有效的數字。 + + + This file is not a valid image. + 這個檔案不是有效的圖片。 + + + This value is not a valid IP address. + 這個數值不是有效的 IP 地址。 + + + This value is not a valid language. + 這個數值不是有效的語言。 + + + This value is not a valid locale. + 這個數值不是有效的地區。 + + + This value is not a valid country. + 這個數值不是有效的國家。 + + + This value is already used. + 已經用過這個數值。 + + + The size of the image could not be detected. + 無法偵測到圖片的大小。 + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + 圖片寬度過大 ({{ width }}px)。允許的最大寬度為 {{ max_width }}px。 + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + 圖片寬度過小 ({{ width }}px)。允許的最小寬度為 {{ max_width }}px。 + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + 圖片高度過大 ({{ height }}px)。允許的最大長度為 {{ max_height }}px。 + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + 圖片高度過小 ({{ height }}px)。允許的最小高度為 {{ max_height }}px。 + + + This value should be the user's current password. + 這個數值應為使用者目前使用的密碼。 + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + 這個數值應剛好為 {{ limit }} 個字元長。|這個數值應剛好為 {{ limit }} 個字元長。 + + + The file was only partially uploaded. + 檔案只上傳了一部分。 + + + No file was uploaded. + 未上傳檔案。 + + + No temporary folder was configured in php.ini, or the configured folder does not exist. + 未在 php.ini 設定暫存資料夾,或者是暫存資料夾不存在。 + + + Cannot write temporary file to disk. + 無法將暫存檔寫入磁碟。 + + + A PHP extension caused the upload to fail. + 有個 PHP 擴充套件導致上傳失敗。 + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + 這個集合應該至少有 {{ limit }} 個元素。|這個集合應該至少有 {{ limit }} 個元素。 + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + 這個集合最多只能有 {{ limit }} 個元素。|這個集合最多只能有 {{ limit }} 個元素。 + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + 這個集合只能有剛好 {{ limit }} 個元素。|這個集合只能有剛好 {{ limit }} 個元素。 + + + Invalid card number. + 卡號無效。 + + + Unsupported card type or invalid card number. + 不支援這個卡片類型,或卡號不正確。 + + + This value is not a valid International Bank Account Number (IBAN). + 這個數值的格式不是國際銀行帳戶號碼(IBAN)。 + + + This value is not a valid ISBN-10. + 這個數值的格式不是 ISBN-10。 + + + This value is not a valid ISBN-13. + 這個數值的格式不是 ISBN-13。 + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + 這個數值的格式不是 ISBN-10 或 ISBN-13。 + + + This value is not a valid ISSN. + 這個數值的格式不是 ISSN。 + + + This value is not a valid currency. + 這個數值不是有效的貨幣。 + + + This value should be equal to {{ compared_value }}. + 這個數值應等於 {{ compared_value }}。 + + + This value should be greater than {{ compared_value }}. + 這個數值應大於 {{ compared_value }}。 + + + This value should be greater than or equal to {{ compared_value }}. + 這個數值應大於等於 {{ compared_value }}。 + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + 這個數值應等於 {{ compared_value_type }} {{ compared_value }}。 + + + This value should be less than {{ compared_value }}. + 這個數值應小於 {{ compared_value }}。 + + + This value should be less than or equal to {{ compared_value }}. + 這個數值應小於等於 {{ compared_value }}。 + + + This value should not be equal to {{ compared_value }}. + 這個數值不應等於 {{ compared_value }}。 + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + 這個數值不應等於 {{ compared_value_type }} {{ compared_value }}。 + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + 圖片的比例過大 ({{ ratio }})。允許的最大比例為 {{ max_ratio }}。 + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + 圖片的比例過小 ({{ ratio }})。允許的最小比例為 {{ min_ratio }}。 + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + 圖片為正方形 ({{ width }}x{{ height }}px)。不允許使用正方形圖片。 + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + 圖片為橫向 ({{ width }}x{{ height }}px)。不允許使用橫向圖片。 + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + 圖片為縱向 ({{ width }}x{{ height }}px)。不允許使用縱向圖片。 + + + An empty file is not allowed. + 不允許空白檔案。 + + + The host could not be resolved. + 無法解析主機。 + + + This value does not match the expected {{ charset }} charset. + 這個數值不符合預期的 {{ charset }} 字元集。 + + + This value is not a valid Business Identifier Code (BIC). + 這個數值不是有效的商業識別碼(BIC)。 + + + Error + 錯誤 + + + This value is not a valid UUID. + 這個數值不是有效的 UUID。 + + + This value should be a multiple of {{ compared_value }}. + 這個數值應為 {{ compared_value }} 的倍數。 + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + 這個商業識別碼(BIC)與 IBAN {{ iban }} 沒有關聯。 + + + This value should be valid JSON. + 這個數值應為有效的 JSON。 + + + This collection should contain only unique elements. + 這個集合不允許有重複元素。 + + + This value should be positive. + 這個數值應為正數。 + + + This value should be either positive or zero. + 這個數值應為正數或 0。 + + + This value should be negative. + 這個數值應為負數。 + + + This value should be either negative or zero. + 這個數值應為負數或 0。 + + + This value is not a valid timezone. + 這個數值不是有效的時區。 + + + This password has been leaked in a data breach, it must not be used. Please use another password. + 這個密碼已在資料洩露中曝光,不應再使用。請使用其他密碼。 + + + This value should be between {{ min }} and {{ max }}. + 這個數值應介於 {{ min }} 和 {{ max }} 之間。 + + + This value is not a valid hostname. + 這個數值不是有效的主機名稱。 + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + 這個集合中的元素數量應為 {{ compared_value }} 的倍數。 + + + This value should satisfy at least one of the following constraints: + 這個數值應滿足以下至少一項限制: + + + Each element of this collection should satisfy its own set of constraints. + 這個集合中的每個元素應滿足其自身的約束條件。 + + + This value is not a valid International Securities Identification Number (ISIN). + 這個數值不是有效的國際證券識別號碼(ISIN)。 + + + This value should be a valid expression. + 這個數值應為有效的表達式。 + + + This value is not a valid CSS color. + 這個數值不是有效的 CSS 顏色。 + + + This value is not a valid CIDR notation. + 這個數值不是有效的 CIDR 表示法。 + + + The value of the netmask should be between {{ min }} and {{ max }}. + 網路遮罩的值應介於 {{ min }} 和 {{ max }} 之間。 + + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + 檔案名稱過長。應最多有 {{ filename_max_length }} 個字元。|檔案名稱過長。應最多有 {{ filename_max_length }} 個字元。 + + + The password strength is too low. Please use a stronger password. + 密碼強度太低。請使用更強的密碼。 + + + This value contains characters that are not allowed by the current restriction-level. + 這個數值包含目前限制級別不允許的字元。 + + + Using invisible characters is not allowed. + 不允許使用隱形字元。 + + + Mixing numbers from different scripts is not allowed. + 不允許混合來自不同文字的數字。 + + + Using hidden overlay characters is not allowed. + 不允許使用隱藏的覆蓋字元。 + + + The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}. + 檔案的副檔名無效({{ extension }})。允許的副檔名有 {{ extensions }}。 + + + The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}. + 偵測到的字元編碼無效({{ detected }})。允許的編碼有 {{ encodings }}。 + + + This value is not a valid MAC address. + 這個數值不是有效的 MAC 位址。 + + + This URL is missing a top-level domain. + 這個 URL 缺少頂級域名。 + + + This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words. + 這個數值過短。應至少包含 1 個單字。|這個數值過短。應至少包含 {{ min }} 個單字。 + + + This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less. + 這個數值過長。應包含 1 個單字。|這個數值過長。應最多包含 {{ max }} 個單字。 + + + This value does not represent a valid week in the ISO 8601 format. + 這個數值不符合 ISO 8601 格式的有效週。 + + + This value is not a valid week. + 這個數值不是有效的週。 + + + This value should not be before week "{{ min }}". + 這個數值不應早於第「{{ min }}」週。 + + + This value should not be after week "{{ max }}". + 這個數值不應晚於第「{{ max }}」週。 + + + This value is not a valid Twig template. + 這個數值不是有效的 Twig 模板。 + + + This file is not a valid video. + 這個檔案不是有效的影片。 + + + The size of the video could not be detected. + 無法偵測到影片的大小。 + + + The video width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + 影片寬度過大 ({{ width }}px)。允許的最大寬度為 {{ max_width }}px。 + + + The video width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + 影片寬度過小 ({{ width }}p)。允許的最小寬度為 {{ min_width }}px。 + + + The video height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + 影片高度過大 ({{ height }}px)。允許的最大高度為 {{ max_height }}px。 + + + The video height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + 影片高度過小 ({{ height }}px)。允許的最小高度為 {{ min_height }}px。 + + + The video has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + 影片的像素過少 ({{ pixels }} 像素). 允許的最小值為 {{ min_pixels }} 像素。 + + + The video has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + 影片的像素過多 ({{ pixels }} 像素)。允許的最大值為 {{ max_pixels }} 像素。 + + + The video ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + 影片的比例過大 ({{ ratio }})。允許的最大比例為 {{ max_ratio }}。 + + + The video ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + 影片的比例過小 ({{ ratio }})。允許的最小比例為 {{ min_ratio }}。 + + + The video is square ({{ width }}x{{ height }}px). Square videos are not allowed. + 影片為正方形 ({{ width }}x{{ height }}px)。不允許使用正方形影片。 + + + The video is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented videos are not allowed. + 影片為橫向 ({{ width }}x{{ height }}px)。不允許使用橫向影片。 + + + The video is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented videos are not allowed. + 影片為縱向 ({{ width }}x{{ height }}px)。不允許使用縱向影片。 + + + The video file is corrupted. + 影片檔案已損壞。 + + + The video contains multiple streams. Only one stream is allowed. + 影片包含多個串流。只允許單個串流。 + + + Unsupported video codec "{{ codec }}". + 不支援的影片編解碼器: {{ codec }}。 + + + Unsupported video container "{{ container }}". + 不支援的影片容器格式: {{ container }}。 + + + The image file is corrupted. + 圖片檔案已損壞。 + + + The image has too few pixels ({{ pixels }} pixels). Minimum amount expected is {{ min_pixels }} pixels. + 圖片的像素過少 ({{ pixels }} 像素)。允許的最小值為 {{ min_pixels }} 像素。 + + + The image has too many pixels ({{ pixels }} pixels). Maximum amount expected is {{ max_pixels }} pixels. + 圖片的像素過多 ({{ pixels }} 像素)。允許的最大值為 {{ max_pixels }} 像素。 + + + This filename does not match the expected charset. + 這個檔名與預期的字元集不相符。 + + + + diff --git a/lib/symfony/validator/Util/PropertyPath.php b/lib/symfony/validator/Util/PropertyPath.php new file mode 100644 index 0000000000..7eeb3bb0a0 --- /dev/null +++ b/lib/symfony/validator/Util/PropertyPath.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Util; + +/** + * Contains utility methods for dealing with property paths. + * + * For more extensive functionality, use Symfony's PropertyAccess component. + * + * @author Bernhard Schussek + */ +class PropertyPath +{ + /** + * Appends a path to a given property path. + * + * If the base path is empty, the appended path will be returned unchanged. + * If the base path is not empty, and the appended path starts with a + * squared opening bracket ("["), the concatenation of the two paths is + * returned. Otherwise, the concatenation of the two paths is returned, + * separated by a dot ("."). + */ + public static function append(string $basePath, string $subPath): string + { + if ('' !== $subPath) { + if ('[' === $subPath[0]) { + return $basePath.$subPath; + } + + return '' !== $basePath ? $basePath.'.'.$subPath : $subPath; + } + + return $basePath; + } + + /** + * Not instantiable. + */ + private function __construct() + { + } +} diff --git a/lib/symfony/validator/Validation.php b/lib/symfony/validator/Validation.php new file mode 100644 index 0000000000..45c5930030 --- /dev/null +++ b/lib/symfony/validator/Validation.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Symfony\Component\Validator\Exception\ValidationFailedException; +use Symfony\Component\Validator\Validator\ValidatorInterface; + +/** + * Entry point for the Validator component. + * + * @author Bernhard Schussek + */ +final class Validation +{ + /** + * Creates a callable chain of constraints. + */ + public static function createCallable(Constraint|ValidatorInterface|null $constraintOrValidator = null, Constraint ...$constraints): callable + { + $validator = self::createIsValidCallable($constraintOrValidator, ...$constraints); + + return static function ($value) use ($validator) { + if (!$validator($value, $violations)) { + throw new ValidationFailedException($value, $violations); + } + + return $value; + }; + } + + /** + * Creates a callable that returns true/false instead of throwing validation exceptions. + * + * @return callable(mixed $value, ConstraintViolationListInterface &$violations = null): bool + */ + public static function createIsValidCallable(Constraint|ValidatorInterface|null $constraintOrValidator = null, Constraint ...$constraints): callable + { + $validator = $constraintOrValidator; + + if ($constraintOrValidator instanceof Constraint) { + $constraints = \func_get_args(); + $validator = null; + } + + $validator ??= self::createValidator(); + + return static function (mixed $value, ?ConstraintViolationListInterface &$violations = null) use ($constraints, $validator): bool { + $violations = $validator->validate($value, $constraints); + + return 0 === $violations->count(); + }; + } + + /** + * Creates a new validator. + * + * If you want to configure the validator, use + * {@link createValidatorBuilder()} instead. + */ + public static function createValidator(): ValidatorInterface + { + return self::createValidatorBuilder()->getValidator(); + } + + /** + * Creates a configurable builder for validator objects. + */ + public static function createValidatorBuilder(): ValidatorBuilder + { + return new ValidatorBuilder(); + } + + /** + * This class cannot be instantiated. + */ + private function __construct() + { + } +} diff --git a/lib/symfony/validator/Validator/ContextualValidatorInterface.php b/lib/symfony/validator/Validator/ContextualValidatorInterface.php new file mode 100644 index 0000000000..8acdf30763 --- /dev/null +++ b/lib/symfony/validator/Validator/ContextualValidatorInterface.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Validator; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\GroupSequence; +use Symfony\Component\Validator\ConstraintViolationListInterface; + +/** + * A validator in a specific execution context. + * + * @author Bernhard Schussek + */ +interface ContextualValidatorInterface +{ + /** + * Appends the given path to the property path of the context. + * + * If called multiple times, the path will always be reset to the context's + * original path with the given path appended to it. + * + * @return $this + */ + public function atPath(string $path): static; + + /** + * Validates a value against a constraint or a list of constraints. + * + * If no constraint is passed, the constraint + * {@link \Symfony\Component\Validator\Constraints\Valid} is assumed. + * + * @param mixed $value The value to validate + * @param Constraint|Constraint[]|null $constraints The constraint(s) to validate against + * @param string|GroupSequence|array|null $groups The validation groups to validate. If none is given, "Default" is assumed + * + * @return $this + */ + public function validate(mixed $value, Constraint|array|null $constraints = null, string|GroupSequence|array|null $groups = null): static; + + /** + * Validates a property of an object against the constraints specified + * for this property. + * + * @param string $propertyName The name of the validated property + * @param string|GroupSequence|array|null $groups The validation groups to validate. If none is given, "Default" is assumed + * + * @return $this + */ + public function validateProperty(object $object, string $propertyName, string|GroupSequence|array|null $groups = null): static; + + /** + * Validates a value against the constraints specified for an object's + * property. + * + * @param object|string $objectOrClass The object or its class name + * @param string $propertyName The name of the property + * @param mixed $value The value to validate against the property's constraints + * @param string|GroupSequence|array|null $groups The validation groups to validate. If none is given, "Default" is assumed + * + * @return $this + */ + public function validatePropertyValue(object|string $objectOrClass, string $propertyName, mixed $value, string|GroupSequence|array|null $groups = null): static; + + /** + * Returns the violations that have been generated so far in the context + * of the validator. + */ + public function getViolations(): ConstraintViolationListInterface; +} diff --git a/lib/symfony/validator/Validator/LazyProperty.php b/lib/symfony/validator/Validator/LazyProperty.php new file mode 100644 index 0000000000..aa76934e23 --- /dev/null +++ b/lib/symfony/validator/Validator/LazyProperty.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Validator; + +/** + * A wrapper for a callable initializing a property from a getter. + * + * @internal + */ +class LazyProperty +{ + private \Closure $propertyValueCallback; + + public function __construct(\Closure $propertyValueCallback) + { + $this->propertyValueCallback = $propertyValueCallback; + } + + public function getPropertyValue(): mixed + { + return ($this->propertyValueCallback)(); + } +} diff --git a/lib/symfony/validator/Validator/RecursiveContextualValidator.php b/lib/symfony/validator/Validator/RecursiveContextualValidator.php new file mode 100644 index 0000000000..93c6700f1d --- /dev/null +++ b/lib/symfony/validator/Validator/RecursiveContextualValidator.php @@ -0,0 +1,775 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Validator; + +use Psr\Container\ContainerInterface; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\Composite; +use Symfony\Component\Validator\Constraints\Existence; +use Symfony\Component\Validator\Constraints\GroupSequence; +use Symfony\Component\Validator\Constraints\Valid; +use Symfony\Component\Validator\ConstraintValidatorFactoryInterface; +use Symfony\Component\Validator\ConstraintViolationListInterface; +use Symfony\Component\Validator\Context\ExecutionContext; +use Symfony\Component\Validator\Context\ExecutionContextInterface; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\NoSuchMetadataException; +use Symfony\Component\Validator\Exception\RuntimeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; +use Symfony\Component\Validator\Exception\UnsupportedMetadataException; +use Symfony\Component\Validator\Exception\ValidatorException; +use Symfony\Component\Validator\Mapping\CascadingStrategy; +use Symfony\Component\Validator\Mapping\ClassMetadataInterface; +use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; +use Symfony\Component\Validator\Mapping\GenericMetadata; +use Symfony\Component\Validator\Mapping\GetterMetadata; +use Symfony\Component\Validator\Mapping\MetadataInterface; +use Symfony\Component\Validator\Mapping\PropertyMetadataInterface; +use Symfony\Component\Validator\Mapping\TraversalStrategy; +use Symfony\Component\Validator\ObjectInitializerInterface; +use Symfony\Component\Validator\Util\PropertyPath; + +/** + * Recursive implementation of {@link ContextualValidatorInterface}. + * + * @author Bernhard Schussek + */ +class RecursiveContextualValidator implements ContextualValidatorInterface +{ + private ExecutionContextInterface $context; + private string $defaultPropertyPath; + private array $defaultGroups; + private MetadataFactoryInterface $metadataFactory; + private ConstraintValidatorFactoryInterface $validatorFactory; + private array $objectInitializers; + private ?ContainerInterface $groupProviderLocator; + + /** + * Creates a validator for the given context. + * + * @param ObjectInitializerInterface[] $objectInitializers The object initializers + */ + public function __construct(ExecutionContextInterface $context, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, array $objectInitializers = [], ?ContainerInterface $groupProviderLocator = null) + { + $this->context = $context; + $this->defaultPropertyPath = $context->getPropertyPath(); + $this->defaultGroups = [$context->getGroup() ?: Constraint::DEFAULT_GROUP]; + $this->metadataFactory = $metadataFactory; + $this->validatorFactory = $validatorFactory; + $this->objectInitializers = $objectInitializers; + $this->groupProviderLocator = $groupProviderLocator; + } + + public function atPath(string $path): static + { + $this->defaultPropertyPath = $this->context->getPropertyPath($path); + + return $this; + } + + public function validate(mixed $value, Constraint|array|null $constraints = null, string|GroupSequence|array|null $groups = null): static + { + $groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups; + + $previousValue = $this->context->getValue(); + $previousObject = $this->context->getObject(); + $previousMetadata = $this->context->getMetadata(); + $previousPath = $this->context->getPropertyPath(); + $previousGroup = $this->context->getGroup(); + $previousConstraint = null; + + if ($this->context instanceof ExecutionContext || method_exists($this->context, 'getConstraint')) { + $previousConstraint = $this->context->getConstraint(); + } + + // If explicit constraints are passed, validate the value against + // those constraints + if (null !== $constraints) { + // You can pass a single constraint or an array of constraints + // Make sure to deal with an array in the rest of the code + if (!\is_array($constraints)) { + $constraints = [$constraints]; + } + + $metadata = new GenericMetadata(); + $metadata->addConstraints($constraints); + + $this->validateGenericNode( + $value, + $previousObject, + \is_object($value) ? $this->generateCacheKey($value) : null, + $metadata, + $this->defaultPropertyPath, + $groups, + null, + TraversalStrategy::IMPLICIT, + $this->context + ); + + $this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath); + $this->context->setGroup($previousGroup); + + if (null !== $previousConstraint) { + $this->context->setConstraint($previousConstraint); + } + + return $this; + } + + // If an object is passed without explicit constraints, validate that + // object against the constraints defined for the object's class + if (\is_object($value)) { + $this->validateObject( + $value, + $this->defaultPropertyPath, + $groups, + TraversalStrategy::IMPLICIT, + $this->context + ); + + $this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath); + $this->context->setGroup($previousGroup); + + return $this; + } + + // If an array is passed without explicit constraints, validate each + // object in the array + if (\is_array($value)) { + $this->validateEachObjectIn( + $value, + $this->defaultPropertyPath, + $groups, + $this->context + ); + + $this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath); + $this->context->setGroup($previousGroup); + + return $this; + } + + throw new RuntimeException(\sprintf('Cannot validate values of type "%s" automatically. Please provide a constraint.', get_debug_type($value))); + } + + public function validateProperty(object $object, string $propertyName, string|GroupSequence|array|null $groups = null): static + { + $classMetadata = $this->metadataFactory->getMetadataFor($object); + + if (!$classMetadata instanceof ClassMetadataInterface) { + throw new ValidatorException(\sprintf('The metadata factory should return instances of "\Symfony\Component\Validator\Mapping\ClassMetadataInterface", got: "%s".', get_debug_type($classMetadata))); + } + + $propertyMetadatas = $classMetadata->getPropertyMetadata($propertyName); + $groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups; + $cacheKey = $this->generateCacheKey($object); + $propertyPath = PropertyPath::append($this->defaultPropertyPath, $propertyName); + + $previousValue = $this->context->getValue(); + $previousObject = $this->context->getObject(); + $previousMetadata = $this->context->getMetadata(); + $previousPath = $this->context->getPropertyPath(); + $previousGroup = $this->context->getGroup(); + + foreach ($propertyMetadatas as $propertyMetadata) { + $propertyValue = $propertyMetadata->getPropertyValue($object); + + $this->validateGenericNode( + $propertyValue, + $object, + $cacheKey.':'.$object::class.':'.$propertyName, + $propertyMetadata, + $propertyPath, + $groups, + null, + TraversalStrategy::IMPLICIT, + $this->context + ); + } + + $this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath); + $this->context->setGroup($previousGroup); + + return $this; + } + + public function validatePropertyValue(object|string $objectOrClass, string $propertyName, mixed $value, string|GroupSequence|array|null $groups = null): static + { + $classMetadata = $this->metadataFactory->getMetadataFor($objectOrClass); + + if (!$classMetadata instanceof ClassMetadataInterface) { + throw new ValidatorException(\sprintf('The metadata factory should return instances of "\Symfony\Component\Validator\Mapping\ClassMetadataInterface", got: "%s".', get_debug_type($classMetadata))); + } + + $propertyMetadatas = $classMetadata->getPropertyMetadata($propertyName); + $groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups; + + if (\is_object($objectOrClass)) { + $object = $objectOrClass; + $class = $object::class; + $cacheKey = $this->generateCacheKey($objectOrClass); + $propertyPath = PropertyPath::append($this->defaultPropertyPath, $propertyName); + } else { + // $objectOrClass contains a class name + $object = null; + $class = $objectOrClass; + $cacheKey = null; + $propertyPath = $this->defaultPropertyPath; + } + + $previousValue = $this->context->getValue(); + $previousObject = $this->context->getObject(); + $previousMetadata = $this->context->getMetadata(); + $previousPath = $this->context->getPropertyPath(); + $previousGroup = $this->context->getGroup(); + + foreach ($propertyMetadatas as $propertyMetadata) { + $this->validateGenericNode( + $value, + $object, + $cacheKey.':'.$class.':'.$propertyName, + $propertyMetadata, + $propertyPath, + $groups, + null, + TraversalStrategy::IMPLICIT, + $this->context + ); + } + + $this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath); + $this->context->setGroup($previousGroup); + + return $this; + } + + public function getViolations(): ConstraintViolationListInterface + { + return $this->context->getViolations(); + } + + /** + * Normalizes the given group or list of groups to an array. + * + * @param string|GroupSequence|array $groups The groups to normalize + * + * @return array + */ + protected function normalizeGroups(string|GroupSequence|array $groups): array + { + if (\is_array($groups)) { + return $groups; + } + + return [$groups]; + } + + /** + * Validates an object against the constraints defined for its class. + * + * If no metadata is available for the class, but the class is an instance + * of {@link \Traversable} and the selected traversal strategy allows + * traversal, the object will be iterated and each nested object will be + * validated instead. + * + * @throws NoSuchMetadataException If the object has no associated metadata + * and does not implement {@link \Traversable} + * or if traversal is disabled via the + * $traversalStrategy argument + * @throws UnsupportedMetadataException If the metadata returned by the + * metadata factory does not implement + * {@link ClassMetadataInterface} + */ + private function validateObject(object $object, string $propertyPath, array $groups, int $traversalStrategy, ExecutionContextInterface $context): void + { + try { + $classMetadata = $this->metadataFactory->getMetadataFor($object); + + if (!$classMetadata instanceof ClassMetadataInterface) { + throw new UnsupportedMetadataException(\sprintf('The metadata factory should return instances of "Symfony\Component\Validator\Mapping\ClassMetadataInterface", got: "%s".', get_debug_type($classMetadata))); + } + + $this->validateClassNode( + $object, + $this->generateCacheKey($object), + $classMetadata, + $propertyPath, + $groups, + null, + $traversalStrategy, + $context + ); + } catch (NoSuchMetadataException $e) { + // Rethrow if not Traversable + if (!$object instanceof \Traversable) { + throw $e; + } + + // Rethrow unless IMPLICIT or TRAVERSE + if (!($traversalStrategy & (TraversalStrategy::IMPLICIT | TraversalStrategy::TRAVERSE))) { + throw $e; + } + + $this->validateEachObjectIn( + $object, + $propertyPath, + $groups, + $context + ); + } + } + + /** + * Validates each object in a collection against the constraints defined + * for their classes. + * + * Nested arrays are also iterated. + */ + private function validateEachObjectIn(iterable $collection, string $propertyPath, array $groups, ExecutionContextInterface $context): void + { + foreach ($collection as $key => $value) { + if (\is_array($value)) { + // Also traverse nested arrays + $this->validateEachObjectIn( + $value, + $propertyPath.'['.$key.']', + $groups, + $context + ); + + continue; + } + + // Scalar and null values in the collection are ignored + if (\is_object($value)) { + $this->validateObject( + $value, + $propertyPath.'['.$key.']', + $groups, + TraversalStrategy::IMPLICIT, + $context + ); + } + } + } + + /** + * Validates a class node. + * + * A class node is a combination of an object with a {@link ClassMetadataInterface} + * instance. Each class node (conceptually) has zero or more succeeding + * property nodes: + * + * (Article:class node) + * \ + * ($title:property node) + * + * This method validates the passed objects against all constraints defined + * at class level. It furthermore triggers the validation of each of the + * class' properties against the constraints for that property. + * + * If the selected traversal strategy allows traversal, the object is + * iterated and each nested object is validated against its own constraints. + * The object is not traversed if traversal is disabled in the class + * metadata. + * + * If the passed groups contain the group "Default", the validator will + * check whether the "Default" group has been replaced by a group sequence + * in the class metadata. If this is the case, the group sequence is + * validated instead. + * + * @throws UnsupportedMetadataException If a property metadata does not + * implement {@link PropertyMetadataInterface} + * @throws ConstraintDefinitionException If traversal was enabled but the + * object does not implement + * {@link \Traversable} + * + * @see TraversalStrategy + */ + private function validateClassNode(object $object, ?string $cacheKey, ClassMetadataInterface $metadata, string $propertyPath, array $groups, ?array $cascadedGroups, int $traversalStrategy, ExecutionContextInterface $context): void + { + $context->setNode($object, $object, $metadata, $propertyPath); + + if (!$context->isObjectInitialized($cacheKey)) { + foreach ($this->objectInitializers as $initializer) { + $initializer->initialize($object); + } + + $context->markObjectAsInitialized($cacheKey); + } + + foreach ($groups as $key => $group) { + // If the "Default" group is replaced by a group sequence, remember + // to cascade the "Default" group when traversing the group + // sequence + $defaultOverridden = false; + + // Use the object hash for group sequences + $groupHash = \is_object($group) ? $this->generateCacheKey($group, true) : $group; + + if ($context->isGroupValidated($cacheKey, $groupHash)) { + // Skip this group when validating the properties and when + // traversing the object + unset($groups[$key]); + + continue; + } + + $context->markGroupAsValidated($cacheKey, $groupHash); + + // Replace the "Default" group by the group sequence defined + // for the class, if applicable. + // This is done after checking the cache, so that + // spl_object_hash() isn't called for this sequence and + // "Default" is used instead in the cache. This is useful + // if the getters below return different group sequences in + // every call. + if (Constraint::DEFAULT_GROUP === $group) { + if ($metadata->hasGroupSequence()) { + // The group sequence is statically defined for the class + $group = $metadata->getGroupSequence(); + $defaultOverridden = true; + } elseif ($metadata->isGroupSequenceProvider()) { + if (null !== $provider = $metadata->getGroupProvider()) { + if (null === $this->groupProviderLocator) { + throw new \LogicException('A group provider locator is required when using group provider.'); + } + + $group = $this->groupProviderLocator->get($provider)->getGroups($object); + } else { + // The group sequence is dynamically obtained from the validated + // object + /** @var \Symfony\Component\Validator\GroupSequenceProviderInterface $object */ + $group = $object->getGroupSequence(); + } + $defaultOverridden = true; + + if (!$group instanceof GroupSequence) { + $group = new GroupSequence($group); + } + } + } + + // If the groups (=[,G3,G4]) contain a group sequence + // (=), then call validateClassNode() with each entry of the + // group sequence and abort if necessary (G1, G2) + if ($group instanceof GroupSequence) { + $this->stepThroughGroupSequence( + $object, + $object, + $cacheKey, + $metadata, + $propertyPath, + $traversalStrategy, + $group, + $defaultOverridden ? Constraint::DEFAULT_GROUP : null, + $context + ); + + // Skip the group sequence when validating properties, because + // stepThroughGroupSequence() already validates the properties + unset($groups[$key]); + + continue; + } + + $this->validateInGroup($object, $cacheKey, $metadata, $group, $context); + } + + // If no more groups should be validated for the property nodes, + // we can safely quit + if (0 === \count($groups)) { + return; + } + + // Validate all properties against their constraints + foreach ($metadata->getConstrainedProperties() as $propertyName) { + // If constraints are defined both on the getter of a property as + // well as on the property itself, then getPropertyMetadata() + // returns two metadata objects, not just one + foreach ($metadata->getPropertyMetadata($propertyName) as $propertyMetadata) { + if (!$propertyMetadata instanceof PropertyMetadataInterface) { + throw new UnsupportedMetadataException(\sprintf('The property metadata instances should implement "Symfony\Component\Validator\Mapping\PropertyMetadataInterface", got: "%s".', get_debug_type($propertyMetadata))); + } + + if ($propertyMetadata instanceof GetterMetadata) { + $propertyValue = new LazyProperty(static fn () => $propertyMetadata->getPropertyValue($object)); + } else { + $propertyValue = $propertyMetadata->getPropertyValue($object); + } + + $this->validateGenericNode( + $propertyValue, + $object, + $cacheKey.':'.$object::class.':'.$propertyName, + $propertyMetadata, + PropertyPath::append($propertyPath, $propertyName), + $groups, + $cascadedGroups, + TraversalStrategy::IMPLICIT, + $context + ); + } + } + + // If no specific traversal strategy was requested when this method + // was called, use the traversal strategy of the class' metadata + if ($traversalStrategy & TraversalStrategy::IMPLICIT) { + $traversalStrategy = $metadata->getTraversalStrategy(); + } + + // Traverse only if IMPLICIT or TRAVERSE + if (!($traversalStrategy & (TraversalStrategy::IMPLICIT | TraversalStrategy::TRAVERSE))) { + return; + } + + // If IMPLICIT, stop unless we deal with a Traversable + if ($traversalStrategy & TraversalStrategy::IMPLICIT && !$object instanceof \Traversable) { + return; + } + + // If TRAVERSE, fail if we have no Traversable + if (!$object instanceof \Traversable) { + throw new ConstraintDefinitionException(\sprintf('Traversal was enabled for "%s", but this class does not implement "\Traversable".', get_debug_type($object))); + } + + $this->validateEachObjectIn( + $object, + $propertyPath, + $groups, + $context + ); + } + + /** + * Validates a node that is not a class node. + * + * Currently, two such node types exist: + * + * - property nodes, which consist of the value of an object's + * property together with a {@link PropertyMetadataInterface} instance + * - generic nodes, which consist of a value and some arbitrary + * constraints defined in a {@link MetadataInterface} container + * + * In both cases, the value is validated against all constraints defined + * in the passed metadata object. Then, if the value is an instance of + * {@link \Traversable} and the selected traversal strategy permits it, + * the value is traversed and each nested object validated against its own + * constraints. If the value is an array, it is traversed regardless of + * the given strategy. + * + * @see TraversalStrategy + */ + private function validateGenericNode(mixed $value, ?object $object, ?string $cacheKey, ?MetadataInterface $metadata, string $propertyPath, array $groups, ?array $cascadedGroups, int $traversalStrategy, ExecutionContextInterface $context): void + { + $context->setNode($value, $object, $metadata, $propertyPath); + + foreach ($groups as $key => $group) { + if ($group instanceof GroupSequence) { + $this->stepThroughGroupSequence( + $value, + $object, + $cacheKey, + $metadata, + $propertyPath, + $traversalStrategy, + $group, + null, + $context + ); + + // Skip the group sequence when cascading, as the cascading + // logic is already done in stepThroughGroupSequence() + unset($groups[$key]); + + continue; + } + + $this->validateInGroup($value, $cacheKey, $metadata, $group, $context); + } + + if (0 === \count($groups)) { + return; + } + + if (null === $value) { + return; + } + + $cascadingStrategy = $metadata->getCascadingStrategy(); + + // Quit unless we cascade + if (!($cascadingStrategy & CascadingStrategy::CASCADE)) { + return; + } + + // If no specific traversal strategy was requested when this method + // was called, use the traversal strategy of the node's metadata + if ($traversalStrategy & TraversalStrategy::IMPLICIT) { + $traversalStrategy = $metadata->getTraversalStrategy(); + } + + // The $cascadedGroups property is set, if the "Default" group is + // overridden by a group sequence + // See validateClassNode() + $cascadedGroups = null !== $cascadedGroups && \count($cascadedGroups) > 0 ? $cascadedGroups : $groups; + + if ($value instanceof LazyProperty) { + $value = $value->getPropertyValue(); + + if (null === $value) { + return; + } + } + + if (\is_array($value)) { + // Arrays are always traversed, independent of the specified + // traversal strategy + $this->validateEachObjectIn( + $value, + $propertyPath, + $cascadedGroups, + $context + ); + + return; + } + + if (!\is_object($value)) { + throw new NoSuchMetadataException(\sprintf('Cannot create metadata for non-objects. Got: "%s".', \gettype($value))); + } + + $this->validateObject( + $value, + $propertyPath, + $cascadedGroups, + $traversalStrategy, + $context + ); + + // Currently, the traversal strategy can only be TRAVERSE for a + // generic node if the cascading strategy is CASCADE. Thus, traversable + // objects will always be handled within validateObject() and there's + // nothing more to do here. + + // see GenericMetadata::addConstraint() + } + + /** + * Sequentially validates a node's value in each group of a group sequence. + * + * If any of the constraints generates a violation, subsequent groups in the + * group sequence are skipped. + */ + private function stepThroughGroupSequence(mixed $value, ?object $object, ?string $cacheKey, ?MetadataInterface $metadata, string $propertyPath, int $traversalStrategy, GroupSequence $groupSequence, ?string $cascadedGroup, ExecutionContextInterface $context): void + { + $violationCount = \count($context->getViolations()); + $cascadedGroups = $cascadedGroup ? [$cascadedGroup] : null; + + foreach ($groupSequence->groups as $groupInSequence) { + $groups = (array) $groupInSequence; + + if ($metadata instanceof ClassMetadataInterface) { + $this->validateClassNode( + $value, + $cacheKey, + $metadata, + $propertyPath, + $groups, + $cascadedGroups, + $traversalStrategy, + $context + ); + } else { + $this->validateGenericNode( + $value, + $object, + $cacheKey, + $metadata, + $propertyPath, + $groups, + $cascadedGroups, + $traversalStrategy, + $context + ); + } + + // Abort sequence validation if a violation was generated + if (\count($context->getViolations()) > $violationCount) { + break; + } + } + } + + /** + * Validates a node's value against all constraints in the given group. + */ + private function validateInGroup(mixed $value, ?string $cacheKey, MetadataInterface $metadata, string $group, ExecutionContextInterface $context): void + { + $context->setGroup($group); + + foreach ($metadata->findConstraints($group) as $constraint) { + if ($constraint instanceof Existence) { + continue; + } + + // Prevent duplicate validation of constraints, in the case + // that constraints belong to multiple validated groups + if (null !== $cacheKey) { + $constraintHash = $this->generateCacheKey($constraint, true); + // instanceof Valid: In case of using a Valid constraint with many groups + // it makes a reference object get validated by each group + if ($constraint instanceof Composite || $constraint instanceof Valid) { + $constraintHash .= $group; + } + + if ($context->isConstraintValidated($cacheKey, $constraintHash)) { + continue; + } + + $context->markConstraintAsValidated($cacheKey, $constraintHash); + } + + $context->setConstraint($constraint); + + $validator = $this->validatorFactory->getInstance($constraint); + $validator->initialize($context); + + if ($value instanceof LazyProperty) { + $value = $value->getPropertyValue(); + } + + try { + $validator->validate($value, $constraint); + } catch (UnexpectedValueException $e) { + $context->buildViolation('This value should be of type {{ type }}.') + ->setParameter('{{ type }}', $e->getExpectedType()) + ->addViolation(); + } + } + } + + private function generateCacheKey(object $object, bool $dependsOnPropertyPath = false): string + { + if ($this->context instanceof ExecutionContext) { + $cacheKey = $this->context->generateCacheKey($object); + } else { + $cacheKey = spl_object_hash($object); + } + + if ($dependsOnPropertyPath) { + $cacheKey .= $this->context->getPropertyPath(); + } + + return $cacheKey; + } +} diff --git a/lib/symfony/validator/Validator/RecursiveValidator.php b/lib/symfony/validator/Validator/RecursiveValidator.php new file mode 100644 index 0000000000..64f311026e --- /dev/null +++ b/lib/symfony/validator/Validator/RecursiveValidator.php @@ -0,0 +1,105 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Validator; + +use Psr\Container\ContainerInterface; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\GroupSequence; +use Symfony\Component\Validator\ConstraintValidatorFactoryInterface; +use Symfony\Component\Validator\ConstraintViolationListInterface; +use Symfony\Component\Validator\Context\ExecutionContextFactoryInterface; +use Symfony\Component\Validator\Context\ExecutionContextInterface; +use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; +use Symfony\Component\Validator\Mapping\MetadataInterface; +use Symfony\Component\Validator\ObjectInitializerInterface; + +/** + * Recursive implementation of {@link ValidatorInterface}. + * + * @author Bernhard Schussek + */ +class RecursiveValidator implements ValidatorInterface +{ + protected $contextFactory; + protected $metadataFactory; + protected $validatorFactory; + protected $objectInitializers; + protected ?ContainerInterface $groupProviderLocator; + + /** + * Creates a new validator. + * + * @param ObjectInitializerInterface[] $objectInitializers The object initializers + */ + public function __construct(ExecutionContextFactoryInterface $contextFactory, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, array $objectInitializers = [], ?ContainerInterface $groupProviderLocator = null) + { + $this->contextFactory = $contextFactory; + $this->metadataFactory = $metadataFactory; + $this->validatorFactory = $validatorFactory; + $this->objectInitializers = $objectInitializers; + $this->groupProviderLocator = $groupProviderLocator; + } + + public function startContext(mixed $root = null): ContextualValidatorInterface + { + return new RecursiveContextualValidator( + $this->contextFactory->createContext($this, $root), + $this->metadataFactory, + $this->validatorFactory, + $this->objectInitializers, + $this->groupProviderLocator, + ); + } + + public function inContext(ExecutionContextInterface $context): ContextualValidatorInterface + { + return new RecursiveContextualValidator( + $context, + $this->metadataFactory, + $this->validatorFactory, + $this->objectInitializers, + $this->groupProviderLocator, + ); + } + + public function getMetadataFor(mixed $object): MetadataInterface + { + return $this->metadataFactory->getMetadataFor($object); + } + + public function hasMetadataFor(mixed $object): bool + { + return $this->metadataFactory->hasMetadataFor($object); + } + + public function validate(mixed $value, Constraint|array|null $constraints = null, string|GroupSequence|array|null $groups = null): ConstraintViolationListInterface + { + return $this->startContext($value) + ->validate($value, $constraints, $groups) + ->getViolations(); + } + + public function validateProperty(object $object, string $propertyName, string|GroupSequence|array|null $groups = null): ConstraintViolationListInterface + { + return $this->startContext($object) + ->validateProperty($object, $propertyName, $groups) + ->getViolations(); + } + + public function validatePropertyValue(object|string $objectOrClass, string $propertyName, mixed $value, string|GroupSequence|array|null $groups = null): ConstraintViolationListInterface + { + // If a class name is passed, take $value as root + return $this->startContext(\is_object($objectOrClass) ? $objectOrClass : $value) + ->validatePropertyValue($objectOrClass, $propertyName, $value, $groups) + ->getViolations(); + } +} diff --git a/lib/symfony/validator/Validator/TraceableValidator.php b/lib/symfony/validator/Validator/TraceableValidator.php new file mode 100644 index 0000000000..4add47fc54 --- /dev/null +++ b/lib/symfony/validator/Validator/TraceableValidator.php @@ -0,0 +1,119 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Validator; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\GroupSequence; +use Symfony\Component\Validator\ConstraintViolationListInterface; +use Symfony\Component\Validator\Context\ExecutionContextInterface; +use Symfony\Component\Validator\Mapping\MetadataInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Collects some data about validator calls. + * + * @author Maxime Steinhausser + */ +class TraceableValidator implements ValidatorInterface, ResetInterface +{ + private ValidatorInterface $validator; + private array $collectedData = []; + + public function __construct(ValidatorInterface $validator) + { + $this->validator = $validator; + } + + public function getCollectedData(): array + { + return $this->collectedData; + } + + /** + * @return void + */ + public function reset() + { + $this->collectedData = []; + } + + public function getMetadataFor(mixed $value): MetadataInterface + { + return $this->validator->getMetadataFor($value); + } + + public function hasMetadataFor(mixed $value): bool + { + return $this->validator->hasMetadataFor($value); + } + + public function validate(mixed $value, Constraint|array|null $constraints = null, string|GroupSequence|array|null $groups = null): ConstraintViolationListInterface + { + $violations = $this->validator->validate($value, $constraints, $groups); + + $trace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 7); + + $file = $trace[0]['file']; + $line = $trace[0]['line']; + + for ($i = 1; $i < 7; ++$i) { + if (isset($trace[$i]['class'], $trace[$i]['function']) + && 'validate' === $trace[$i]['function'] + && is_a($trace[$i]['class'], ValidatorInterface::class, true) + ) { + $file = $trace[$i]['file']; + $line = $trace[$i]['line']; + + while (++$i < 7) { + if (isset($trace[$i]['function'], $trace[$i]['file']) && empty($trace[$i]['class']) && !str_starts_with($trace[$i]['function'], 'call_user_func')) { + $file = $trace[$i]['file']; + $line = $trace[$i]['line']; + + break; + } + } + break; + } + } + + $name = str_replace('\\', '/', $file); + $name = substr($name, strrpos($name, '/') + 1); + + $this->collectedData[] = [ + 'caller' => compact('name', 'file', 'line'), + 'context' => compact('value', 'constraints', 'groups'), + 'violations' => iterator_to_array($violations), + ]; + + return $violations; + } + + public function validateProperty(object $object, string $propertyName, string|GroupSequence|array|null $groups = null): ConstraintViolationListInterface + { + return $this->validator->validateProperty($object, $propertyName, $groups); + } + + public function validatePropertyValue(object|string $objectOrClass, string $propertyName, mixed $value, string|GroupSequence|array|null $groups = null): ConstraintViolationListInterface + { + return $this->validator->validatePropertyValue($objectOrClass, $propertyName, $value, $groups); + } + + public function startContext(): ContextualValidatorInterface + { + return $this->validator->startContext(); + } + + public function inContext(ExecutionContextInterface $context): ContextualValidatorInterface + { + return $this->validator->inContext($context); + } +} diff --git a/lib/symfony/validator/Validator/ValidatorInterface.php b/lib/symfony/validator/Validator/ValidatorInterface.php new file mode 100644 index 0000000000..f26a9b99a0 --- /dev/null +++ b/lib/symfony/validator/Validator/ValidatorInterface.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Validator; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\GroupSequence; +use Symfony\Component\Validator\ConstraintViolationListInterface; +use Symfony\Component\Validator\Context\ExecutionContextInterface; +use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; + +/** + * Validates PHP values against constraints. + * + * @author Bernhard Schussek + */ +interface ValidatorInterface extends MetadataFactoryInterface +{ + /** + * Validates a value against a constraint or a list of constraints. + * + * If no constraint is passed, the constraint + * {@link \Symfony\Component\Validator\Constraints\Valid} is assumed. + * + * @param Constraint|Constraint[] $constraints The constraint(s) to validate against + * @param string|GroupSequence|array|null $groups The validation groups to validate. If none is given, "Default" is assumed + * + * @return ConstraintViolationListInterface A list of constraint violations + * If the list is empty, validation + * succeeded + */ + public function validate(mixed $value, Constraint|array|null $constraints = null, string|GroupSequence|array|null $groups = null): ConstraintViolationListInterface; + + /** + * Validates a property of an object against the constraints specified + * for this property. + * + * @param string $propertyName The name of the validated property + * @param string|GroupSequence|array|null $groups The validation groups to validate. If none is given, "Default" is assumed + * + * @return ConstraintViolationListInterface A list of constraint violations + * If the list is empty, validation + * succeeded + */ + public function validateProperty(object $object, string $propertyName, string|GroupSequence|array|null $groups = null): ConstraintViolationListInterface; + + /** + * Validates a value against the constraints specified for an object's + * property. + * + * @param object|string $objectOrClass The object or its class name + * @param string $propertyName The name of the property + * @param mixed $value The value to validate against the property's constraints + * @param string|GroupSequence|array|null $groups The validation groups to validate. If none is given, "Default" is assumed + * + * @return ConstraintViolationListInterface A list of constraint violations + * If the list is empty, validation + * succeeded + */ + public function validatePropertyValue(object|string $objectOrClass, string $propertyName, mixed $value, string|GroupSequence|array|null $groups = null): ConstraintViolationListInterface; + + /** + * Starts a new validation context and returns a validator for that context. + * + * The returned validator collects all violations generated within its + * context. You can access these violations with the + * {@link ContextualValidatorInterface::getViolations()} method. + */ + public function startContext(): ContextualValidatorInterface; + + /** + * Returns a validator in the given execution context. + * + * The returned validator adds all generated violations to the given + * context. + */ + public function inContext(ExecutionContextInterface $context): ContextualValidatorInterface; +} diff --git a/lib/symfony/validator/ValidatorBuilder.php b/lib/symfony/validator/ValidatorBuilder.php new file mode 100644 index 0000000000..9ab08e44b3 --- /dev/null +++ b/lib/symfony/validator/ValidatorBuilder.php @@ -0,0 +1,444 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Doctrine\Common\Annotations\AnnotationReader; +use Doctrine\Common\Annotations\PsrCachedReader; +use Doctrine\Common\Annotations\Reader; +use Psr\Cache\CacheItemPoolInterface; +use Psr\Container\ContainerInterface; +use Symfony\Component\Cache\Adapter\ArrayAdapter; +use Symfony\Component\Validator\Context\ExecutionContextFactory; +use Symfony\Component\Validator\Exception\LogicException; +use Symfony\Component\Validator\Exception\ValidatorException; +use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory; +use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; +use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Validator\Mapping\Loader\AttributeLoader; +use Symfony\Component\Validator\Mapping\Loader\LoaderChain; +use Symfony\Component\Validator\Mapping\Loader\LoaderInterface; +use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader; +use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader; +use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader; +use Symfony\Component\Validator\Validator\RecursiveValidator; +use Symfony\Component\Validator\Validator\ValidatorInterface; +use Symfony\Contracts\Translation\LocaleAwareInterface; +use Symfony\Contracts\Translation\TranslatorInterface; +use Symfony\Contracts\Translation\TranslatorTrait; + +// Help opcache.preload discover always-needed symbols +class_exists(TranslatorInterface::class); +class_exists(LocaleAwareInterface::class); +class_exists(TranslatorTrait::class); + +/** + * @author Bernhard Schussek + */ +class ValidatorBuilder +{ + private array $initializers = []; + private array $loaders = []; + private array $xmlMappings = []; + private array $yamlMappings = []; + private array $methodMappings = []; + private ?Reader $annotationReader = null; + private bool $enableAttributeMapping = false; + private ?MetadataFactoryInterface $metadataFactory = null; + private ConstraintValidatorFactoryInterface $validatorFactory; + private ?ContainerInterface $groupProviderLocator = null; + private ?CacheItemPoolInterface $mappingCache = null; + private ?TranslatorInterface $translator = null; + private ?string $translationDomain = null; + + /** + * Adds an object initializer to the validator. + * + * @return $this + */ + public function addObjectInitializer(ObjectInitializerInterface $initializer): static + { + $this->initializers[] = $initializer; + + return $this; + } + + /** + * Adds a list of object initializers to the validator. + * + * @param ObjectInitializerInterface[] $initializers + * + * @return $this + */ + public function addObjectInitializers(array $initializers): static + { + $this->initializers = array_merge($this->initializers, $initializers); + + return $this; + } + + /** + * Adds an XML constraint mapping file to the validator. + * + * @return $this + */ + public function addXmlMapping(string $path): static + { + if (null !== $this->metadataFactory) { + throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.'); + } + + $this->xmlMappings[] = $path; + + return $this; + } + + /** + * Adds a list of XML constraint mapping files to the validator. + * + * @param string[] $paths The paths to the mapping files + * + * @return $this + */ + public function addXmlMappings(array $paths): static + { + if (null !== $this->metadataFactory) { + throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.'); + } + + $this->xmlMappings = array_merge($this->xmlMappings, $paths); + + return $this; + } + + /** + * Adds a YAML constraint mapping file to the validator. + * + * @param string $path The path to the mapping file + * + * @return $this + */ + public function addYamlMapping(string $path): static + { + if (null !== $this->metadataFactory) { + throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.'); + } + + $this->yamlMappings[] = $path; + + return $this; + } + + /** + * Adds a list of YAML constraint mappings file to the validator. + * + * @param string[] $paths The paths to the mapping files + * + * @return $this + */ + public function addYamlMappings(array $paths): static + { + if (null !== $this->metadataFactory) { + throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.'); + } + + $this->yamlMappings = array_merge($this->yamlMappings, $paths); + + return $this; + } + + /** + * Enables constraint mapping using the given static method. + * + * @return $this + */ + public function addMethodMapping(string $methodName): static + { + if (null !== $this->metadataFactory) { + throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.'); + } + + $this->methodMappings[] = $methodName; + + return $this; + } + + /** + * Enables constraint mapping using the given static methods. + * + * @param string[] $methodNames The names of the methods + * + * @return $this + */ + public function addMethodMappings(array $methodNames): static + { + if (null !== $this->metadataFactory) { + throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.'); + } + + $this->methodMappings = array_merge($this->methodMappings, $methodNames); + + return $this; + } + + /** + * @deprecated since Symfony 6.4, use "enableAttributeMapping()" instead. + * + * @return $this + */ + public function enableAnnotationMapping(): static + { + trigger_deprecation('symfony/validator', '6.4', 'Method "%s()" is deprecated, use "enableAttributeMapping()" instead.', __METHOD__); + + return $this->enableAttributeMapping(); + } + + /** + * Enables attribute-based constraint mapping. + * + * @return $this + */ + public function enableAttributeMapping(): static + { + if (null !== $this->metadataFactory) { + throw new ValidatorException('You cannot enable attribute mapping after setting a custom metadata factory. Configure your metadata factory instead.'); + } + + $this->enableAttributeMapping = true; + + return $this; + } + + /** + * @deprecated since Symfony 6.4, use "disableAttributeMapping()" instead + * + * @return $this + */ + public function disableAnnotationMapping(): static + { + trigger_deprecation('symfony/validator', '6.4', 'Method "%s()" is deprecated, use "disableAttributeMapping()" instead.', __METHOD__); + + return $this->disableAttributeMapping(); + } + + /** + * Disables attribute-based constraint mapping. + * + * @return $this + */ + public function disableAttributeMapping(): static + { + $this->annotationReader = null; + $this->enableAttributeMapping = false; + + return $this; + } + + /** + * @deprecated since Symfony 6.4 without replacement + * + * @return $this + */ + public function setDoctrineAnnotationReader(?Reader $reader): static + { + trigger_deprecation('symfony/validator', '6.4', 'Method "%s()" is deprecated without replacement.', __METHOD__); + + $this->annotationReader = $reader; + + return $this; + } + + /** + * @deprecated since Symfony 6.4 without replacement + * + * @return $this + */ + public function addDefaultDoctrineAnnotationReader(): static + { + trigger_deprecation('symfony/validator', '6.4', 'Method "%s()" is deprecated without replacement.', __METHOD__); + + $this->annotationReader = $this->createAnnotationReader(); + + return $this; + } + + /** + * Sets the class metadata factory used by the validator. + * + * @return $this + */ + public function setMetadataFactory(MetadataFactoryInterface $metadataFactory): static + { + if (\count($this->xmlMappings) > 0 || \count($this->yamlMappings) > 0 || \count($this->methodMappings) > 0 || $this->enableAttributeMapping) { + throw new ValidatorException('You cannot set a custom metadata factory after adding custom mappings. You should do either of both.'); + } + + $this->metadataFactory = $metadataFactory; + + return $this; + } + + /** + * Sets the cache for caching class metadata. + * + * @return $this + */ + public function setMappingCache(CacheItemPoolInterface $cache): static + { + if (null !== $this->metadataFactory) { + throw new ValidatorException('You cannot set a custom mapping cache after setting a custom metadata factory. Configure your metadata factory instead.'); + } + + $this->mappingCache = $cache; + + return $this; + } + + /** + * Sets the constraint validator factory used by the validator. + * + * @return $this + */ + public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $validatorFactory): static + { + $this->validatorFactory = $validatorFactory; + + return $this; + } + + /** + * @return $this + */ + public function setGroupProviderLocator(ContainerInterface $groupProviderLocator): static + { + $this->groupProviderLocator = $groupProviderLocator; + + return $this; + } + + /** + * Sets the translator used for translating violation messages. + * + * @return $this + */ + public function setTranslator(TranslatorInterface $translator): static + { + $this->translator = $translator; + + return $this; + } + + /** + * Sets the default translation domain of violation messages. + * + * The same message can have different translations in different domains. + * Pass the domain that is used for violation messages by default to this + * method. + * + * @return $this + */ + public function setTranslationDomain(?string $translationDomain): static + { + $this->translationDomain = $translationDomain; + + return $this; + } + + /** + * @return $this + */ + public function addLoader(LoaderInterface $loader): static + { + $this->loaders[] = $loader; + + return $this; + } + + /** + * @return LoaderInterface[] + */ + public function getLoaders(): array + { + $loaders = []; + + foreach ($this->xmlMappings as $xmlMapping) { + $loaders[] = new XmlFileLoader($xmlMapping); + } + + foreach ($this->yamlMappings as $yamlMappings) { + $loaders[] = new YamlFileLoader($yamlMappings); + } + + foreach ($this->methodMappings as $methodName) { + $loaders[] = new StaticMethodLoader($methodName); + } + + if ($this->enableAttributeMapping && $this->annotationReader) { + $loaders[] = new AnnotationLoader($this->annotationReader); + } elseif ($this->enableAttributeMapping) { + $loaders[] = new AttributeLoader(); + } + + return array_merge($loaders, $this->loaders); + } + + /** + * Builds and returns a new validator object. + */ + public function getValidator(): ValidatorInterface + { + $metadataFactory = $this->metadataFactory; + + if (!$metadataFactory) { + $loaders = $this->getLoaders(); + $loader = null; + + if (\count($loaders) > 1) { + $loader = new LoaderChain($loaders); + } elseif (1 === \count($loaders)) { + $loader = $loaders[0]; + } + + $metadataFactory = new LazyLoadingMetadataFactory($loader, $this->mappingCache); + } + + $validatorFactory = $this->validatorFactory ?? new ConstraintValidatorFactory(); + $translator = $this->translator; + + if (null === $translator) { + $translator = new class implements TranslatorInterface, LocaleAwareInterface { + use TranslatorTrait; + }; + // Force the locale to be 'en' when no translator is provided rather than relying on the Intl default locale + // This avoids depending on Intl or the stub implementation being available. It also ensures that Symfony + // validation messages are pluralized properly even when the default locale gets changed because they are in + // English. + $translator->setLocale('en'); + } + + $contextFactory = new ExecutionContextFactory($translator, $this->translationDomain); + + return new RecursiveValidator($contextFactory, $metadataFactory, $validatorFactory, $this->initializers, $this->groupProviderLocator); + } + + private function createAnnotationReader(): Reader + { + if (!class_exists(AnnotationReader::class)) { + throw new LogicException('Enabling annotation based constraint mapping requires the packages doctrine/annotations and symfony/cache to be installed.'); + } + + if (class_exists(ArrayAdapter::class)) { + return new PsrCachedReader(new AnnotationReader(), new ArrayAdapter()); + } + + throw new LogicException('Enabling annotation based constraint mapping requires the packages doctrine/annotations and symfony/cache to be installed.'); + } +} diff --git a/lib/symfony/validator/Violation/ConstraintViolationBuilder.php b/lib/symfony/validator/Violation/ConstraintViolationBuilder.php new file mode 100644 index 0000000000..e6ce597df5 --- /dev/null +++ b/lib/symfony/validator/Violation/ConstraintViolationBuilder.php @@ -0,0 +1,147 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Violation; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintViolation; +use Symfony\Component\Validator\ConstraintViolationList; +use Symfony\Component\Validator\Util\PropertyPath; +use Symfony\Contracts\Translation\TranslatorInterface; + +/** + * Default implementation of {@link ConstraintViolationBuilderInterface}. + * + * @author Bernhard Schussek + * + * @internal since version 2.5. Code against ConstraintViolationBuilderInterface instead. + */ +class ConstraintViolationBuilder implements ConstraintViolationBuilderInterface +{ + private ConstraintViolationList $violations; + private string|\Stringable $message; + private array $parameters; + private mixed $root; + private mixed $invalidValue; + private string $propertyPath; + private TranslatorInterface $translator; + private string|false|null $translationDomain; + private ?int $plural = null; + private ?Constraint $constraint; + private ?string $code = null; + private mixed $cause = null; + + public function __construct(ConstraintViolationList $violations, ?Constraint $constraint, string|\Stringable $message, array $parameters, mixed $root, ?string $propertyPath, mixed $invalidValue, TranslatorInterface $translator, string|false|null $translationDomain = null) + { + $this->violations = $violations; + $this->message = $message; + $this->parameters = $parameters; + $this->root = $root; + $this->propertyPath = $propertyPath ?? ''; + $this->invalidValue = $invalidValue; + $this->translator = $translator; + $this->translationDomain = $translationDomain; + $this->constraint = $constraint; + } + + public function atPath(string $path): static + { + $this->propertyPath = PropertyPath::append($this->propertyPath, $path); + + return $this; + } + + public function setParameter(string $key, string $value): static + { + $this->parameters[$key] = $value; + + return $this; + } + + public function setParameters(array $parameters): static + { + $this->parameters = $parameters; + + return $this; + } + + public function setTranslationDomain(string $translationDomain): static + { + $this->translationDomain = $translationDomain; + + return $this; + } + + /** + * @return $this + */ + public function disableTranslation(): static + { + $this->translationDomain = false; + + return $this; + } + + public function setInvalidValue(mixed $invalidValue): static + { + $this->invalidValue = $invalidValue; + + return $this; + } + + public function setPlural(int $number): static + { + $this->plural = $number; + + return $this; + } + + public function setCode(?string $code): static + { + $this->code = $code; + + return $this; + } + + public function setCause(mixed $cause): static + { + $this->cause = $cause; + + return $this; + } + + public function addViolation(): void + { + $parameters = null === $this->plural ? $this->parameters : (['%count%' => $this->plural] + $this->parameters); + if (false === $this->translationDomain) { + $translatedMessage = strtr($this->message, $parameters); + } else { + $translatedMessage = $this->translator->trans( + $this->message, + $parameters, + $this->translationDomain + ); + } + + $this->violations->add(new ConstraintViolation( + $translatedMessage, + $this->message, + $this->parameters, + $this->root, + $this->propertyPath, + $this->invalidValue, + $this->plural, + $this->code, + $this->constraint, + $this->cause + )); + } +} diff --git a/lib/symfony/validator/Violation/ConstraintViolationBuilderInterface.php b/lib/symfony/validator/Violation/ConstraintViolationBuilderInterface.php new file mode 100644 index 0000000000..02fbeb797c --- /dev/null +++ b/lib/symfony/validator/Violation/ConstraintViolationBuilderInterface.php @@ -0,0 +1,116 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Violation; + +/** + * Builds {@link \Symfony\Component\Validator\ConstraintViolationInterface} + * objects. + * + * Use the various methods on this interface to configure the built violation. + * Finally, call {@link addViolation()} to add the violation to the current + * execution context. + * + * @author Bernhard Schussek + * + * @method $this disableTranslation() + */ +interface ConstraintViolationBuilderInterface +{ + /** + * Stores the property path at which the violation should be generated. + * + * The passed path will be appended to the current property path of the + * execution context. + * + * @param string $path The property path + * + * @return $this + */ + public function atPath(string $path): static; + + /** + * Sets a parameter to be inserted into the violation message. + * + * @param string $key The name of the parameter + * @param string $value The value to be inserted in the parameter's place + * + * @return $this + */ + public function setParameter(string $key, string $value): static; + + /** + * Sets all parameters to be inserted into the violation message. + * + * @param array $parameters An array with the parameter names as keys and + * the values to be inserted in their place as + * values + * + * @return $this + */ + public function setParameters(array $parameters): static; + + /** + * Sets the translation domain which should be used for translating the + * violation message. + * + * @param string $translationDomain The translation domain + * + * @return $this + * + * @see \Symfony\Contracts\Translation\TranslatorInterface + */ + public function setTranslationDomain(string $translationDomain): static; + + /** + * Sets the invalid value that caused this violation. + * + * @return $this + */ + public function setInvalidValue(mixed $invalidValue): static; + + /** + * Sets the number which determines how the plural form of the violation + * message is chosen when it is translated. + * + * @param int $number The number for determining the plural form + * + * @return $this + * + * @see \Symfony\Contracts\Translation\TranslatorInterface::trans() + */ + public function setPlural(int $number): static; + + /** + * Sets the violation code. + * + * @param string|null $code The violation code + * + * @return $this + */ + public function setCode(?string $code): static; + + /** + * Sets the cause of the violation. + * + * @param mixed $cause The cause of the violation + * + * @return $this + */ + public function setCause(mixed $cause): static; + + /** + * Adds the violation to the current execution context. + * + * @return void + */ + public function addViolation(); +} diff --git a/lib/symfony/validator/composer.json b/lib/symfony/validator/composer.json new file mode 100644 index 0000000000..ece01e2fd9 --- /dev/null +++ b/lib/symfony/validator/composer.json @@ -0,0 +1,64 @@ +{ + "name": "symfony/validator", + "type": "library", + "description": "Provides tools to validate values", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php83": "^1.27", + "symfony/translation-contracts": "^2.5|^3" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4.35|~6.3.12|^6.4.3|^7.0.3", + "doctrine/annotations": "^1.13|^2", + "egulias/email-validator": "^2.1.10|^3|^4" + }, + "conflict": { + "doctrine/annotations": "<1.13", + "doctrine/lexer": "<1.1", + "symfony/dependency-injection": "<5.4", + "symfony/expression-language": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/intl": "<5.4", + "symfony/property-info": "<5.4", + "symfony/translation": "<5.4.35|>=6.0,<6.3.12|>=6.4,<6.4.3|>=7.0,<7.0.3", + "symfony/yaml": "<5.4" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Validator\\": "" }, + "exclude-from-classmap": [ + "/Tests/", + "/Resources/bin/" + ] + }, + "minimum-stability": "dev" +} diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index 78077502a4..9a6f709c38 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -13,6 +13,27 @@ "resolved": "https://registry.npmjs.org/@fontsource/raleway/-/raleway-4.5.0.tgz", "integrity": "sha512-Rzj90wbZQnNzazqzoiu5HzMEMdqMJLUVFOo699sinTXrZRm1aB5iX2HTiK2VlPnH4M6u8yYnJ7CebOyamfWlqw==" }, + "node_modules/@hotwired/turbo": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/@hotwired/turbo/-/turbo-8.0.5.tgz", + "integrity": "sha512-TdZDA7fxVQ2ZycygvpnzjGPmFq4sO/E2QVg+2em/sJ3YTSsIWVEis8HmWlumz+c9DjWcUkcCuB+muF08TInpAQ==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@orchidjs/sifter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@orchidjs/sifter/-/sifter-1.1.0.tgz", + "integrity": "sha512-mYwHCfr736cIWWdhhSZvDbf90AKt2xyrJspKFC3qyIJG1LtrJeJunYEqCGG4Aq2ijENbc4WkOjszcvNaIAS/pQ==", + "dependencies": { + "@orchidjs/unicode-variants": "^1.1.2" + } + }, + "node_modules/@orchidjs/unicode-variants": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@orchidjs/unicode-variants/-/unicode-variants-1.1.2.tgz", + "integrity": "sha512-5DobW1CHgnBROOEpFlEXytED5OosEWESFvg/VYmH0143oXcijYTprRYJTs+55HzGM4IqxiLFSuqEzu9mPNwVsA==" + }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -275,6 +296,22 @@ "version": "1.12.0", "resolved": "https://registry.npmjs.org/toastify-js/-/toastify-js-1.12.0.tgz", "integrity": "sha512-HeMHCO9yLPvP9k0apGSdPUWrUbLnxUKNFzgUoZp1PHCLploIX/4DSQ7V8H25ef+h4iO9n0he7ImfcndnN6nDrQ==" + }, + "node_modules/tom-select": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tom-select/-/tom-select-2.4.3.tgz", + "integrity": "sha512-MFFrMxP1bpnAMPbdvPCZk0KwYxLqhYZso39torcdoefeV/NThNyDu8dV96/INJ5XQVTL3O55+GqQ78Pkj5oCfw==", + "dependencies": { + "@orchidjs/sifter": "^1.1.0", + "@orchidjs/unicode-variants": "^1.1.2" + }, + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tom-select" + } } } } diff --git a/node_modules/@hotwired/turbo/README.md b/node_modules/@hotwired/turbo/README.md new file mode 100644 index 0000000000..ed74ef6da7 --- /dev/null +++ b/node_modules/@hotwired/turbo/README.md @@ -0,0 +1,18 @@ +# Turbo + +Turbo uses complementary techniques to dramatically reduce the amount of custom JavaScript that most web applications will need to write: + +* Turbo Drive accelerates links and form submissions by negating the need for full page reloads. +* Turbo Frames decompose pages into independent contexts, which scope navigation and can be lazily loaded. +* Turbo Streams deliver page changes over WebSocket or in response to form submissions using just HTML and a set of CRUD-like actions. +* Turbo Native lets your majestic monolith form the center of your native iOS and Android apps, with seamless transitions between web and native sections. + +It's all done by sending HTML over the wire. And for those instances when that's not enough, you can reach for the other side of Hotwire, and finish the job with [Stimulus](https://github.com/hotwired/stimulus). + +Read more on [turbo.hotwired.dev](https://turbo.hotwired.dev). + +## Contributing + +Please read [CONTRIBUTING.md](./CONTRIBUTING.md). + +© 2024 37signals LLC. diff --git a/node_modules/@hotwired/turbo/dist/turbo.es2017-esm.js b/node_modules/@hotwired/turbo/dist/turbo.es2017-esm.js new file mode 100644 index 0000000000..2a43bcb3a5 --- /dev/null +++ b/node_modules/@hotwired/turbo/dist/turbo.es2017-esm.js @@ -0,0 +1,6580 @@ +/*! +Turbo 8.0.5 +Copyright © 2024 37signals LLC + */ +/** + * The MIT License (MIT) + * + * Copyright (c) 2019 Javan Makhmali + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +(function (prototype) { + if (typeof prototype.requestSubmit == "function") return + + prototype.requestSubmit = function (submitter) { + if (submitter) { + validateSubmitter(submitter, this); + submitter.click(); + } else { + submitter = document.createElement("input"); + submitter.type = "submit"; + submitter.hidden = true; + this.appendChild(submitter); + submitter.click(); + this.removeChild(submitter); + } + }; + + function validateSubmitter(submitter, form) { + submitter instanceof HTMLElement || raise(TypeError, "parameter 1 is not of type 'HTMLElement'"); + submitter.type == "submit" || raise(TypeError, "The specified element is not a submit button"); + submitter.form == form || + raise(DOMException, "The specified element is not owned by this form element", "NotFoundError"); + } + + function raise(errorConstructor, message, name) { + throw new errorConstructor("Failed to execute 'requestSubmit' on 'HTMLFormElement': " + message + ".", name) + } +})(HTMLFormElement.prototype); + +const submittersByForm = new WeakMap(); + +function findSubmitterFromClickTarget(target) { + const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null; + const candidate = element ? element.closest("input, button") : null; + return candidate?.type == "submit" ? candidate : null +} + +function clickCaptured(event) { + const submitter = findSubmitterFromClickTarget(event.target); + + if (submitter && submitter.form) { + submittersByForm.set(submitter.form, submitter); + } +} + +(function () { + if ("submitter" in Event.prototype) return + + let prototype = window.Event.prototype; + // Certain versions of Safari 15 have a bug where they won't + // populate the submitter. This hurts TurboDrive's enable/disable detection. + // See https://bugs.webkit.org/show_bug.cgi?id=229660 + if ("SubmitEvent" in window) { + const prototypeOfSubmitEvent = window.SubmitEvent.prototype; + + if (/Apple Computer/.test(navigator.vendor) && !("submitter" in prototypeOfSubmitEvent)) { + prototype = prototypeOfSubmitEvent; + } else { + return // polyfill not needed + } + } + + addEventListener("click", clickCaptured, true); + + Object.defineProperty(prototype, "submitter", { + get() { + if (this.type == "submit" && this.target instanceof HTMLFormElement) { + return submittersByForm.get(this.target) + } + } + }); +})(); + +const FrameLoadingStyle = { + eager: "eager", + lazy: "lazy" +}; + +/** + * Contains a fragment of HTML which is updated based on navigation within + * it (e.g. via links or form submissions). + * + * @customElement turbo-frame + * @example + * + * + * Show all expanded messages in this frame. + * + * + *
+ * Show response from this form within this frame. + *
+ *
+ */ +class FrameElement extends HTMLElement { + static delegateConstructor = undefined + + loaded = Promise.resolve() + + static get observedAttributes() { + return ["disabled", "loading", "src"] + } + + constructor() { + super(); + this.delegate = new FrameElement.delegateConstructor(this); + } + + connectedCallback() { + this.delegate.connect(); + } + + disconnectedCallback() { + this.delegate.disconnect(); + } + + reload() { + return this.delegate.sourceURLReloaded() + } + + attributeChangedCallback(name) { + if (name == "loading") { + this.delegate.loadingStyleChanged(); + } else if (name == "src") { + this.delegate.sourceURLChanged(); + } else if (name == "disabled") { + this.delegate.disabledChanged(); + } + } + + /** + * Gets the URL to lazily load source HTML from + */ + get src() { + return this.getAttribute("src") + } + + /** + * Sets the URL to lazily load source HTML from + */ + set src(value) { + if (value) { + this.setAttribute("src", value); + } else { + this.removeAttribute("src"); + } + } + + /** + * Gets the refresh mode for the frame. + */ + get refresh() { + return this.getAttribute("refresh") + } + + /** + * Sets the refresh mode for the frame. + */ + set refresh(value) { + if (value) { + this.setAttribute("refresh", value); + } else { + this.removeAttribute("refresh"); + } + } + + /** + * Determines if the element is loading + */ + get loading() { + return frameLoadingStyleFromString(this.getAttribute("loading") || "") + } + + /** + * Sets the value of if the element is loading + */ + set loading(value) { + if (value) { + this.setAttribute("loading", value); + } else { + this.removeAttribute("loading"); + } + } + + /** + * Gets the disabled state of the frame. + * + * If disabled, no requests will be intercepted by the frame. + */ + get disabled() { + return this.hasAttribute("disabled") + } + + /** + * Sets the disabled state of the frame. + * + * If disabled, no requests will be intercepted by the frame. + */ + set disabled(value) { + if (value) { + this.setAttribute("disabled", ""); + } else { + this.removeAttribute("disabled"); + } + } + + /** + * Gets the autoscroll state of the frame. + * + * If true, the frame will be scrolled into view automatically on update. + */ + get autoscroll() { + return this.hasAttribute("autoscroll") + } + + /** + * Sets the autoscroll state of the frame. + * + * If true, the frame will be scrolled into view automatically on update. + */ + set autoscroll(value) { + if (value) { + this.setAttribute("autoscroll", ""); + } else { + this.removeAttribute("autoscroll"); + } + } + + /** + * Determines if the element has finished loading + */ + get complete() { + return !this.delegate.isLoading + } + + /** + * Gets the active state of the frame. + * + * If inactive, source changes will not be observed. + */ + get isActive() { + return this.ownerDocument === document && !this.isPreview + } + + /** + * Sets the active state of the frame. + * + * If inactive, source changes will not be observed. + */ + get isPreview() { + return this.ownerDocument?.documentElement?.hasAttribute("data-turbo-preview") + } +} + +function frameLoadingStyleFromString(style) { + switch (style.toLowerCase()) { + case "lazy": + return FrameLoadingStyle.lazy + default: + return FrameLoadingStyle.eager + } +} + +function expandURL(locatable) { + return new URL(locatable.toString(), document.baseURI) +} + +function getAnchor(url) { + let anchorMatch; + if (url.hash) { + return url.hash.slice(1) + // eslint-disable-next-line no-cond-assign + } else if ((anchorMatch = url.href.match(/#(.*)$/))) { + return anchorMatch[1] + } +} + +function getAction$1(form, submitter) { + const action = submitter?.getAttribute("formaction") || form.getAttribute("action") || form.action; + + return expandURL(action) +} + +function getExtension(url) { + return (getLastPathComponent(url).match(/\.[^.]*$/) || [])[0] || "" +} + +function isHTML(url) { + return !!getExtension(url).match(/^(?:|\.(?:htm|html|xhtml|php))$/) +} + +function isPrefixedBy(baseURL, url) { + const prefix = getPrefix(url); + return baseURL.href === expandURL(prefix).href || baseURL.href.startsWith(prefix) +} + +function locationIsVisitable(location, rootLocation) { + return isPrefixedBy(location, rootLocation) && isHTML(location) +} + +function getRequestURL(url) { + const anchor = getAnchor(url); + return anchor != null ? url.href.slice(0, -(anchor.length + 1)) : url.href +} + +function toCacheKey(url) { + return getRequestURL(url) +} + +function urlsAreEqual(left, right) { + return expandURL(left).href == expandURL(right).href +} + +function getPathComponents(url) { + return url.pathname.split("/").slice(1) +} + +function getLastPathComponent(url) { + return getPathComponents(url).slice(-1)[0] +} + +function getPrefix(url) { + return addTrailingSlash(url.origin + url.pathname) +} + +function addTrailingSlash(value) { + return value.endsWith("/") ? value : value + "/" +} + +class FetchResponse { + constructor(response) { + this.response = response; + } + + get succeeded() { + return this.response.ok + } + + get failed() { + return !this.succeeded + } + + get clientError() { + return this.statusCode >= 400 && this.statusCode <= 499 + } + + get serverError() { + return this.statusCode >= 500 && this.statusCode <= 599 + } + + get redirected() { + return this.response.redirected + } + + get location() { + return expandURL(this.response.url) + } + + get isHTML() { + return this.contentType && this.contentType.match(/^(?:text\/([^\s;,]+\b)?html|application\/xhtml\+xml)\b/) + } + + get statusCode() { + return this.response.status + } + + get contentType() { + return this.header("Content-Type") + } + + get responseText() { + return this.response.clone().text() + } + + get responseHTML() { + if (this.isHTML) { + return this.response.clone().text() + } else { + return Promise.resolve(undefined) + } + } + + header(name) { + return this.response.headers.get(name) + } +} + +function activateScriptElement(element) { + if (element.getAttribute("data-turbo-eval") == "false") { + return element + } else { + const createdScriptElement = document.createElement("script"); + const cspNonce = getMetaContent("csp-nonce"); + if (cspNonce) { + createdScriptElement.nonce = cspNonce; + } + createdScriptElement.textContent = element.textContent; + createdScriptElement.async = false; + copyElementAttributes(createdScriptElement, element); + return createdScriptElement + } +} + +function copyElementAttributes(destinationElement, sourceElement) { + for (const { name, value } of sourceElement.attributes) { + destinationElement.setAttribute(name, value); + } +} + +function createDocumentFragment(html) { + const template = document.createElement("template"); + template.innerHTML = html; + return template.content +} + +function dispatch(eventName, { target, cancelable, detail } = {}) { + const event = new CustomEvent(eventName, { + cancelable, + bubbles: true, + composed: true, + detail + }); + + if (target && target.isConnected) { + target.dispatchEvent(event); + } else { + document.documentElement.dispatchEvent(event); + } + + return event +} + +function nextRepaint() { + if (document.visibilityState === "hidden") { + return nextEventLoopTick() + } else { + return nextAnimationFrame() + } +} + +function nextAnimationFrame() { + return new Promise((resolve) => requestAnimationFrame(() => resolve())) +} + +function nextEventLoopTick() { + return new Promise((resolve) => setTimeout(() => resolve(), 0)) +} + +function nextMicrotask() { + return Promise.resolve() +} + +function parseHTMLDocument(html = "") { + return new DOMParser().parseFromString(html, "text/html") +} + +function unindent(strings, ...values) { + const lines = interpolate(strings, values).replace(/^\n/, "").split("\n"); + const match = lines[0].match(/^\s+/); + const indent = match ? match[0].length : 0; + return lines.map((line) => line.slice(indent)).join("\n") +} + +function interpolate(strings, values) { + return strings.reduce((result, string, i) => { + const value = values[i] == undefined ? "" : values[i]; + return result + string + value + }, "") +} + +function uuid() { + return Array.from({ length: 36 }) + .map((_, i) => { + if (i == 8 || i == 13 || i == 18 || i == 23) { + return "-" + } else if (i == 14) { + return "4" + } else if (i == 19) { + return (Math.floor(Math.random() * 4) + 8).toString(16) + } else { + return Math.floor(Math.random() * 15).toString(16) + } + }) + .join("") +} + +function getAttribute(attributeName, ...elements) { + for (const value of elements.map((element) => element?.getAttribute(attributeName))) { + if (typeof value == "string") return value + } + + return null +} + +function hasAttribute(attributeName, ...elements) { + return elements.some((element) => element && element.hasAttribute(attributeName)) +} + +function markAsBusy(...elements) { + for (const element of elements) { + if (element.localName == "turbo-frame") { + element.setAttribute("busy", ""); + } + element.setAttribute("aria-busy", "true"); + } +} + +function clearBusyState(...elements) { + for (const element of elements) { + if (element.localName == "turbo-frame") { + element.removeAttribute("busy"); + } + + element.removeAttribute("aria-busy"); + } +} + +function waitForLoad(element, timeoutInMilliseconds = 2000) { + return new Promise((resolve) => { + const onComplete = () => { + element.removeEventListener("error", onComplete); + element.removeEventListener("load", onComplete); + resolve(); + }; + + element.addEventListener("load", onComplete, { once: true }); + element.addEventListener("error", onComplete, { once: true }); + setTimeout(resolve, timeoutInMilliseconds); + }) +} + +function getHistoryMethodForAction(action) { + switch (action) { + case "replace": + return history.replaceState + case "advance": + case "restore": + return history.pushState + } +} + +function isAction(action) { + return action == "advance" || action == "replace" || action == "restore" +} + +function getVisitAction(...elements) { + const action = getAttribute("data-turbo-action", ...elements); + + return isAction(action) ? action : null +} + +function getMetaElement(name) { + return document.querySelector(`meta[name="${name}"]`) +} + +function getMetaContent(name) { + const element = getMetaElement(name); + return element && element.content +} + +function setMetaContent(name, content) { + let element = getMetaElement(name); + + if (!element) { + element = document.createElement("meta"); + element.setAttribute("name", name); + + document.head.appendChild(element); + } + + element.setAttribute("content", content); + + return element +} + +function findClosestRecursively(element, selector) { + if (element instanceof Element) { + return ( + element.closest(selector) || findClosestRecursively(element.assignedSlot || element.getRootNode()?.host, selector) + ) + } +} + +function elementIsFocusable(element) { + const inertDisabledOrHidden = "[inert], :disabled, [hidden], details:not([open]), dialog:not([open])"; + + return !!element && element.closest(inertDisabledOrHidden) == null && typeof element.focus == "function" +} + +function queryAutofocusableElement(elementOrDocumentFragment) { + return Array.from(elementOrDocumentFragment.querySelectorAll("[autofocus]")).find(elementIsFocusable) +} + +async function around(callback, reader) { + const before = reader(); + + callback(); + + await nextAnimationFrame(); + + const after = reader(); + + return [before, after] +} + +function doesNotTargetIFrame(name) { + if (name === "_blank") { + return false + } else if (name) { + for (const element of document.getElementsByName(name)) { + if (element instanceof HTMLIFrameElement) return false + } + + return true + } else { + return true + } +} + +function findLinkFromClickTarget(target) { + return findClosestRecursively(target, "a[href]:not([target^=_]):not([download])") +} + +function getLocationForLink(link) { + return expandURL(link.getAttribute("href") || "") +} + +function debounce(fn, delay) { + let timeoutId = null; + + return (...args) => { + const callback = () => fn.apply(this, args); + clearTimeout(timeoutId); + timeoutId = setTimeout(callback, delay); + } +} + +class LimitedSet extends Set { + constructor(maxSize) { + super(); + this.maxSize = maxSize; + } + + add(value) { + if (this.size >= this.maxSize) { + const iterator = this.values(); + const oldestValue = iterator.next().value; + this.delete(oldestValue); + } + super.add(value); + } +} + +const recentRequests = new LimitedSet(20); + +const nativeFetch = window.fetch; + +function fetchWithTurboHeaders(url, options = {}) { + const modifiedHeaders = new Headers(options.headers || {}); + const requestUID = uuid(); + recentRequests.add(requestUID); + modifiedHeaders.append("X-Turbo-Request-Id", requestUID); + + return nativeFetch(url, { + ...options, + headers: modifiedHeaders + }) +} + +function fetchMethodFromString(method) { + switch (method.toLowerCase()) { + case "get": + return FetchMethod.get + case "post": + return FetchMethod.post + case "put": + return FetchMethod.put + case "patch": + return FetchMethod.patch + case "delete": + return FetchMethod.delete + } +} + +const FetchMethod = { + get: "get", + post: "post", + put: "put", + patch: "patch", + delete: "delete" +}; + +function fetchEnctypeFromString(encoding) { + switch (encoding.toLowerCase()) { + case FetchEnctype.multipart: + return FetchEnctype.multipart + case FetchEnctype.plain: + return FetchEnctype.plain + default: + return FetchEnctype.urlEncoded + } +} + +const FetchEnctype = { + urlEncoded: "application/x-www-form-urlencoded", + multipart: "multipart/form-data", + plain: "text/plain" +}; + +class FetchRequest { + abortController = new AbortController() + #resolveRequestPromise = (_value) => {} + + constructor(delegate, method, location, requestBody = new URLSearchParams(), target = null, enctype = FetchEnctype.urlEncoded) { + const [url, body] = buildResourceAndBody(expandURL(location), method, requestBody, enctype); + + this.delegate = delegate; + this.url = url; + this.target = target; + this.fetchOptions = { + credentials: "same-origin", + redirect: "follow", + method: method.toUpperCase(), + headers: { ...this.defaultHeaders }, + body: body, + signal: this.abortSignal, + referrer: this.delegate.referrer?.href + }; + this.enctype = enctype; + } + + get method() { + return this.fetchOptions.method + } + + set method(value) { + const fetchBody = this.isSafe ? this.url.searchParams : this.fetchOptions.body || new FormData(); + const fetchMethod = fetchMethodFromString(value) || FetchMethod.get; + + this.url.search = ""; + + const [url, body] = buildResourceAndBody(this.url, fetchMethod, fetchBody, this.enctype); + + this.url = url; + this.fetchOptions.body = body; + this.fetchOptions.method = fetchMethod.toUpperCase(); + } + + get headers() { + return this.fetchOptions.headers + } + + set headers(value) { + this.fetchOptions.headers = value; + } + + get body() { + if (this.isSafe) { + return this.url.searchParams + } else { + return this.fetchOptions.body + } + } + + set body(value) { + this.fetchOptions.body = value; + } + + get location() { + return this.url + } + + get params() { + return this.url.searchParams + } + + get entries() { + return this.body ? Array.from(this.body.entries()) : [] + } + + cancel() { + this.abortController.abort(); + } + + async perform() { + const { fetchOptions } = this; + this.delegate.prepareRequest(this); + const event = await this.#allowRequestToBeIntercepted(fetchOptions); + try { + this.delegate.requestStarted(this); + + if (event.detail.fetchRequest) { + this.response = event.detail.fetchRequest.response; + } else { + this.response = fetchWithTurboHeaders(this.url.href, fetchOptions); + } + + const response = await this.response; + return await this.receive(response) + } catch (error) { + if (error.name !== "AbortError") { + if (this.#willDelegateErrorHandling(error)) { + this.delegate.requestErrored(this, error); + } + throw error + } + } finally { + this.delegate.requestFinished(this); + } + } + + async receive(response) { + const fetchResponse = new FetchResponse(response); + const event = dispatch("turbo:before-fetch-response", { + cancelable: true, + detail: { fetchResponse }, + target: this.target + }); + if (event.defaultPrevented) { + this.delegate.requestPreventedHandlingResponse(this, fetchResponse); + } else if (fetchResponse.succeeded) { + this.delegate.requestSucceededWithResponse(this, fetchResponse); + } else { + this.delegate.requestFailedWithResponse(this, fetchResponse); + } + return fetchResponse + } + + get defaultHeaders() { + return { + Accept: "text/html, application/xhtml+xml" + } + } + + get isSafe() { + return isSafe(this.method) + } + + get abortSignal() { + return this.abortController.signal + } + + acceptResponseType(mimeType) { + this.headers["Accept"] = [mimeType, this.headers["Accept"]].join(", "); + } + + async #allowRequestToBeIntercepted(fetchOptions) { + const requestInterception = new Promise((resolve) => (this.#resolveRequestPromise = resolve)); + const event = dispatch("turbo:before-fetch-request", { + cancelable: true, + detail: { + fetchOptions, + url: this.url, + resume: this.#resolveRequestPromise + }, + target: this.target + }); + this.url = event.detail.url; + if (event.defaultPrevented) await requestInterception; + + return event + } + + #willDelegateErrorHandling(error) { + const event = dispatch("turbo:fetch-request-error", { + target: this.target, + cancelable: true, + detail: { request: this, error: error } + }); + + return !event.defaultPrevented + } +} + +function isSafe(fetchMethod) { + return fetchMethodFromString(fetchMethod) == FetchMethod.get +} + +function buildResourceAndBody(resource, method, requestBody, enctype) { + const searchParams = + Array.from(requestBody).length > 0 ? new URLSearchParams(entriesExcludingFiles(requestBody)) : resource.searchParams; + + if (isSafe(method)) { + return [mergeIntoURLSearchParams(resource, searchParams), null] + } else if (enctype == FetchEnctype.urlEncoded) { + return [resource, searchParams] + } else { + return [resource, requestBody] + } +} + +function entriesExcludingFiles(requestBody) { + const entries = []; + + for (const [name, value] of requestBody) { + if (value instanceof File) continue + else entries.push([name, value]); + } + + return entries +} + +function mergeIntoURLSearchParams(url, requestBody) { + const searchParams = new URLSearchParams(entriesExcludingFiles(requestBody)); + + url.search = searchParams.toString(); + + return url +} + +class AppearanceObserver { + started = false + + constructor(delegate, element) { + this.delegate = delegate; + this.element = element; + this.intersectionObserver = new IntersectionObserver(this.intersect); + } + + start() { + if (!this.started) { + this.started = true; + this.intersectionObserver.observe(this.element); + } + } + + stop() { + if (this.started) { + this.started = false; + this.intersectionObserver.unobserve(this.element); + } + } + + intersect = (entries) => { + const lastEntry = entries.slice(-1)[0]; + if (lastEntry?.isIntersecting) { + this.delegate.elementAppearedInViewport(this.element); + } + } +} + +class StreamMessage { + static contentType = "text/vnd.turbo-stream.html" + + static wrap(message) { + if (typeof message == "string") { + return new this(createDocumentFragment(message)) + } else { + return message + } + } + + constructor(fragment) { + this.fragment = importStreamElements(fragment); + } +} + +function importStreamElements(fragment) { + for (const element of fragment.querySelectorAll("turbo-stream")) { + const streamElement = document.importNode(element, true); + + for (const inertScriptElement of streamElement.templateElement.content.querySelectorAll("script")) { + inertScriptElement.replaceWith(activateScriptElement(inertScriptElement)); + } + + element.replaceWith(streamElement); + } + + return fragment +} + +const PREFETCH_DELAY = 100; + +class PrefetchCache { + #prefetchTimeout = null + #prefetched = null + + get(url) { + if (this.#prefetched && this.#prefetched.url === url && this.#prefetched.expire > Date.now()) { + return this.#prefetched.request + } + } + + setLater(url, request, ttl) { + this.clear(); + + this.#prefetchTimeout = setTimeout(() => { + request.perform(); + this.set(url, request, ttl); + this.#prefetchTimeout = null; + }, PREFETCH_DELAY); + } + + set(url, request, ttl) { + this.#prefetched = { url, request, expire: new Date(new Date().getTime() + ttl) }; + } + + clear() { + if (this.#prefetchTimeout) clearTimeout(this.#prefetchTimeout); + this.#prefetched = null; + } +} + +const cacheTtl = 10 * 1000; +const prefetchCache = new PrefetchCache(); + +const FormSubmissionState = { + initialized: "initialized", + requesting: "requesting", + waiting: "waiting", + receiving: "receiving", + stopping: "stopping", + stopped: "stopped" +}; + +class FormSubmission { + state = FormSubmissionState.initialized + + static confirmMethod(message, _element, _submitter) { + return Promise.resolve(confirm(message)) + } + + constructor(delegate, formElement, submitter, mustRedirect = false) { + const method = getMethod(formElement, submitter); + const action = getAction(getFormAction(formElement, submitter), method); + const body = buildFormData(formElement, submitter); + const enctype = getEnctype(formElement, submitter); + + this.delegate = delegate; + this.formElement = formElement; + this.submitter = submitter; + this.fetchRequest = new FetchRequest(this, method, action, body, formElement, enctype); + this.mustRedirect = mustRedirect; + } + + get method() { + return this.fetchRequest.method + } + + set method(value) { + this.fetchRequest.method = value; + } + + get action() { + return this.fetchRequest.url.toString() + } + + set action(value) { + this.fetchRequest.url = expandURL(value); + } + + get body() { + return this.fetchRequest.body + } + + get enctype() { + return this.fetchRequest.enctype + } + + get isSafe() { + return this.fetchRequest.isSafe + } + + get location() { + return this.fetchRequest.url + } + + // The submission process + + async start() { + const { initialized, requesting } = FormSubmissionState; + const confirmationMessage = getAttribute("data-turbo-confirm", this.submitter, this.formElement); + + if (typeof confirmationMessage === "string") { + const answer = await FormSubmission.confirmMethod(confirmationMessage, this.formElement, this.submitter); + if (!answer) { + return + } + } + + if (this.state == initialized) { + this.state = requesting; + return this.fetchRequest.perform() + } + } + + stop() { + const { stopping, stopped } = FormSubmissionState; + if (this.state != stopping && this.state != stopped) { + this.state = stopping; + this.fetchRequest.cancel(); + return true + } + } + + // Fetch request delegate + + prepareRequest(request) { + if (!request.isSafe) { + const token = getCookieValue(getMetaContent("csrf-param")) || getMetaContent("csrf-token"); + if (token) { + request.headers["X-CSRF-Token"] = token; + } + } + + if (this.requestAcceptsTurboStreamResponse(request)) { + request.acceptResponseType(StreamMessage.contentType); + } + } + + requestStarted(_request) { + this.state = FormSubmissionState.waiting; + this.submitter?.setAttribute("disabled", ""); + this.setSubmitsWith(); + markAsBusy(this.formElement); + dispatch("turbo:submit-start", { + target: this.formElement, + detail: { formSubmission: this } + }); + this.delegate.formSubmissionStarted(this); + } + + requestPreventedHandlingResponse(request, response) { + prefetchCache.clear(); + + this.result = { success: response.succeeded, fetchResponse: response }; + } + + requestSucceededWithResponse(request, response) { + if (response.clientError || response.serverError) { + this.delegate.formSubmissionFailedWithResponse(this, response); + return + } + + prefetchCache.clear(); + + if (this.requestMustRedirect(request) && responseSucceededWithoutRedirect(response)) { + const error = new Error("Form responses must redirect to another location"); + this.delegate.formSubmissionErrored(this, error); + } else { + this.state = FormSubmissionState.receiving; + this.result = { success: true, fetchResponse: response }; + this.delegate.formSubmissionSucceededWithResponse(this, response); + } + } + + requestFailedWithResponse(request, response) { + this.result = { success: false, fetchResponse: response }; + this.delegate.formSubmissionFailedWithResponse(this, response); + } + + requestErrored(request, error) { + this.result = { success: false, error }; + this.delegate.formSubmissionErrored(this, error); + } + + requestFinished(_request) { + this.state = FormSubmissionState.stopped; + this.submitter?.removeAttribute("disabled"); + this.resetSubmitterText(); + clearBusyState(this.formElement); + dispatch("turbo:submit-end", { + target: this.formElement, + detail: { formSubmission: this, ...this.result } + }); + this.delegate.formSubmissionFinished(this); + } + + // Private + + setSubmitsWith() { + if (!this.submitter || !this.submitsWith) return + + if (this.submitter.matches("button")) { + this.originalSubmitText = this.submitter.innerHTML; + this.submitter.innerHTML = this.submitsWith; + } else if (this.submitter.matches("input")) { + const input = this.submitter; + this.originalSubmitText = input.value; + input.value = this.submitsWith; + } + } + + resetSubmitterText() { + if (!this.submitter || !this.originalSubmitText) return + + if (this.submitter.matches("button")) { + this.submitter.innerHTML = this.originalSubmitText; + } else if (this.submitter.matches("input")) { + const input = this.submitter; + input.value = this.originalSubmitText; + } + } + + requestMustRedirect(request) { + return !request.isSafe && this.mustRedirect + } + + requestAcceptsTurboStreamResponse(request) { + return !request.isSafe || hasAttribute("data-turbo-stream", this.submitter, this.formElement) + } + + get submitsWith() { + return this.submitter?.getAttribute("data-turbo-submits-with") + } +} + +function buildFormData(formElement, submitter) { + const formData = new FormData(formElement); + const name = submitter?.getAttribute("name"); + const value = submitter?.getAttribute("value"); + + if (name) { + formData.append(name, value || ""); + } + + return formData +} + +function getCookieValue(cookieName) { + if (cookieName != null) { + const cookies = document.cookie ? document.cookie.split("; ") : []; + const cookie = cookies.find((cookie) => cookie.startsWith(cookieName)); + if (cookie) { + const value = cookie.split("=").slice(1).join("="); + return value ? decodeURIComponent(value) : undefined + } + } +} + +function responseSucceededWithoutRedirect(response) { + return response.statusCode == 200 && !response.redirected +} + +function getFormAction(formElement, submitter) { + const formElementAction = typeof formElement.action === "string" ? formElement.action : null; + + if (submitter?.hasAttribute("formaction")) { + return submitter.getAttribute("formaction") || "" + } else { + return formElement.getAttribute("action") || formElementAction || "" + } +} + +function getAction(formAction, fetchMethod) { + const action = expandURL(formAction); + + if (isSafe(fetchMethod)) { + action.search = ""; + } + + return action +} + +function getMethod(formElement, submitter) { + const method = submitter?.getAttribute("formmethod") || formElement.getAttribute("method") || ""; + return fetchMethodFromString(method.toLowerCase()) || FetchMethod.get +} + +function getEnctype(formElement, submitter) { + return fetchEnctypeFromString(submitter?.getAttribute("formenctype") || formElement.enctype) +} + +class Snapshot { + constructor(element) { + this.element = element; + } + + get activeElement() { + return this.element.ownerDocument.activeElement + } + + get children() { + return [...this.element.children] + } + + hasAnchor(anchor) { + return this.getElementForAnchor(anchor) != null + } + + getElementForAnchor(anchor) { + return anchor ? this.element.querySelector(`[id='${anchor}'], a[name='${anchor}']`) : null + } + + get isConnected() { + return this.element.isConnected + } + + get firstAutofocusableElement() { + return queryAutofocusableElement(this.element) + } + + get permanentElements() { + return queryPermanentElementsAll(this.element) + } + + getPermanentElementById(id) { + return getPermanentElementById(this.element, id) + } + + getPermanentElementMapForSnapshot(snapshot) { + const permanentElementMap = {}; + + for (const currentPermanentElement of this.permanentElements) { + const { id } = currentPermanentElement; + const newPermanentElement = snapshot.getPermanentElementById(id); + if (newPermanentElement) { + permanentElementMap[id] = [currentPermanentElement, newPermanentElement]; + } + } + + return permanentElementMap + } +} + +function getPermanentElementById(node, id) { + return node.querySelector(`#${id}[data-turbo-permanent]`) +} + +function queryPermanentElementsAll(node) { + return node.querySelectorAll("[id][data-turbo-permanent]") +} + +class FormSubmitObserver { + started = false + + constructor(delegate, eventTarget) { + this.delegate = delegate; + this.eventTarget = eventTarget; + } + + start() { + if (!this.started) { + this.eventTarget.addEventListener("submit", this.submitCaptured, true); + this.started = true; + } + } + + stop() { + if (this.started) { + this.eventTarget.removeEventListener("submit", this.submitCaptured, true); + this.started = false; + } + } + + submitCaptured = () => { + this.eventTarget.removeEventListener("submit", this.submitBubbled, false); + this.eventTarget.addEventListener("submit", this.submitBubbled, false); + } + + submitBubbled = (event) => { + if (!event.defaultPrevented) { + const form = event.target instanceof HTMLFormElement ? event.target : undefined; + const submitter = event.submitter || undefined; + + if ( + form && + submissionDoesNotDismissDialog(form, submitter) && + submissionDoesNotTargetIFrame(form, submitter) && + this.delegate.willSubmitForm(form, submitter) + ) { + event.preventDefault(); + event.stopImmediatePropagation(); + this.delegate.formSubmitted(form, submitter); + } + } + } +} + +function submissionDoesNotDismissDialog(form, submitter) { + const method = submitter?.getAttribute("formmethod") || form.getAttribute("method"); + + return method != "dialog" +} + +function submissionDoesNotTargetIFrame(form, submitter) { + const target = submitter?.getAttribute("formtarget") || form.getAttribute("target"); + + return doesNotTargetIFrame(target) +} + +class View { + #resolveRenderPromise = (_value) => {} + #resolveInterceptionPromise = (_value) => {} + + constructor(delegate, element) { + this.delegate = delegate; + this.element = element; + } + + // Scrolling + + scrollToAnchor(anchor) { + const element = this.snapshot.getElementForAnchor(anchor); + if (element) { + this.scrollToElement(element); + this.focusElement(element); + } else { + this.scrollToPosition({ x: 0, y: 0 }); + } + } + + scrollToAnchorFromLocation(location) { + this.scrollToAnchor(getAnchor(location)); + } + + scrollToElement(element) { + element.scrollIntoView(); + } + + focusElement(element) { + if (element instanceof HTMLElement) { + if (element.hasAttribute("tabindex")) { + element.focus(); + } else { + element.setAttribute("tabindex", "-1"); + element.focus(); + element.removeAttribute("tabindex"); + } + } + } + + scrollToPosition({ x, y }) { + this.scrollRoot.scrollTo(x, y); + } + + scrollToTop() { + this.scrollToPosition({ x: 0, y: 0 }); + } + + get scrollRoot() { + return window + } + + // Rendering + + async render(renderer) { + const { isPreview, shouldRender, willRender, newSnapshot: snapshot } = renderer; + + // A workaround to ignore tracked element mismatch reloads when performing + // a promoted Visit from a frame navigation + const shouldInvalidate = willRender; + + if (shouldRender) { + try { + this.renderPromise = new Promise((resolve) => (this.#resolveRenderPromise = resolve)); + this.renderer = renderer; + await this.prepareToRenderSnapshot(renderer); + + const renderInterception = new Promise((resolve) => (this.#resolveInterceptionPromise = resolve)); + const options = { resume: this.#resolveInterceptionPromise, render: this.renderer.renderElement, renderMethod: this.renderer.renderMethod }; + const immediateRender = this.delegate.allowsImmediateRender(snapshot, options); + if (!immediateRender) await renderInterception; + + await this.renderSnapshot(renderer); + this.delegate.viewRenderedSnapshot(snapshot, isPreview, this.renderer.renderMethod); + this.delegate.preloadOnLoadLinksForView(this.element); + this.finishRenderingSnapshot(renderer); + } finally { + delete this.renderer; + this.#resolveRenderPromise(undefined); + delete this.renderPromise; + } + } else if (shouldInvalidate) { + this.invalidate(renderer.reloadReason); + } + } + + invalidate(reason) { + this.delegate.viewInvalidated(reason); + } + + async prepareToRenderSnapshot(renderer) { + this.markAsPreview(renderer.isPreview); + await renderer.prepareToRender(); + } + + markAsPreview(isPreview) { + if (isPreview) { + this.element.setAttribute("data-turbo-preview", ""); + } else { + this.element.removeAttribute("data-turbo-preview"); + } + } + + markVisitDirection(direction) { + this.element.setAttribute("data-turbo-visit-direction", direction); + } + + unmarkVisitDirection() { + this.element.removeAttribute("data-turbo-visit-direction"); + } + + async renderSnapshot(renderer) { + await renderer.render(); + } + + finishRenderingSnapshot(renderer) { + renderer.finishRendering(); + } +} + +class FrameView extends View { + missing() { + this.element.innerHTML = `Content missing`; + } + + get snapshot() { + return new Snapshot(this.element) + } +} + +class LinkInterceptor { + constructor(delegate, element) { + this.delegate = delegate; + this.element = element; + } + + start() { + this.element.addEventListener("click", this.clickBubbled); + document.addEventListener("turbo:click", this.linkClicked); + document.addEventListener("turbo:before-visit", this.willVisit); + } + + stop() { + this.element.removeEventListener("click", this.clickBubbled); + document.removeEventListener("turbo:click", this.linkClicked); + document.removeEventListener("turbo:before-visit", this.willVisit); + } + + clickBubbled = (event) => { + if (this.clickEventIsSignificant(event)) { + this.clickEvent = event; + } else { + delete this.clickEvent; + } + } + + linkClicked = (event) => { + if (this.clickEvent && this.clickEventIsSignificant(event)) { + if (this.delegate.shouldInterceptLinkClick(event.target, event.detail.url, event.detail.originalEvent)) { + this.clickEvent.preventDefault(); + event.preventDefault(); + this.delegate.linkClickIntercepted(event.target, event.detail.url, event.detail.originalEvent); + } + } + delete this.clickEvent; + } + + willVisit = (_event) => { + delete this.clickEvent; + } + + clickEventIsSignificant(event) { + const target = event.composed ? event.target?.parentElement : event.target; + const element = findLinkFromClickTarget(target) || target; + + return element instanceof Element && element.closest("turbo-frame, html") == this.element + } +} + +class LinkClickObserver { + started = false + + constructor(delegate, eventTarget) { + this.delegate = delegate; + this.eventTarget = eventTarget; + } + + start() { + if (!this.started) { + this.eventTarget.addEventListener("click", this.clickCaptured, true); + this.started = true; + } + } + + stop() { + if (this.started) { + this.eventTarget.removeEventListener("click", this.clickCaptured, true); + this.started = false; + } + } + + clickCaptured = () => { + this.eventTarget.removeEventListener("click", this.clickBubbled, false); + this.eventTarget.addEventListener("click", this.clickBubbled, false); + } + + clickBubbled = (event) => { + if (event instanceof MouseEvent && this.clickEventIsSignificant(event)) { + const target = (event.composedPath && event.composedPath()[0]) || event.target; + const link = findLinkFromClickTarget(target); + if (link && doesNotTargetIFrame(link.target)) { + const location = getLocationForLink(link); + if (this.delegate.willFollowLinkToLocation(link, location, event)) { + event.preventDefault(); + this.delegate.followedLinkToLocation(link, location); + } + } + } + } + + clickEventIsSignificant(event) { + return !( + (event.target && event.target.isContentEditable) || + event.defaultPrevented || + event.which > 1 || + event.altKey || + event.ctrlKey || + event.metaKey || + event.shiftKey + ) + } +} + +class FormLinkClickObserver { + constructor(delegate, element) { + this.delegate = delegate; + this.linkInterceptor = new LinkClickObserver(this, element); + } + + start() { + this.linkInterceptor.start(); + } + + stop() { + this.linkInterceptor.stop(); + } + + // Link hover observer delegate + + canPrefetchRequestToLocation(link, location) { + return false + } + + prefetchAndCacheRequestToLocation(link, location) { + return + } + + // Link click observer delegate + + willFollowLinkToLocation(link, location, originalEvent) { + return ( + this.delegate.willSubmitFormLinkToLocation(link, location, originalEvent) && + (link.hasAttribute("data-turbo-method") || link.hasAttribute("data-turbo-stream")) + ) + } + + followedLinkToLocation(link, location) { + const form = document.createElement("form"); + + const type = "hidden"; + for (const [name, value] of location.searchParams) { + form.append(Object.assign(document.createElement("input"), { type, name, value })); + } + + const action = Object.assign(location, { search: "" }); + form.setAttribute("data-turbo", "true"); + form.setAttribute("action", action.href); + form.setAttribute("hidden", ""); + + const method = link.getAttribute("data-turbo-method"); + if (method) form.setAttribute("method", method); + + const turboFrame = link.getAttribute("data-turbo-frame"); + if (turboFrame) form.setAttribute("data-turbo-frame", turboFrame); + + const turboAction = getVisitAction(link); + if (turboAction) form.setAttribute("data-turbo-action", turboAction); + + const turboConfirm = link.getAttribute("data-turbo-confirm"); + if (turboConfirm) form.setAttribute("data-turbo-confirm", turboConfirm); + + const turboStream = link.hasAttribute("data-turbo-stream"); + if (turboStream) form.setAttribute("data-turbo-stream", ""); + + this.delegate.submittedFormLinkToLocation(link, location, form); + + document.body.appendChild(form); + form.addEventListener("turbo:submit-end", () => form.remove(), { once: true }); + requestAnimationFrame(() => form.requestSubmit()); + } +} + +class Bardo { + static async preservingPermanentElements(delegate, permanentElementMap, callback) { + const bardo = new this(delegate, permanentElementMap); + bardo.enter(); + await callback(); + bardo.leave(); + } + + constructor(delegate, permanentElementMap) { + this.delegate = delegate; + this.permanentElementMap = permanentElementMap; + } + + enter() { + for (const id in this.permanentElementMap) { + const [currentPermanentElement, newPermanentElement] = this.permanentElementMap[id]; + this.delegate.enteringBardo(currentPermanentElement, newPermanentElement); + this.replaceNewPermanentElementWithPlaceholder(newPermanentElement); + } + } + + leave() { + for (const id in this.permanentElementMap) { + const [currentPermanentElement] = this.permanentElementMap[id]; + this.replaceCurrentPermanentElementWithClone(currentPermanentElement); + this.replacePlaceholderWithPermanentElement(currentPermanentElement); + this.delegate.leavingBardo(currentPermanentElement); + } + } + + replaceNewPermanentElementWithPlaceholder(permanentElement) { + const placeholder = createPlaceholderForPermanentElement(permanentElement); + permanentElement.replaceWith(placeholder); + } + + replaceCurrentPermanentElementWithClone(permanentElement) { + const clone = permanentElement.cloneNode(true); + permanentElement.replaceWith(clone); + } + + replacePlaceholderWithPermanentElement(permanentElement) { + const placeholder = this.getPlaceholderById(permanentElement.id); + placeholder?.replaceWith(permanentElement); + } + + getPlaceholderById(id) { + return this.placeholders.find((element) => element.content == id) + } + + get placeholders() { + return [...document.querySelectorAll("meta[name=turbo-permanent-placeholder][content]")] + } +} + +function createPlaceholderForPermanentElement(permanentElement) { + const element = document.createElement("meta"); + element.setAttribute("name", "turbo-permanent-placeholder"); + element.setAttribute("content", permanentElement.id); + return element +} + +class Renderer { + #activeElement = null + + constructor(currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) { + this.currentSnapshot = currentSnapshot; + this.newSnapshot = newSnapshot; + this.isPreview = isPreview; + this.willRender = willRender; + this.renderElement = renderElement; + this.promise = new Promise((resolve, reject) => (this.resolvingFunctions = { resolve, reject })); + } + + get shouldRender() { + return true + } + + get shouldAutofocus() { + return true + } + + get reloadReason() { + return + } + + prepareToRender() { + return + } + + render() { + // Abstract method + } + + finishRendering() { + if (this.resolvingFunctions) { + this.resolvingFunctions.resolve(); + delete this.resolvingFunctions; + } + } + + async preservingPermanentElements(callback) { + await Bardo.preservingPermanentElements(this, this.permanentElementMap, callback); + } + + focusFirstAutofocusableElement() { + if (this.shouldAutofocus) { + const element = this.connectedSnapshot.firstAutofocusableElement; + if (element) { + element.focus(); + } + } + } + + // Bardo delegate + + enteringBardo(currentPermanentElement) { + if (this.#activeElement) return + + if (currentPermanentElement.contains(this.currentSnapshot.activeElement)) { + this.#activeElement = this.currentSnapshot.activeElement; + } + } + + leavingBardo(currentPermanentElement) { + if (currentPermanentElement.contains(this.#activeElement) && this.#activeElement instanceof HTMLElement) { + this.#activeElement.focus(); + + this.#activeElement = null; + } + } + + get connectedSnapshot() { + return this.newSnapshot.isConnected ? this.newSnapshot : this.currentSnapshot + } + + get currentElement() { + return this.currentSnapshot.element + } + + get newElement() { + return this.newSnapshot.element + } + + get permanentElementMap() { + return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot) + } + + get renderMethod() { + return "replace" + } +} + +class FrameRenderer extends Renderer { + static renderElement(currentElement, newElement) { + const destinationRange = document.createRange(); + destinationRange.selectNodeContents(currentElement); + destinationRange.deleteContents(); + + const frameElement = newElement; + const sourceRange = frameElement.ownerDocument?.createRange(); + if (sourceRange) { + sourceRange.selectNodeContents(frameElement); + currentElement.appendChild(sourceRange.extractContents()); + } + } + + constructor(delegate, currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) { + super(currentSnapshot, newSnapshot, renderElement, isPreview, willRender); + this.delegate = delegate; + } + + get shouldRender() { + return true + } + + async render() { + await nextRepaint(); + this.preservingPermanentElements(() => { + this.loadFrameElement(); + }); + this.scrollFrameIntoView(); + await nextRepaint(); + this.focusFirstAutofocusableElement(); + await nextRepaint(); + this.activateScriptElements(); + } + + loadFrameElement() { + this.delegate.willRenderFrame(this.currentElement, this.newElement); + this.renderElement(this.currentElement, this.newElement); + } + + scrollFrameIntoView() { + if (this.currentElement.autoscroll || this.newElement.autoscroll) { + const element = this.currentElement.firstElementChild; + const block = readScrollLogicalPosition(this.currentElement.getAttribute("data-autoscroll-block"), "end"); + const behavior = readScrollBehavior(this.currentElement.getAttribute("data-autoscroll-behavior"), "auto"); + + if (element) { + element.scrollIntoView({ block, behavior }); + return true + } + } + return false + } + + activateScriptElements() { + for (const inertScriptElement of this.newScriptElements) { + const activatedScriptElement = activateScriptElement(inertScriptElement); + inertScriptElement.replaceWith(activatedScriptElement); + } + } + + get newScriptElements() { + return this.currentElement.querySelectorAll("script") + } +} + +function readScrollLogicalPosition(value, defaultValue) { + if (value == "end" || value == "start" || value == "center" || value == "nearest") { + return value + } else { + return defaultValue + } +} + +function readScrollBehavior(value, defaultValue) { + if (value == "auto" || value == "smooth") { + return value + } else { + return defaultValue + } +} + +class ProgressBar { + static animationDuration = 300 /*ms*/ + + static get defaultCSS() { + return unindent` + .turbo-progress-bar { + position: fixed; + display: block; + top: 0; + left: 0; + height: 3px; + background: #0076ff; + z-index: 2147483647; + transition: + width ${ProgressBar.animationDuration}ms ease-out, + opacity ${ProgressBar.animationDuration / 2}ms ${ProgressBar.animationDuration / 2}ms ease-in; + transform: translate3d(0, 0, 0); + } + ` + } + + hiding = false + value = 0 + visible = false + + constructor() { + this.stylesheetElement = this.createStylesheetElement(); + this.progressElement = this.createProgressElement(); + this.installStylesheetElement(); + this.setValue(0); + } + + show() { + if (!this.visible) { + this.visible = true; + this.installProgressElement(); + this.startTrickling(); + } + } + + hide() { + if (this.visible && !this.hiding) { + this.hiding = true; + this.fadeProgressElement(() => { + this.uninstallProgressElement(); + this.stopTrickling(); + this.visible = false; + this.hiding = false; + }); + } + } + + setValue(value) { + this.value = value; + this.refresh(); + } + + // Private + + installStylesheetElement() { + document.head.insertBefore(this.stylesheetElement, document.head.firstChild); + } + + installProgressElement() { + this.progressElement.style.width = "0"; + this.progressElement.style.opacity = "1"; + document.documentElement.insertBefore(this.progressElement, document.body); + this.refresh(); + } + + fadeProgressElement(callback) { + this.progressElement.style.opacity = "0"; + setTimeout(callback, ProgressBar.animationDuration * 1.5); + } + + uninstallProgressElement() { + if (this.progressElement.parentNode) { + document.documentElement.removeChild(this.progressElement); + } + } + + startTrickling() { + if (!this.trickleInterval) { + this.trickleInterval = window.setInterval(this.trickle, ProgressBar.animationDuration); + } + } + + stopTrickling() { + window.clearInterval(this.trickleInterval); + delete this.trickleInterval; + } + + trickle = () => { + this.setValue(this.value + Math.random() / 100); + } + + refresh() { + requestAnimationFrame(() => { + this.progressElement.style.width = `${10 + this.value * 90}%`; + }); + } + + createStylesheetElement() { + const element = document.createElement("style"); + element.type = "text/css"; + element.textContent = ProgressBar.defaultCSS; + if (this.cspNonce) { + element.nonce = this.cspNonce; + } + return element + } + + createProgressElement() { + const element = document.createElement("div"); + element.className = "turbo-progress-bar"; + return element + } + + get cspNonce() { + return getMetaContent("csp-nonce") + } +} + +class HeadSnapshot extends Snapshot { + detailsByOuterHTML = this.children + .filter((element) => !elementIsNoscript(element)) + .map((element) => elementWithoutNonce(element)) + .reduce((result, element) => { + const { outerHTML } = element; + const details = + outerHTML in result + ? result[outerHTML] + : { + type: elementType(element), + tracked: elementIsTracked(element), + elements: [] + }; + return { + ...result, + [outerHTML]: { + ...details, + elements: [...details.elements, element] + } + } + }, {}) + + get trackedElementSignature() { + return Object.keys(this.detailsByOuterHTML) + .filter((outerHTML) => this.detailsByOuterHTML[outerHTML].tracked) + .join("") + } + + getScriptElementsNotInSnapshot(snapshot) { + return this.getElementsMatchingTypeNotInSnapshot("script", snapshot) + } + + getStylesheetElementsNotInSnapshot(snapshot) { + return this.getElementsMatchingTypeNotInSnapshot("stylesheet", snapshot) + } + + getElementsMatchingTypeNotInSnapshot(matchedType, snapshot) { + return Object.keys(this.detailsByOuterHTML) + .filter((outerHTML) => !(outerHTML in snapshot.detailsByOuterHTML)) + .map((outerHTML) => this.detailsByOuterHTML[outerHTML]) + .filter(({ type }) => type == matchedType) + .map(({ elements: [element] }) => element) + } + + get provisionalElements() { + return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => { + const { type, tracked, elements } = this.detailsByOuterHTML[outerHTML]; + if (type == null && !tracked) { + return [...result, ...elements] + } else if (elements.length > 1) { + return [...result, ...elements.slice(1)] + } else { + return result + } + }, []) + } + + getMetaValue(name) { + const element = this.findMetaElementByName(name); + return element ? element.getAttribute("content") : null + } + + findMetaElementByName(name) { + return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => { + const { + elements: [element] + } = this.detailsByOuterHTML[outerHTML]; + return elementIsMetaElementWithName(element, name) ? element : result + }, undefined | undefined) + } +} + +function elementType(element) { + if (elementIsScript(element)) { + return "script" + } else if (elementIsStylesheet(element)) { + return "stylesheet" + } +} + +function elementIsTracked(element) { + return element.getAttribute("data-turbo-track") == "reload" +} + +function elementIsScript(element) { + const tagName = element.localName; + return tagName == "script" +} + +function elementIsNoscript(element) { + const tagName = element.localName; + return tagName == "noscript" +} + +function elementIsStylesheet(element) { + const tagName = element.localName; + return tagName == "style" || (tagName == "link" && element.getAttribute("rel") == "stylesheet") +} + +function elementIsMetaElementWithName(element, name) { + const tagName = element.localName; + return tagName == "meta" && element.getAttribute("name") == name +} + +function elementWithoutNonce(element) { + if (element.hasAttribute("nonce")) { + element.setAttribute("nonce", ""); + } + + return element +} + +class PageSnapshot extends Snapshot { + static fromHTMLString(html = "") { + return this.fromDocument(parseHTMLDocument(html)) + } + + static fromElement(element) { + return this.fromDocument(element.ownerDocument) + } + + static fromDocument({ documentElement, body, head }) { + return new this(documentElement, body, new HeadSnapshot(head)) + } + + constructor(documentElement, body, headSnapshot) { + super(body); + this.documentElement = documentElement; + this.headSnapshot = headSnapshot; + } + + clone() { + const clonedElement = this.element.cloneNode(true); + + const selectElements = this.element.querySelectorAll("select"); + const clonedSelectElements = clonedElement.querySelectorAll("select"); + + for (const [index, source] of selectElements.entries()) { + const clone = clonedSelectElements[index]; + for (const option of clone.selectedOptions) option.selected = false; + for (const option of source.selectedOptions) clone.options[option.index].selected = true; + } + + for (const clonedPasswordInput of clonedElement.querySelectorAll('input[type="password"]')) { + clonedPasswordInput.value = ""; + } + + return new PageSnapshot(this.documentElement, clonedElement, this.headSnapshot) + } + + get lang() { + return this.documentElement.getAttribute("lang") + } + + get headElement() { + return this.headSnapshot.element + } + + get rootLocation() { + const root = this.getSetting("root") ?? "/"; + return expandURL(root) + } + + get cacheControlValue() { + return this.getSetting("cache-control") + } + + get isPreviewable() { + return this.cacheControlValue != "no-preview" + } + + get isCacheable() { + return this.cacheControlValue != "no-cache" + } + + get isVisitable() { + return this.getSetting("visit-control") != "reload" + } + + get prefersViewTransitions() { + return this.headSnapshot.getMetaValue("view-transition") === "same-origin" + } + + get shouldMorphPage() { + return this.getSetting("refresh-method") === "morph" + } + + get shouldPreserveScrollPosition() { + return this.getSetting("refresh-scroll") === "preserve" + } + + // Private + + getSetting(name) { + return this.headSnapshot.getMetaValue(`turbo-${name}`) + } +} + +class ViewTransitioner { + #viewTransitionStarted = false + #lastOperation = Promise.resolve() + + renderChange(useViewTransition, render) { + if (useViewTransition && this.viewTransitionsAvailable && !this.#viewTransitionStarted) { + this.#viewTransitionStarted = true; + this.#lastOperation = this.#lastOperation.then(async () => { + await document.startViewTransition(render).finished; + }); + } else { + this.#lastOperation = this.#lastOperation.then(render); + } + + return this.#lastOperation + } + + get viewTransitionsAvailable() { + return document.startViewTransition + } +} + +const defaultOptions = { + action: "advance", + historyChanged: false, + visitCachedSnapshot: () => {}, + willRender: true, + updateHistory: true, + shouldCacheSnapshot: true, + acceptsStreamResponse: false +}; + +const TimingMetric = { + visitStart: "visitStart", + requestStart: "requestStart", + requestEnd: "requestEnd", + visitEnd: "visitEnd" +}; + +const VisitState = { + initialized: "initialized", + started: "started", + canceled: "canceled", + failed: "failed", + completed: "completed" +}; + +const SystemStatusCode = { + networkFailure: 0, + timeoutFailure: -1, + contentTypeMismatch: -2 +}; + +const Direction = { + advance: "forward", + restore: "back", + replace: "none" +}; + +class Visit { + identifier = uuid() // Required by turbo-ios + timingMetrics = {} + + followedRedirect = false + historyChanged = false + scrolled = false + shouldCacheSnapshot = true + acceptsStreamResponse = false + snapshotCached = false + state = VisitState.initialized + viewTransitioner = new ViewTransitioner() + + constructor(delegate, location, restorationIdentifier, options = {}) { + this.delegate = delegate; + this.location = location; + this.restorationIdentifier = restorationIdentifier || uuid(); + + const { + action, + historyChanged, + referrer, + snapshot, + snapshotHTML, + response, + visitCachedSnapshot, + willRender, + updateHistory, + shouldCacheSnapshot, + acceptsStreamResponse, + direction + } = { + ...defaultOptions, + ...options + }; + this.action = action; + this.historyChanged = historyChanged; + this.referrer = referrer; + this.snapshot = snapshot; + this.snapshotHTML = snapshotHTML; + this.response = response; + this.isSamePage = this.delegate.locationWithActionIsSamePage(this.location, this.action); + this.isPageRefresh = this.view.isPageRefresh(this); + this.visitCachedSnapshot = visitCachedSnapshot; + this.willRender = willRender; + this.updateHistory = updateHistory; + this.scrolled = !willRender; + this.shouldCacheSnapshot = shouldCacheSnapshot; + this.acceptsStreamResponse = acceptsStreamResponse; + this.direction = direction || Direction[action]; + } + + get adapter() { + return this.delegate.adapter + } + + get view() { + return this.delegate.view + } + + get history() { + return this.delegate.history + } + + get restorationData() { + return this.history.getRestorationDataForIdentifier(this.restorationIdentifier) + } + + get silent() { + return this.isSamePage + } + + start() { + if (this.state == VisitState.initialized) { + this.recordTimingMetric(TimingMetric.visitStart); + this.state = VisitState.started; + this.adapter.visitStarted(this); + this.delegate.visitStarted(this); + } + } + + cancel() { + if (this.state == VisitState.started) { + if (this.request) { + this.request.cancel(); + } + this.cancelRender(); + this.state = VisitState.canceled; + } + } + + complete() { + if (this.state == VisitState.started) { + this.recordTimingMetric(TimingMetric.visitEnd); + this.adapter.visitCompleted(this); + this.state = VisitState.completed; + this.followRedirect(); + + if (!this.followedRedirect) { + this.delegate.visitCompleted(this); + } + } + } + + fail() { + if (this.state == VisitState.started) { + this.state = VisitState.failed; + this.adapter.visitFailed(this); + this.delegate.visitCompleted(this); + } + } + + changeHistory() { + if (!this.historyChanged && this.updateHistory) { + const actionForHistory = this.location.href === this.referrer?.href ? "replace" : this.action; + const method = getHistoryMethodForAction(actionForHistory); + this.history.update(method, this.location, this.restorationIdentifier); + this.historyChanged = true; + } + } + + issueRequest() { + if (this.hasPreloadedResponse()) { + this.simulateRequest(); + } else if (this.shouldIssueRequest() && !this.request) { + this.request = new FetchRequest(this, FetchMethod.get, this.location); + this.request.perform(); + } + } + + simulateRequest() { + if (this.response) { + this.startRequest(); + this.recordResponse(); + this.finishRequest(); + } + } + + startRequest() { + this.recordTimingMetric(TimingMetric.requestStart); + this.adapter.visitRequestStarted(this); + } + + recordResponse(response = this.response) { + this.response = response; + if (response) { + const { statusCode } = response; + if (isSuccessful(statusCode)) { + this.adapter.visitRequestCompleted(this); + } else { + this.adapter.visitRequestFailedWithStatusCode(this, statusCode); + } + } + } + + finishRequest() { + this.recordTimingMetric(TimingMetric.requestEnd); + this.adapter.visitRequestFinished(this); + } + + loadResponse() { + if (this.response) { + const { statusCode, responseHTML } = this.response; + this.render(async () => { + if (this.shouldCacheSnapshot) this.cacheSnapshot(); + if (this.view.renderPromise) await this.view.renderPromise; + + if (isSuccessful(statusCode) && responseHTML != null) { + const snapshot = PageSnapshot.fromHTMLString(responseHTML); + await this.renderPageSnapshot(snapshot, false); + + this.adapter.visitRendered(this); + this.complete(); + } else { + await this.view.renderError(PageSnapshot.fromHTMLString(responseHTML), this); + this.adapter.visitRendered(this); + this.fail(); + } + }); + } + } + + getCachedSnapshot() { + const snapshot = this.view.getCachedSnapshotForLocation(this.location) || this.getPreloadedSnapshot(); + + if (snapshot && (!getAnchor(this.location) || snapshot.hasAnchor(getAnchor(this.location)))) { + if (this.action == "restore" || snapshot.isPreviewable) { + return snapshot + } + } + } + + getPreloadedSnapshot() { + if (this.snapshotHTML) { + return PageSnapshot.fromHTMLString(this.snapshotHTML) + } + } + + hasCachedSnapshot() { + return this.getCachedSnapshot() != null + } + + loadCachedSnapshot() { + const snapshot = this.getCachedSnapshot(); + if (snapshot) { + const isPreview = this.shouldIssueRequest(); + this.render(async () => { + this.cacheSnapshot(); + if (this.isSamePage || this.isPageRefresh) { + this.adapter.visitRendered(this); + } else { + if (this.view.renderPromise) await this.view.renderPromise; + + await this.renderPageSnapshot(snapshot, isPreview); + + this.adapter.visitRendered(this); + if (!isPreview) { + this.complete(); + } + } + }); + } + } + + followRedirect() { + if (this.redirectedToLocation && !this.followedRedirect && this.response?.redirected) { + this.adapter.visitProposedToLocation(this.redirectedToLocation, { + action: "replace", + response: this.response, + shouldCacheSnapshot: false, + willRender: false + }); + this.followedRedirect = true; + } + } + + goToSamePageAnchor() { + if (this.isSamePage) { + this.render(async () => { + this.cacheSnapshot(); + this.performScroll(); + this.changeHistory(); + this.adapter.visitRendered(this); + }); + } + } + + // Fetch request delegate + + prepareRequest(request) { + if (this.acceptsStreamResponse) { + request.acceptResponseType(StreamMessage.contentType); + } + } + + requestStarted() { + this.startRequest(); + } + + requestPreventedHandlingResponse(_request, _response) {} + + async requestSucceededWithResponse(request, response) { + const responseHTML = await response.responseHTML; + const { redirected, statusCode } = response; + if (responseHTML == undefined) { + this.recordResponse({ + statusCode: SystemStatusCode.contentTypeMismatch, + redirected + }); + } else { + this.redirectedToLocation = response.redirected ? response.location : undefined; + this.recordResponse({ statusCode: statusCode, responseHTML, redirected }); + } + } + + async requestFailedWithResponse(request, response) { + const responseHTML = await response.responseHTML; + const { redirected, statusCode } = response; + if (responseHTML == undefined) { + this.recordResponse({ + statusCode: SystemStatusCode.contentTypeMismatch, + redirected + }); + } else { + this.recordResponse({ statusCode: statusCode, responseHTML, redirected }); + } + } + + requestErrored(_request, _error) { + this.recordResponse({ + statusCode: SystemStatusCode.networkFailure, + redirected: false + }); + } + + requestFinished() { + this.finishRequest(); + } + + // Scrolling + + performScroll() { + if (!this.scrolled && !this.view.forceReloaded && !this.view.shouldPreserveScrollPosition(this)) { + if (this.action == "restore") { + this.scrollToRestoredPosition() || this.scrollToAnchor() || this.view.scrollToTop(); + } else { + this.scrollToAnchor() || this.view.scrollToTop(); + } + if (this.isSamePage) { + this.delegate.visitScrolledToSamePageLocation(this.view.lastRenderedLocation, this.location); + } + + this.scrolled = true; + } + } + + scrollToRestoredPosition() { + const { scrollPosition } = this.restorationData; + if (scrollPosition) { + this.view.scrollToPosition(scrollPosition); + return true + } + } + + scrollToAnchor() { + const anchor = getAnchor(this.location); + if (anchor != null) { + this.view.scrollToAnchor(anchor); + return true + } + } + + // Instrumentation + + recordTimingMetric(metric) { + this.timingMetrics[metric] = new Date().getTime(); + } + + getTimingMetrics() { + return { ...this.timingMetrics } + } + + // Private + + getHistoryMethodForAction(action) { + switch (action) { + case "replace": + return history.replaceState + case "advance": + case "restore": + return history.pushState + } + } + + hasPreloadedResponse() { + return typeof this.response == "object" + } + + shouldIssueRequest() { + if (this.isSamePage) { + return false + } else if (this.action == "restore") { + return !this.hasCachedSnapshot() + } else { + return this.willRender + } + } + + cacheSnapshot() { + if (!this.snapshotCached) { + this.view.cacheSnapshot(this.snapshot).then((snapshot) => snapshot && this.visitCachedSnapshot(snapshot)); + this.snapshotCached = true; + } + } + + async render(callback) { + this.cancelRender(); + this.frame = await nextRepaint(); + await callback(); + delete this.frame; + } + + async renderPageSnapshot(snapshot, isPreview) { + await this.viewTransitioner.renderChange(this.view.shouldTransitionTo(snapshot), async () => { + await this.view.renderPage(snapshot, isPreview, this.willRender, this); + this.performScroll(); + }); + } + + cancelRender() { + if (this.frame) { + cancelAnimationFrame(this.frame); + delete this.frame; + } + } +} + +function isSuccessful(statusCode) { + return statusCode >= 200 && statusCode < 300 +} + +class BrowserAdapter { + progressBar = new ProgressBar() + + constructor(session) { + this.session = session; + } + + visitProposedToLocation(location, options) { + if (locationIsVisitable(location, this.navigator.rootLocation)) { + this.navigator.startVisit(location, options?.restorationIdentifier || uuid(), options); + } else { + window.location.href = location.toString(); + } + } + + visitStarted(visit) { + this.location = visit.location; + visit.loadCachedSnapshot(); + visit.issueRequest(); + visit.goToSamePageAnchor(); + } + + visitRequestStarted(visit) { + this.progressBar.setValue(0); + if (visit.hasCachedSnapshot() || visit.action != "restore") { + this.showVisitProgressBarAfterDelay(); + } else { + this.showProgressBar(); + } + } + + visitRequestCompleted(visit) { + visit.loadResponse(); + } + + visitRequestFailedWithStatusCode(visit, statusCode) { + switch (statusCode) { + case SystemStatusCode.networkFailure: + case SystemStatusCode.timeoutFailure: + case SystemStatusCode.contentTypeMismatch: + return this.reload({ + reason: "request_failed", + context: { + statusCode + } + }) + default: + return visit.loadResponse() + } + } + + visitRequestFinished(_visit) {} + + visitCompleted(_visit) { + this.progressBar.setValue(1); + this.hideVisitProgressBar(); + } + + pageInvalidated(reason) { + this.reload(reason); + } + + visitFailed(_visit) { + this.progressBar.setValue(1); + this.hideVisitProgressBar(); + } + + visitRendered(_visit) {} + + // Form Submission Delegate + + formSubmissionStarted(_formSubmission) { + this.progressBar.setValue(0); + this.showFormProgressBarAfterDelay(); + } + + formSubmissionFinished(_formSubmission) { + this.progressBar.setValue(1); + this.hideFormProgressBar(); + } + + // Private + + showVisitProgressBarAfterDelay() { + this.visitProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay); + } + + hideVisitProgressBar() { + this.progressBar.hide(); + if (this.visitProgressBarTimeout != null) { + window.clearTimeout(this.visitProgressBarTimeout); + delete this.visitProgressBarTimeout; + } + } + + showFormProgressBarAfterDelay() { + if (this.formProgressBarTimeout == null) { + this.formProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay); + } + } + + hideFormProgressBar() { + this.progressBar.hide(); + if (this.formProgressBarTimeout != null) { + window.clearTimeout(this.formProgressBarTimeout); + delete this.formProgressBarTimeout; + } + } + + showProgressBar = () => { + this.progressBar.show(); + } + + reload(reason) { + dispatch("turbo:reload", { detail: reason }); + + window.location.href = this.location?.toString() || window.location.href; + } + + get navigator() { + return this.session.navigator + } +} + +class CacheObserver { + selector = "[data-turbo-temporary]" + deprecatedSelector = "[data-turbo-cache=false]" + + started = false + + start() { + if (!this.started) { + this.started = true; + addEventListener("turbo:before-cache", this.removeTemporaryElements, false); + } + } + + stop() { + if (this.started) { + this.started = false; + removeEventListener("turbo:before-cache", this.removeTemporaryElements, false); + } + } + + removeTemporaryElements = (_event) => { + for (const element of this.temporaryElements) { + element.remove(); + } + } + + get temporaryElements() { + return [...document.querySelectorAll(this.selector), ...this.temporaryElementsWithDeprecation] + } + + get temporaryElementsWithDeprecation() { + const elements = document.querySelectorAll(this.deprecatedSelector); + + if (elements.length) { + console.warn( + `The ${this.deprecatedSelector} selector is deprecated and will be removed in a future version. Use ${this.selector} instead.` + ); + } + + return [...elements] + } +} + +class FrameRedirector { + constructor(session, element) { + this.session = session; + this.element = element; + this.linkInterceptor = new LinkInterceptor(this, element); + this.formSubmitObserver = new FormSubmitObserver(this, element); + } + + start() { + this.linkInterceptor.start(); + this.formSubmitObserver.start(); + } + + stop() { + this.linkInterceptor.stop(); + this.formSubmitObserver.stop(); + } + + // Link interceptor delegate + + shouldInterceptLinkClick(element, _location, _event) { + return this.#shouldRedirect(element) + } + + linkClickIntercepted(element, url, event) { + const frame = this.#findFrameElement(element); + if (frame) { + frame.delegate.linkClickIntercepted(element, url, event); + } + } + + // Form submit observer delegate + + willSubmitForm(element, submitter) { + return ( + element.closest("turbo-frame") == null && + this.#shouldSubmit(element, submitter) && + this.#shouldRedirect(element, submitter) + ) + } + + formSubmitted(element, submitter) { + const frame = this.#findFrameElement(element, submitter); + if (frame) { + frame.delegate.formSubmitted(element, submitter); + } + } + + #shouldSubmit(form, submitter) { + const action = getAction$1(form, submitter); + const meta = this.element.ownerDocument.querySelector(`meta[name="turbo-root"]`); + const rootLocation = expandURL(meta?.content ?? "/"); + + return this.#shouldRedirect(form, submitter) && locationIsVisitable(action, rootLocation) + } + + #shouldRedirect(element, submitter) { + const isNavigatable = + element instanceof HTMLFormElement + ? this.session.submissionIsNavigatable(element, submitter) + : this.session.elementIsNavigatable(element); + + if (isNavigatable) { + const frame = this.#findFrameElement(element, submitter); + return frame ? frame != element.closest("turbo-frame") : false + } else { + return false + } + } + + #findFrameElement(element, submitter) { + const id = submitter?.getAttribute("data-turbo-frame") || element.getAttribute("data-turbo-frame"); + if (id && id != "_top") { + const frame = this.element.querySelector(`#${id}:not([disabled])`); + if (frame instanceof FrameElement) { + return frame + } + } + } +} + +class History { + location + restorationIdentifier = uuid() + restorationData = {} + started = false + pageLoaded = false + currentIndex = 0 + + constructor(delegate) { + this.delegate = delegate; + } + + start() { + if (!this.started) { + addEventListener("popstate", this.onPopState, false); + addEventListener("load", this.onPageLoad, false); + this.currentIndex = history.state?.turbo?.restorationIndex || 0; + this.started = true; + this.replace(new URL(window.location.href)); + } + } + + stop() { + if (this.started) { + removeEventListener("popstate", this.onPopState, false); + removeEventListener("load", this.onPageLoad, false); + this.started = false; + } + } + + push(location, restorationIdentifier) { + this.update(history.pushState, location, restorationIdentifier); + } + + replace(location, restorationIdentifier) { + this.update(history.replaceState, location, restorationIdentifier); + } + + update(method, location, restorationIdentifier = uuid()) { + if (method === history.pushState) ++this.currentIndex; + + const state = { turbo: { restorationIdentifier, restorationIndex: this.currentIndex } }; + method.call(history, state, "", location.href); + this.location = location; + this.restorationIdentifier = restorationIdentifier; + } + + // Restoration data + + getRestorationDataForIdentifier(restorationIdentifier) { + return this.restorationData[restorationIdentifier] || {} + } + + updateRestorationData(additionalData) { + const { restorationIdentifier } = this; + const restorationData = this.restorationData[restorationIdentifier]; + this.restorationData[restorationIdentifier] = { + ...restorationData, + ...additionalData + }; + } + + // Scroll restoration + + assumeControlOfScrollRestoration() { + if (!this.previousScrollRestoration) { + this.previousScrollRestoration = history.scrollRestoration ?? "auto"; + history.scrollRestoration = "manual"; + } + } + + relinquishControlOfScrollRestoration() { + if (this.previousScrollRestoration) { + history.scrollRestoration = this.previousScrollRestoration; + delete this.previousScrollRestoration; + } + } + + // Event handlers + + onPopState = (event) => { + if (this.shouldHandlePopState()) { + const { turbo } = event.state || {}; + if (turbo) { + this.location = new URL(window.location.href); + const { restorationIdentifier, restorationIndex } = turbo; + this.restorationIdentifier = restorationIdentifier; + const direction = restorationIndex > this.currentIndex ? "forward" : "back"; + this.delegate.historyPoppedToLocationWithRestorationIdentifierAndDirection(this.location, restorationIdentifier, direction); + this.currentIndex = restorationIndex; + } + } + } + + onPageLoad = async (_event) => { + await nextMicrotask(); + this.pageLoaded = true; + } + + // Private + + shouldHandlePopState() { + // Safari dispatches a popstate event after window's load event, ignore it + return this.pageIsLoaded() + } + + pageIsLoaded() { + return this.pageLoaded || document.readyState == "complete" + } +} + +class LinkPrefetchObserver { + started = false + #prefetchedLink = null + + constructor(delegate, eventTarget) { + this.delegate = delegate; + this.eventTarget = eventTarget; + } + + start() { + if (this.started) return + + if (this.eventTarget.readyState === "loading") { + this.eventTarget.addEventListener("DOMContentLoaded", this.#enable, { once: true }); + } else { + this.#enable(); + } + } + + stop() { + if (!this.started) return + + this.eventTarget.removeEventListener("mouseenter", this.#tryToPrefetchRequest, { + capture: true, + passive: true + }); + this.eventTarget.removeEventListener("mouseleave", this.#cancelRequestIfObsolete, { + capture: true, + passive: true + }); + + this.eventTarget.removeEventListener("turbo:before-fetch-request", this.#tryToUsePrefetchedRequest, true); + this.started = false; + } + + #enable = () => { + this.eventTarget.addEventListener("mouseenter", this.#tryToPrefetchRequest, { + capture: true, + passive: true + }); + this.eventTarget.addEventListener("mouseleave", this.#cancelRequestIfObsolete, { + capture: true, + passive: true + }); + + this.eventTarget.addEventListener("turbo:before-fetch-request", this.#tryToUsePrefetchedRequest, true); + this.started = true; + } + + #tryToPrefetchRequest = (event) => { + if (getMetaContent("turbo-prefetch") === "false") return + + const target = event.target; + const isLink = target.matches && target.matches("a[href]:not([target^=_]):not([download])"); + + if (isLink && this.#isPrefetchable(target)) { + const link = target; + const location = getLocationForLink(link); + + if (this.delegate.canPrefetchRequestToLocation(link, location)) { + this.#prefetchedLink = link; + + const fetchRequest = new FetchRequest( + this, + FetchMethod.get, + location, + new URLSearchParams(), + target + ); + + prefetchCache.setLater(location.toString(), fetchRequest, this.#cacheTtl); + } + } + } + + #cancelRequestIfObsolete = (event) => { + if (event.target === this.#prefetchedLink) this.#cancelPrefetchRequest(); + } + + #cancelPrefetchRequest = () => { + prefetchCache.clear(); + this.#prefetchedLink = null; + } + + #tryToUsePrefetchedRequest = (event) => { + if (event.target.tagName !== "FORM" && event.detail.fetchOptions.method === "GET") { + const cached = prefetchCache.get(event.detail.url.toString()); + + if (cached) { + // User clicked link, use cache response + event.detail.fetchRequest = cached; + } + + prefetchCache.clear(); + } + } + + prepareRequest(request) { + const link = request.target; + + request.headers["X-Sec-Purpose"] = "prefetch"; + + const turboFrame = link.closest("turbo-frame"); + const turboFrameTarget = link.getAttribute("data-turbo-frame") || turboFrame?.getAttribute("target") || turboFrame?.id; + + if (turboFrameTarget && turboFrameTarget !== "_top") { + request.headers["Turbo-Frame"] = turboFrameTarget; + } + } + + // Fetch request interface + + requestSucceededWithResponse() {} + + requestStarted(fetchRequest) {} + + requestErrored(fetchRequest) {} + + requestFinished(fetchRequest) {} + + requestPreventedHandlingResponse(fetchRequest, fetchResponse) {} + + requestFailedWithResponse(fetchRequest, fetchResponse) {} + + get #cacheTtl() { + return Number(getMetaContent("turbo-prefetch-cache-time")) || cacheTtl + } + + #isPrefetchable(link) { + const href = link.getAttribute("href"); + + if (!href) return false + + if (unfetchableLink(link)) return false + if (linkToTheSamePage(link)) return false + if (linkOptsOut(link)) return false + if (nonSafeLink(link)) return false + if (eventPrevented(link)) return false + + return true + } +} + +const unfetchableLink = (link) => { + return link.origin !== document.location.origin || !["http:", "https:"].includes(link.protocol) || link.hasAttribute("target") +}; + +const linkToTheSamePage = (link) => { + return (link.pathname + link.search === document.location.pathname + document.location.search) || link.href.startsWith("#") +}; + +const linkOptsOut = (link) => { + if (link.getAttribute("data-turbo-prefetch") === "false") return true + if (link.getAttribute("data-turbo") === "false") return true + + const turboPrefetchParent = findClosestRecursively(link, "[data-turbo-prefetch]"); + if (turboPrefetchParent && turboPrefetchParent.getAttribute("data-turbo-prefetch") === "false") return true + + return false +}; + +const nonSafeLink = (link) => { + const turboMethod = link.getAttribute("data-turbo-method"); + if (turboMethod && turboMethod.toLowerCase() !== "get") return true + + if (isUJS(link)) return true + if (link.hasAttribute("data-turbo-confirm")) return true + if (link.hasAttribute("data-turbo-stream")) return true + + return false +}; + +const isUJS = (link) => { + return link.hasAttribute("data-remote") || link.hasAttribute("data-behavior") || link.hasAttribute("data-confirm") || link.hasAttribute("data-method") +}; + +const eventPrevented = (link) => { + const event = dispatch("turbo:before-prefetch", { target: link, cancelable: true }); + return event.defaultPrevented +}; + +class Navigator { + constructor(delegate) { + this.delegate = delegate; + } + + proposeVisit(location, options = {}) { + if (this.delegate.allowsVisitingLocationWithAction(location, options.action)) { + this.delegate.visitProposedToLocation(location, options); + } + } + + startVisit(locatable, restorationIdentifier, options = {}) { + this.stop(); + this.currentVisit = new Visit(this, expandURL(locatable), restorationIdentifier, { + referrer: this.location, + ...options + }); + this.currentVisit.start(); + } + + submitForm(form, submitter) { + this.stop(); + this.formSubmission = new FormSubmission(this, form, submitter, true); + + this.formSubmission.start(); + } + + stop() { + if (this.formSubmission) { + this.formSubmission.stop(); + delete this.formSubmission; + } + + if (this.currentVisit) { + this.currentVisit.cancel(); + delete this.currentVisit; + } + } + + get adapter() { + return this.delegate.adapter + } + + get view() { + return this.delegate.view + } + + get rootLocation() { + return this.view.snapshot.rootLocation + } + + get history() { + return this.delegate.history + } + + // Form submission delegate + + formSubmissionStarted(formSubmission) { + // Not all adapters implement formSubmissionStarted + if (typeof this.adapter.formSubmissionStarted === "function") { + this.adapter.formSubmissionStarted(formSubmission); + } + } + + async formSubmissionSucceededWithResponse(formSubmission, fetchResponse) { + if (formSubmission == this.formSubmission) { + const responseHTML = await fetchResponse.responseHTML; + if (responseHTML) { + const shouldCacheSnapshot = formSubmission.isSafe; + if (!shouldCacheSnapshot) { + this.view.clearSnapshotCache(); + } + + const { statusCode, redirected } = fetchResponse; + const action = this.#getActionForFormSubmission(formSubmission, fetchResponse); + const visitOptions = { + action, + shouldCacheSnapshot, + response: { statusCode, responseHTML, redirected } + }; + this.proposeVisit(fetchResponse.location, visitOptions); + } + } + } + + async formSubmissionFailedWithResponse(formSubmission, fetchResponse) { + const responseHTML = await fetchResponse.responseHTML; + + if (responseHTML) { + const snapshot = PageSnapshot.fromHTMLString(responseHTML); + if (fetchResponse.serverError) { + await this.view.renderError(snapshot, this.currentVisit); + } else { + await this.view.renderPage(snapshot, false, true, this.currentVisit); + } + if(!snapshot.shouldPreserveScrollPosition) { + this.view.scrollToTop(); + } + this.view.clearSnapshotCache(); + } + } + + formSubmissionErrored(formSubmission, error) { + console.error(error); + } + + formSubmissionFinished(formSubmission) { + // Not all adapters implement formSubmissionFinished + if (typeof this.adapter.formSubmissionFinished === "function") { + this.adapter.formSubmissionFinished(formSubmission); + } + } + + // Visit delegate + + visitStarted(visit) { + this.delegate.visitStarted(visit); + } + + visitCompleted(visit) { + this.delegate.visitCompleted(visit); + delete this.currentVisit; + } + + locationWithActionIsSamePage(location, action) { + const anchor = getAnchor(location); + const currentAnchor = getAnchor(this.view.lastRenderedLocation); + const isRestorationToTop = action === "restore" && typeof anchor === "undefined"; + + return ( + action !== "replace" && + getRequestURL(location) === getRequestURL(this.view.lastRenderedLocation) && + (isRestorationToTop || (anchor != null && anchor !== currentAnchor)) + ) + } + + visitScrolledToSamePageLocation(oldURL, newURL) { + this.delegate.visitScrolledToSamePageLocation(oldURL, newURL); + } + + // Visits + + get location() { + return this.history.location + } + + get restorationIdentifier() { + return this.history.restorationIdentifier + } + + #getActionForFormSubmission(formSubmission, fetchResponse) { + const { submitter, formElement } = formSubmission; + return getVisitAction(submitter, formElement) || this.#getDefaultAction(fetchResponse) + } + + #getDefaultAction(fetchResponse) { + const sameLocationRedirect = fetchResponse.redirected && fetchResponse.location.href === this.location?.href; + return sameLocationRedirect ? "replace" : "advance" + } +} + +const PageStage = { + initial: 0, + loading: 1, + interactive: 2, + complete: 3 +}; + +class PageObserver { + stage = PageStage.initial + started = false + + constructor(delegate) { + this.delegate = delegate; + } + + start() { + if (!this.started) { + if (this.stage == PageStage.initial) { + this.stage = PageStage.loading; + } + document.addEventListener("readystatechange", this.interpretReadyState, false); + addEventListener("pagehide", this.pageWillUnload, false); + this.started = true; + } + } + + stop() { + if (this.started) { + document.removeEventListener("readystatechange", this.interpretReadyState, false); + removeEventListener("pagehide", this.pageWillUnload, false); + this.started = false; + } + } + + interpretReadyState = () => { + const { readyState } = this; + if (readyState == "interactive") { + this.pageIsInteractive(); + } else if (readyState == "complete") { + this.pageIsComplete(); + } + } + + pageIsInteractive() { + if (this.stage == PageStage.loading) { + this.stage = PageStage.interactive; + this.delegate.pageBecameInteractive(); + } + } + + pageIsComplete() { + this.pageIsInteractive(); + if (this.stage == PageStage.interactive) { + this.stage = PageStage.complete; + this.delegate.pageLoaded(); + } + } + + pageWillUnload = () => { + this.delegate.pageWillUnload(); + } + + get readyState() { + return document.readyState + } +} + +class ScrollObserver { + started = false + + constructor(delegate) { + this.delegate = delegate; + } + + start() { + if (!this.started) { + addEventListener("scroll", this.onScroll, false); + this.onScroll(); + this.started = true; + } + } + + stop() { + if (this.started) { + removeEventListener("scroll", this.onScroll, false); + this.started = false; + } + } + + onScroll = () => { + this.updatePosition({ x: window.pageXOffset, y: window.pageYOffset }); + } + + // Private + + updatePosition(position) { + this.delegate.scrollPositionChanged(position); + } +} + +class StreamMessageRenderer { + render({ fragment }) { + Bardo.preservingPermanentElements(this, getPermanentElementMapForFragment(fragment), () => { + withAutofocusFromFragment(fragment, () => { + withPreservedFocus(() => { + document.documentElement.appendChild(fragment); + }); + }); + }); + } + + // Bardo delegate + + enteringBardo(currentPermanentElement, newPermanentElement) { + newPermanentElement.replaceWith(currentPermanentElement.cloneNode(true)); + } + + leavingBardo() {} +} + +function getPermanentElementMapForFragment(fragment) { + const permanentElementsInDocument = queryPermanentElementsAll(document.documentElement); + const permanentElementMap = {}; + for (const permanentElementInDocument of permanentElementsInDocument) { + const { id } = permanentElementInDocument; + + for (const streamElement of fragment.querySelectorAll("turbo-stream")) { + const elementInStream = getPermanentElementById(streamElement.templateElement.content, id); + + if (elementInStream) { + permanentElementMap[id] = [permanentElementInDocument, elementInStream]; + } + } + } + + return permanentElementMap +} + +async function withAutofocusFromFragment(fragment, callback) { + const generatedID = `turbo-stream-autofocus-${uuid()}`; + const turboStreams = fragment.querySelectorAll("turbo-stream"); + const elementWithAutofocus = firstAutofocusableElementInStreams(turboStreams); + let willAutofocusId = null; + + if (elementWithAutofocus) { + if (elementWithAutofocus.id) { + willAutofocusId = elementWithAutofocus.id; + } else { + willAutofocusId = generatedID; + } + + elementWithAutofocus.id = willAutofocusId; + } + + callback(); + await nextRepaint(); + + const hasNoActiveElement = document.activeElement == null || document.activeElement == document.body; + + if (hasNoActiveElement && willAutofocusId) { + const elementToAutofocus = document.getElementById(willAutofocusId); + + if (elementIsFocusable(elementToAutofocus)) { + elementToAutofocus.focus(); + } + if (elementToAutofocus && elementToAutofocus.id == generatedID) { + elementToAutofocus.removeAttribute("id"); + } + } +} + +async function withPreservedFocus(callback) { + const [activeElementBeforeRender, activeElementAfterRender] = await around(callback, () => document.activeElement); + + const restoreFocusTo = activeElementBeforeRender && activeElementBeforeRender.id; + + if (restoreFocusTo) { + const elementToFocus = document.getElementById(restoreFocusTo); + + if (elementIsFocusable(elementToFocus) && elementToFocus != activeElementAfterRender) { + elementToFocus.focus(); + } + } +} + +function firstAutofocusableElementInStreams(nodeListOfStreamElements) { + for (const streamElement of nodeListOfStreamElements) { + const elementWithAutofocus = queryAutofocusableElement(streamElement.templateElement.content); + + if (elementWithAutofocus) return elementWithAutofocus + } + + return null +} + +class StreamObserver { + sources = new Set() + #started = false + + constructor(delegate) { + this.delegate = delegate; + } + + start() { + if (!this.#started) { + this.#started = true; + addEventListener("turbo:before-fetch-response", this.inspectFetchResponse, false); + } + } + + stop() { + if (this.#started) { + this.#started = false; + removeEventListener("turbo:before-fetch-response", this.inspectFetchResponse, false); + } + } + + connectStreamSource(source) { + if (!this.streamSourceIsConnected(source)) { + this.sources.add(source); + source.addEventListener("message", this.receiveMessageEvent, false); + } + } + + disconnectStreamSource(source) { + if (this.streamSourceIsConnected(source)) { + this.sources.delete(source); + source.removeEventListener("message", this.receiveMessageEvent, false); + } + } + + streamSourceIsConnected(source) { + return this.sources.has(source) + } + + inspectFetchResponse = (event) => { + const response = fetchResponseFromEvent(event); + if (response && fetchResponseIsStream(response)) { + event.preventDefault(); + this.receiveMessageResponse(response); + } + } + + receiveMessageEvent = (event) => { + if (this.#started && typeof event.data == "string") { + this.receiveMessageHTML(event.data); + } + } + + async receiveMessageResponse(response) { + const html = await response.responseHTML; + if (html) { + this.receiveMessageHTML(html); + } + } + + receiveMessageHTML(html) { + this.delegate.receivedMessageFromStream(StreamMessage.wrap(html)); + } +} + +function fetchResponseFromEvent(event) { + const fetchResponse = event.detail?.fetchResponse; + if (fetchResponse instanceof FetchResponse) { + return fetchResponse + } +} + +function fetchResponseIsStream(response) { + const contentType = response.contentType ?? ""; + return contentType.startsWith(StreamMessage.contentType) +} + +class ErrorRenderer extends Renderer { + static renderElement(currentElement, newElement) { + const { documentElement, body } = document; + + documentElement.replaceChild(newElement, body); + } + + async render() { + this.replaceHeadAndBody(); + this.activateScriptElements(); + } + + replaceHeadAndBody() { + const { documentElement, head } = document; + documentElement.replaceChild(this.newHead, head); + this.renderElement(this.currentElement, this.newElement); + } + + activateScriptElements() { + for (const replaceableElement of this.scriptElements) { + const parentNode = replaceableElement.parentNode; + if (parentNode) { + const element = activateScriptElement(replaceableElement); + parentNode.replaceChild(element, replaceableElement); + } + } + } + + get newHead() { + return this.newSnapshot.headSnapshot.element + } + + get scriptElements() { + return document.documentElement.querySelectorAll("script") + } +} + +// base IIFE to define idiomorph +var Idiomorph = (function () { + + //============================================================================= + // AND NOW IT BEGINS... + //============================================================================= + let EMPTY_SET = new Set(); + + // default configuration values, updatable by users now + let defaults = { + morphStyle: "outerHTML", + callbacks : { + beforeNodeAdded: noOp, + afterNodeAdded: noOp, + beforeNodeMorphed: noOp, + afterNodeMorphed: noOp, + beforeNodeRemoved: noOp, + afterNodeRemoved: noOp, + beforeAttributeUpdated: noOp, + + }, + head: { + style: 'merge', + shouldPreserve: function (elt) { + return elt.getAttribute("im-preserve") === "true"; + }, + shouldReAppend: function (elt) { + return elt.getAttribute("im-re-append") === "true"; + }, + shouldRemove: noOp, + afterHeadMorphed: noOp, + } + }; + + //============================================================================= + // Core Morphing Algorithm - morph, morphNormalizedContent, morphOldNodeTo, morphChildren + //============================================================================= + function morph(oldNode, newContent, config = {}) { + + if (oldNode instanceof Document) { + oldNode = oldNode.documentElement; + } + + if (typeof newContent === 'string') { + newContent = parseContent(newContent); + } + + let normalizedContent = normalizeContent(newContent); + + let ctx = createMorphContext(oldNode, normalizedContent, config); + + return morphNormalizedContent(oldNode, normalizedContent, ctx); + } + + function morphNormalizedContent(oldNode, normalizedNewContent, ctx) { + if (ctx.head.block) { + let oldHead = oldNode.querySelector('head'); + let newHead = normalizedNewContent.querySelector('head'); + if (oldHead && newHead) { + let promises = handleHeadElement(newHead, oldHead, ctx); + // when head promises resolve, call morph again, ignoring the head tag + Promise.all(promises).then(function () { + morphNormalizedContent(oldNode, normalizedNewContent, Object.assign(ctx, { + head: { + block: false, + ignore: true + } + })); + }); + return; + } + } + + if (ctx.morphStyle === "innerHTML") { + + // innerHTML, so we are only updating the children + morphChildren(normalizedNewContent, oldNode, ctx); + return oldNode.children; + + } else if (ctx.morphStyle === "outerHTML" || ctx.morphStyle == null) { + // otherwise find the best element match in the new content, morph that, and merge its siblings + // into either side of the best match + let bestMatch = findBestNodeMatch(normalizedNewContent, oldNode, ctx); + + // stash the siblings that will need to be inserted on either side of the best match + let previousSibling = bestMatch?.previousSibling; + let nextSibling = bestMatch?.nextSibling; + + // morph it + let morphedNode = morphOldNodeTo(oldNode, bestMatch, ctx); + + if (bestMatch) { + // if there was a best match, merge the siblings in too and return the + // whole bunch + return insertSiblings(previousSibling, morphedNode, nextSibling); + } else { + // otherwise nothing was added to the DOM + return [] + } + } else { + throw "Do not understand how to morph style " + ctx.morphStyle; + } + } + + + /** + * @param possibleActiveElement + * @param ctx + * @returns {boolean} + */ + function ignoreValueOfActiveElement(possibleActiveElement, ctx) { + return ctx.ignoreActiveValue && possibleActiveElement === document.activeElement && possibleActiveElement !== document.body; + } + + /** + * @param oldNode root node to merge content into + * @param newContent new content to merge + * @param ctx the merge context + * @returns {Element} the element that ended up in the DOM + */ + function morphOldNodeTo(oldNode, newContent, ctx) { + if (ctx.ignoreActive && oldNode === document.activeElement) ; else if (newContent == null) { + if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode; + + oldNode.remove(); + ctx.callbacks.afterNodeRemoved(oldNode); + return null; + } else if (!isSoftMatch(oldNode, newContent)) { + if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode; + if (ctx.callbacks.beforeNodeAdded(newContent) === false) return oldNode; + + oldNode.parentElement.replaceChild(newContent, oldNode); + ctx.callbacks.afterNodeAdded(newContent); + ctx.callbacks.afterNodeRemoved(oldNode); + return newContent; + } else { + if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) return oldNode; + + if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) ; else if (oldNode instanceof HTMLHeadElement && ctx.head.style !== "morph") { + handleHeadElement(newContent, oldNode, ctx); + } else { + syncNodeFrom(newContent, oldNode, ctx); + if (!ignoreValueOfActiveElement(oldNode, ctx)) { + morphChildren(newContent, oldNode, ctx); + } + } + ctx.callbacks.afterNodeMorphed(oldNode, newContent); + return oldNode; + } + } + + /** + * This is the core algorithm for matching up children. The idea is to use id sets to try to match up + * nodes as faithfully as possible. We greedily match, which allows us to keep the algorithm fast, but + * by using id sets, we are able to better match up with content deeper in the DOM. + * + * Basic algorithm is, for each node in the new content: + * + * - if we have reached the end of the old parent, append the new content + * - if the new content has an id set match with the current insertion point, morph + * - search for an id set match + * - if id set match found, morph + * - otherwise search for a "soft" match + * - if a soft match is found, morph + * - otherwise, prepend the new node before the current insertion point + * + * The two search algorithms terminate if competing node matches appear to outweigh what can be achieved + * with the current node. See findIdSetMatch() and findSoftMatch() for details. + * + * @param {Element} newParent the parent element of the new content + * @param {Element } oldParent the old content that we are merging the new content into + * @param ctx the merge context + */ + function morphChildren(newParent, oldParent, ctx) { + + let nextNewChild = newParent.firstChild; + let insertionPoint = oldParent.firstChild; + let newChild; + + // run through all the new content + while (nextNewChild) { + + newChild = nextNewChild; + nextNewChild = newChild.nextSibling; + + // if we are at the end of the exiting parent's children, just append + if (insertionPoint == null) { + if (ctx.callbacks.beforeNodeAdded(newChild) === false) return; + + oldParent.appendChild(newChild); + ctx.callbacks.afterNodeAdded(newChild); + removeIdsFromConsideration(ctx, newChild); + continue; + } + + // if the current node has an id set match then morph + if (isIdSetMatch(newChild, insertionPoint, ctx)) { + morphOldNodeTo(insertionPoint, newChild, ctx); + insertionPoint = insertionPoint.nextSibling; + removeIdsFromConsideration(ctx, newChild); + continue; + } + + // otherwise search forward in the existing old children for an id set match + let idSetMatch = findIdSetMatch(newParent, oldParent, newChild, insertionPoint, ctx); + + // if we found a potential match, remove the nodes until that point and morph + if (idSetMatch) { + insertionPoint = removeNodesBetween(insertionPoint, idSetMatch, ctx); + morphOldNodeTo(idSetMatch, newChild, ctx); + removeIdsFromConsideration(ctx, newChild); + continue; + } + + // no id set match found, so scan forward for a soft match for the current node + let softMatch = findSoftMatch(newParent, oldParent, newChild, insertionPoint, ctx); + + // if we found a soft match for the current node, morph + if (softMatch) { + insertionPoint = removeNodesBetween(insertionPoint, softMatch, ctx); + morphOldNodeTo(softMatch, newChild, ctx); + removeIdsFromConsideration(ctx, newChild); + continue; + } + + // abandon all hope of morphing, just insert the new child before the insertion point + // and move on + if (ctx.callbacks.beforeNodeAdded(newChild) === false) return; + + oldParent.insertBefore(newChild, insertionPoint); + ctx.callbacks.afterNodeAdded(newChild); + removeIdsFromConsideration(ctx, newChild); + } + + // remove any remaining old nodes that didn't match up with new content + while (insertionPoint !== null) { + + let tempNode = insertionPoint; + insertionPoint = insertionPoint.nextSibling; + removeNode(tempNode, ctx); + } + } + + //============================================================================= + // Attribute Syncing Code + //============================================================================= + + /** + * @param attr {String} the attribute to be mutated + * @param to {Element} the element that is going to be updated + * @param updateType {("update"|"remove")} + * @param ctx the merge context + * @returns {boolean} true if the attribute should be ignored, false otherwise + */ + function ignoreAttribute(attr, to, updateType, ctx) { + if(attr === 'value' && ctx.ignoreActiveValue && to === document.activeElement){ + return true; + } + return ctx.callbacks.beforeAttributeUpdated(attr, to, updateType) === false; + } + + /** + * syncs a given node with another node, copying over all attributes and + * inner element state from the 'from' node to the 'to' node + * + * @param {Element} from the element to copy attributes & state from + * @param {Element} to the element to copy attributes & state to + * @param ctx the merge context + */ + function syncNodeFrom(from, to, ctx) { + let type = from.nodeType; + + // if is an element type, sync the attributes from the + // new node into the new node + if (type === 1 /* element type */) { + const fromAttributes = from.attributes; + const toAttributes = to.attributes; + for (const fromAttribute of fromAttributes) { + if (ignoreAttribute(fromAttribute.name, to, 'update', ctx)) { + continue; + } + if (to.getAttribute(fromAttribute.name) !== fromAttribute.value) { + to.setAttribute(fromAttribute.name, fromAttribute.value); + } + } + // iterate backwards to avoid skipping over items when a delete occurs + for (let i = toAttributes.length - 1; 0 <= i; i--) { + const toAttribute = toAttributes[i]; + if (ignoreAttribute(toAttribute.name, to, 'remove', ctx)) { + continue; + } + if (!from.hasAttribute(toAttribute.name)) { + to.removeAttribute(toAttribute.name); + } + } + } + + // sync text nodes + if (type === 8 /* comment */ || type === 3 /* text */) { + if (to.nodeValue !== from.nodeValue) { + to.nodeValue = from.nodeValue; + } + } + + if (!ignoreValueOfActiveElement(to, ctx)) { + // sync input values + syncInputValue(from, to, ctx); + } + } + + /** + * @param from {Element} element to sync the value from + * @param to {Element} element to sync the value to + * @param attributeName {String} the attribute name + * @param ctx the merge context + */ + function syncBooleanAttribute(from, to, attributeName, ctx) { + if (from[attributeName] !== to[attributeName]) { + let ignoreUpdate = ignoreAttribute(attributeName, to, 'update', ctx); + if (!ignoreUpdate) { + to[attributeName] = from[attributeName]; + } + if (from[attributeName]) { + if (!ignoreUpdate) { + to.setAttribute(attributeName, from[attributeName]); + } + } else { + if (!ignoreAttribute(attributeName, to, 'remove', ctx)) { + to.removeAttribute(attributeName); + } + } + } + } + + /** + * NB: many bothans died to bring us information: + * + * https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js + * https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113 + * + * @param from {Element} the element to sync the input value from + * @param to {Element} the element to sync the input value to + * @param ctx the merge context + */ + function syncInputValue(from, to, ctx) { + if (from instanceof HTMLInputElement && + to instanceof HTMLInputElement && + from.type !== 'file') { + + let fromValue = from.value; + let toValue = to.value; + + // sync boolean attributes + syncBooleanAttribute(from, to, 'checked', ctx); + syncBooleanAttribute(from, to, 'disabled', ctx); + + if (!from.hasAttribute('value')) { + if (!ignoreAttribute('value', to, 'remove', ctx)) { + to.value = ''; + to.removeAttribute('value'); + } + } else if (fromValue !== toValue) { + if (!ignoreAttribute('value', to, 'update', ctx)) { + to.setAttribute('value', fromValue); + to.value = fromValue; + } + } + } else if (from instanceof HTMLOptionElement) { + syncBooleanAttribute(from, to, 'selected', ctx); + } else if (from instanceof HTMLTextAreaElement && to instanceof HTMLTextAreaElement) { + let fromValue = from.value; + let toValue = to.value; + if (ignoreAttribute('value', to, 'update', ctx)) { + return; + } + if (fromValue !== toValue) { + to.value = fromValue; + } + if (to.firstChild && to.firstChild.nodeValue !== fromValue) { + to.firstChild.nodeValue = fromValue; + } + } + } + + //============================================================================= + // the HEAD tag can be handled specially, either w/ a 'merge' or 'append' style + //============================================================================= + function handleHeadElement(newHeadTag, currentHead, ctx) { + + let added = []; + let removed = []; + let preserved = []; + let nodesToAppend = []; + + let headMergeStyle = ctx.head.style; + + // put all new head elements into a Map, by their outerHTML + let srcToNewHeadNodes = new Map(); + for (const newHeadChild of newHeadTag.children) { + srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild); + } + + // for each elt in the current head + for (const currentHeadElt of currentHead.children) { + + // If the current head element is in the map + let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML); + let isReAppended = ctx.head.shouldReAppend(currentHeadElt); + let isPreserved = ctx.head.shouldPreserve(currentHeadElt); + if (inNewContent || isPreserved) { + if (isReAppended) { + // remove the current version and let the new version replace it and re-execute + removed.push(currentHeadElt); + } else { + // this element already exists and should not be re-appended, so remove it from + // the new content map, preserving it in the DOM + srcToNewHeadNodes.delete(currentHeadElt.outerHTML); + preserved.push(currentHeadElt); + } + } else { + if (headMergeStyle === "append") { + // we are appending and this existing element is not new content + // so if and only if it is marked for re-append do we do anything + if (isReAppended) { + removed.push(currentHeadElt); + nodesToAppend.push(currentHeadElt); + } + } else { + // if this is a merge, we remove this content since it is not in the new head + if (ctx.head.shouldRemove(currentHeadElt) !== false) { + removed.push(currentHeadElt); + } + } + } + } + + // Push the remaining new head elements in the Map into the + // nodes to append to the head tag + nodesToAppend.push(...srcToNewHeadNodes.values()); + + let promises = []; + for (const newNode of nodesToAppend) { + let newElt = document.createRange().createContextualFragment(newNode.outerHTML).firstChild; + if (ctx.callbacks.beforeNodeAdded(newElt) !== false) { + if (newElt.href || newElt.src) { + let resolve = null; + let promise = new Promise(function (_resolve) { + resolve = _resolve; + }); + newElt.addEventListener('load', function () { + resolve(); + }); + promises.push(promise); + } + currentHead.appendChild(newElt); + ctx.callbacks.afterNodeAdded(newElt); + added.push(newElt); + } + } + + // remove all removed elements, after we have appended the new elements to avoid + // additional network requests for things like style sheets + for (const removedElement of removed) { + if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) { + currentHead.removeChild(removedElement); + ctx.callbacks.afterNodeRemoved(removedElement); + } + } + + ctx.head.afterHeadMorphed(currentHead, {added: added, kept: preserved, removed: removed}); + return promises; + } + + function noOp() { + } + + /* + Deep merges the config object and the Idiomoroph.defaults object to + produce a final configuration object + */ + function mergeDefaults(config) { + let finalConfig = {}; + // copy top level stuff into final config + Object.assign(finalConfig, defaults); + Object.assign(finalConfig, config); + + // copy callbacks into final config (do this to deep merge the callbacks) + finalConfig.callbacks = {}; + Object.assign(finalConfig.callbacks, defaults.callbacks); + Object.assign(finalConfig.callbacks, config.callbacks); + + // copy head config into final config (do this to deep merge the head) + finalConfig.head = {}; + Object.assign(finalConfig.head, defaults.head); + Object.assign(finalConfig.head, config.head); + return finalConfig; + } + + function createMorphContext(oldNode, newContent, config) { + config = mergeDefaults(config); + return { + target: oldNode, + newContent: newContent, + config: config, + morphStyle: config.morphStyle, + ignoreActive: config.ignoreActive, + ignoreActiveValue: config.ignoreActiveValue, + idMap: createIdMap(oldNode, newContent), + deadIds: new Set(), + callbacks: config.callbacks, + head: config.head + } + } + + function isIdSetMatch(node1, node2, ctx) { + if (node1 == null || node2 == null) { + return false; + } + if (node1.nodeType === node2.nodeType && node1.tagName === node2.tagName) { + if (node1.id !== "" && node1.id === node2.id) { + return true; + } else { + return getIdIntersectionCount(ctx, node1, node2) > 0; + } + } + return false; + } + + function isSoftMatch(node1, node2) { + if (node1 == null || node2 == null) { + return false; + } + return node1.nodeType === node2.nodeType && node1.tagName === node2.tagName + } + + function removeNodesBetween(startInclusive, endExclusive, ctx) { + while (startInclusive !== endExclusive) { + let tempNode = startInclusive; + startInclusive = startInclusive.nextSibling; + removeNode(tempNode, ctx); + } + removeIdsFromConsideration(ctx, endExclusive); + return endExclusive.nextSibling; + } + + //============================================================================= + // Scans forward from the insertionPoint in the old parent looking for a potential id match + // for the newChild. We stop if we find a potential id match for the new child OR + // if the number of potential id matches we are discarding is greater than the + // potential id matches for the new child + //============================================================================= + function findIdSetMatch(newContent, oldParent, newChild, insertionPoint, ctx) { + + // max id matches we are willing to discard in our search + let newChildPotentialIdCount = getIdIntersectionCount(ctx, newChild, oldParent); + + let potentialMatch = null; + + // only search forward if there is a possibility of an id match + if (newChildPotentialIdCount > 0) { + let potentialMatch = insertionPoint; + // if there is a possibility of an id match, scan forward + // keep track of the potential id match count we are discarding (the + // newChildPotentialIdCount must be greater than this to make it likely + // worth it) + let otherMatchCount = 0; + while (potentialMatch != null) { + + // If we have an id match, return the current potential match + if (isIdSetMatch(newChild, potentialMatch, ctx)) { + return potentialMatch; + } + + // computer the other potential matches of this new content + otherMatchCount += getIdIntersectionCount(ctx, potentialMatch, newContent); + if (otherMatchCount > newChildPotentialIdCount) { + // if we have more potential id matches in _other_ content, we + // do not have a good candidate for an id match, so return null + return null; + } + + // advanced to the next old content child + potentialMatch = potentialMatch.nextSibling; + } + } + return potentialMatch; + } + + //============================================================================= + // Scans forward from the insertionPoint in the old parent looking for a potential soft match + // for the newChild. We stop if we find a potential soft match for the new child OR + // if we find a potential id match in the old parents children OR if we find two + // potential soft matches for the next two pieces of new content + //============================================================================= + function findSoftMatch(newContent, oldParent, newChild, insertionPoint, ctx) { + + let potentialSoftMatch = insertionPoint; + let nextSibling = newChild.nextSibling; + let siblingSoftMatchCount = 0; + + while (potentialSoftMatch != null) { + + if (getIdIntersectionCount(ctx, potentialSoftMatch, newContent) > 0) { + // the current potential soft match has a potential id set match with the remaining new + // content so bail out of looking + return null; + } + + // if we have a soft match with the current node, return it + if (isSoftMatch(newChild, potentialSoftMatch)) { + return potentialSoftMatch; + } + + if (isSoftMatch(nextSibling, potentialSoftMatch)) { + // the next new node has a soft match with this node, so + // increment the count of future soft matches + siblingSoftMatchCount++; + nextSibling = nextSibling.nextSibling; + + // If there are two future soft matches, bail to allow the siblings to soft match + // so that we don't consume future soft matches for the sake of the current node + if (siblingSoftMatchCount >= 2) { + return null; + } + } + + // advanced to the next old content child + potentialSoftMatch = potentialSoftMatch.nextSibling; + } + + return potentialSoftMatch; + } + + function parseContent(newContent) { + let parser = new DOMParser(); + + // remove svgs to avoid false-positive matches on head, etc. + let contentWithSvgsRemoved = newContent.replace(/]*>|>)([\s\S]*?)<\/svg>/gim, ''); + + // if the newContent contains a html, head or body tag, we can simply parse it w/o wrapping + if (contentWithSvgsRemoved.match(/<\/html>/) || contentWithSvgsRemoved.match(/<\/head>/) || contentWithSvgsRemoved.match(/<\/body>/)) { + let content = parser.parseFromString(newContent, "text/html"); + // if it is a full HTML document, return the document itself as the parent container + if (contentWithSvgsRemoved.match(/<\/html>/)) { + content.generatedByIdiomorph = true; + return content; + } else { + // otherwise return the html element as the parent container + let htmlElement = content.firstChild; + if (htmlElement) { + htmlElement.generatedByIdiomorph = true; + return htmlElement; + } else { + return null; + } + } + } else { + // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help + // deal with touchy tags like tr, tbody, etc. + let responseDoc = parser.parseFromString("", "text/html"); + let content = responseDoc.body.querySelector('template').content; + content.generatedByIdiomorph = true; + return content + } + } + + function normalizeContent(newContent) { + if (newContent == null) { + // noinspection UnnecessaryLocalVariableJS + const dummyParent = document.createElement('div'); + return dummyParent; + } else if (newContent.generatedByIdiomorph) { + // the template tag created by idiomorph parsing can serve as a dummy parent + return newContent; + } else if (newContent instanceof Node) { + // a single node is added as a child to a dummy parent + const dummyParent = document.createElement('div'); + dummyParent.append(newContent); + return dummyParent; + } else { + // all nodes in the array or HTMLElement collection are consolidated under + // a single dummy parent element + const dummyParent = document.createElement('div'); + for (const elt of [...newContent]) { + dummyParent.append(elt); + } + return dummyParent; + } + } + + function insertSiblings(previousSibling, morphedNode, nextSibling) { + let stack = []; + let added = []; + while (previousSibling != null) { + stack.push(previousSibling); + previousSibling = previousSibling.previousSibling; + } + while (stack.length > 0) { + let node = stack.pop(); + added.push(node); // push added preceding siblings on in order and insert + morphedNode.parentElement.insertBefore(node, morphedNode); + } + added.push(morphedNode); + while (nextSibling != null) { + stack.push(nextSibling); + added.push(nextSibling); // here we are going in order, so push on as we scan, rather than add + nextSibling = nextSibling.nextSibling; + } + while (stack.length > 0) { + morphedNode.parentElement.insertBefore(stack.pop(), morphedNode.nextSibling); + } + return added; + } + + function findBestNodeMatch(newContent, oldNode, ctx) { + let currentElement; + currentElement = newContent.firstChild; + let bestElement = currentElement; + let score = 0; + while (currentElement) { + let newScore = scoreElement(currentElement, oldNode, ctx); + if (newScore > score) { + bestElement = currentElement; + score = newScore; + } + currentElement = currentElement.nextSibling; + } + return bestElement; + } + + function scoreElement(node1, node2, ctx) { + if (isSoftMatch(node1, node2)) { + return .5 + getIdIntersectionCount(ctx, node1, node2); + } + return 0; + } + + function removeNode(tempNode, ctx) { + removeIdsFromConsideration(ctx, tempNode); + if (ctx.callbacks.beforeNodeRemoved(tempNode) === false) return; + + tempNode.remove(); + ctx.callbacks.afterNodeRemoved(tempNode); + } + + //============================================================================= + // ID Set Functions + //============================================================================= + + function isIdInConsideration(ctx, id) { + return !ctx.deadIds.has(id); + } + + function idIsWithinNode(ctx, id, targetNode) { + let idSet = ctx.idMap.get(targetNode) || EMPTY_SET; + return idSet.has(id); + } + + function removeIdsFromConsideration(ctx, node) { + let idSet = ctx.idMap.get(node) || EMPTY_SET; + for (const id of idSet) { + ctx.deadIds.add(id); + } + } + + function getIdIntersectionCount(ctx, node1, node2) { + let sourceSet = ctx.idMap.get(node1) || EMPTY_SET; + let matchCount = 0; + for (const id of sourceSet) { + // a potential match is an id in the source and potentialIdsSet, but + // that has not already been merged into the DOM + if (isIdInConsideration(ctx, id) && idIsWithinNode(ctx, id, node2)) { + ++matchCount; + } + } + return matchCount; + } + + /** + * A bottom up algorithm that finds all elements with ids inside of the node + * argument and populates id sets for those nodes and all their parents, generating + * a set of ids contained within all nodes for the entire hierarchy in the DOM + * + * @param node {Element} + * @param {Map>} idMap + */ + function populateIdMapForNode(node, idMap) { + let nodeParent = node.parentElement; + // find all elements with an id property + let idElements = node.querySelectorAll('[id]'); + for (const elt of idElements) { + let current = elt; + // walk up the parent hierarchy of that element, adding the id + // of element to the parent's id set + while (current !== nodeParent && current != null) { + let idSet = idMap.get(current); + // if the id set doesn't exist, create it and insert it in the map + if (idSet == null) { + idSet = new Set(); + idMap.set(current, idSet); + } + idSet.add(elt.id); + current = current.parentElement; + } + } + } + + /** + * This function computes a map of nodes to all ids contained within that node (inclusive of the + * node). This map can be used to ask if two nodes have intersecting sets of ids, which allows + * for a looser definition of "matching" than tradition id matching, and allows child nodes + * to contribute to a parent nodes matching. + * + * @param {Element} oldContent the old content that will be morphed + * @param {Element} newContent the new content to morph to + * @returns {Map>} a map of nodes to id sets for the + */ + function createIdMap(oldContent, newContent) { + let idMap = new Map(); + populateIdMapForNode(oldContent, idMap); + populateIdMapForNode(newContent, idMap); + return idMap; + } + + //============================================================================= + // This is what ends up becoming the Idiomorph global object + //============================================================================= + return { + morph, + defaults + } + })(); + +function morphElements(currentElement, newElement, { callbacks, ...options } = {}) { + Idiomorph.morph(currentElement, newElement, { + ...options, + callbacks: new DefaultIdiomorphCallbacks(callbacks) + }); +} + +function morphChildren(currentElement, newElement) { + morphElements(currentElement, newElement.children, { + morphStyle: "innerHTML" + }); +} + +class DefaultIdiomorphCallbacks { + #beforeNodeMorphed + + constructor({ beforeNodeMorphed } = {}) { + this.#beforeNodeMorphed = beforeNodeMorphed || (() => true); + } + + beforeNodeAdded = (node) => { + return !(node.id && node.hasAttribute("data-turbo-permanent") && document.getElementById(node.id)) + } + + beforeNodeMorphed = (currentElement, newElement) => { + if (currentElement instanceof Element) { + if (!currentElement.hasAttribute("data-turbo-permanent") && this.#beforeNodeMorphed(currentElement, newElement)) { + const event = dispatch("turbo:before-morph-element", { + cancelable: true, + target: currentElement, + detail: { currentElement, newElement } + }); + + return !event.defaultPrevented + } else { + return false + } + } + } + + beforeAttributeUpdated = (attributeName, target, mutationType) => { + const event = dispatch("turbo:before-morph-attribute", { + cancelable: true, + target, + detail: { attributeName, mutationType } + }); + + return !event.defaultPrevented + } + + beforeNodeRemoved = (node) => { + return this.beforeNodeMorphed(node) + } + + afterNodeMorphed = (currentElement, newElement) => { + if (currentElement instanceof Element) { + dispatch("turbo:morph-element", { + target: currentElement, + detail: { currentElement, newElement } + }); + } + } +} + +class MorphingFrameRenderer extends FrameRenderer { + static renderElement(currentElement, newElement) { + dispatch("turbo:before-frame-morph", { + target: currentElement, + detail: { currentElement, newElement } + }); + + morphChildren(currentElement, newElement); + } +} + +class PageRenderer extends Renderer { + static renderElement(currentElement, newElement) { + if (document.body && newElement instanceof HTMLBodyElement) { + document.body.replaceWith(newElement); + } else { + document.documentElement.appendChild(newElement); + } + } + + get shouldRender() { + return this.newSnapshot.isVisitable && this.trackedElementsAreIdentical + } + + get reloadReason() { + if (!this.newSnapshot.isVisitable) { + return { + reason: "turbo_visit_control_is_reload" + } + } + + if (!this.trackedElementsAreIdentical) { + return { + reason: "tracked_element_mismatch" + } + } + } + + async prepareToRender() { + this.#setLanguage(); + await this.mergeHead(); + } + + async render() { + if (this.willRender) { + await this.replaceBody(); + } + } + + finishRendering() { + super.finishRendering(); + if (!this.isPreview) { + this.focusFirstAutofocusableElement(); + } + } + + get currentHeadSnapshot() { + return this.currentSnapshot.headSnapshot + } + + get newHeadSnapshot() { + return this.newSnapshot.headSnapshot + } + + get newElement() { + return this.newSnapshot.element + } + + #setLanguage() { + const { documentElement } = this.currentSnapshot; + const { lang } = this.newSnapshot; + + if (lang) { + documentElement.setAttribute("lang", lang); + } else { + documentElement.removeAttribute("lang"); + } + } + + async mergeHead() { + const mergedHeadElements = this.mergeProvisionalElements(); + const newStylesheetElements = this.copyNewHeadStylesheetElements(); + this.copyNewHeadScriptElements(); + + await mergedHeadElements; + await newStylesheetElements; + + if (this.willRender) { + this.removeUnusedDynamicStylesheetElements(); + } + } + + async replaceBody() { + await this.preservingPermanentElements(async () => { + this.activateNewBody(); + await this.assignNewBody(); + }); + } + + get trackedElementsAreIdentical() { + return this.currentHeadSnapshot.trackedElementSignature == this.newHeadSnapshot.trackedElementSignature + } + + async copyNewHeadStylesheetElements() { + const loadingElements = []; + + for (const element of this.newHeadStylesheetElements) { + loadingElements.push(waitForLoad(element)); + + document.head.appendChild(element); + } + + await Promise.all(loadingElements); + } + + copyNewHeadScriptElements() { + for (const element of this.newHeadScriptElements) { + document.head.appendChild(activateScriptElement(element)); + } + } + + removeUnusedDynamicStylesheetElements() { + for (const element of this.unusedDynamicStylesheetElements) { + document.head.removeChild(element); + } + } + + async mergeProvisionalElements() { + const newHeadElements = [...this.newHeadProvisionalElements]; + + for (const element of this.currentHeadProvisionalElements) { + if (!this.isCurrentElementInElementList(element, newHeadElements)) { + document.head.removeChild(element); + } + } + + for (const element of newHeadElements) { + document.head.appendChild(element); + } + } + + isCurrentElementInElementList(element, elementList) { + for (const [index, newElement] of elementList.entries()) { + // if title element... + if (element.tagName == "TITLE") { + if (newElement.tagName != "TITLE") { + continue + } + if (element.innerHTML == newElement.innerHTML) { + elementList.splice(index, 1); + return true + } + } + + // if any other element... + if (newElement.isEqualNode(element)) { + elementList.splice(index, 1); + return true + } + } + + return false + } + + removeCurrentHeadProvisionalElements() { + for (const element of this.currentHeadProvisionalElements) { + document.head.removeChild(element); + } + } + + copyNewHeadProvisionalElements() { + for (const element of this.newHeadProvisionalElements) { + document.head.appendChild(element); + } + } + + activateNewBody() { + document.adoptNode(this.newElement); + this.activateNewBodyScriptElements(); + } + + activateNewBodyScriptElements() { + for (const inertScriptElement of this.newBodyScriptElements) { + const activatedScriptElement = activateScriptElement(inertScriptElement); + inertScriptElement.replaceWith(activatedScriptElement); + } + } + + async assignNewBody() { + await this.renderElement(this.currentElement, this.newElement); + } + + get unusedDynamicStylesheetElements() { + return this.oldHeadStylesheetElements.filter((element) => { + return element.getAttribute("data-turbo-track") === "dynamic" + }) + } + + get oldHeadStylesheetElements() { + return this.currentHeadSnapshot.getStylesheetElementsNotInSnapshot(this.newHeadSnapshot) + } + + get newHeadStylesheetElements() { + return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot) + } + + get newHeadScriptElements() { + return this.newHeadSnapshot.getScriptElementsNotInSnapshot(this.currentHeadSnapshot) + } + + get currentHeadProvisionalElements() { + return this.currentHeadSnapshot.provisionalElements + } + + get newHeadProvisionalElements() { + return this.newHeadSnapshot.provisionalElements + } + + get newBodyScriptElements() { + return this.newElement.querySelectorAll("script") + } +} + +class MorphingPageRenderer extends PageRenderer { + static renderElement(currentElement, newElement) { + morphElements(currentElement, newElement, { + callbacks: { + beforeNodeMorphed: element => !canRefreshFrame(element) + } + }); + + for (const frame of currentElement.querySelectorAll("turbo-frame")) { + if (canRefreshFrame(frame)) refreshFrame(frame); + } + + dispatch("turbo:morph", { detail: { currentElement, newElement } }); + } + + async preservingPermanentElements(callback) { + return await callback() + } + + get renderMethod() { + return "morph" + } + + get shouldAutofocus() { + return false + } +} + +function canRefreshFrame(frame) { + return frame instanceof FrameElement && + frame.src && + frame.refresh === "morph" && + !frame.closest("[data-turbo-permanent]") +} + +function refreshFrame(frame) { + frame.addEventListener("turbo:before-frame-render", ({ detail }) => { + detail.render = MorphingFrameRenderer.renderElement; + }, { once: true }); + + frame.reload(); +} + +class SnapshotCache { + keys = [] + snapshots = {} + + constructor(size) { + this.size = size; + } + + has(location) { + return toCacheKey(location) in this.snapshots + } + + get(location) { + if (this.has(location)) { + const snapshot = this.read(location); + this.touch(location); + return snapshot + } + } + + put(location, snapshot) { + this.write(location, snapshot); + this.touch(location); + return snapshot + } + + clear() { + this.snapshots = {}; + } + + // Private + + read(location) { + return this.snapshots[toCacheKey(location)] + } + + write(location, snapshot) { + this.snapshots[toCacheKey(location)] = snapshot; + } + + touch(location) { + const key = toCacheKey(location); + const index = this.keys.indexOf(key); + if (index > -1) this.keys.splice(index, 1); + this.keys.unshift(key); + this.trim(); + } + + trim() { + for (const key of this.keys.splice(this.size)) { + delete this.snapshots[key]; + } + } +} + +class PageView extends View { + snapshotCache = new SnapshotCache(10) + lastRenderedLocation = new URL(location.href) + forceReloaded = false + + shouldTransitionTo(newSnapshot) { + return this.snapshot.prefersViewTransitions && newSnapshot.prefersViewTransitions + } + + renderPage(snapshot, isPreview = false, willRender = true, visit) { + const shouldMorphPage = this.isPageRefresh(visit) && this.snapshot.shouldMorphPage; + const rendererClass = shouldMorphPage ? MorphingPageRenderer : PageRenderer; + + const renderer = new rendererClass(this.snapshot, snapshot, rendererClass.renderElement, isPreview, willRender); + + if (!renderer.shouldRender) { + this.forceReloaded = true; + } else { + visit?.changeHistory(); + } + + return this.render(renderer) + } + + renderError(snapshot, visit) { + visit?.changeHistory(); + const renderer = new ErrorRenderer(this.snapshot, snapshot, ErrorRenderer.renderElement, false); + return this.render(renderer) + } + + clearSnapshotCache() { + this.snapshotCache.clear(); + } + + async cacheSnapshot(snapshot = this.snapshot) { + if (snapshot.isCacheable) { + this.delegate.viewWillCacheSnapshot(); + const { lastRenderedLocation: location } = this; + await nextEventLoopTick(); + const cachedSnapshot = snapshot.clone(); + this.snapshotCache.put(location, cachedSnapshot); + return cachedSnapshot + } + } + + getCachedSnapshotForLocation(location) { + return this.snapshotCache.get(location) + } + + isPageRefresh(visit) { + return !visit || (this.lastRenderedLocation.pathname === visit.location.pathname && visit.action === "replace") + } + + shouldPreserveScrollPosition(visit) { + return this.isPageRefresh(visit) && this.snapshot.shouldPreserveScrollPosition + } + + get snapshot() { + return PageSnapshot.fromElement(this.element) + } +} + +class Preloader { + selector = "a[data-turbo-preload]" + + constructor(delegate, snapshotCache) { + this.delegate = delegate; + this.snapshotCache = snapshotCache; + } + + start() { + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", this.#preloadAll); + } else { + this.preloadOnLoadLinksForView(document.body); + } + } + + stop() { + document.removeEventListener("DOMContentLoaded", this.#preloadAll); + } + + preloadOnLoadLinksForView(element) { + for (const link of element.querySelectorAll(this.selector)) { + if (this.delegate.shouldPreloadLink(link)) { + this.preloadURL(link); + } + } + } + + async preloadURL(link) { + const location = new URL(link.href); + + if (this.snapshotCache.has(location)) { + return + } + + const fetchRequest = new FetchRequest(this, FetchMethod.get, location, new URLSearchParams(), link); + await fetchRequest.perform(); + } + + // Fetch request delegate + + prepareRequest(fetchRequest) { + fetchRequest.headers["X-Sec-Purpose"] = "prefetch"; + } + + async requestSucceededWithResponse(fetchRequest, fetchResponse) { + try { + const responseHTML = await fetchResponse.responseHTML; + const snapshot = PageSnapshot.fromHTMLString(responseHTML); + + this.snapshotCache.put(fetchRequest.url, snapshot); + } catch (_) { + // If we cannot preload that is ok! + } + } + + requestStarted(fetchRequest) {} + + requestErrored(fetchRequest) {} + + requestFinished(fetchRequest) {} + + requestPreventedHandlingResponse(fetchRequest, fetchResponse) {} + + requestFailedWithResponse(fetchRequest, fetchResponse) {} + + #preloadAll = () => { + this.preloadOnLoadLinksForView(document.body); + } +} + +class Cache { + constructor(session) { + this.session = session; + } + + clear() { + this.session.clearCache(); + } + + resetCacheControl() { + this.#setCacheControl(""); + } + + exemptPageFromCache() { + this.#setCacheControl("no-cache"); + } + + exemptPageFromPreview() { + this.#setCacheControl("no-preview"); + } + + #setCacheControl(value) { + setMetaContent("turbo-cache-control", value); + } +} + +class Session { + navigator = new Navigator(this) + history = new History(this) + view = new PageView(this, document.documentElement) + adapter = new BrowserAdapter(this) + + pageObserver = new PageObserver(this) + cacheObserver = new CacheObserver() + linkPrefetchObserver = new LinkPrefetchObserver(this, document) + linkClickObserver = new LinkClickObserver(this, window) + formSubmitObserver = new FormSubmitObserver(this, document) + scrollObserver = new ScrollObserver(this) + streamObserver = new StreamObserver(this) + formLinkClickObserver = new FormLinkClickObserver(this, document.documentElement) + frameRedirector = new FrameRedirector(this, document.documentElement) + streamMessageRenderer = new StreamMessageRenderer() + cache = new Cache(this) + + drive = true + enabled = true + progressBarDelay = 500 + started = false + formMode = "on" + #pageRefreshDebouncePeriod = 150 + + constructor(recentRequests) { + this.recentRequests = recentRequests; + this.preloader = new Preloader(this, this.view.snapshotCache); + this.debouncedRefresh = this.refresh; + this.pageRefreshDebouncePeriod = this.pageRefreshDebouncePeriod; + } + + start() { + if (!this.started) { + this.pageObserver.start(); + this.cacheObserver.start(); + this.linkPrefetchObserver.start(); + this.formLinkClickObserver.start(); + this.linkClickObserver.start(); + this.formSubmitObserver.start(); + this.scrollObserver.start(); + this.streamObserver.start(); + this.frameRedirector.start(); + this.history.start(); + this.preloader.start(); + this.started = true; + this.enabled = true; + } + } + + disable() { + this.enabled = false; + } + + stop() { + if (this.started) { + this.pageObserver.stop(); + this.cacheObserver.stop(); + this.linkPrefetchObserver.stop(); + this.formLinkClickObserver.stop(); + this.linkClickObserver.stop(); + this.formSubmitObserver.stop(); + this.scrollObserver.stop(); + this.streamObserver.stop(); + this.frameRedirector.stop(); + this.history.stop(); + this.preloader.stop(); + this.started = false; + } + } + + registerAdapter(adapter) { + this.adapter = adapter; + } + + visit(location, options = {}) { + const frameElement = options.frame ? document.getElementById(options.frame) : null; + + if (frameElement instanceof FrameElement) { + const action = options.action || getVisitAction(frameElement); + + frameElement.delegate.proposeVisitIfNavigatedWithAction(frameElement, action); + frameElement.src = location.toString(); + } else { + this.navigator.proposeVisit(expandURL(location), options); + } + } + + refresh(url, requestId) { + const isRecentRequest = requestId && this.recentRequests.has(requestId); + if (!isRecentRequest && !this.navigator.currentVisit) { + this.visit(url, { action: "replace", shouldCacheSnapshot: false }); + } + } + + connectStreamSource(source) { + this.streamObserver.connectStreamSource(source); + } + + disconnectStreamSource(source) { + this.streamObserver.disconnectStreamSource(source); + } + + renderStreamMessage(message) { + this.streamMessageRenderer.render(StreamMessage.wrap(message)); + } + + clearCache() { + this.view.clearSnapshotCache(); + } + + setProgressBarDelay(delay) { + this.progressBarDelay = delay; + } + + setFormMode(mode) { + this.formMode = mode; + } + + get location() { + return this.history.location + } + + get restorationIdentifier() { + return this.history.restorationIdentifier + } + + get pageRefreshDebouncePeriod() { + return this.#pageRefreshDebouncePeriod + } + + set pageRefreshDebouncePeriod(value) { + this.refresh = debounce(this.debouncedRefresh.bind(this), value); + this.#pageRefreshDebouncePeriod = value; + } + + // Preloader delegate + + shouldPreloadLink(element) { + const isUnsafe = element.hasAttribute("data-turbo-method"); + const isStream = element.hasAttribute("data-turbo-stream"); + const frameTarget = element.getAttribute("data-turbo-frame"); + const frame = frameTarget == "_top" ? + null : + document.getElementById(frameTarget) || findClosestRecursively(element, "turbo-frame:not([disabled])"); + + if (isUnsafe || isStream || frame instanceof FrameElement) { + return false + } else { + const location = new URL(element.href); + + return this.elementIsNavigatable(element) && locationIsVisitable(location, this.snapshot.rootLocation) + } + } + + // History delegate + + historyPoppedToLocationWithRestorationIdentifierAndDirection(location, restorationIdentifier, direction) { + if (this.enabled) { + this.navigator.startVisit(location, restorationIdentifier, { + action: "restore", + historyChanged: true, + direction + }); + } else { + this.adapter.pageInvalidated({ + reason: "turbo_disabled" + }); + } + } + + // Scroll observer delegate + + scrollPositionChanged(position) { + this.history.updateRestorationData({ scrollPosition: position }); + } + + // Form click observer delegate + + willSubmitFormLinkToLocation(link, location) { + return this.elementIsNavigatable(link) && locationIsVisitable(location, this.snapshot.rootLocation) + } + + submittedFormLinkToLocation() {} + + // Link hover observer delegate + + canPrefetchRequestToLocation(link, location) { + return ( + this.elementIsNavigatable(link) && + locationIsVisitable(location, this.snapshot.rootLocation) + ) + } + + // Link click observer delegate + + willFollowLinkToLocation(link, location, event) { + return ( + this.elementIsNavigatable(link) && + locationIsVisitable(location, this.snapshot.rootLocation) && + this.applicationAllowsFollowingLinkToLocation(link, location, event) + ) + } + + followedLinkToLocation(link, location) { + const action = this.getActionForLink(link); + const acceptsStreamResponse = link.hasAttribute("data-turbo-stream"); + + this.visit(location.href, { action, acceptsStreamResponse }); + } + + // Navigator delegate + + allowsVisitingLocationWithAction(location, action) { + return this.locationWithActionIsSamePage(location, action) || this.applicationAllowsVisitingLocation(location) + } + + visitProposedToLocation(location, options) { + extendURLWithDeprecatedProperties(location); + this.adapter.visitProposedToLocation(location, options); + } + + // Visit delegate + + visitStarted(visit) { + if (!visit.acceptsStreamResponse) { + markAsBusy(document.documentElement); + this.view.markVisitDirection(visit.direction); + } + extendURLWithDeprecatedProperties(visit.location); + if (!visit.silent) { + this.notifyApplicationAfterVisitingLocation(visit.location, visit.action); + } + } + + visitCompleted(visit) { + this.view.unmarkVisitDirection(); + clearBusyState(document.documentElement); + this.notifyApplicationAfterPageLoad(visit.getTimingMetrics()); + } + + locationWithActionIsSamePage(location, action) { + return this.navigator.locationWithActionIsSamePage(location, action) + } + + visitScrolledToSamePageLocation(oldURL, newURL) { + this.notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL); + } + + // Form submit observer delegate + + willSubmitForm(form, submitter) { + const action = getAction$1(form, submitter); + + return ( + this.submissionIsNavigatable(form, submitter) && + locationIsVisitable(expandURL(action), this.snapshot.rootLocation) + ) + } + + formSubmitted(form, submitter) { + this.navigator.submitForm(form, submitter); + } + + // Page observer delegate + + pageBecameInteractive() { + this.view.lastRenderedLocation = this.location; + this.notifyApplicationAfterPageLoad(); + } + + pageLoaded() { + this.history.assumeControlOfScrollRestoration(); + } + + pageWillUnload() { + this.history.relinquishControlOfScrollRestoration(); + } + + // Stream observer delegate + + receivedMessageFromStream(message) { + this.renderStreamMessage(message); + } + + // Page view delegate + + viewWillCacheSnapshot() { + if (!this.navigator.currentVisit?.silent) { + this.notifyApplicationBeforeCachingSnapshot(); + } + } + + allowsImmediateRender({ element }, options) { + const event = this.notifyApplicationBeforeRender(element, options); + const { + defaultPrevented, + detail: { render } + } = event; + + if (this.view.renderer && render) { + this.view.renderer.renderElement = render; + } + + return !defaultPrevented + } + + viewRenderedSnapshot(_snapshot, _isPreview, renderMethod) { + this.view.lastRenderedLocation = this.history.location; + this.notifyApplicationAfterRender(renderMethod); + } + + preloadOnLoadLinksForView(element) { + this.preloader.preloadOnLoadLinksForView(element); + } + + viewInvalidated(reason) { + this.adapter.pageInvalidated(reason); + } + + // Frame element + + frameLoaded(frame) { + this.notifyApplicationAfterFrameLoad(frame); + } + + frameRendered(fetchResponse, frame) { + this.notifyApplicationAfterFrameRender(fetchResponse, frame); + } + + // Application events + + applicationAllowsFollowingLinkToLocation(link, location, ev) { + const event = this.notifyApplicationAfterClickingLinkToLocation(link, location, ev); + return !event.defaultPrevented + } + + applicationAllowsVisitingLocation(location) { + const event = this.notifyApplicationBeforeVisitingLocation(location); + return !event.defaultPrevented + } + + notifyApplicationAfterClickingLinkToLocation(link, location, event) { + return dispatch("turbo:click", { + target: link, + detail: { url: location.href, originalEvent: event }, + cancelable: true + }) + } + + notifyApplicationBeforeVisitingLocation(location) { + return dispatch("turbo:before-visit", { + detail: { url: location.href }, + cancelable: true + }) + } + + notifyApplicationAfterVisitingLocation(location, action) { + return dispatch("turbo:visit", { detail: { url: location.href, action } }) + } + + notifyApplicationBeforeCachingSnapshot() { + return dispatch("turbo:before-cache") + } + + notifyApplicationBeforeRender(newBody, options) { + return dispatch("turbo:before-render", { + detail: { newBody, ...options }, + cancelable: true + }) + } + + notifyApplicationAfterRender(renderMethod) { + return dispatch("turbo:render", { detail: { renderMethod } }) + } + + notifyApplicationAfterPageLoad(timing = {}) { + return dispatch("turbo:load", { + detail: { url: this.location.href, timing } + }) + } + + notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL) { + dispatchEvent( + new HashChangeEvent("hashchange", { + oldURL: oldURL.toString(), + newURL: newURL.toString() + }) + ); + } + + notifyApplicationAfterFrameLoad(frame) { + return dispatch("turbo:frame-load", { target: frame }) + } + + notifyApplicationAfterFrameRender(fetchResponse, frame) { + return dispatch("turbo:frame-render", { + detail: { fetchResponse }, + target: frame, + cancelable: true + }) + } + + // Helpers + + submissionIsNavigatable(form, submitter) { + if (this.formMode == "off") { + return false + } else { + const submitterIsNavigatable = submitter ? this.elementIsNavigatable(submitter) : true; + + if (this.formMode == "optin") { + return submitterIsNavigatable && form.closest('[data-turbo="true"]') != null + } else { + return submitterIsNavigatable && this.elementIsNavigatable(form) + } + } + } + + elementIsNavigatable(element) { + const container = findClosestRecursively(element, "[data-turbo]"); + const withinFrame = findClosestRecursively(element, "turbo-frame"); + + // Check if Drive is enabled on the session or we're within a Frame. + if (this.drive || withinFrame) { + // Element is navigatable by default, unless `data-turbo="false"`. + if (container) { + return container.getAttribute("data-turbo") != "false" + } else { + return true + } + } else { + // Element isn't navigatable by default, unless `data-turbo="true"`. + if (container) { + return container.getAttribute("data-turbo") == "true" + } else { + return false + } + } + } + + // Private + + getActionForLink(link) { + return getVisitAction(link) || "advance" + } + + get snapshot() { + return this.view.snapshot + } +} + +// Older versions of the Turbo Native adapters referenced the +// `Location#absoluteURL` property in their implementations of +// the `Adapter#visitProposedToLocation()` and `#visitStarted()` +// methods. The Location class has since been removed in favor +// of the DOM URL API, and accordingly all Adapter methods now +// receive URL objects. +// +// We alias #absoluteURL to #toString() here to avoid crashing +// older adapters which do not expect URL objects. We should +// consider removing this support at some point in the future. + +function extendURLWithDeprecatedProperties(url) { + Object.defineProperties(url, deprecatedLocationPropertyDescriptors); +} + +const deprecatedLocationPropertyDescriptors = { + absoluteURL: { + get() { + return this.toString() + } + } +}; + +const session = new Session(recentRequests); +const { cache, navigator: navigator$1 } = session; + +/** + * Starts the main session. + * This initialises any necessary observers such as those to monitor + * link interactions. + */ +function start() { + session.start(); +} + +/** + * Registers an adapter for the main session. + * + * @param adapter Adapter to register + */ +function registerAdapter(adapter) { + session.registerAdapter(adapter); +} + +/** + * Performs an application visit to the given location. + * + * @param location Location to visit (a URL or path) + * @param options Options to apply + * @param options.action Type of history navigation to apply ("restore", + * "replace" or "advance") + * @param options.historyChanged Specifies whether the browser history has + * already been changed for this visit or not + * @param options.referrer Specifies the referrer of this visit such that + * navigations to the same page will not result in a new history entry. + * @param options.snapshotHTML Cached snapshot to render + * @param options.response Response of the specified location + */ +function visit(location, options) { + session.visit(location, options); +} + +/** + * Connects a stream source to the main session. + * + * @param source Stream source to connect + */ +function connectStreamSource(source) { + session.connectStreamSource(source); +} + +/** + * Disconnects a stream source from the main session. + * + * @param source Stream source to disconnect + */ +function disconnectStreamSource(source) { + session.disconnectStreamSource(source); +} + +/** + * Renders a stream message to the main session by appending it to the + * current document. + * + * @param message Message to render + */ +function renderStreamMessage(message) { + session.renderStreamMessage(message); +} + +/** + * Removes all entries from the Turbo Drive page cache. + * Call this when state has changed on the server that may affect cached pages. + * + * @deprecated since version 7.2.0 in favor of `Turbo.cache.clear()` + */ +function clearCache() { + console.warn( + "Please replace `Turbo.clearCache()` with `Turbo.cache.clear()`. The top-level function is deprecated and will be removed in a future version of Turbo.`" + ); + session.clearCache(); +} + +/** + * Sets the delay after which the progress bar will appear during navigation. + * + * The progress bar appears after 500ms by default. + * + * Note that this method has no effect when used with the iOS or Android + * adapters. + * + * @param delay Time to delay in milliseconds + */ +function setProgressBarDelay(delay) { + session.setProgressBarDelay(delay); +} + +function setConfirmMethod(confirmMethod) { + FormSubmission.confirmMethod = confirmMethod; +} + +function setFormMode(mode) { + session.setFormMode(mode); +} + +var Turbo = /*#__PURE__*/Object.freeze({ + __proto__: null, + navigator: navigator$1, + session: session, + cache: cache, + PageRenderer: PageRenderer, + PageSnapshot: PageSnapshot, + FrameRenderer: FrameRenderer, + fetch: fetchWithTurboHeaders, + start: start, + registerAdapter: registerAdapter, + visit: visit, + connectStreamSource: connectStreamSource, + disconnectStreamSource: disconnectStreamSource, + renderStreamMessage: renderStreamMessage, + clearCache: clearCache, + setProgressBarDelay: setProgressBarDelay, + setConfirmMethod: setConfirmMethod, + setFormMode: setFormMode +}); + +class TurboFrameMissingError extends Error {} + +class FrameController { + fetchResponseLoaded = (_fetchResponse) => Promise.resolve() + #currentFetchRequest = null + #resolveVisitPromise = () => {} + #connected = false + #hasBeenLoaded = false + #ignoredAttributes = new Set() + action = null + + constructor(element) { + this.element = element; + this.view = new FrameView(this, this.element); + this.appearanceObserver = new AppearanceObserver(this, this.element); + this.formLinkClickObserver = new FormLinkClickObserver(this, this.element); + this.linkInterceptor = new LinkInterceptor(this, this.element); + this.restorationIdentifier = uuid(); + this.formSubmitObserver = new FormSubmitObserver(this, this.element); + } + + // Frame delegate + + connect() { + if (!this.#connected) { + this.#connected = true; + if (this.loadingStyle == FrameLoadingStyle.lazy) { + this.appearanceObserver.start(); + } else { + this.#loadSourceURL(); + } + this.formLinkClickObserver.start(); + this.linkInterceptor.start(); + this.formSubmitObserver.start(); + } + } + + disconnect() { + if (this.#connected) { + this.#connected = false; + this.appearanceObserver.stop(); + this.formLinkClickObserver.stop(); + this.linkInterceptor.stop(); + this.formSubmitObserver.stop(); + } + } + + disabledChanged() { + if (this.loadingStyle == FrameLoadingStyle.eager) { + this.#loadSourceURL(); + } + } + + sourceURLChanged() { + if (this.#isIgnoringChangesTo("src")) return + + if (this.element.isConnected) { + this.complete = false; + } + + if (this.loadingStyle == FrameLoadingStyle.eager || this.#hasBeenLoaded) { + this.#loadSourceURL(); + } + } + + sourceURLReloaded() { + const { src } = this.element; + this.element.removeAttribute("complete"); + this.element.src = null; + this.element.src = src; + return this.element.loaded + } + + loadingStyleChanged() { + if (this.loadingStyle == FrameLoadingStyle.lazy) { + this.appearanceObserver.start(); + } else { + this.appearanceObserver.stop(); + this.#loadSourceURL(); + } + } + + async #loadSourceURL() { + if (this.enabled && this.isActive && !this.complete && this.sourceURL) { + this.element.loaded = this.#visit(expandURL(this.sourceURL)); + this.appearanceObserver.stop(); + await this.element.loaded; + this.#hasBeenLoaded = true; + } + } + + async loadResponse(fetchResponse) { + if (fetchResponse.redirected || (fetchResponse.succeeded && fetchResponse.isHTML)) { + this.sourceURL = fetchResponse.response.url; + } + + try { + const html = await fetchResponse.responseHTML; + if (html) { + const document = parseHTMLDocument(html); + const pageSnapshot = PageSnapshot.fromDocument(document); + + if (pageSnapshot.isVisitable) { + await this.#loadFrameResponse(fetchResponse, document); + } else { + await this.#handleUnvisitableFrameResponse(fetchResponse); + } + } + } finally { + this.fetchResponseLoaded = () => Promise.resolve(); + } + } + + // Appearance observer delegate + + elementAppearedInViewport(element) { + this.proposeVisitIfNavigatedWithAction(element, getVisitAction(element)); + this.#loadSourceURL(); + } + + // Form link click observer delegate + + willSubmitFormLinkToLocation(link) { + return this.#shouldInterceptNavigation(link) + } + + submittedFormLinkToLocation(link, _location, form) { + const frame = this.#findFrameElement(link); + if (frame) form.setAttribute("data-turbo-frame", frame.id); + } + + // Link interceptor delegate + + shouldInterceptLinkClick(element, _location, _event) { + return this.#shouldInterceptNavigation(element) + } + + linkClickIntercepted(element, location) { + this.#navigateFrame(element, location); + } + + // Form submit observer delegate + + willSubmitForm(element, submitter) { + return element.closest("turbo-frame") == this.element && this.#shouldInterceptNavigation(element, submitter) + } + + formSubmitted(element, submitter) { + if (this.formSubmission) { + this.formSubmission.stop(); + } + + this.formSubmission = new FormSubmission(this, element, submitter); + const { fetchRequest } = this.formSubmission; + this.prepareRequest(fetchRequest); + this.formSubmission.start(); + } + + // Fetch request delegate + + prepareRequest(request) { + request.headers["Turbo-Frame"] = this.id; + + if (this.currentNavigationElement?.hasAttribute("data-turbo-stream")) { + request.acceptResponseType(StreamMessage.contentType); + } + } + + requestStarted(_request) { + markAsBusy(this.element); + } + + requestPreventedHandlingResponse(_request, _response) { + this.#resolveVisitPromise(); + } + + async requestSucceededWithResponse(request, response) { + await this.loadResponse(response); + this.#resolveVisitPromise(); + } + + async requestFailedWithResponse(request, response) { + await this.loadResponse(response); + this.#resolveVisitPromise(); + } + + requestErrored(request, error) { + console.error(error); + this.#resolveVisitPromise(); + } + + requestFinished(_request) { + clearBusyState(this.element); + } + + // Form submission delegate + + formSubmissionStarted({ formElement }) { + markAsBusy(formElement, this.#findFrameElement(formElement)); + } + + formSubmissionSucceededWithResponse(formSubmission, response) { + const frame = this.#findFrameElement(formSubmission.formElement, formSubmission.submitter); + + frame.delegate.proposeVisitIfNavigatedWithAction(frame, getVisitAction(formSubmission.submitter, formSubmission.formElement, frame)); + frame.delegate.loadResponse(response); + + if (!formSubmission.isSafe) { + session.clearCache(); + } + } + + formSubmissionFailedWithResponse(formSubmission, fetchResponse) { + this.element.delegate.loadResponse(fetchResponse); + session.clearCache(); + } + + formSubmissionErrored(formSubmission, error) { + console.error(error); + } + + formSubmissionFinished({ formElement }) { + clearBusyState(formElement, this.#findFrameElement(formElement)); + } + + // View delegate + + allowsImmediateRender({ element: newFrame }, options) { + const event = dispatch("turbo:before-frame-render", { + target: this.element, + detail: { newFrame, ...options }, + cancelable: true + }); + const { + defaultPrevented, + detail: { render } + } = event; + + if (this.view.renderer && render) { + this.view.renderer.renderElement = render; + } + + return !defaultPrevented + } + + viewRenderedSnapshot(_snapshot, _isPreview, _renderMethod) {} + + preloadOnLoadLinksForView(element) { + session.preloadOnLoadLinksForView(element); + } + + viewInvalidated() {} + + // Frame renderer delegate + + willRenderFrame(currentElement, _newElement) { + this.previousFrameElement = currentElement.cloneNode(true); + } + + visitCachedSnapshot = ({ element }) => { + const frame = element.querySelector("#" + this.element.id); + + if (frame && this.previousFrameElement) { + frame.replaceChildren(...this.previousFrameElement.children); + } + + delete this.previousFrameElement; + } + + // Private + + async #loadFrameResponse(fetchResponse, document) { + const newFrameElement = await this.extractForeignFrameElement(document.body); + + if (newFrameElement) { + const snapshot = new Snapshot(newFrameElement); + const renderer = new FrameRenderer(this, this.view.snapshot, snapshot, FrameRenderer.renderElement, false, false); + if (this.view.renderPromise) await this.view.renderPromise; + this.changeHistory(); + + await this.view.render(renderer); + this.complete = true; + session.frameRendered(fetchResponse, this.element); + session.frameLoaded(this.element); + await this.fetchResponseLoaded(fetchResponse); + } else if (this.#willHandleFrameMissingFromResponse(fetchResponse)) { + this.#handleFrameMissingFromResponse(fetchResponse); + } + } + + async #visit(url) { + const request = new FetchRequest(this, FetchMethod.get, url, new URLSearchParams(), this.element); + + this.#currentFetchRequest?.cancel(); + this.#currentFetchRequest = request; + + return new Promise((resolve) => { + this.#resolveVisitPromise = () => { + this.#resolveVisitPromise = () => {}; + this.#currentFetchRequest = null; + resolve(); + }; + request.perform(); + }) + } + + #navigateFrame(element, url, submitter) { + const frame = this.#findFrameElement(element, submitter); + + frame.delegate.proposeVisitIfNavigatedWithAction(frame, getVisitAction(submitter, element, frame)); + + this.#withCurrentNavigationElement(element, () => { + frame.src = url; + }); + } + + proposeVisitIfNavigatedWithAction(frame, action = null) { + this.action = action; + + if (this.action) { + const pageSnapshot = PageSnapshot.fromElement(frame).clone(); + const { visitCachedSnapshot } = frame.delegate; + + frame.delegate.fetchResponseLoaded = async (fetchResponse) => { + if (frame.src) { + const { statusCode, redirected } = fetchResponse; + const responseHTML = await fetchResponse.responseHTML; + const response = { statusCode, redirected, responseHTML }; + const options = { + response, + visitCachedSnapshot, + willRender: false, + updateHistory: false, + restorationIdentifier: this.restorationIdentifier, + snapshot: pageSnapshot + }; + + if (this.action) options.action = this.action; + + session.visit(frame.src, options); + } + }; + } + } + + changeHistory() { + if (this.action) { + const method = getHistoryMethodForAction(this.action); + session.history.update(method, expandURL(this.element.src || ""), this.restorationIdentifier); + } + } + + async #handleUnvisitableFrameResponse(fetchResponse) { + console.warn( + `The response (${fetchResponse.statusCode}) from is performing a full page visit due to turbo-visit-control.` + ); + + await this.#visitResponse(fetchResponse.response); + } + + #willHandleFrameMissingFromResponse(fetchResponse) { + this.element.setAttribute("complete", ""); + + const response = fetchResponse.response; + const visit = async (url, options) => { + if (url instanceof Response) { + this.#visitResponse(url); + } else { + session.visit(url, options); + } + }; + + const event = dispatch("turbo:frame-missing", { + target: this.element, + detail: { response, visit }, + cancelable: true + }); + + return !event.defaultPrevented + } + + #handleFrameMissingFromResponse(fetchResponse) { + this.view.missing(); + this.#throwFrameMissingError(fetchResponse); + } + + #throwFrameMissingError(fetchResponse) { + const message = `The response (${fetchResponse.statusCode}) did not contain the expected and will be ignored. To perform a full page visit instead, set turbo-visit-control to reload.`; + throw new TurboFrameMissingError(message) + } + + async #visitResponse(response) { + const wrapped = new FetchResponse(response); + const responseHTML = await wrapped.responseHTML; + const { location, redirected, statusCode } = wrapped; + + return session.visit(location, { response: { redirected, statusCode, responseHTML } }) + } + + #findFrameElement(element, submitter) { + const id = getAttribute("data-turbo-frame", submitter, element) || this.element.getAttribute("target"); + return getFrameElementById(id) ?? this.element + } + + async extractForeignFrameElement(container) { + let element; + const id = CSS.escape(this.id); + + try { + element = activateElement(container.querySelector(`turbo-frame#${id}`), this.sourceURL); + if (element) { + return element + } + + element = activateElement(container.querySelector(`turbo-frame[src][recurse~=${id}]`), this.sourceURL); + if (element) { + await element.loaded; + return await this.extractForeignFrameElement(element) + } + } catch (error) { + console.error(error); + return new FrameElement() + } + + return null + } + + #formActionIsVisitable(form, submitter) { + const action = getAction$1(form, submitter); + + return locationIsVisitable(expandURL(action), this.rootLocation) + } + + #shouldInterceptNavigation(element, submitter) { + const id = getAttribute("data-turbo-frame", submitter, element) || this.element.getAttribute("target"); + + if (element instanceof HTMLFormElement && !this.#formActionIsVisitable(element, submitter)) { + return false + } + + if (!this.enabled || id == "_top") { + return false + } + + if (id) { + const frameElement = getFrameElementById(id); + if (frameElement) { + return !frameElement.disabled + } + } + + if (!session.elementIsNavigatable(element)) { + return false + } + + if (submitter && !session.elementIsNavigatable(submitter)) { + return false + } + + return true + } + + // Computed properties + + get id() { + return this.element.id + } + + get enabled() { + return !this.element.disabled + } + + get sourceURL() { + if (this.element.src) { + return this.element.src + } + } + + set sourceURL(sourceURL) { + this.#ignoringChangesToAttribute("src", () => { + this.element.src = sourceURL ?? null; + }); + } + + get loadingStyle() { + return this.element.loading + } + + get isLoading() { + return this.formSubmission !== undefined || this.#resolveVisitPromise() !== undefined + } + + get complete() { + return this.element.hasAttribute("complete") + } + + set complete(value) { + if (value) { + this.element.setAttribute("complete", ""); + } else { + this.element.removeAttribute("complete"); + } + } + + get isActive() { + return this.element.isActive && this.#connected + } + + get rootLocation() { + const meta = this.element.ownerDocument.querySelector(`meta[name="turbo-root"]`); + const root = meta?.content ?? "/"; + return expandURL(root) + } + + #isIgnoringChangesTo(attributeName) { + return this.#ignoredAttributes.has(attributeName) + } + + #ignoringChangesToAttribute(attributeName, callback) { + this.#ignoredAttributes.add(attributeName); + callback(); + this.#ignoredAttributes.delete(attributeName); + } + + #withCurrentNavigationElement(element, callback) { + this.currentNavigationElement = element; + callback(); + delete this.currentNavigationElement; + } +} + +function getFrameElementById(id) { + if (id != null) { + const element = document.getElementById(id); + if (element instanceof FrameElement) { + return element + } + } +} + +function activateElement(element, currentURL) { + if (element) { + const src = element.getAttribute("src"); + if (src != null && currentURL != null && urlsAreEqual(src, currentURL)) { + throw new Error(`Matching element has a source URL which references itself`) + } + if (element.ownerDocument !== document) { + element = document.importNode(element, true); + } + + if (element instanceof FrameElement) { + element.connectedCallback(); + element.disconnectedCallback(); + return element + } + } +} + +const StreamActions = { + after() { + this.targetElements.forEach((e) => e.parentElement?.insertBefore(this.templateContent, e.nextSibling)); + }, + + append() { + this.removeDuplicateTargetChildren(); + this.targetElements.forEach((e) => e.append(this.templateContent)); + }, + + before() { + this.targetElements.forEach((e) => e.parentElement?.insertBefore(this.templateContent, e)); + }, + + prepend() { + this.removeDuplicateTargetChildren(); + this.targetElements.forEach((e) => e.prepend(this.templateContent)); + }, + + remove() { + this.targetElements.forEach((e) => e.remove()); + }, + + replace() { + const method = this.getAttribute("method"); + + this.targetElements.forEach((targetElement) => { + if (method === "morph") { + morphElements(targetElement, this.templateContent); + } else { + targetElement.replaceWith(this.templateContent); + } + }); + }, + + update() { + const method = this.getAttribute("method"); + + this.targetElements.forEach((targetElement) => { + if (method === "morph") { + morphChildren(targetElement, this.templateContent); + } else { + targetElement.innerHTML = ""; + targetElement.append(this.templateContent); + } + }); + }, + + refresh() { + session.refresh(this.baseURI, this.requestId); + } +}; + +//