summaryrefslogtreecommitdiffstats
path: root/vendor
diff options
context:
space:
mode:
authorStefan Suhren <suhren.stefan@fh-swf.de>2015-05-05 19:34:39 +0200
committerStefan Suhren <suhren.stefan@fh-swf.de>2015-05-05 19:34:39 +0200
commit705c4cb50eea66585cc95c7314001fce9dd197cd (patch)
tree4a448f4e30b117e12306b643121f49da15e6376b /vendor
downloadCatalog-705c4cb50eea66585cc95c7314001fce9dd197cd.tar.gz
Catalog-705c4cb50eea66585cc95c7314001fce9dd197cd.zip
Initial commit
Diffstat (limited to 'vendor')
-rw-r--r--vendor/autoload.php7
-rwxr-xr-xvendor/bin/propel4
-rw-r--r--vendor/composer/ClassLoader.php413
-rw-r--r--vendor/composer/autoload_classmap.php29
-rw-r--r--vendor/composer/autoload_namespaces.php18
-rw-r--r--vendor/composer/autoload_psr4.php9
-rw-r--r--vendor/composer/autoload_real.php50
-rw-r--r--vendor/composer/installed.json513
m---------vendor/propel/propel0
-rw-r--r--vendor/psr/log/.gitignore1
-rw-r--r--vendor/psr/log/LICENSE19
-rw-r--r--vendor/psr/log/Psr/Log/AbstractLogger.php120
-rw-r--r--vendor/psr/log/Psr/Log/InvalidArgumentException.php7
-rw-r--r--vendor/psr/log/Psr/Log/LogLevel.php18
-rw-r--r--vendor/psr/log/Psr/Log/LoggerAwareInterface.php17
-rw-r--r--vendor/psr/log/Psr/Log/LoggerAwareTrait.php22
-rw-r--r--vendor/psr/log/Psr/Log/LoggerInterface.php114
-rw-r--r--vendor/psr/log/Psr/Log/LoggerTrait.php131
-rw-r--r--vendor/psr/log/Psr/Log/NullLogger.php27
-rw-r--r--vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php116
-rw-r--r--vendor/psr/log/README.md45
-rw-r--r--vendor/psr/log/composer.json17
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/.gitignore3
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/CHANGELOG.md21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/ConfigCache.php126
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/ArrayNode.php393
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/BaseNode.php360
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/BooleanNode.php42
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php489
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php42
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php58
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ExprBuilder.php238
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php32
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php32
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/MergeBuilder.php72
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeBuilder.php245
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeDefinition.php343
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php67
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php61
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php26
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php32
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/TreeBuilder.php63
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php51
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php64
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/ConfigurationInterface.php27
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php300
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php198
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/EnumNode.php58
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php22
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/Exception.php21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php22
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php49
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php22
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/FloatNode.php43
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/IntegerNode.php38
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/NodeInterface.php88
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/NumericNode.php55
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Processor.php97
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/PrototypeNodeInterface.php27
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/PrototypedArrayNode.php331
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/ReferenceDumper.php21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/ScalarNode.php49
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/VariableNode.php119
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php27
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderLoadException.php100
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/FileLocator.php95
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/FileLocatorInterface.php31
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/LICENSE19
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Loader/DelegatingLoader.php55
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Loader/FileLoader.php124
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Loader/Loader.php78
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Loader/LoaderInterface.php54
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolver.php75
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolverInterface.php30
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/README.md17
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Resource/DirectoryResource.php99
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Resource/FileResource.php75
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Resource/ResourceInterface.php43
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/ConfigCacheTest.php138
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php160
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php60
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php207
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php46
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php215
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php94
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php93
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php126
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php80
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php67
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php41
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FinalizationTest.php73
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php64
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php61
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/MergeTest.php195
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/NormalizationTest.php229
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php180
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php79
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Exception/FileLoaderLoadExceptionTest.php83
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/FileLocatorTest.php119
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml0
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php34
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php18
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php71
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/document_type.xml3
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid.xml2
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid_schema.xml2
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/schema.xsd9
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/valid.xml3
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/foo.xml0
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php83
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php106
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php56
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderTest.php117
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php152
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Resource/FileResourceTest.php61
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php197
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Util/XmlUtils.php238
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/composer.json35
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/phpunit.xml.dist28
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/.gitignore3
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Application.php1173
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/CHANGELOG.md62
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Command/Command.php661
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Command/HelpCommand.php91
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Command/ListCommand.php95
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/ConsoleEvents.php61
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Descriptor/ApplicationDescription.php155
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.php121
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.php31
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php167
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php141
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php255
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php266
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Event/ConsoleCommandEvent.php62
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Event/ConsoleEvent.php67
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php67
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Event/ConsoleTerminateEvent.php58
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatter.php241
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterInterface.php83
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyle.php227
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php72
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php121
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/DebugFormatterHelper.php127
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php96
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/DialogHelper.php476
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/FormatterHelper.php82
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/Helper.php121
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/HelperInterface.php49
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/HelperSet.php108
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/InputAwareHelper.php33
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/ProcessHelper.php142
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/ProgressBar.php611
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/ProgressHelper.php457
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/QuestionHelper.php418
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/Table.php410
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/TableHelper.php263
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/TableSeparator.php21
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Helper/TableStyle.php251
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Input/ArgvInput.php353
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Input/ArrayInput.php211
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Input/Input.php226
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Input/InputArgument.php132
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Input/InputAwareInterface.php28
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Input/InputDefinition.php453
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Input/InputInterface.php152
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Input/InputOption.php213
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Input/StringInput.php83
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/LICENSE19
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Logger/ConsoleLogger.php118
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Output/BufferedOutput.php48
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutput.php113
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutputInterface.php35
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Output/NullOutput.php113
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Output/Output.php165
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Output/OutputInterface.php113
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Output/StreamOutput.php103
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Question/ChoiceQuestion.php150
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Question/ConfirmationQuestion.php55
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Question/Question.php238
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/README.md67
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Resources/bin/hiddeninput.exebin0 -> 9216 bytes
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Shell.php228
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php128
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tester/CommandTester.php132
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/ApplicationTest.php1060
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Command/CommandTest.php348
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Command/HelpCommandTest.php64
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Command/ListCommandTest.php64
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php105
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/JsonDescriptorTest.php27
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/MarkdownDescriptorTest.php27
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php74
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/TextDescriptorTest.php27
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/XmlDescriptorTest.php27
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/BarBucCommand.php11
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication1.php18
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication2.php24
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand1.php27
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand2.php30
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DummyOutput.php36
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo1Command.php26
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo2Command.php21
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php29
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo4Command.php11
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo5Command.php10
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooCommand.php33
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooSubnamespaced1Command.php26
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooSubnamespaced2Command.php26
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FoobarCommand.php25
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/TestCommand.php28
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md199
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.txt17
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml108
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md388
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.txt22
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml185
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt20
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt16
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt144
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml2.txt37
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_gethelp.txt1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception1.txt8
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception2.txt11
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt27
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt27
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception4.txt9
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1.txt11
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txt11
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth2.txt12
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run1.txt17
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run2.txt29
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run3.txt27
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run4.txt1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.md8
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.txt7
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.xml12
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.md30
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.txt11
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.xml18
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_astext.txt18
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_asxml.txt38
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_astext.txt11
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_asxml.txt39
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.md7
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.txt1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.xml5
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.md7
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.txt1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.xml5
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.md7
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.txt1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.xml7
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.md0
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.txt0
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.xml5
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.md9
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.txt2
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.xml10
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.md11
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.txt2
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.xml9
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.md21
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.txt5
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.xml14
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.md9
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.txt1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.xml4
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.md9
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.txt1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.xml7
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.md9
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.txt1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.xml5
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.json1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.md9
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.txt1
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.xml5
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php70
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleTest.php93
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php257
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Helper/FormatterHelperTest.php99
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php153
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyDialogHelperTest.php200
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyProgressHelperTest.php232
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyTableHelperTest.php325
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php118
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php598
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php238
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Helper/TableTest.php357
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArgvInputTest.php317
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArrayInputTest.php138
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputArgumentTest.php111
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php430
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputOptionTest.php204
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputTest.php121
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Input/StringInputTest.php101
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Logger/ConsoleLoggerTest.php58
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php25
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Output/NullOutputTest.php39
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Output/OutputTest.php156
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Output/StreamOutputTest.php60
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php69
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php84
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/composer.json42
-rw-r--r--vendor/symfony/console/Symfony/Component/Console/phpunit.xml.dist28
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/.gitignore3
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/CHANGELOG.md28
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/ExceptionInterface.php23
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/FileNotFoundException.php34
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOException.php41
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOExceptionInterface.php27
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/Filesystem.php497
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/LICENSE19
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/LockHandler.php111
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/README.md47
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/ExceptionTest.php46
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTest.php998
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php131
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/LockHandlerTest.php85
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/composer.json34
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/phpunit.xml.dist26
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/.gitignore3
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php236
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php327
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php144
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php103
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php104
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php98
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/CHANGELOG.md34
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Comparator/Comparator.php98
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Comparator/DateComparator.php53
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.php81
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php19
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php46
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.php23
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php19
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php45
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Expression/Expression.php146
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Expression/Glob.php157
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Expression/Regex.php321
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Expression/ValueInterface.php60
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Finder.php840
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Glob.php103
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php63
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php60
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php47
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php55
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php131
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php55
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php76
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php67
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.php49
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php66
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.php74
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php126
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php59
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.php82
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/LICENSE19
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/README.md53
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Shell/Command.php294
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Shell/Shell.php97
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/SplFileInfo.php77
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/ComparatorTest.php64
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/DateComparatorTest.php63
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/NumberComparatorTest.php107
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/ExpressionTest.php68
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/GlobTest.php47
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/RegexTest.php143
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/DummyAdapter.php57
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/FailingAdapter.php45
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/NamedAdapter.php57
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/UnsupportedAdapter.php44
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/FinderTest.php869
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/C/abc.dat0
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/ab.dat0
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/a.dat0
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy0
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/ab.dat.copy0
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/a.dat.copy0
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/dolor.txt2
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/ipsum.txt2
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/lorem.txt2
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/a0
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/c.neon0
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/d.neon0
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.dat0
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/with space/foo.txt0
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php46
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DateRangeFilterIteratorTest.php72
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php80
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php64
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php69
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php72
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php86
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilenameFilterIteratorTest.php54
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php50
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/Iterator.php55
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php98
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockFileListIterator.php21
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php134
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php67
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/PathFilterIteratorTest.php83
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RealIteratorTestCase.php109
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php83
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SizeRangeFilterIteratorTest.php68
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php169
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/composer.json34
-rw-r--r--vendor/symfony/finder/Symfony/Component/Finder/phpunit.xml.dist27
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/.gitignore3
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/CHANGELOG.md42
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Catalogue/AbstractOperation.php146
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Catalogue/DiffOperation.php55
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Catalogue/MergeOperation.php51
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Catalogue/OperationInterface.php63
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Dumper/CsvFileDumper.php63
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Dumper/DumperInterface.php31
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Dumper/FileDumper.php122
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Dumper/IcuResFileDumper.php112
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Dumper/IniFileDumper.php45
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Dumper/JsonFileDumper.php42
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Dumper/MoFileDumper.php82
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Dumper/PhpFileDumper.php40
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Dumper/PoFileDumper.php61
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Dumper/QtFileDumper.php50
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Dumper/XliffFileDumper.php109
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Dumper/YamlFileDumper.php39
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Exception/ExceptionInterface.php23
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Exception/InvalidResourceException.php23
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Exception/NotFoundResourceException.php23
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Extractor/ChainExtractor.php60
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Extractor/ExtractorInterface.php38
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/IdentityTranslator.php77
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Interval.php107
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/LICENSE19
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/ArrayLoader.php70
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/CsvFileLoader.php92
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/IcuDatFileLoader.php59
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/IcuResFileLoader.php89
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/IniFileLoader.php45
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/JsonFileLoader.php78
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/LoaderInterface.php42
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/MoFileLoader.php188
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/PhpFileLoader.php49
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/PoFileLoader.php177
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/QtFileLoader.php78
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/XliffFileLoader.php185
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/YamlFileLoader.php71
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd2223
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xml.xsd309
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/LoggingTranslator.php132
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/MessageCatalogue.php293
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/MessageCatalogueInterface.php172
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/MessageSelector.php90
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/MetadataAwareInterface.php54
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/PluralizationRules.php214
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/README.md37
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/AbstractOperationTest.php73
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/DiffOperationTest.php82
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/MergeOperationTest.php83
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/CsvFileDumperTest.php33
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php70
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/IcuResFileDumperTest.php38
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/IniFileDumperTest.php32
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/JsonFileDumperTest.php36
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/MoFileDumperTest.php31
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/PhpFileDumperTest.php32
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/PoFileDumperTest.php31
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/QtFileDumperTest.php32
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php41
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/YamlFileDumperTest.php32
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php95
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/IntervalTest.php48
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/CsvFileLoaderTest.php60
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IcuDatFileLoaderTest.php68
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IcuResFileLoaderTest.php55
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IniFileLoaderTest.php50
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/JsonFileLoaderTest.php68
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/LocalizedTestCase.php22
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/MoFileLoaderTest.php71
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/PhpFileLoaderTest.php49
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/PoFileLoaderTest.php96
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/QtFileLoaderTest.php67
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php142
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/YamlFileLoaderTest.php70
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/LoggingTranslatorTest.php56
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/MessageCatalogueTest.php200
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/MessageSelectorTest.php98
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/PluralizationRulesTest.php123
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/TranslatorCacheTest.php231
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/TranslatorTest.php604
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty-translation.mobin0 -> 49 bytes
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty-translation.po3
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.csv0
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.ini0
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.json0
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.mo0
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.po0
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.xlf0
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.yml0
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/encoding.xlf16
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/escaped-id-plurals.po10
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/escaped-id.po8
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/invalid-xml-resources.xlf23
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/malformed.json3
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/non-valid.xlf11
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/non-valid.yml1
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/plurals.mobin0 -> 74 bytes
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/plurals.po5
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resname.xlf19
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/corrupted/resources.dat1
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.resbin0 -> 120 bytes
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.txt3
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.resbin0 -> 124 bytes
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.txt3
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/packagelist.txt2
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/resources.datbin0 -> 352 bytes
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/res/en.resbin0 -> 84 bytes
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources-clean.xlf22
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.csv4
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.ini1
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.json3
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.mobin0 -> 52 bytes
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.php5
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.po8
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.ts10
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.xlf23
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.yml1
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/valid.csv4
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/withdoctype.xlf12
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/withnote.xlf22
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Translator.php466
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/TranslatorBagInterface.php29
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/TranslatorInterface.php75
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/Writer/TranslationWriter.php87
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/composer.json43
-rw-r--r--vendor/symfony/translation/Symfony/Component/Translation/phpunit.xml.dist28
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/.gitignore3
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/CHANGELOG.md159
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ClassBasedInterface.php30
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraint.php321
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidator.php216
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactory.php51
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactoryInterface.php29
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorInterface.php37
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolation.php233
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationInterface.php136
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationList.php159
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationListInterface.php83
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/AbstractComparison.php49
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php74
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/All.php40
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/AllValidator.php58
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Blank.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/BlankValidator.php40
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Callback.php77
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/CallbackValidator.php76
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardScheme.php47
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardSchemeValidator.php122
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Choice.php54
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/ChoiceValidator.php103
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection.php87
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Optional.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Required.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/CollectionValidator.php94
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Composite.php152
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Count.php56
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountValidator.php60
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Country.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountryValidator.php54
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Currency.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/CurrencyValidator.php54
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Date.php35
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTime.php37
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTimeValidator.php68
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateValidator.php78
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Email.php40
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/EmailValidator.php130
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/EqualTo.php23
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/EqualToValidator.php28
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Existence.php30
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Expression.php59
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/ExpressionValidator.php117
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/False.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/FalseValidator.php42
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/File.php86
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/FileValidator.php240
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThan.php23
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanOrEqual.php23
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanOrEqualValidator.php28
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanValidator.php28
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequence.php196
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php22
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Iban.php41
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/IbanValidator.php143
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/IdenticalTo.php23
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/IdenticalToValidator.php28
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Image.php81
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/ImageValidator.php182
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Ip.php82
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/IpValidator.php103
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Isbn.php65
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/IsbnValidator.php192
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Issn.php44
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/IssnValidator.php132
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Language.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/LanguageValidator.php54
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Length.php58
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/LengthValidator.php98
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThan.php23
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanOrEqual.php23
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanOrEqualValidator.php28
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanValidator.php28
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Locale.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/LocaleValidator.php54
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Luhn.php37
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/LuhnValidator.php96
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlank.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlankValidator.php40
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotEqualTo.php23
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotEqualToValidator.php28
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotIdenticalTo.php23
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotIdenticalToValidator.php28
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNull.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNullValidator.php38
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Null.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/NullValidator.php40
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Optional.php22
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Range.php51
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/RangeValidator.php80
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Regex.php98
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/RegexValidator.php53
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Required.php22
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Time.php35
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/TimeValidator.php78
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Traverse.php54
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/True.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/TrueValidator.php44
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Type.php44
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/TypeValidator.php56
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Url.php28
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/UrlValidator.php67
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Uuid.php77
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/UuidValidator.php264
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Constraints/Valid.php45
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContext.php404
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextFactory.php64
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextFactoryInterface.php37
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextInterface.php226
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Context/LegacyExecutionContext.php156
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Context/LegacyExecutionContextFactory.php73
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/DefaultTranslator.php167
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/BadMethodCallException.php21
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/ConstraintDefinitionException.php16
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/ExceptionInterface.php21
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/GroupDefinitionException.php16
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/InvalidArgumentException.php21
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/InvalidOptionsException.php29
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/MappingException.php16
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/MissingOptionsException.php29
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/NoSuchMetadataException.php19
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/OutOfBoundsException.php21
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/RuntimeException.php21
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/UnexpectedTypeException.php20
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/UnsupportedMetadataException.php20
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Exception/ValidatorException.php16
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ExecutionContext.php293
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ExecutionContextInterface.php329
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/GlobalExecutionContextInterface.php71
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/GroupSequenceProviderInterface.php26
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/LICENSE19
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/BlackholeMetadataFactory.php24
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/ApcCache.php55
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/CacheInterface.php45
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/DoctrineCache.php69
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/CascadingStrategy.php53
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadata.php548
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactory.php26
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataInterface.php80
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/ElementMetadata.php24
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/BlackHoleMetadataFactory.php40
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php153
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/MetadataFactoryInterface.php24
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/GenericMetadata.php243
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/GetterMetadata.php77
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php91
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php95
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FileLoader.php56
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php61
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php62
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.php31
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php71
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php219
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFilesLoader.php31
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php179
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFilesLoader.php31
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd160
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/MemberMetadata.php251
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/MetadataInterface.php58
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/PropertyMetadata.php71
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/PropertyMetadataInterface.php36
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Mapping/TraversalStrategy.php66
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/MetadataFactoryInterface.php43
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/MetadataInterface.php73
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ObjectInitializerInterface.php35
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataContainerInterface.php45
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataInterface.php47
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/README.md126
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.af.xlf227
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ar.xlf283
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.az.xlf227
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.bg.xlf283
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ca.xlf307
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.cs.xlf307
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.cy.xlf227
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.da.xlf247
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.de.xlf311
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.el.xlf283
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.en.xlf311
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.es.xlf311
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.et.xlf283
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.eu.xlf283
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fa.xlf283
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fi.xlf227
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fr.xlf311
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.gl.xlf315
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.he.xlf307
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hr.xlf283
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hu.xlf311
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hy.xlf187
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.id.xlf283
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.it.xlf307
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ja.xlf315
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.lb.xlf303
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.lt.xlf307
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.mn.xlf151
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.nb.xlf155
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.nl.xlf311
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.no.xlf227
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pl.xlf311
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pt.xlf307
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pt_BR.xlf315
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ro.xlf283
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ru.xlf311
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sk.xlf307
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sl.xlf311
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sq.xlf227
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sr_Cyrl.xlf303
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sr_Latn.xlf303
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sv.xlf307
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.th.xlf303
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.tr.xlf227
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.uk.xlf283
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.vi.xlf283
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf283
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.zh_TW.xlf283
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintTest.php209
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationListTest.php134
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationTest.php55
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php173
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AbstractConstraintValidatorTest.php545
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllTest.php41
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php93
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.php69
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php336
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php133
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ChoiceValidatorTest.php287
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionTest.php112
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayObjectTest.php20
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayTest.php20
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorCustomArrayObjectTest.php22
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php389
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CompositeTest.php137
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorArrayTest.php23
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorCountableTest.php25
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorTest.php203
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php116
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php116
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php110
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php106
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php105
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php69
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php214
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FalseValidatorTest.php56
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileTest.php107
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorObjectTest.php22
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorPathTest.php36
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php477
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/foo0
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test.gifbin0 -> 801 bytes
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_4by3.gifbin0 -> 57 bytes
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_landscape.gifbin0 -> 43 bytes
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_portrait.gifbin0 -> 43 bytes
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GreaterThanOrEqualValidatorTest.php71
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php74
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GroupSequenceTest.php84
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php193
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php89
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php329
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php444
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IsbnValidatorTest.php271
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IssnValidatorTest.php187
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php114
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyAllValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyAllValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyBlankValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyBlankValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCallbackValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCallbackValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCardSchemeValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCardSchemeValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyChoiceValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyChoiceValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArray2Dot4ApiTest.php25
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayLegacyApiTest.php25
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayObject2Dot4ApiTest.php25
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayObjectLegacyApiTest.php25
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorCustomArrayObject2Dot4ApiTest.php25
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorCustomArrayObjectLegacyApiTest.php25
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorArray2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorArrayLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorCountable2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorCountableLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCurrencyValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCurrencyValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateTimeValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateTimeValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEmailValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEmailValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEqualToValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEqualToValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyExpressionValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyExpressionValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFalseValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFalseValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorObject2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorObjectLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorPath2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorPathLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanOrEqualValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanOrEqualValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIbanValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIbanValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIdenticalToValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIdenticalToValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyImageValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyImageValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIpValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIpValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIsbnValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIsbnValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIssnValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIssnValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLanguageValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLanguageValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLengthValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLengthValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanOrEqualValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanOrEqualValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLocaleValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLocaleValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLuhnValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLuhnValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotBlankValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotBlankValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotEqualToValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotEqualToValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotIdenticalToValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotIdenticalToValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotNullValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotNullValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNullValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNullValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRangeValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRangeValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRegexValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRegexValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTimeValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTimeValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTrueValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTrueValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTypeValidator2Dot4ApiTest.php37
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTypeValidatorLegacyApiTest.php29
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUrlValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUrlValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUuidValidator2Dot4ApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUuidValidatorLegacyApiTest.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LengthValidatorTest.php255
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php74
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php73
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.php104
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LuhnValidatorTest.php127
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php102
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php69
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php92
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.php60
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NullValidatorTest.php66
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php403
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RegexTest.php87
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.php97
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TimeValidatorTest.php107
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TrueValidatorTest.php56
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php185
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php179
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/UuidValidatorTest.php211
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ValidTest.php28
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/CallbackClass.php24
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ClassConstraint.php22
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintA.php31
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintAValidator.php37
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintB.php23
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintC.php30
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithValue.php31
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithValueAsDefault.php31
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Countable.php27
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/CustomArrayObject.php70
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Entity.php100
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityInterface.php16
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php31
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraint.php24
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraintValidator.php23
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FakeClassMetadata.php26
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FakeMetadataFactory.php72
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FilesLoader.php39
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderEntity.php36
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraint.php18
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraintValidator.php16
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/LegacyClassMetadata.php20
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/PropertyConstraint.php22
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Reference.php29
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/StubGlobalExecutionContext.php72
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/LegacyExecutionContextTest.php336
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Cache/DoctrineCacheTest.php84
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Cache/LegacyApcCacheTest.php83
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php280
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Factory/BlackHoleMetadataFactoryTest.php33
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php118
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php62
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/LegacyElementMetadataTest.php80
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AbstractStaticMethodLoader.php10
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php172
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/FilesLoaderTest.php48
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/LoaderChainTest.php84
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/StaticMethodLoaderTest.php143
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php133
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php123
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping-non-strings.xml19
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml119
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml62
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/empty-mapping.yml0
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/nonvalid-mapping.yml1
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/withdoctype.xml7
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.php110
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php45
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Util/PropertyPathTest.php35
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php776
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/AbstractLegacyApiTest.php315
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/AbstractValidatorTest.php1288
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/LegacyValidator2Dot5ApiTest.php41
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/LegacyValidatorLegacyApiTest.php41
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/RecursiveValidator2Dot5ApiTest.php29
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php160
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorTest.php36
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Util/PropertyPath.php57
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Validation.php66
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitor.php210
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitorInterface.php86
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Validator.php235
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Validator/ContextualValidatorInterface.php89
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Validator/LegacyValidator.php79
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php866
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Validator/RecursiveValidator.php140
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Validator/ValidatorInterface.php100
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilder.php412
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilderInterface.php193
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/ValidatorInterface.php114
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php225
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Violation/ConstraintViolationBuilderInterface.php115
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/Violation/LegacyConstraintViolationBuilder.php164
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/composer.json56
-rw-r--r--vendor/symfony/validator/Symfony/Component/Validator/phpunit.xml.dist28
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/.gitignore3
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/CHANGELOG.md8
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Dumper.php73
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Escaper.php97
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.php23
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.php23
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.php148
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.php23
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Inline.php546
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/LICENSE19
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php697
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/README.md21
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/DumperTest.php236
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsAnchorAlias.yml31
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBasicTests.yml202
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBlockMapping.yml51
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsDocumentSeparator.yml85
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsErrorTests.yml25
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsFlowCollections.yml60
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsFoldedScalars.yml176
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsNullsAndEmpties.yml45
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml1697
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsTypeTransfers.yml244
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/embededPhp.yml1
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/escapedCharacters.yml147
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/index.yml18
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfComments.yml73
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfCompact.yml159
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfMergeKey.yml45
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfObjects.yml11
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfQuotes.yml33
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfTests.yml135
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/unindentedCollections.yml82
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/InlineTest.php380
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParseExceptionTest.php41
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParserTest.php740
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Tests/YamlTest.php31
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Unescaper.php141
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/Yaml.php100
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/composer.json34
-rw-r--r--vendor/symfony/yaml/Symfony/Component/Yaml/phpunit.xml.dist27
1045 files changed, 104325 insertions, 0 deletions
diff --git a/vendor/autoload.php b/vendor/autoload.php
new file mode 100644
index 0000000..60ba31e
--- /dev/null
+++ b/vendor/autoload.php
@@ -0,0 +1,7 @@
+<?php
+
+// autoload.php @generated by Composer
+
+require_once __DIR__ . '/composer' . '/autoload_real.php';
+
+return ComposerAutoloaderInitb64ad69a59a51cd1e2aaf5c77c925e41::getLoader();
diff --git a/vendor/bin/propel b/vendor/bin/propel
new file mode 100755
index 0000000..9301b05
--- /dev/null
+++ b/vendor/bin/propel
@@ -0,0 +1,4 @@
+#!/usr/bin/env php
+<?php
+
+include('propel.php');
diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php
new file mode 100644
index 0000000..4e05d3b
--- /dev/null
+++ b/vendor/composer/ClassLoader.php
@@ -0,0 +1,413 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ * Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0 class loader
+ *
+ * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
+ *
+ * $loader = new \Composer\Autoload\ClassLoader();
+ *
+ * // register classes with namespaces
+ * $loader->add('Symfony\Component', __DIR__.'/component');
+ * $loader->add('Symfony', __DIR__.'/framework');
+ *
+ * // activate the autoloader
+ * $loader->register();
+ *
+ * // to enable searching the include path (eg. for PEAR packages)
+ * $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class ClassLoader
+{
+ // PSR-4
+ private $prefixLengthsPsr4 = array();
+ private $prefixDirsPsr4 = array();
+ private $fallbackDirsPsr4 = array();
+
+ // PSR-0
+ private $prefixesPsr0 = array();
+ private $fallbackDirsPsr0 = array();
+
+ private $useIncludePath = false;
+ private $classMap = array();
+
+ private $classMapAuthoritative = false;
+
+ public function getPrefixes()
+ {
+ if (!empty($this->prefixesPsr0)) {
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
+ }
+
+ return array();
+ }
+
+ public function getPrefixesPsr4()
+ {
+ return $this->prefixDirsPsr4;
+ }
+
+ public function getFallbackDirs()
+ {
+ return $this->fallbackDirsPsr0;
+ }
+
+ public function getFallbackDirsPsr4()
+ {
+ return $this->fallbackDirsPsr4;
+ }
+
+ public function getClassMap()
+ {
+ return $this->classMap;
+ }
+
+ /**
+ * @param array $classMap Class to filename map
+ */
+ public function addClassMap(array $classMap)
+ {
+ if ($this->classMap) {
+ $this->classMap = array_merge($this->classMap, $classMap);
+ } else {
+ $this->classMap = $classMap;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix, either
+ * appending or prepending to the ones previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 root directories
+ * @param bool $prepend Whether to prepend the directories
+ */
+ public function add($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ if ($prepend) {
+ $this->fallbackDirsPsr0 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr0
+ );
+ } else {
+ $this->fallbackDirsPsr0 = array_merge(
+ $this->fallbackDirsPsr0,
+ (array) $paths
+ );
+ }
+
+ return;
+ }
+
+ $first = $prefix[0];
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+ return;
+ }
+ if ($prepend) {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixesPsr0[$first][$prefix]
+ );
+ } else {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ $this->prefixesPsr0[$first][$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace, either
+ * appending or prepending to the ones previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-0 base directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function addPsr4($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ // Register directories for the root namespace.
+ if ($prepend) {
+ $this->fallbackDirsPsr4 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr4
+ );
+ } else {
+ $this->fallbackDirsPsr4 = array_merge(
+ $this->fallbackDirsPsr4,
+ (array) $paths
+ );
+ }
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+ // Register directories for a new namespace.
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ } elseif ($prepend) {
+ // Prepend directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixDirsPsr4[$prefix]
+ );
+ } else {
+ // Append directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ $this->prefixDirsPsr4[$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix,
+ * replacing any others previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 base directories
+ */
+ public function set($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr0 = (array) $paths;
+ } else {
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace,
+ * replacing any others previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-4 base directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setPsr4($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr4 = (array) $paths;
+ } else {
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Turns on searching the include path for class files.
+ *
+ * @param bool $useIncludePath
+ */
+ public function setUseIncludePath($useIncludePath)
+ {
+ $this->useIncludePath = $useIncludePath;
+ }
+
+ /**
+ * Can be used to check if the autoloader uses the include path to check
+ * for classes.
+ *
+ * @return bool
+ */
+ public function getUseIncludePath()
+ {
+ return $this->useIncludePath;
+ }
+
+ /**
+ * Turns off searching the prefix and fallback directories for classes
+ * that have not been registered with the class map.
+ *
+ * @param bool $classMapAuthoritative
+ */
+ public function setClassMapAuthoritative($classMapAuthoritative)
+ {
+ $this->classMapAuthoritative = $classMapAuthoritative;
+ }
+
+ /**
+ * Should class lookup fail if not found in the current class map?
+ *
+ * @return bool
+ */
+ public function isClassMapAuthoritative()
+ {
+ return $this->classMapAuthoritative;
+ }
+
+ /**
+ * Registers this instance as an autoloader.
+ *
+ * @param bool $prepend Whether to prepend the autoloader or not
+ */
+ public function register($prepend = false)
+ {
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+ }
+
+ /**
+ * Unregisters this instance as an autoloader.
+ */
+ public function unregister()
+ {
+ spl_autoload_unregister(array($this, 'loadClass'));
+ }
+
+ /**
+ * Loads the given class or interface.
+ *
+ * @param string $class The name of the class
+ * @return bool|null True if loaded, null otherwise
+ */
+ public function loadClass($class)
+ {
+ if ($file = $this->findFile($class)) {
+ includeFile($file);
+
+ return true;
+ }
+ }
+
+ /**
+ * Finds the path to the file where the class is defined.
+ *
+ * @param string $class The name of the class
+ *
+ * @return string|false The path if found, false otherwise
+ */
+ public function findFile($class)
+ {
+ // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
+ if ('\\' == $class[0]) {
+ $class = substr($class, 1);
+ }
+
+ // class map lookup
+ if (isset($this->classMap[$class])) {
+ return $this->classMap[$class];
+ }
+ if ($this->classMapAuthoritative) {
+ return false;
+ }
+
+ $file = $this->findFileWithExtension($class, '.php');
+
+ // Search for Hack files if we are running on HHVM
+ if ($file === null && defined('HHVM_VERSION')) {
+ $file = $this->findFileWithExtension($class, '.hh');
+ }
+
+ if ($file === null) {
+ // Remember that this class does not exist.
+ return $this->classMap[$class] = false;
+ }
+
+ return $file;
+ }
+
+ private function findFileWithExtension($class, $ext)
+ {
+ // PSR-4 lookup
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+ $first = $class[0];
+ if (isset($this->prefixLengthsPsr4[$first])) {
+ foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
+ if (is_file($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-4 fallback dirs
+ foreach ($this->fallbackDirsPsr4 as $dir) {
+ if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 lookup
+ if (false !== $pos = strrpos($class, '\\')) {
+ // namespaced class name
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+ } else {
+ // PEAR-like class name
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+ }
+
+ if (isset($this->prefixesPsr0[$first])) {
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($dirs as $dir) {
+ if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-0 fallback dirs
+ foreach ($this->fallbackDirsPsr0 as $dir) {
+ if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 include paths.
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+ return $file;
+ }
+ }
+}
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ */
+function includeFile($file)
+{
+ include $file;
+}
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
new file mode 100644
index 0000000..68b2d7e
--- /dev/null
+++ b/vendor/composer/autoload_classmap.php
@@ -0,0 +1,29 @@
+<?php
+
+// autoload_classmap.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'Base\\Category' => $baseDir . '/generated-classes/Base/Category.php',
+ 'Base\\CategoryQuery' => $baseDir . '/generated-classes/Base/CategoryQuery.php',
+ 'Base\\Product' => $baseDir . '/generated-classes/Base/Product.php',
+ 'Base\\ProductCategory' => $baseDir . '/generated-classes/Base/ProductCategory.php',
+ 'Base\\ProductCategoryQuery' => $baseDir . '/generated-classes/Base/ProductCategoryQuery.php',
+ 'Base\\ProductQuery' => $baseDir . '/generated-classes/Base/ProductQuery.php',
+ 'Base\\User' => $baseDir . '/generated-classes/Base/User.php',
+ 'Base\\UserQuery' => $baseDir . '/generated-classes/Base/UserQuery.php',
+ 'Category' => $baseDir . '/generated-classes/Category.php',
+ 'CategoryQuery' => $baseDir . '/generated-classes/CategoryQuery.php',
+ 'Map\\CategoryTableMap' => $baseDir . '/generated-classes/Map/CategoryTableMap.php',
+ 'Map\\ProductCategoryTableMap' => $baseDir . '/generated-classes/Map/ProductCategoryTableMap.php',
+ 'Map\\ProductTableMap' => $baseDir . '/generated-classes/Map/ProductTableMap.php',
+ 'Map\\UserTableMap' => $baseDir . '/generated-classes/Map/UserTableMap.php',
+ 'Product' => $baseDir . '/generated-classes/Product.php',
+ 'ProductCategory' => $baseDir . '/generated-classes/ProductCategory.php',
+ 'ProductCategoryQuery' => $baseDir . '/generated-classes/ProductCategoryQuery.php',
+ 'ProductQuery' => $baseDir . '/generated-classes/ProductQuery.php',
+ 'User' => $baseDir . '/generated-classes/User.php',
+ 'UserQuery' => $baseDir . '/generated-classes/UserQuery.php',
+);
diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php
new file mode 100644
index 0000000..032e393
--- /dev/null
+++ b/vendor/composer/autoload_namespaces.php
@@ -0,0 +1,18 @@
+<?php
+
+// autoload_namespaces.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
+ 'Symfony\\Component\\Validator\\' => array($vendorDir . '/symfony/validator'),
+ 'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
+ 'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
+ 'Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'),
+ 'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
+ 'Symfony\\Component\\Config\\' => array($vendorDir . '/symfony/config'),
+ 'Psr\\Log\\' => array($vendorDir . '/psr/log'),
+ 'Propel' => array($vendorDir . '/propel/propel/src'),
+);
diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php
new file mode 100644
index 0000000..b265c64
--- /dev/null
+++ b/vendor/composer/autoload_psr4.php
@@ -0,0 +1,9 @@
+<?php
+
+// autoload_psr4.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+);
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
new file mode 100644
index 0000000..80e6208
--- /dev/null
+++ b/vendor/composer/autoload_real.php
@@ -0,0 +1,50 @@
+<?php
+
+// autoload_real.php @generated by Composer
+
+class ComposerAutoloaderInitb64ad69a59a51cd1e2aaf5c77c925e41
+{
+ private static $loader;
+
+ public static function loadClassLoader($class)
+ {
+ if ('Composer\Autoload\ClassLoader' === $class) {
+ require __DIR__ . '/ClassLoader.php';
+ }
+ }
+
+ public static function getLoader()
+ {
+ if (null !== self::$loader) {
+ return self::$loader;
+ }
+
+ spl_autoload_register(array('ComposerAutoloaderInitb64ad69a59a51cd1e2aaf5c77c925e41', 'loadClassLoader'), true, true);
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
+ spl_autoload_unregister(array('ComposerAutoloaderInitb64ad69a59a51cd1e2aaf5c77c925e41', 'loadClassLoader'));
+
+ $map = require __DIR__ . '/autoload_namespaces.php';
+ foreach ($map as $namespace => $path) {
+ $loader->set($namespace, $path);
+ }
+
+ $map = require __DIR__ . '/autoload_psr4.php';
+ foreach ($map as $namespace => $path) {
+ $loader->setPsr4($namespace, $path);
+ }
+
+ $classMap = require __DIR__ . '/autoload_classmap.php';
+ if ($classMap) {
+ $loader->addClassMap($classMap);
+ }
+
+ $loader->register(true);
+
+ return $loader;
+ }
+}
+
+function composerRequireb64ad69a59a51cd1e2aaf5c77c925e41($file)
+{
+ require $file;
+}
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
new file mode 100644
index 0000000..e3a297f
--- /dev/null
+++ b/vendor/composer/installed.json
@@ -0,0 +1,513 @@
+[
+ {
+ "name": "symfony/filesystem",
+ "version": "v2.6.6",
+ "version_normalized": "2.6.6.0",
+ "target-dir": "Symfony/Component/Filesystem",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Filesystem.git",
+ "reference": "4983964b3693e4f13449cb3800c64a9112c301b4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Filesystem/zipball/4983964b3693e4f13449cb3800c64a9112c301b4",
+ "reference": "4983964b3693e4f13449cb3800c64a9112c301b4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7"
+ },
+ "time": "2015-03-22 16:55:57",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Filesystem\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ },
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Symfony Filesystem Component",
+ "homepage": "http://symfony.com"
+ },
+ {
+ "name": "symfony/config",
+ "version": "v2.6.6",
+ "version_normalized": "2.6.6.0",
+ "target-dir": "Symfony/Component/Config",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Config.git",
+ "reference": "d91be01336605db8da21b79bc771e46a7276d1bc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Config/zipball/d91be01336605db8da21b79bc771e46a7276d1bc",
+ "reference": "d91be01336605db8da21b79bc771e46a7276d1bc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "symfony/filesystem": "~2.3"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7"
+ },
+ "time": "2015-03-30 15:54:10",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Config\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ },
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Symfony Config Component",
+ "homepage": "http://symfony.com"
+ },
+ {
+ "name": "symfony/translation",
+ "version": "v2.6.6",
+ "version_normalized": "2.6.6.0",
+ "target-dir": "Symfony/Component/Translation",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Translation.git",
+ "reference": "bd939f05cdaca128f4ddbae1b447d6f0203b60af"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Translation/zipball/bd939f05cdaca128f4ddbae1b447d6f0203b60af",
+ "reference": "bd939f05cdaca128f4ddbae1b447d6f0203b60af",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~2.3,>=2.3.12",
+ "symfony/intl": "~2.3",
+ "symfony/phpunit-bridge": "~2.7",
+ "symfony/yaml": "~2.2"
+ },
+ "suggest": {
+ "psr/log": "To use logging capability in translator",
+ "symfony/config": "",
+ "symfony/yaml": ""
+ },
+ "time": "2015-03-30 15:54:10",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Translation\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ },
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Symfony Translation Component",
+ "homepage": "http://symfony.com"
+ },
+ {
+ "name": "symfony/validator",
+ "version": "v2.6.6",
+ "version_normalized": "2.6.6.0",
+ "target-dir": "Symfony/Component/Validator",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Validator.git",
+ "reference": "85d9b42fe71bf88e7a1e5dec2094605dc9fbff28"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Validator/zipball/85d9b42fe71bf88e7a1e5dec2094605dc9fbff28",
+ "reference": "85d9b42fe71bf88e7a1e5dec2094605dc9fbff28",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "symfony/translation": "~2.0,>=2.0.5"
+ },
+ "require-dev": {
+ "doctrine/annotations": "~1.0",
+ "doctrine/cache": "~1.0",
+ "doctrine/common": "~2.3",
+ "egulias/email-validator": "~1.2,>=1.2.1",
+ "symfony/config": "~2.2",
+ "symfony/expression-language": "~2.4",
+ "symfony/http-foundation": "~2.1",
+ "symfony/intl": "~2.3",
+ "symfony/phpunit-bridge": "~2.7",
+ "symfony/property-access": "~2.3",
+ "symfony/yaml": "~2.0,>=2.0.5"
+ },
+ "suggest": {
+ "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
+ "doctrine/cache": "For using the default cached annotation reader and metadata cache.",
+ "egulias/email-validator": "Strict (RFC compliant) email validation",
+ "symfony/config": "",
+ "symfony/expression-language": "For using the 2.4 Expression validator",
+ "symfony/http-foundation": "",
+ "symfony/intl": "",
+ "symfony/property-access": "For using the 2.4 Validator API",
+ "symfony/yaml": ""
+ },
+ "time": "2015-03-30 15:54:10",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Validator\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ },
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Symfony Validator Component",
+ "homepage": "http://symfony.com"
+ },
+ {
+ "name": "symfony/finder",
+ "version": "v2.6.6",
+ "version_normalized": "2.6.6.0",
+ "target-dir": "Symfony/Component/Finder",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Finder.git",
+ "reference": "5dbe2e73a580618f5b4880fda93406eed25de251"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Finder/zipball/5dbe2e73a580618f5b4880fda93406eed25de251",
+ "reference": "5dbe2e73a580618f5b4880fda93406eed25de251",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7"
+ },
+ "time": "2015-03-30 15:54:10",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Finder\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ },
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Symfony Finder Component",
+ "homepage": "http://symfony.com"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v2.6.6",
+ "version_normalized": "2.6.6.0",
+ "target-dir": "Symfony/Component/Console",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Console.git",
+ "reference": "5b91dc4ed5eb08553f57f6df04c4730a73992667"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Console/zipball/5b91dc4ed5eb08553f57f6df04c4730a73992667",
+ "reference": "5b91dc4ed5eb08553f57f6df04c4730a73992667",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/event-dispatcher": "~2.1",
+ "symfony/phpunit-bridge": "~2.7",
+ "symfony/process": "~2.1"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/process": ""
+ },
+ "time": "2015-03-30 15:54:10",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Console\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ },
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Symfony Console Component",
+ "homepage": "http://symfony.com"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v2.6.6",
+ "version_normalized": "2.6.6.0",
+ "target-dir": "Symfony/Component/Yaml",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Yaml.git",
+ "reference": "174f009ed36379a801109955fc5a71a49fe62dd4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/174f009ed36379a801109955fc5a71a49fe62dd4",
+ "reference": "174f009ed36379a801109955fc5a71a49fe62dd4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7"
+ },
+ "time": "2015-03-30 15:54:10",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Yaml\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ },
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Symfony Yaml Component",
+ "homepage": "http://symfony.com"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.0.0",
+ "version_normalized": "1.0.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
+ "shasum": ""
+ },
+ "time": "2012-12-21 11:40:51",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Psr\\Log\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ]
+ },
+ {
+ "name": "propel/propel",
+ "version": "dev-master",
+ "version_normalized": "9999999-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/propelorm/Propel2.git",
+ "reference": "4968909779b239360cf52d30036c63452f94859b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/propelorm/Propel2/zipball/4968909779b239360cf52d30036c63452f94859b",
+ "reference": "4968909779b239360cf52d30036c63452f94859b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4",
+ "psr/log": "~1.0",
+ "symfony/config": "~2.3",
+ "symfony/console": "~2.3",
+ "symfony/filesystem": "~2.3",
+ "symfony/finder": "~2.3",
+ "symfony/validator": "~2.3",
+ "symfony/yaml": "~2.3"
+ },
+ "require-dev": {
+ "behat/behat": "~2.4",
+ "monolog/monolog": "~1.3",
+ "phpunit/phpunit": "~4.0"
+ },
+ "suggest": {
+ "monolog/monolog": "The recommended logging library to use with Propel."
+ },
+ "time": "2015-05-01 21:21:08",
+ "bin": [
+ "bin/propel"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "installation-source": "source",
+ "autoload": {
+ "psr-0": {
+ "Propel": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "William Durand",
+ "email": "william.durand1@gmail.com"
+ }
+ ],
+ "description": "Propel2 is an open-source Object-Relational Mapping (ORM) for PHP 5.4",
+ "homepage": "http://www.propelorm.org/",
+ "keywords": [
+ "Active Record",
+ "orm",
+ "persistence"
+ ]
+ }
+]
diff --git a/vendor/propel/propel b/vendor/propel/propel
new file mode 160000
+Subproject 4968909779b239360cf52d30036c63452f94859
diff --git a/vendor/psr/log/.gitignore b/vendor/psr/log/.gitignore
new file mode 100644
index 0000000..22d0d82
--- /dev/null
+++ b/vendor/psr/log/.gitignore
@@ -0,0 +1 @@
+vendor
diff --git a/vendor/psr/log/LICENSE b/vendor/psr/log/LICENSE
new file mode 100644
index 0000000..474c952
--- /dev/null
+++ b/vendor/psr/log/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 PHP Framework Interoperability Group
+
+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/vendor/psr/log/Psr/Log/AbstractLogger.php b/vendor/psr/log/Psr/Log/AbstractLogger.php
new file mode 100644
index 0000000..00f9034
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/AbstractLogger.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * This is a simple Logger implementation that other Loggers can inherit from.
+ *
+ * It simply delegates all log-level-specific methods to the `log` method to
+ * reduce boilerplate code that a simple Logger that does the same thing with
+ * messages regardless of the error level has to implement.
+ */
+abstract class AbstractLogger implements LoggerInterface
+{
+ /**
+ * System is unusable.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function emergency($message, array $context = array())
+ {
+ $this->log(LogLevel::EMERGENCY, $message, $context);
+ }
+
+ /**
+ * Action must be taken immediately.
+ *
+ * Example: Entire website down, database unavailable, etc. This should
+ * trigger the SMS alerts and wake you up.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function alert($message, array $context = array())
+ {
+ $this->log(LogLevel::ALERT, $message, $context);
+ }
+
+ /**
+ * Critical conditions.
+ *
+ * Example: Application component unavailable, unexpected exception.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function critical($message, array $context = array())
+ {
+ $this->log(LogLevel::CRITICAL, $message, $context);
+ }
+
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function error($message, array $context = array())
+ {
+ $this->log(LogLevel::ERROR, $message, $context);
+ }
+
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
+ * that are not necessarily wrong.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function warning($message, array $context = array())
+ {
+ $this->log(LogLevel::WARNING, $message, $context);
+ }
+
+ /**
+ * Normal but significant events.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function notice($message, array $context = array())
+ {
+ $this->log(LogLevel::NOTICE, $message, $context);
+ }
+
+ /**
+ * Interesting events.
+ *
+ * Example: User logs in, SQL logs.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function info($message, array $context = array())
+ {
+ $this->log(LogLevel::INFO, $message, $context);
+ }
+
+ /**
+ * Detailed debug information.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function debug($message, array $context = array())
+ {
+ $this->log(LogLevel::DEBUG, $message, $context);
+ }
+}
diff --git a/vendor/psr/log/Psr/Log/InvalidArgumentException.php b/vendor/psr/log/Psr/Log/InvalidArgumentException.php
new file mode 100644
index 0000000..67f852d
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/InvalidArgumentException.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Psr\Log;
+
+class InvalidArgumentException extends \InvalidArgumentException
+{
+}
diff --git a/vendor/psr/log/Psr/Log/LogLevel.php b/vendor/psr/log/Psr/Log/LogLevel.php
new file mode 100644
index 0000000..e32c151
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/LogLevel.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Describes log levels
+ */
+class LogLevel
+{
+ const EMERGENCY = 'emergency';
+ const ALERT = 'alert';
+ const CRITICAL = 'critical';
+ const ERROR = 'error';
+ const WARNING = 'warning';
+ const NOTICE = 'notice';
+ const INFO = 'info';
+ const DEBUG = 'debug';
+}
diff --git a/vendor/psr/log/Psr/Log/LoggerAwareInterface.php b/vendor/psr/log/Psr/Log/LoggerAwareInterface.php
new file mode 100644
index 0000000..2eebc4e
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/LoggerAwareInterface.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Describes a logger-aware instance
+ */
+interface LoggerAwareInterface
+{
+ /**
+ * Sets a logger instance on the object
+ *
+ * @param LoggerInterface $logger
+ * @return null
+ */
+ public function setLogger(LoggerInterface $logger);
+}
diff --git a/vendor/psr/log/Psr/Log/LoggerAwareTrait.php b/vendor/psr/log/Psr/Log/LoggerAwareTrait.php
new file mode 100644
index 0000000..f087a3d
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/LoggerAwareTrait.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Basic Implementation of LoggerAwareInterface.
+ */
+trait LoggerAwareTrait
+{
+ /** @var LoggerInterface */
+ protected $logger;
+
+ /**
+ * Sets a logger.
+ *
+ * @param LoggerInterface $logger
+ */
+ public function setLogger(LoggerInterface $logger)
+ {
+ $this->logger = $logger;
+ }
+}
diff --git a/vendor/psr/log/Psr/Log/LoggerInterface.php b/vendor/psr/log/Psr/Log/LoggerInterface.php
new file mode 100644
index 0000000..476bb96
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/LoggerInterface.php
@@ -0,0 +1,114 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Describes a logger instance
+ *
+ * The message MUST be a string or object implementing __toString().
+ *
+ * The message MAY contain placeholders in the form: {foo} where foo
+ * will be replaced by the context data in key "foo".
+ *
+ * The context array can contain arbitrary data, the only assumption that
+ * can be made by implementors is that if an Exception instance is given
+ * to produce a stack trace, it MUST be in a key named "exception".
+ *
+ * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
+ * for the full interface specification.
+ */
+interface LoggerInterface
+{
+ /**
+ * System is unusable.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function emergency($message, array $context = array());
+
+ /**
+ * Action must be taken immediately.
+ *
+ * Example: Entire website down, database unavailable, etc. This should
+ * trigger the SMS alerts and wake you up.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function alert($message, array $context = array());
+
+ /**
+ * Critical conditions.
+ *
+ * Example: Application component unavailable, unexpected exception.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function critical($message, array $context = array());
+
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function error($message, array $context = array());
+
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
+ * that are not necessarily wrong.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function warning($message, array $context = array());
+
+ /**
+ * Normal but significant events.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function notice($message, array $context = array());
+
+ /**
+ * Interesting events.
+ *
+ * Example: User logs in, SQL logs.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function info($message, array $context = array());
+
+ /**
+ * Detailed debug information.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function debug($message, array $context = array());
+
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @param mixed $level
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function log($level, $message, array $context = array());
+}
diff --git a/vendor/psr/log/Psr/Log/LoggerTrait.php b/vendor/psr/log/Psr/Log/LoggerTrait.php
new file mode 100644
index 0000000..5912496
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/LoggerTrait.php
@@ -0,0 +1,131 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * This is a simple Logger trait that classes unable to extend AbstractLogger
+ * (because they extend another class, etc) can include.
+ *
+ * It simply delegates all log-level-specific methods to the `log` method to
+ * reduce boilerplate code that a simple Logger that does the same thing with
+ * messages regardless of the error level has to implement.
+ */
+trait LoggerTrait
+{
+ /**
+ * System is unusable.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function emergency($message, array $context = array())
+ {
+ $this->log(LogLevel::EMERGENCY, $message, $context);
+ }
+
+ /**
+ * Action must be taken immediately.
+ *
+ * Example: Entire website down, database unavailable, etc. This should
+ * trigger the SMS alerts and wake you up.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function alert($message, array $context = array())
+ {
+ $this->log(LogLevel::ALERT, $message, $context);
+ }
+
+ /**
+ * Critical conditions.
+ *
+ * Example: Application component unavailable, unexpected exception.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function critical($message, array $context = array())
+ {
+ $this->log(LogLevel::CRITICAL, $message, $context);
+ }
+
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function error($message, array $context = array())
+ {
+ $this->log(LogLevel::ERROR, $message, $context);
+ }
+
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
+ * that are not necessarily wrong.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function warning($message, array $context = array())
+ {
+ $this->log(LogLevel::WARNING, $message, $context);
+ }
+
+ /**
+ * Normal but significant events.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function notice($message, array $context = array())
+ {
+ $this->log(LogLevel::NOTICE, $message, $context);
+ }
+
+ /**
+ * Interesting events.
+ *
+ * Example: User logs in, SQL logs.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function info($message, array $context = array())
+ {
+ $this->log(LogLevel::INFO, $message, $context);
+ }
+
+ /**
+ * Detailed debug information.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function debug($message, array $context = array())
+ {
+ $this->log(LogLevel::DEBUG, $message, $context);
+ }
+
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @param mixed $level
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ abstract public function log($level, $message, array $context = array());
+}
diff --git a/vendor/psr/log/Psr/Log/NullLogger.php b/vendor/psr/log/Psr/Log/NullLogger.php
new file mode 100644
index 0000000..553a3c5
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/NullLogger.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * This Logger can be used to avoid conditional log calls
+ *
+ * Logging should always be optional, and if no logger is provided to your
+ * library creating a NullLogger instance to have something to throw logs at
+ * is a good way to avoid littering your code with `if ($this->logger) { }`
+ * blocks.
+ */
+class NullLogger extends AbstractLogger
+{
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @param mixed $level
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function log($level, $message, array $context = array())
+ {
+ // noop
+ }
+}
diff --git a/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php
new file mode 100644
index 0000000..a932815
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php
@@ -0,0 +1,116 @@
+<?php
+
+namespace Psr\Log\Test;
+
+use Psr\Log\LogLevel;
+
+/**
+ * Provides a base test class for ensuring compliance with the LoggerInterface
+ *
+ * Implementors can extend the class and implement abstract methods to run this as part of their test suite
+ */
+abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @return LoggerInterface
+ */
+ abstract function getLogger();
+
+ /**
+ * This must return the log messages in order with a simple formatting: "<LOG LEVEL> <MESSAGE>"
+ *
+ * Example ->error('Foo') would yield "error Foo"
+ *
+ * @return string[]
+ */
+ abstract function getLogs();
+
+ public function testImplements()
+ {
+ $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger());
+ }
+
+ /**
+ * @dataProvider provideLevelsAndMessages
+ */
+ public function testLogsAtAllLevels($level, $message)
+ {
+ $logger = $this->getLogger();
+ $logger->{$level}($message, array('user' => 'Bob'));
+ $logger->log($level, $message, array('user' => 'Bob'));
+
+ $expected = array(
+ $level.' message of level '.$level.' with context: Bob',
+ $level.' message of level '.$level.' with context: Bob',
+ );
+ $this->assertEquals($expected, $this->getLogs());
+ }
+
+ public function provideLevelsAndMessages()
+ {
+ return array(
+ LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'),
+ LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'),
+ LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'),
+ LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'),
+ LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'),
+ LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'),
+ LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'),
+ LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'),
+ );
+ }
+
+ /**
+ * @expectedException Psr\Log\InvalidArgumentException
+ */
+ public function testThrowsOnInvalidLevel()
+ {
+ $logger = $this->getLogger();
+ $logger->log('invalid level', 'Foo');
+ }
+
+ public function testContextReplacement()
+ {
+ $logger = $this->getLogger();
+ $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
+
+ $expected = array('info {Message {nothing} Bob Bar a}');
+ $this->assertEquals($expected, $this->getLogs());
+ }
+
+ public function testObjectCastToString()
+ {
+ $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString'));
+ $dummy->expects($this->once())
+ ->method('__toString')
+ ->will($this->returnValue('DUMMY'));
+
+ $this->getLogger()->warning($dummy);
+ }
+
+ public function testContextCanContainAnything()
+ {
+ $context = array(
+ 'bool' => true,
+ 'null' => null,
+ 'string' => 'Foo',
+ 'int' => 0,
+ 'float' => 0.5,
+ 'nested' => array('with object' => new DummyTest),
+ 'object' => new \DateTime,
+ 'resource' => fopen('php://memory', 'r'),
+ );
+
+ $this->getLogger()->warning('Crazy context data', $context);
+ }
+
+ public function testContextExceptionKeyCanBeExceptionOrOtherValues()
+ {
+ $this->getLogger()->warning('Random message', array('exception' => 'oops'));
+ $this->getLogger()->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail')));
+ }
+}
+
+class DummyTest
+{
+} \ No newline at end of file
diff --git a/vendor/psr/log/README.md b/vendor/psr/log/README.md
new file mode 100644
index 0000000..574bc1c
--- /dev/null
+++ b/vendor/psr/log/README.md
@@ -0,0 +1,45 @@
+PSR Log
+=======
+
+This repository holds all interfaces/classes/traits related to
+[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md).
+
+Note that this is not a logger of its own. It is merely an interface that
+describes a logger. See the specification for more details.
+
+Usage
+-----
+
+If you need a logger, you can use the interface like this:
+
+```php
+<?php
+
+use Psr\Log\LoggerInterface;
+
+class Foo
+{
+ private $logger;
+
+ public function __construct(LoggerInterface $logger = null)
+ {
+ $this->logger = $logger;
+ }
+
+ public function doSomething()
+ {
+ if ($this->logger) {
+ $this->logger->info('Doing work');
+ }
+
+ // do something useful
+ }
+}
+```
+
+You can then pick one of the implementations of the interface to get a logger.
+
+If you want to implement the interface, you can require this package and
+implement `Psr\Log\LoggerInterface` in your code. Please read the
+[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
+for details.
diff --git a/vendor/psr/log/composer.json b/vendor/psr/log/composer.json
new file mode 100644
index 0000000..6bdcc21
--- /dev/null
+++ b/vendor/psr/log/composer.json
@@ -0,0 +1,17 @@
+{
+ "name": "psr/log",
+ "description": "Common interface for logging libraries",
+ "keywords": ["psr", "psr-3", "log"],
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "autoload": {
+ "psr-0": {
+ "Psr\\Log\\": ""
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/.gitignore b/vendor/symfony/config/Symfony/Component/Config/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/vendor/symfony/config/Symfony/Component/Config/CHANGELOG.md b/vendor/symfony/config/Symfony/Component/Config/CHANGELOG.md
new file mode 100644
index 0000000..59b30a3
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/CHANGELOG.md
@@ -0,0 +1,21 @@
+CHANGELOG
+=========
+
+2.2.0
+-----
+
+ * added ArrayNodeDefinition::canBeEnabled() and ArrayNodeDefinition::canBeDisabled()
+ to ease configuration when some sections are respectively disabled / enabled
+ by default.
+ * added a `normalizeKeys()` method for array nodes (to avoid key normalization)
+ * added numerical type handling for config definitions
+ * added convenience methods for optional configuration sections to ArrayNodeDefinition
+ * added a utils class for XML manipulations
+
+2.1.0
+-----
+
+ * added a way to add documentation on configuration
+ * implemented `Serializable` on resources
+ * LoaderResolverInterface is now used instead of LoaderResolver for type
+ hinting
diff --git a/vendor/symfony/config/Symfony/Component/Config/ConfigCache.php b/vendor/symfony/config/Symfony/Component/Config/ConfigCache.php
new file mode 100644
index 0000000..ebf107f
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/ConfigCache.php
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config;
+
+use Symfony\Component\Config\Resource\ResourceInterface;
+use Symfony\Component\Filesystem\Exception\IOException;
+use Symfony\Component\Filesystem\Filesystem;
+
+/**
+ * ConfigCache manages PHP cache files.
+ *
+ * When debug is enabled, it knows when to flush the cache
+ * thanks to an array of ResourceInterface instances.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ConfigCache
+{
+ private $debug;
+ private $file;
+
+ /**
+ * Constructor.
+ *
+ * @param string $file The absolute cache path
+ * @param bool $debug Whether debugging is enabled or not
+ */
+ public function __construct($file, $debug)
+ {
+ $this->file = $file;
+ $this->debug = (bool) $debug;
+ }
+
+ /**
+ * Gets the cache file path.
+ *
+ * @return string The cache file path
+ */
+ public function __toString()
+ {
+ return $this->file;
+ }
+
+ /**
+ * Checks if the cache is still fresh.
+ *
+ * This method always returns true when debug is off and the
+ * cache file exists.
+ *
+ * @return bool true if the cache is fresh, false otherwise
+ */
+ public function isFresh()
+ {
+ if (!is_file($this->file)) {
+ return false;
+ }
+
+ if (!$this->debug) {
+ return true;
+ }
+
+ $metadata = $this->getMetaFile();
+ if (!is_file($metadata)) {
+ return false;
+ }
+
+ $time = filemtime($this->file);
+ $meta = unserialize(file_get_contents($metadata));
+ foreach ($meta as $resource) {
+ if (!$resource->isFresh($time)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Writes cache.
+ *
+ * @param string $content The content to write in the cache
+ * @param ResourceInterface[] $metadata An array of ResourceInterface instances
+ *
+ * @throws \RuntimeException When cache file can't be written
+ */
+ public function write($content, array $metadata = null)
+ {
+ $mode = 0666;
+ $umask = umask();
+ $filesystem = new Filesystem();
+ $filesystem->dumpFile($this->file, $content, null);
+ try {
+ $filesystem->chmod($this->file, $mode, $umask);
+ } catch (IOException $e) {
+ // discard chmod failure (some filesystem may not support it)
+ }
+
+ if (null !== $metadata && true === $this->debug) {
+ $filesystem->dumpFile($this->getMetaFile(), serialize($metadata), null);
+ try {
+ $filesystem->chmod($this->getMetaFile(), $mode, $umask);
+ } catch (IOException $e) {
+ // discard chmod failure (some filesystem may not support it)
+ }
+ }
+ }
+
+ /**
+ * Gets the meta file path.
+ *
+ * @return string The meta file path
+ */
+ private function getMetaFile()
+ {
+ return $this->file.'.meta';
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/ArrayNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/ArrayNode.php
new file mode 100644
index 0000000..5deb472
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/ArrayNode.php
@@ -0,0 +1,393 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
+use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
+
+/**
+ * Represents an Array node in the config tree.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ArrayNode extends BaseNode implements PrototypeNodeInterface
+{
+ protected $xmlRemappings = array();
+ protected $children = array();
+ protected $allowFalse = false;
+ protected $allowNewKeys = true;
+ protected $addIfNotSet = false;
+ protected $performDeepMerging = true;
+ protected $ignoreExtraKeys = false;
+ protected $normalizeKeys = true;
+
+ public function setNormalizeKeys($normalizeKeys)
+ {
+ $this->normalizeKeys = (bool) $normalizeKeys;
+ }
+
+ /**
+ * Normalizes keys between the different configuration formats.
+ *
+ * Namely, you mostly have foo_bar in YAML while you have foo-bar in XML.
+ * After running this method, all keys are normalized to foo_bar.
+ *
+ * If you have a mixed key like foo-bar_moo, it will not be altered.
+ * The key will also not be altered if the target key already exists.
+ *
+ * @param mixed $value
+ *
+ * @return array The value with normalized keys
+ */
+ protected function preNormalize($value)
+ {
+ if (!$this->normalizeKeys || !is_array($value)) {
+ return $value;
+ }
+
+ foreach ($value as $k => $v) {
+ if (false !== strpos($k, '-') && false === strpos($k, '_') && !array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) {
+ $value[$normalizedKey] = $v;
+ unset($value[$k]);
+ }
+ }
+
+ return $value;
+ }
+
+ /**
+ * Retrieves the children of this node.
+ *
+ * @return array The children
+ */
+ public function getChildren()
+ {
+ return $this->children;
+ }
+
+ /**
+ * Sets the xml remappings that should be performed.
+ *
+ * @param array $remappings an array of the form array(array(string, string))
+ */
+ public function setXmlRemappings(array $remappings)
+ {
+ $this->xmlRemappings = $remappings;
+ }
+
+ /**
+ * Gets the xml remappings that should be performed.
+ *
+ * @return array $remappings an array of the form array(array(string, string))
+ */
+ public function getXmlRemappings()
+ {
+ return $this->xmlRemappings;
+ }
+
+ /**
+ * Sets whether to add default values for this array if it has not been
+ * defined in any of the configuration files.
+ *
+ * @param bool $boolean
+ */
+ public function setAddIfNotSet($boolean)
+ {
+ $this->addIfNotSet = (bool) $boolean;
+ }
+
+ /**
+ * Sets whether false is allowed as value indicating that the array should be unset.
+ *
+ * @param bool $allow
+ */
+ public function setAllowFalse($allow)
+ {
+ $this->allowFalse = (bool) $allow;
+ }
+
+ /**
+ * Sets whether new keys can be defined in subsequent configurations.
+ *
+ * @param bool $allow
+ */
+ public function setAllowNewKeys($allow)
+ {
+ $this->allowNewKeys = (bool) $allow;
+ }
+
+ /**
+ * Sets if deep merging should occur.
+ *
+ * @param bool $boolean
+ */
+ public function setPerformDeepMerging($boolean)
+ {
+ $this->performDeepMerging = (bool) $boolean;
+ }
+
+ /**
+ * Whether extra keys should just be ignore without an exception.
+ *
+ * @param bool $boolean To allow extra keys
+ */
+ public function setIgnoreExtraKeys($boolean)
+ {
+ $this->ignoreExtraKeys = (bool) $boolean;
+ }
+
+ /**
+ * Sets the node Name.
+ *
+ * @param string $name The node's name
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Checks if the node has a default value.
+ *
+ * @return bool
+ */
+ public function hasDefaultValue()
+ {
+ return $this->addIfNotSet;
+ }
+
+ /**
+ * Retrieves the default value.
+ *
+ * @return array The default value
+ *
+ * @throws \RuntimeException if the node has no default value
+ */
+ public function getDefaultValue()
+ {
+ if (!$this->hasDefaultValue()) {
+ throw new \RuntimeException(sprintf('The node at path "%s" has no default value.', $this->getPath()));
+ }
+
+ $defaults = array();
+ foreach ($this->children as $name => $child) {
+ if ($child->hasDefaultValue()) {
+ $defaults[$name] = $child->getDefaultValue();
+ }
+ }
+
+ return $defaults;
+ }
+
+ /**
+ * Adds a child node.
+ *
+ * @param NodeInterface $node The child node to add
+ *
+ * @throws \InvalidArgumentException when the child node has no name
+ * @throws \InvalidArgumentException when the child node's name is not unique
+ */
+ public function addChild(NodeInterface $node)
+ {
+ $name = $node->getName();
+ if (!strlen($name)) {
+ throw new \InvalidArgumentException('Child nodes must be named.');
+ }
+ if (isset($this->children[$name])) {
+ throw new \InvalidArgumentException(sprintf('A child node named "%s" already exists.', $name));
+ }
+
+ $this->children[$name] = $node;
+ }
+
+ /**
+ * Finalizes the value of this node.
+ *
+ * @param mixed $value
+ *
+ * @return mixed The finalised value
+ *
+ * @throws UnsetKeyException
+ * @throws InvalidConfigurationException if the node doesn't have enough children
+ */
+ protected function finalizeValue($value)
+ {
+ if (false === $value) {
+ $msg = sprintf('Unsetting key for path "%s", value: %s', $this->getPath(), json_encode($value));
+ throw new UnsetKeyException($msg);
+ }
+
+ foreach ($this->children as $name => $child) {
+ if (!array_key_exists($name, $value)) {
+ if ($child->isRequired()) {
+ $msg = sprintf('The child node "%s" at path "%s" must be configured.', $name, $this->getPath());
+ $ex = new InvalidConfigurationException($msg);
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ if ($child->hasDefaultValue()) {
+ $value[$name] = $child->getDefaultValue();
+ }
+
+ continue;
+ }
+
+ try {
+ $value[$name] = $child->finalize($value[$name]);
+ } catch (UnsetKeyException $unset) {
+ unset($value[$name]);
+ }
+ }
+
+ return $value;
+ }
+
+ /**
+ * Validates the type of the value.
+ *
+ * @param mixed $value
+ *
+ * @throws InvalidTypeException
+ */
+ protected function validateType($value)
+ {
+ if (!is_array($value) && (!$this->allowFalse || false !== $value)) {
+ $ex = new InvalidTypeException(sprintf(
+ 'Invalid type for path "%s". Expected array, but got %s',
+ $this->getPath(),
+ gettype($value)
+ ));
+ if ($hint = $this->getInfo()) {
+ $ex->addHint($hint);
+ }
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+ }
+
+ /**
+ * Normalizes the value.
+ *
+ * @param mixed $value The value to normalize
+ *
+ * @return mixed The normalized value
+ *
+ * @throws InvalidConfigurationException
+ */
+ protected function normalizeValue($value)
+ {
+ if (false === $value) {
+ return $value;
+ }
+
+ $value = $this->remapXml($value);
+
+ $normalized = array();
+ foreach ($value as $name => $val) {
+ if (isset($this->children[$name])) {
+ $normalized[$name] = $this->children[$name]->normalize($val);
+ unset($value[$name]);
+ }
+ }
+
+ // if extra fields are present, throw exception
+ if (count($value) && !$this->ignoreExtraKeys) {
+ $msg = sprintf('Unrecognized option%s "%s" under "%s"', 1 === count($value) ? '' : 's', implode(', ', array_keys($value)), $this->getPath());
+ $ex = new InvalidConfigurationException($msg);
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ return $normalized;
+ }
+
+ /**
+ * Remaps multiple singular values to a single plural value.
+ *
+ * @param array $value The source values
+ *
+ * @return array The remapped values
+ */
+ protected function remapXml($value)
+ {
+ foreach ($this->xmlRemappings as $transformation) {
+ list($singular, $plural) = $transformation;
+
+ if (!isset($value[$singular])) {
+ continue;
+ }
+
+ $value[$plural] = Processor::normalizeConfig($value, $singular, $plural);
+ unset($value[$singular]);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Merges values together.
+ *
+ * @param mixed $leftSide The left side to merge.
+ * @param mixed $rightSide The right side to merge.
+ *
+ * @return mixed The merged values
+ *
+ * @throws InvalidConfigurationException
+ * @throws \RuntimeException
+ */
+ protected function mergeValues($leftSide, $rightSide)
+ {
+ if (false === $rightSide) {
+ // if this is still false after the last config has been merged the
+ // finalization pass will take care of removing this key entirely
+ return false;
+ }
+
+ if (false === $leftSide || !$this->performDeepMerging) {
+ return $rightSide;
+ }
+
+ foreach ($rightSide as $k => $v) {
+ // no conflict
+ if (!array_key_exists($k, $leftSide)) {
+ if (!$this->allowNewKeys) {
+ $ex = new InvalidConfigurationException(sprintf(
+ 'You are not allowed to define new elements for path "%s". '
+ .'Please define all elements for this path in one config file. '
+ .'If you are trying to overwrite an element, make sure you redefine it '
+ .'with the same name.',
+ $this->getPath()
+ ));
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ $leftSide[$k] = $v;
+ continue;
+ }
+
+ if (!isset($this->children[$k])) {
+ throw new \RuntimeException('merge() expects a normalized config array.');
+ }
+
+ $leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v);
+ }
+
+ return $leftSide;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/BaseNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/BaseNode.php
new file mode 100644
index 0000000..afccc1c
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/BaseNode.php
@@ -0,0 +1,360 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\Exception;
+use Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException;
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
+
+/**
+ * The base node class.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+abstract class BaseNode implements NodeInterface
+{
+ protected $name;
+ protected $parent;
+ protected $normalizationClosures = array();
+ protected $finalValidationClosures = array();
+ protected $allowOverwrite = true;
+ protected $required = false;
+ protected $equivalentValues = array();
+ protected $attributes = array();
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of the node
+ * @param NodeInterface $parent The parent of this node
+ *
+ * @throws \InvalidArgumentException if the name contains a period.
+ */
+ public function __construct($name, NodeInterface $parent = null)
+ {
+ if (false !== strpos($name, '.')) {
+ throw new \InvalidArgumentException('The name must not contain ".".');
+ }
+
+ $this->name = $name;
+ $this->parent = $parent;
+ }
+
+ public function setAttribute($key, $value)
+ {
+ $this->attributes[$key] = $value;
+ }
+
+ public function getAttribute($key, $default = null)
+ {
+ return isset($this->attributes[$key]) ? $this->attributes[$key] : $default;
+ }
+
+ public function hasAttribute($key)
+ {
+ return isset($this->attributes[$key]);
+ }
+
+ public function getAttributes()
+ {
+ return $this->attributes;
+ }
+
+ public function setAttributes(array $attributes)
+ {
+ $this->attributes = $attributes;
+ }
+
+ public function removeAttribute($key)
+ {
+ unset($this->attributes[$key]);
+ }
+
+ /**
+ * Sets an info message.
+ *
+ * @param string $info
+ */
+ public function setInfo($info)
+ {
+ $this->setAttribute('info', $info);
+ }
+
+ /**
+ * Returns info message.
+ *
+ * @return string The info text
+ */
+ public function getInfo()
+ {
+ return $this->getAttribute('info');
+ }
+
+ /**
+ * Sets the example configuration for this node.
+ *
+ * @param string|array $example
+ */
+ public function setExample($example)
+ {
+ $this->setAttribute('example', $example);
+ }
+
+ /**
+ * Retrieves the example configuration for this node.
+ *
+ * @return string|array The example
+ */
+ public function getExample()
+ {
+ return $this->getAttribute('example');
+ }
+
+ /**
+ * Adds an equivalent value.
+ *
+ * @param mixed $originalValue
+ * @param mixed $equivalentValue
+ */
+ public function addEquivalentValue($originalValue, $equivalentValue)
+ {
+ $this->equivalentValues[] = array($originalValue, $equivalentValue);
+ }
+
+ /**
+ * Set this node as required.
+ *
+ * @param bool $boolean Required node
+ */
+ public function setRequired($boolean)
+ {
+ $this->required = (bool) $boolean;
+ }
+
+ /**
+ * Sets if this node can be overridden.
+ *
+ * @param bool $allow
+ */
+ public function setAllowOverwrite($allow)
+ {
+ $this->allowOverwrite = (bool) $allow;
+ }
+
+ /**
+ * Sets the closures used for normalization.
+ *
+ * @param \Closure[] $closures An array of Closures used for normalization
+ */
+ public function setNormalizationClosures(array $closures)
+ {
+ $this->normalizationClosures = $closures;
+ }
+
+ /**
+ * Sets the closures used for final validation.
+ *
+ * @param \Closure[] $closures An array of Closures used for final validation
+ */
+ public function setFinalValidationClosures(array $closures)
+ {
+ $this->finalValidationClosures = $closures;
+ }
+
+ /**
+ * Checks if this node is required.
+ *
+ * @return bool
+ */
+ public function isRequired()
+ {
+ return $this->required;
+ }
+
+ /**
+ * Returns the name of this node.
+ *
+ * @return string The Node's name.
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Retrieves the path of this node.
+ *
+ * @return string The Node's path
+ */
+ public function getPath()
+ {
+ $path = $this->name;
+
+ if (null !== $this->parent) {
+ $path = $this->parent->getPath().'.'.$path;
+ }
+
+ return $path;
+ }
+
+ /**
+ * Merges two values together.
+ *
+ * @param mixed $leftSide
+ * @param mixed $rightSide
+ *
+ * @return mixed The merged value
+ *
+ * @throws ForbiddenOverwriteException
+ */
+ final public function merge($leftSide, $rightSide)
+ {
+ if (!$this->allowOverwrite) {
+ throw new ForbiddenOverwriteException(sprintf(
+ 'Configuration path "%s" cannot be overwritten. You have to '
+ .'define all options for this path, and any of its sub-paths in '
+ .'one configuration section.',
+ $this->getPath()
+ ));
+ }
+
+ $this->validateType($leftSide);
+ $this->validateType($rightSide);
+
+ return $this->mergeValues($leftSide, $rightSide);
+ }
+
+ /**
+ * Normalizes a value, applying all normalization closures.
+ *
+ * @param mixed $value Value to normalize.
+ *
+ * @return mixed The normalized value.
+ */
+ final public function normalize($value)
+ {
+ $value = $this->preNormalize($value);
+
+ // run custom normalization closures
+ foreach ($this->normalizationClosures as $closure) {
+ $value = $closure($value);
+ }
+
+ // replace value with their equivalent
+ foreach ($this->equivalentValues as $data) {
+ if ($data[0] === $value) {
+ $value = $data[1];
+ }
+ }
+
+ // validate type
+ $this->validateType($value);
+
+ // normalize value
+ return $this->normalizeValue($value);
+ }
+
+ /**
+ * Normalizes the value before any other normalization is applied.
+ *
+ * @param $value
+ *
+ * @return $value The normalized array value
+ */
+ protected function preNormalize($value)
+ {
+ return $value;
+ }
+
+ /**
+ * Returns parent node for this node.
+ *
+ * @return NodeInterface|null
+ */
+ public function getParent()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Finalizes a value, applying all finalization closures.
+ *
+ * @param mixed $value The value to finalize
+ *
+ * @return mixed The finalized value
+ *
+ * @throws Exception
+ * @throws InvalidConfigurationException
+ */
+ final public function finalize($value)
+ {
+ $this->validateType($value);
+
+ $value = $this->finalizeValue($value);
+
+ // Perform validation on the final value if a closure has been set.
+ // The closure is also allowed to return another value.
+ foreach ($this->finalValidationClosures as $closure) {
+ try {
+ $value = $closure($value);
+ } catch (Exception $correctEx) {
+ throw $correctEx;
+ } catch (\Exception $invalid) {
+ throw new InvalidConfigurationException(sprintf(
+ 'Invalid configuration for path "%s": %s',
+ $this->getPath(),
+ $invalid->getMessage()
+ ), $invalid->getCode(), $invalid);
+ }
+ }
+
+ return $value;
+ }
+
+ /**
+ * Validates the type of a Node.
+ *
+ * @param mixed $value The value to validate
+ *
+ * @throws InvalidTypeException when the value is invalid
+ */
+ abstract protected function validateType($value);
+
+ /**
+ * Normalizes the value.
+ *
+ * @param mixed $value The value to normalize.
+ *
+ * @return mixed The normalized value
+ */
+ abstract protected function normalizeValue($value);
+
+ /**
+ * Merges two values together.
+ *
+ * @param mixed $leftSide
+ * @param mixed $rightSide
+ *
+ * @return mixed The merged value
+ */
+ abstract protected function mergeValues($leftSide, $rightSide);
+
+ /**
+ * Finalizes a value.
+ *
+ * @param mixed $value The value to finalize
+ *
+ * @return mixed The finalized value
+ */
+ abstract protected function finalizeValue($value);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/BooleanNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/BooleanNode.php
new file mode 100644
index 0000000..df06b30
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/BooleanNode.php
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
+
+/**
+ * This node represents a Boolean value in the config tree.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class BooleanNode extends ScalarNode
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function validateType($value)
+ {
+ if (!is_bool($value)) {
+ $ex = new InvalidTypeException(sprintf(
+ 'Invalid type for path "%s". Expected boolean, but got %s.',
+ $this->getPath(),
+ gettype($value)
+ ));
+ if ($hint = $this->getInfo()) {
+ $ex->addHint($hint);
+ }
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php
new file mode 100644
index 0000000..c64b2ec
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php
@@ -0,0 +1,489 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\ArrayNode;
+use Symfony\Component\Config\Definition\PrototypedArrayNode;
+use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
+
+/**
+ * This class provides a fluent interface for defining an array node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinitionInterface
+{
+ protected $performDeepMerging = true;
+ protected $ignoreExtraKeys = false;
+ protected $children = array();
+ protected $prototype;
+ protected $atLeastOne = false;
+ protected $allowNewKeys = true;
+ protected $key;
+ protected $removeKeyItem;
+ protected $addDefaults = false;
+ protected $addDefaultChildren = false;
+ protected $nodeBuilder;
+ protected $normalizeKeys = true;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct($name, NodeParentInterface $parent = null)
+ {
+ parent::__construct($name, $parent);
+
+ $this->nullEquivalent = array();
+ $this->trueEquivalent = array();
+ }
+
+ /**
+ * Sets a custom children builder.
+ *
+ * @param NodeBuilder $builder A custom NodeBuilder
+ */
+ public function setBuilder(NodeBuilder $builder)
+ {
+ $this->nodeBuilder = $builder;
+ }
+
+ /**
+ * Returns a builder to add children nodes.
+ *
+ * @return NodeBuilder
+ */
+ public function children()
+ {
+ return $this->getNodeBuilder();
+ }
+
+ /**
+ * Sets a prototype for child nodes.
+ *
+ * @param string $type the type of node
+ *
+ * @return NodeDefinition
+ */
+ public function prototype($type)
+ {
+ return $this->prototype = $this->getNodeBuilder()->node(null, $type)->setParent($this);
+ }
+
+ /**
+ * Adds the default value if the node is not set in the configuration.
+ *
+ * This method is applicable to concrete nodes only (not to prototype nodes).
+ * If this function has been called and the node is not set during the finalization
+ * phase, it's default value will be derived from its children default values.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function addDefaultsIfNotSet()
+ {
+ $this->addDefaults = true;
+
+ return $this;
+ }
+
+ /**
+ * Adds children with a default value when none are defined.
+ *
+ * @param int|string|array|null $children The number of children|The child name|The children names to be added
+ *
+ * This method is applicable to prototype nodes only.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function addDefaultChildrenIfNoneSet($children = null)
+ {
+ $this->addDefaultChildren = $children;
+
+ return $this;
+ }
+
+ /**
+ * Requires the node to have at least one element.
+ *
+ * This method is applicable to prototype nodes only.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function requiresAtLeastOneElement()
+ {
+ $this->atLeastOne = true;
+
+ return $this;
+ }
+
+ /**
+ * Disallows adding news keys in a subsequent configuration.
+ *
+ * If used all keys have to be defined in the same configuration file.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function disallowNewKeysInSubsequentConfigs()
+ {
+ $this->allowNewKeys = false;
+
+ return $this;
+ }
+
+ /**
+ * Sets a normalization rule for XML configurations.
+ *
+ * @param string $singular The key to remap
+ * @param string $plural The plural of the key for irregular plurals
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function fixXmlConfig($singular, $plural = null)
+ {
+ $this->normalization()->remap($singular, $plural);
+
+ return $this;
+ }
+
+ /**
+ * Sets the attribute which value is to be used as key.
+ *
+ * This is useful when you have an indexed array that should be an
+ * associative array. You can select an item from within the array
+ * to be the key of the particular item. For example, if "id" is the
+ * "key", then:
+ *
+ * array(
+ * array('id' => 'my_name', 'foo' => 'bar'),
+ * );
+ *
+ * becomes
+ *
+ * array(
+ * 'my_name' => array('foo' => 'bar'),
+ * );
+ *
+ * If you'd like "'id' => 'my_name'" to still be present in the resulting
+ * array, then you can set the second argument of this method to false.
+ *
+ * This method is applicable to prototype nodes only.
+ *
+ * @param string $name The name of the key
+ * @param bool $removeKeyItem Whether or not the key item should be removed.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function useAttributeAsKey($name, $removeKeyItem = true)
+ {
+ $this->key = $name;
+ $this->removeKeyItem = $removeKeyItem;
+
+ return $this;
+ }
+
+ /**
+ * Sets whether the node can be unset.
+ *
+ * @param bool $allow
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function canBeUnset($allow = true)
+ {
+ $this->merge()->allowUnset($allow);
+
+ return $this;
+ }
+
+ /**
+ * Adds an "enabled" boolean to enable the current section.
+ *
+ * By default, the section is disabled. If any configuration is specified then
+ * the node will be automatically enabled:
+ *
+ * enableableArrayNode: {enabled: true, ...} # The config is enabled & default values get overridden
+ * enableableArrayNode: ~ # The config is enabled & use the default values
+ * enableableArrayNode: true # The config is enabled & use the default values
+ * enableableArrayNode: {other: value, ...} # The config is enabled & default values get overridden
+ * enableableArrayNode: {enabled: false, ...} # The config is disabled
+ * enableableArrayNode: false # The config is disabled
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function canBeEnabled()
+ {
+ $this
+ ->addDefaultsIfNotSet()
+ ->treatFalseLike(array('enabled' => false))
+ ->treatTrueLike(array('enabled' => true))
+ ->treatNullLike(array('enabled' => true))
+ ->beforeNormalization()
+ ->ifArray()
+ ->then(function ($v) {
+ $v['enabled'] = isset($v['enabled']) ? $v['enabled'] : true;
+
+ return $v;
+ })
+ ->end()
+ ->children()
+ ->booleanNode('enabled')
+ ->defaultFalse()
+ ;
+
+ return $this;
+ }
+
+ /**
+ * Adds an "enabled" boolean to enable the current section.
+ *
+ * By default, the section is enabled.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function canBeDisabled()
+ {
+ $this
+ ->addDefaultsIfNotSet()
+ ->treatFalseLike(array('enabled' => false))
+ ->treatTrueLike(array('enabled' => true))
+ ->treatNullLike(array('enabled' => true))
+ ->children()
+ ->booleanNode('enabled')
+ ->defaultTrue()
+ ;
+
+ return $this;
+ }
+
+ /**
+ * Disables the deep merging of the node.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function performNoDeepMerging()
+ {
+ $this->performDeepMerging = false;
+
+ return $this;
+ }
+
+ /**
+ * Allows extra config keys to be specified under an array without
+ * throwing an exception.
+ *
+ * Those config values are simply ignored and removed from the
+ * resulting array. This should be used only in special cases where
+ * you want to send an entire configuration array through a special
+ * tree that processes only part of the array.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function ignoreExtraKeys()
+ {
+ $this->ignoreExtraKeys = true;
+
+ return $this;
+ }
+
+ /**
+ * Sets key normalization.
+ *
+ * @param bool $bool Whether to enable key normalization
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function normalizeKeys($bool)
+ {
+ $this->normalizeKeys = (bool) $bool;
+
+ return $this;
+ }
+
+ /**
+ * Appends a node definition.
+ *
+ * $node = new ArrayNodeDefinition()
+ * ->children()
+ * ->scalarNode('foo')->end()
+ * ->scalarNode('baz')->end()
+ * ->end()
+ * ->append($this->getBarNodeDefinition())
+ * ;
+ *
+ * @param NodeDefinition $node A NodeDefinition instance
+ *
+ * @return ArrayNodeDefinition This node
+ */
+ public function append(NodeDefinition $node)
+ {
+ $this->children[$node->name] = $node->setParent($this);
+
+ return $this;
+ }
+
+ /**
+ * Returns a node builder to be used to add children and prototype.
+ *
+ * @return NodeBuilder The node builder
+ */
+ protected function getNodeBuilder()
+ {
+ if (null === $this->nodeBuilder) {
+ $this->nodeBuilder = new NodeBuilder();
+ }
+
+ return $this->nodeBuilder->setParent($this);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function createNode()
+ {
+ if (null === $this->prototype) {
+ $node = new ArrayNode($this->name, $this->parent);
+
+ $this->validateConcreteNode($node);
+
+ $node->setAddIfNotSet($this->addDefaults);
+
+ foreach ($this->children as $child) {
+ $child->parent = $node;
+ $node->addChild($child->getNode());
+ }
+ } else {
+ $node = new PrototypedArrayNode($this->name, $this->parent);
+
+ $this->validatePrototypeNode($node);
+
+ if (null !== $this->key) {
+ $node->setKeyAttribute($this->key, $this->removeKeyItem);
+ }
+
+ if (true === $this->atLeastOne) {
+ $node->setMinNumberOfElements(1);
+ }
+
+ if ($this->default) {
+ $node->setDefaultValue($this->defaultValue);
+ }
+
+ if (false !== $this->addDefaultChildren) {
+ $node->setAddChildrenIfNoneSet($this->addDefaultChildren);
+ if ($this->prototype instanceof static && null === $this->prototype->prototype) {
+ $this->prototype->addDefaultsIfNotSet();
+ }
+ }
+
+ $this->prototype->parent = $node;
+ $node->setPrototype($this->prototype->getNode());
+ }
+
+ $node->setAllowNewKeys($this->allowNewKeys);
+ $node->addEquivalentValue(null, $this->nullEquivalent);
+ $node->addEquivalentValue(true, $this->trueEquivalent);
+ $node->addEquivalentValue(false, $this->falseEquivalent);
+ $node->setPerformDeepMerging($this->performDeepMerging);
+ $node->setRequired($this->required);
+ $node->setIgnoreExtraKeys($this->ignoreExtraKeys);
+ $node->setNormalizeKeys($this->normalizeKeys);
+
+ if (null !== $this->normalization) {
+ $node->setNormalizationClosures($this->normalization->before);
+ $node->setXmlRemappings($this->normalization->remappings);
+ }
+
+ if (null !== $this->merge) {
+ $node->setAllowOverwrite($this->merge->allowOverwrite);
+ $node->setAllowFalse($this->merge->allowFalse);
+ }
+
+ if (null !== $this->validation) {
+ $node->setFinalValidationClosures($this->validation->rules);
+ }
+
+ return $node;
+ }
+
+ /**
+ * Validate the configuration of a concrete node.
+ *
+ * @param ArrayNode $node The related node
+ *
+ * @throws InvalidDefinitionException
+ */
+ protected function validateConcreteNode(ArrayNode $node)
+ {
+ $path = $node->getPath();
+
+ if (null !== $this->key) {
+ throw new InvalidDefinitionException(
+ sprintf('->useAttributeAsKey() is not applicable to concrete nodes at path "%s"', $path)
+ );
+ }
+
+ if (true === $this->atLeastOne) {
+ throw new InvalidDefinitionException(
+ sprintf('->requiresAtLeastOneElement() is not applicable to concrete nodes at path "%s"', $path)
+ );
+ }
+
+ if ($this->default) {
+ throw new InvalidDefinitionException(
+ sprintf('->defaultValue() is not applicable to concrete nodes at path "%s"', $path)
+ );
+ }
+
+ if (false !== $this->addDefaultChildren) {
+ throw new InvalidDefinitionException(
+ sprintf('->addDefaultChildrenIfNoneSet() is not applicable to concrete nodes at path "%s"', $path)
+ );
+ }
+ }
+
+ /**
+ * Validate the configuration of a prototype node.
+ *
+ * @param PrototypedArrayNode $node The related node
+ *
+ * @throws InvalidDefinitionException
+ */
+ protected function validatePrototypeNode(PrototypedArrayNode $node)
+ {
+ $path = $node->getPath();
+
+ if ($this->addDefaults) {
+ throw new InvalidDefinitionException(
+ sprintf('->addDefaultsIfNotSet() is not applicable to prototype nodes at path "%s"', $path)
+ );
+ }
+
+ if (false !== $this->addDefaultChildren) {
+ if ($this->default) {
+ throw new InvalidDefinitionException(
+ sprintf('A default value and default children might not be used together at path "%s"', $path)
+ );
+ }
+
+ if (null !== $this->key && (null === $this->addDefaultChildren || is_int($this->addDefaultChildren) && $this->addDefaultChildren > 0)) {
+ throw new InvalidDefinitionException(
+ sprintf('->addDefaultChildrenIfNoneSet() should set default children names as ->useAttributeAsKey() is used at path "%s"', $path)
+ );
+ }
+
+ if (null === $this->key && (is_string($this->addDefaultChildren) || is_array($this->addDefaultChildren))) {
+ throw new InvalidDefinitionException(
+ sprintf('->addDefaultChildrenIfNoneSet() might not set default children names as ->useAttributeAsKey() is not used at path "%s"', $path)
+ );
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php
new file mode 100644
index 0000000..db7ebc2
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\BooleanNode;
+
+/**
+ * This class provides a fluent interface for defining a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class BooleanNodeDefinition extends ScalarNodeDefinition
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct($name, NodeParentInterface $parent = null)
+ {
+ parent::__construct($name, $parent);
+
+ $this->nullEquivalent = true;
+ }
+
+ /**
+ * Instantiate a Node.
+ *
+ * @return BooleanNode The node
+ */
+ protected function instantiateNode()
+ {
+ return new BooleanNode($this->name, $this->parent);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php
new file mode 100644
index 0000000..dc25fcb
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\EnumNode;
+
+/**
+ * Enum Node Definition.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class EnumNodeDefinition extends ScalarNodeDefinition
+{
+ private $values;
+
+ /**
+ * @param array $values
+ *
+ * @return EnumNodeDefinition|$this
+ */
+ public function values(array $values)
+ {
+ $values = array_unique($values);
+
+ if (count($values) <= 1) {
+ throw new \InvalidArgumentException('->values() must be called with at least two distinct values.');
+ }
+
+ $this->values = $values;
+
+ return $this;
+ }
+
+ /**
+ * Instantiate a Node.
+ *
+ * @return EnumNode The node
+ *
+ * @throws \RuntimeException
+ */
+ protected function instantiateNode()
+ {
+ if (null === $this->values) {
+ throw new \RuntimeException('You must call ->values() on enum nodes.');
+ }
+
+ return new EnumNode($this->name, $this->parent, $this->values);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ExprBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ExprBuilder.php
new file mode 100644
index 0000000..7887f2d
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ExprBuilder.php
@@ -0,0 +1,238 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
+
+/**
+ * This class builds an if expression.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class ExprBuilder
+{
+ protected $node;
+ public $ifPart;
+ public $thenPart;
+
+ /**
+ * Constructor.
+ *
+ * @param NodeDefinition $node The related node
+ */
+ public function __construct(NodeDefinition $node)
+ {
+ $this->node = $node;
+ }
+
+ /**
+ * Marks the expression as being always used.
+ *
+ * @param \Closure $then
+ *
+ * @return ExprBuilder
+ */
+ public function always(\Closure $then = null)
+ {
+ $this->ifPart = function ($v) { return true; };
+
+ if (null !== $then) {
+ $this->thenPart = $then;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Sets a closure to use as tests.
+ *
+ * The default one tests if the value is true.
+ *
+ * @param \Closure $closure
+ *
+ * @return ExprBuilder
+ */
+ public function ifTrue(\Closure $closure = null)
+ {
+ if (null === $closure) {
+ $closure = function ($v) { return true === $v; };
+ }
+
+ $this->ifPart = $closure;
+
+ return $this;
+ }
+
+ /**
+ * Tests if the value is a string.
+ *
+ * @return ExprBuilder
+ */
+ public function ifString()
+ {
+ $this->ifPart = function ($v) { return is_string($v); };
+
+ return $this;
+ }
+
+ /**
+ * Tests if the value is null.
+ *
+ * @return ExprBuilder
+ */
+ public function ifNull()
+ {
+ $this->ifPart = function ($v) { return null === $v; };
+
+ return $this;
+ }
+
+ /**
+ * Tests if the value is an array.
+ *
+ * @return ExprBuilder
+ */
+ public function ifArray()
+ {
+ $this->ifPart = function ($v) { return is_array($v); };
+
+ return $this;
+ }
+
+ /**
+ * Tests if the value is in an array.
+ *
+ * @param array $array
+ *
+ * @return ExprBuilder
+ */
+ public function ifInArray(array $array)
+ {
+ $this->ifPart = function ($v) use ($array) { return in_array($v, $array, true); };
+
+ return $this;
+ }
+
+ /**
+ * Tests if the value is not in an array.
+ *
+ * @param array $array
+ *
+ * @return ExprBuilder
+ */
+ public function ifNotInArray(array $array)
+ {
+ $this->ifPart = function ($v) use ($array) { return !in_array($v, $array, true); };
+
+ return $this;
+ }
+
+ /**
+ * Sets the closure to run if the test pass.
+ *
+ * @param \Closure $closure
+ *
+ * @return ExprBuilder
+ */
+ public function then(\Closure $closure)
+ {
+ $this->thenPart = $closure;
+
+ return $this;
+ }
+
+ /**
+ * Sets a closure returning an empty array.
+ *
+ * @return ExprBuilder
+ */
+ public function thenEmptyArray()
+ {
+ $this->thenPart = function ($v) { return array(); };
+
+ return $this;
+ }
+
+ /**
+ * Sets a closure marking the value as invalid at validation time.
+ *
+ * if you want to add the value of the node in your message just use a %s placeholder.
+ *
+ * @param string $message
+ *
+ * @return ExprBuilder
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function thenInvalid($message)
+ {
+ $this->thenPart = function ($v) use ($message) {throw new \InvalidArgumentException(sprintf($message, json_encode($v))); };
+
+ return $this;
+ }
+
+ /**
+ * Sets a closure unsetting this key of the array at validation time.
+ *
+ * @return ExprBuilder
+ *
+ * @throws UnsetKeyException
+ */
+ public function thenUnset()
+ {
+ $this->thenPart = function ($v) { throw new UnsetKeyException('Unsetting key'); };
+
+ return $this;
+ }
+
+ /**
+ * Returns the related node.
+ *
+ * @return NodeDefinition
+ *
+ * @throws \RuntimeException
+ */
+ public function end()
+ {
+ if (null === $this->ifPart) {
+ throw new \RuntimeException('You must specify an if part.');
+ }
+ if (null === $this->thenPart) {
+ throw new \RuntimeException('You must specify a then part.');
+ }
+
+ return $this->node;
+ }
+
+ /**
+ * Builds the expressions.
+ *
+ * @param ExprBuilder[] $expressions An array of ExprBuilder instances to build
+ *
+ * @return array
+ */
+ public static function buildExpressions(array $expressions)
+ {
+ foreach ($expressions as $k => $expr) {
+ if ($expr instanceof ExprBuilder) {
+ $if = $expr->ifPart;
+ $then = $expr->thenPart;
+ $expressions[$k] = function ($v) use ($if, $then) {
+ return $if($v) ? $then($v) : $v;
+ };
+ }
+ }
+
+ return $expressions;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php
new file mode 100644
index 0000000..c0bed46
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\FloatNode;
+
+/**
+ * This class provides a fluent interface for defining a float node.
+ *
+ * @author Jeanmonod David <david.jeanmonod@gmail.com>
+ */
+class FloatNodeDefinition extends NumericNodeDefinition
+{
+ /**
+ * Instantiates a Node.
+ *
+ * @return FloatNode The node
+ */
+ protected function instantiateNode()
+ {
+ return new FloatNode($this->name, $this->parent, $this->min, $this->max);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php
new file mode 100644
index 0000000..f6c3c14
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\IntegerNode;
+
+/**
+ * This class provides a fluent interface for defining an integer node.
+ *
+ * @author Jeanmonod David <david.jeanmonod@gmail.com>
+ */
+class IntegerNodeDefinition extends NumericNodeDefinition
+{
+ /**
+ * Instantiates a Node.
+ *
+ * @return IntegerNode The node
+ */
+ protected function instantiateNode()
+ {
+ return new IntegerNode($this->name, $this->parent, $this->min, $this->max);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/MergeBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/MergeBuilder.php
new file mode 100644
index 0000000..f908a49
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/MergeBuilder.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+/**
+ * This class builds merge conditions.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class MergeBuilder
+{
+ protected $node;
+ public $allowFalse = false;
+ public $allowOverwrite = true;
+
+ /**
+ * Constructor.
+ *
+ * @param NodeDefinition $node The related node
+ */
+ public function __construct(NodeDefinition $node)
+ {
+ $this->node = $node;
+ }
+
+ /**
+ * Sets whether the node can be unset.
+ *
+ * @param bool $allow
+ *
+ * @return MergeBuilder
+ */
+ public function allowUnset($allow = true)
+ {
+ $this->allowFalse = $allow;
+
+ return $this;
+ }
+
+ /**
+ * Sets whether the node can be overwritten.
+ *
+ * @param bool $deny Whether the overwriting is forbidden or not
+ *
+ * @return MergeBuilder
+ */
+ public function denyOverwrite($deny = true)
+ {
+ $this->allowOverwrite = !$deny;
+
+ return $this;
+ }
+
+ /**
+ * Returns the related node.
+ *
+ * @return NodeDefinition
+ */
+ public function end()
+ {
+ return $this->node;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeBuilder.php
new file mode 100644
index 0000000..b2b6336
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeBuilder.php
@@ -0,0 +1,245 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+/**
+ * This class provides a fluent interface for building a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class NodeBuilder implements NodeParentInterface
+{
+ protected $parent;
+ protected $nodeMapping;
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ $this->nodeMapping = array(
+ 'variable' => __NAMESPACE__.'\\VariableNodeDefinition',
+ 'scalar' => __NAMESPACE__.'\\ScalarNodeDefinition',
+ 'boolean' => __NAMESPACE__.'\\BooleanNodeDefinition',
+ 'integer' => __NAMESPACE__.'\\IntegerNodeDefinition',
+ 'float' => __NAMESPACE__.'\\FloatNodeDefinition',
+ 'array' => __NAMESPACE__.'\\ArrayNodeDefinition',
+ 'enum' => __NAMESPACE__.'\\EnumNodeDefinition',
+ );
+ }
+
+ /**
+ * Set the parent node.
+ *
+ * @param ParentNodeDefinitionInterface $parent The parent node
+ *
+ * @return NodeBuilder This node builder
+ */
+ public function setParent(ParentNodeDefinitionInterface $parent = null)
+ {
+ $this->parent = $parent;
+
+ return $this;
+ }
+
+ /**
+ * Creates a child array node.
+ *
+ * @param string $name The name of the node
+ *
+ * @return ArrayNodeDefinition The child node
+ */
+ public function arrayNode($name)
+ {
+ return $this->node($name, 'array');
+ }
+
+ /**
+ * Creates a child scalar node.
+ *
+ * @param string $name the name of the node
+ *
+ * @return ScalarNodeDefinition The child node
+ */
+ public function scalarNode($name)
+ {
+ return $this->node($name, 'scalar');
+ }
+
+ /**
+ * Creates a child Boolean node.
+ *
+ * @param string $name The name of the node
+ *
+ * @return BooleanNodeDefinition The child node
+ */
+ public function booleanNode($name)
+ {
+ return $this->node($name, 'boolean');
+ }
+
+ /**
+ * Creates a child integer node.
+ *
+ * @param string $name the name of the node
+ *
+ * @return IntegerNodeDefinition The child node
+ */
+ public function integerNode($name)
+ {
+ return $this->node($name, 'integer');
+ }
+
+ /**
+ * Creates a child float node.
+ *
+ * @param string $name the name of the node
+ *
+ * @return FloatNodeDefinition The child node
+ */
+ public function floatNode($name)
+ {
+ return $this->node($name, 'float');
+ }
+
+ /**
+ * Creates a child EnumNode.
+ *
+ * @param string $name
+ *
+ * @return EnumNodeDefinition
+ */
+ public function enumNode($name)
+ {
+ return $this->node($name, 'enum');
+ }
+
+ /**
+ * Creates a child variable node.
+ *
+ * @param string $name The name of the node
+ *
+ * @return VariableNodeDefinition The builder of the child node
+ */
+ public function variableNode($name)
+ {
+ return $this->node($name, 'variable');
+ }
+
+ /**
+ * Returns the parent node.
+ *
+ * @return ParentNodeDefinitionInterface The parent node
+ */
+ public function end()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Creates a child node.
+ *
+ * @param string $name The name of the node
+ * @param string $type The type of the node
+ *
+ * @return NodeDefinition The child node
+ *
+ * @throws \RuntimeException When the node type is not registered
+ * @throws \RuntimeException When the node class is not found
+ */
+ public function node($name, $type)
+ {
+ $class = $this->getNodeClass($type);
+
+ $node = new $class($name);
+
+ $this->append($node);
+
+ return $node;
+ }
+
+ /**
+ * Appends a node definition.
+ *
+ * Usage:
+ *
+ * $node = new ArrayNodeDefinition('name')
+ * ->children()
+ * ->scalarNode('foo')->end()
+ * ->scalarNode('baz')->end()
+ * ->append($this->getBarNodeDefinition())
+ * ->end()
+ * ;
+ *
+ * @param NodeDefinition $node
+ *
+ * @return NodeBuilder This node builder
+ */
+ public function append(NodeDefinition $node)
+ {
+ if ($node instanceof ParentNodeDefinitionInterface) {
+ $builder = clone $this;
+ $builder->setParent(null);
+ $node->setBuilder($builder);
+ }
+
+ if (null !== $this->parent) {
+ $this->parent->append($node);
+ // Make this builder the node parent to allow for a fluid interface
+ $node->setParent($this);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds or overrides a node Type.
+ *
+ * @param string $type The name of the type
+ * @param string $class The fully qualified name the node definition class
+ *
+ * @return NodeBuilder This node builder
+ */
+ public function setNodeClass($type, $class)
+ {
+ $this->nodeMapping[strtolower($type)] = $class;
+
+ return $this;
+ }
+
+ /**
+ * Returns the class name of the node definition.
+ *
+ * @param string $type The node type
+ *
+ * @return string The node definition class name
+ *
+ * @throws \RuntimeException When the node type is not registered
+ * @throws \RuntimeException When the node class is not found
+ */
+ protected function getNodeClass($type)
+ {
+ $type = strtolower($type);
+
+ if (!isset($this->nodeMapping[$type])) {
+ throw new \RuntimeException(sprintf('The node type "%s" is not registered.', $type));
+ }
+
+ $class = $this->nodeMapping[$type];
+
+ if (!class_exists($class)) {
+ throw new \RuntimeException(sprintf('The node class "%s" does not exist.', $class));
+ }
+
+ return $class;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeDefinition.php
new file mode 100644
index 0000000..f7f84bc
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeDefinition.php
@@ -0,0 +1,343 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\NodeInterface;
+use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
+
+/**
+ * This class provides a fluent interface for defining a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+abstract class NodeDefinition implements NodeParentInterface
+{
+ protected $name;
+ protected $normalization;
+ protected $validation;
+ protected $defaultValue;
+ protected $default = false;
+ protected $required = false;
+ protected $merge;
+ protected $allowEmptyValue = true;
+ protected $nullEquivalent;
+ protected $trueEquivalent = true;
+ protected $falseEquivalent = false;
+
+ /**
+ * @var NodeParentInterface|null
+ */
+ protected $parent;
+ protected $attributes = array();
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of the node
+ * @param NodeParentInterface|null $parent The parent
+ */
+ public function __construct($name, NodeParentInterface $parent = null)
+ {
+ $this->parent = $parent;
+ $this->name = $name;
+ }
+
+ /**
+ * Sets the parent node.
+ *
+ * @param NodeParentInterface $parent The parent
+ *
+ * @return NodeDefinition|$this
+ */
+ public function setParent(NodeParentInterface $parent)
+ {
+ $this->parent = $parent;
+
+ return $this;
+ }
+
+ /**
+ * Sets info message.
+ *
+ * @param string $info The info text
+ *
+ * @return NodeDefinition|$this
+ */
+ public function info($info)
+ {
+ return $this->attribute('info', $info);
+ }
+
+ /**
+ * Sets example configuration.
+ *
+ * @param string|array $example
+ *
+ * @return NodeDefinition|$this
+ */
+ public function example($example)
+ {
+ return $this->attribute('example', $example);
+ }
+
+ /**
+ * Sets an attribute on the node.
+ *
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return NodeDefinition|$this
+ */
+ public function attribute($key, $value)
+ {
+ $this->attributes[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Returns the parent node.
+ *
+ * @return NodeParentInterface|null The builder of the parent node
+ */
+ public function end()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Creates the node.
+ *
+ * @param bool $forceRootNode Whether to force this node as the root node
+ *
+ * @return NodeInterface
+ */
+ public function getNode($forceRootNode = false)
+ {
+ if ($forceRootNode) {
+ $this->parent = null;
+ }
+
+ if (null !== $this->normalization) {
+ $this->normalization->before = ExprBuilder::buildExpressions($this->normalization->before);
+ }
+
+ if (null !== $this->validation) {
+ $this->validation->rules = ExprBuilder::buildExpressions($this->validation->rules);
+ }
+
+ $node = $this->createNode();
+ $node->setAttributes($this->attributes);
+
+ return $node;
+ }
+
+ /**
+ * Sets the default value.
+ *
+ * @param mixed $value The default value
+ *
+ * @return NodeDefinition|$this
+ */
+ public function defaultValue($value)
+ {
+ $this->default = true;
+ $this->defaultValue = $value;
+
+ return $this;
+ }
+
+ /**
+ * Sets the node as required.
+ *
+ * @return NodeDefinition|$this
+ */
+ public function isRequired()
+ {
+ $this->required = true;
+
+ return $this;
+ }
+
+ /**
+ * Sets the equivalent value used when the node contains null.
+ *
+ * @param mixed $value
+ *
+ * @return NodeDefinition|$this
+ */
+ public function treatNullLike($value)
+ {
+ $this->nullEquivalent = $value;
+
+ return $this;
+ }
+
+ /**
+ * Sets the equivalent value used when the node contains true.
+ *
+ * @param mixed $value
+ *
+ * @return NodeDefinition|$this
+ */
+ public function treatTrueLike($value)
+ {
+ $this->trueEquivalent = $value;
+
+ return $this;
+ }
+
+ /**
+ * Sets the equivalent value used when the node contains false.
+ *
+ * @param mixed $value
+ *
+ * @return NodeDefinition|$this
+ */
+ public function treatFalseLike($value)
+ {
+ $this->falseEquivalent = $value;
+
+ return $this;
+ }
+
+ /**
+ * Sets null as the default value.
+ *
+ * @return NodeDefinition|$this
+ */
+ public function defaultNull()
+ {
+ return $this->defaultValue(null);
+ }
+
+ /**
+ * Sets true as the default value.
+ *
+ * @return NodeDefinition|$this
+ */
+ public function defaultTrue()
+ {
+ return $this->defaultValue(true);
+ }
+
+ /**
+ * Sets false as the default value.
+ *
+ * @return NodeDefinition|$this
+ */
+ public function defaultFalse()
+ {
+ return $this->defaultValue(false);
+ }
+
+ /**
+ * Sets an expression to run before the normalization.
+ *
+ * @return ExprBuilder
+ */
+ public function beforeNormalization()
+ {
+ return $this->normalization()->before();
+ }
+
+ /**
+ * Denies the node value being empty.
+ *
+ * @return NodeDefinition|$this
+ */
+ public function cannotBeEmpty()
+ {
+ $this->allowEmptyValue = false;
+
+ return $this;
+ }
+
+ /**
+ * Sets an expression to run for the validation.
+ *
+ * The expression receives the value of the node and must return it. It can
+ * modify it.
+ * An exception should be thrown when the node is not valid.
+ *
+ * @return ExprBuilder
+ */
+ public function validate()
+ {
+ return $this->validation()->rule();
+ }
+
+ /**
+ * Sets whether the node can be overwritten.
+ *
+ * @param bool $deny Whether the overwriting is forbidden or not
+ *
+ * @return NodeDefinition|$this
+ */
+ public function cannotBeOverwritten($deny = true)
+ {
+ $this->merge()->denyOverwrite($deny);
+
+ return $this;
+ }
+
+ /**
+ * Gets the builder for validation rules.
+ *
+ * @return ValidationBuilder
+ */
+ protected function validation()
+ {
+ if (null === $this->validation) {
+ $this->validation = new ValidationBuilder($this);
+ }
+
+ return $this->validation;
+ }
+
+ /**
+ * Gets the builder for merging rules.
+ *
+ * @return MergeBuilder
+ */
+ protected function merge()
+ {
+ if (null === $this->merge) {
+ $this->merge = new MergeBuilder($this);
+ }
+
+ return $this->merge;
+ }
+
+ /**
+ * Gets the builder for normalization rules.
+ *
+ * @return NormalizationBuilder
+ */
+ protected function normalization()
+ {
+ if (null === $this->normalization) {
+ $this->normalization = new NormalizationBuilder($this);
+ }
+
+ return $this->normalization;
+ }
+
+ /**
+ * Instantiate and configure the node according to this definition.
+ *
+ * @return NodeInterface $node The node instance
+ *
+ * @throws InvalidDefinitionException When the definition is invalid
+ */
+ abstract protected function createNode();
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php
new file mode 100644
index 0000000..305e993
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+/**
+ * An interface that must be implemented by all node parents.
+ *
+ * @author Victor Berchet <victor@suumit.com>
+ */
+interface NodeParentInterface
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php
new file mode 100644
index 0000000..748c9f2
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+/**
+ * This class builds normalization conditions.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class NormalizationBuilder
+{
+ protected $node;
+ public $before = array();
+ public $remappings = array();
+
+ /**
+ * Constructor.
+ *
+ * @param NodeDefinition $node The related node
+ */
+ public function __construct(NodeDefinition $node)
+ {
+ $this->node = $node;
+ }
+
+ /**
+ * Registers a key to remap to its plural form.
+ *
+ * @param string $key The key to remap
+ * @param string $plural The plural of the key in case of irregular plural
+ *
+ * @return NormalizationBuilder
+ */
+ public function remap($key, $plural = null)
+ {
+ $this->remappings[] = array($key, null === $plural ? $key.'s' : $plural);
+
+ return $this;
+ }
+
+ /**
+ * Registers a closure to run before the normalization or an expression builder to build it if null is provided.
+ *
+ * @param \Closure $closure
+ *
+ * @return ExprBuilder|NormalizationBuilder
+ */
+ public function before(\Closure $closure = null)
+ {
+ if (null !== $closure) {
+ $this->before[] = $closure;
+
+ return $this;
+ }
+
+ return $this->before[] = new ExprBuilder($this->node);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php
new file mode 100644
index 0000000..ddd716d
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+/**
+ * Abstract class that contains common code of integer and float node definitions.
+ *
+ * @author David Jeanmonod <david.jeanmonod@gmail.com>
+ */
+abstract class NumericNodeDefinition extends ScalarNodeDefinition
+{
+ protected $min;
+ protected $max;
+
+ /**
+ * Ensures that the value is smaller than the given reference.
+ *
+ * @param mixed $max
+ *
+ * @return NumericNodeDefinition
+ *
+ * @throws \InvalidArgumentException when the constraint is inconsistent
+ */
+ public function max($max)
+ {
+ if (isset($this->min) && $this->min > $max) {
+ throw new \InvalidArgumentException(sprintf('You cannot define a max(%s) as you already have a min(%s)', $max, $this->min));
+ }
+ $this->max = $max;
+
+ return $this;
+ }
+
+ /**
+ * Ensures that the value is bigger than the given reference.
+ *
+ * @param mixed $min
+ *
+ * @return NumericNodeDefinition
+ *
+ * @throws \InvalidArgumentException when the constraint is inconsistent
+ */
+ public function min($min)
+ {
+ if (isset($this->max) && $this->max < $min) {
+ throw new \InvalidArgumentException(sprintf('You cannot define a min(%s) as you already have a max(%s)', $min, $this->max));
+ }
+ $this->min = $min;
+
+ return $this;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php
new file mode 100644
index 0000000..575495b
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+/**
+ * An interface that must be implemented by nodes which can have children.
+ *
+ * @author Victor Berchet <victor@suumit.com>
+ */
+interface ParentNodeDefinitionInterface
+{
+ public function children();
+
+ public function append(NodeDefinition $node);
+
+ public function setBuilder(NodeBuilder $builder);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php
new file mode 100644
index 0000000..6170555
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\ScalarNode;
+
+/**
+ * This class provides a fluent interface for defining a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ScalarNodeDefinition extends VariableNodeDefinition
+{
+ /**
+ * Instantiate a Node.
+ *
+ * @return ScalarNode The node
+ */
+ protected function instantiateNode()
+ {
+ return new ScalarNode($this->name, $this->parent);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/TreeBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/TreeBuilder.php
new file mode 100644
index 0000000..5d02848
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/TreeBuilder.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\NodeInterface;
+
+/**
+ * This is the entry class for building a config tree.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class TreeBuilder implements NodeParentInterface
+{
+ protected $tree;
+ protected $root;
+ protected $builder;
+
+ /**
+ * Creates the root node.
+ *
+ * @param string $name The name of the root node
+ * @param string $type The type of the root node
+ * @param NodeBuilder $builder A custom node builder instance
+ *
+ * @return ArrayNodeDefinition|NodeDefinition The root node (as an ArrayNodeDefinition when the type is 'array')
+ *
+ * @throws \RuntimeException When the node type is not supported
+ */
+ public function root($name, $type = 'array', NodeBuilder $builder = null)
+ {
+ $builder = $builder ?: new NodeBuilder();
+
+ return $this->root = $builder->node($name, $type)->setParent($this);
+ }
+
+ /**
+ * Builds the tree.
+ *
+ * @return NodeInterface
+ *
+ * @throws \RuntimeException
+ */
+ public function buildTree()
+ {
+ if (null === $this->root) {
+ throw new \RuntimeException('The configuration tree has no root node.');
+ }
+ if (null !== $this->tree) {
+ return $this->tree;
+ }
+
+ return $this->tree = $this->root->getNode(true);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php
new file mode 100644
index 0000000..e885823
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+/**
+ * This class builds validation conditions.
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class ValidationBuilder
+{
+ protected $node;
+ public $rules = array();
+
+ /**
+ * Constructor.
+ *
+ * @param NodeDefinition $node The related node
+ */
+ public function __construct(NodeDefinition $node)
+ {
+ $this->node = $node;
+ }
+
+ /**
+ * Registers a closure to run as normalization or an expression builder to build it if null is provided.
+ *
+ * @param \Closure $closure
+ *
+ * @return ExprBuilder|ValidationBuilder
+ */
+ public function rule(\Closure $closure = null)
+ {
+ if (null !== $closure) {
+ $this->rules[] = $closure;
+
+ return $this;
+ }
+
+ return $this->rules[] = new ExprBuilder($this->node);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php
new file mode 100644
index 0000000..a46b7ea
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\VariableNode;
+
+/**
+ * This class provides a fluent interface for defining a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class VariableNodeDefinition extends NodeDefinition
+{
+ /**
+ * Instantiate a Node.
+ *
+ * @return VariableNode The node
+ */
+ protected function instantiateNode()
+ {
+ return new VariableNode($this->name, $this->parent);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function createNode()
+ {
+ $node = $this->instantiateNode();
+
+ if (null !== $this->normalization) {
+ $node->setNormalizationClosures($this->normalization->before);
+ }
+
+ if (null !== $this->merge) {
+ $node->setAllowOverwrite($this->merge->allowOverwrite);
+ }
+
+ if (true === $this->default) {
+ $node->setDefaultValue($this->defaultValue);
+ }
+
+ $node->setAllowEmptyValue($this->allowEmptyValue);
+ $node->addEquivalentValue(null, $this->nullEquivalent);
+ $node->addEquivalentValue(true, $this->trueEquivalent);
+ $node->addEquivalentValue(false, $this->falseEquivalent);
+ $node->setRequired($this->required);
+
+ if (null !== $this->validation) {
+ $node->setFinalValidationClosures($this->validation->rules);
+ }
+
+ return $node;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/ConfigurationInterface.php b/vendor/symfony/config/Symfony/Component/Config/Definition/ConfigurationInterface.php
new file mode 100644
index 0000000..d6456ed
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/ConfigurationInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+/**
+ * Configuration interface.
+ *
+ * @author Victor Berchet <victor@suumit.com>
+ */
+interface ConfigurationInterface
+{
+ /**
+ * Generates the configuration tree builder.
+ *
+ * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder
+ */
+ public function getConfigTreeBuilder();
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php
new file mode 100644
index 0000000..ab56a92
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php
@@ -0,0 +1,300 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Dumper;
+
+use Symfony\Component\Config\Definition\ConfigurationInterface;
+use Symfony\Component\Config\Definition\NodeInterface;
+use Symfony\Component\Config\Definition\ArrayNode;
+use Symfony\Component\Config\Definition\EnumNode;
+use Symfony\Component\Config\Definition\PrototypedArrayNode;
+
+/**
+ * Dumps a XML reference configuration for the given configuration/node instance.
+ *
+ * @author Wouter J <waldio.webdesign@gmail.com>
+ */
+class XmlReferenceDumper
+{
+ private $reference;
+
+ public function dump(ConfigurationInterface $configuration, $namespace = null)
+ {
+ return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree(), $namespace);
+ }
+
+ public function dumpNode(NodeInterface $node, $namespace = null)
+ {
+ $this->reference = '';
+ $this->writeNode($node, 0, true, $namespace);
+ $ref = $this->reference;
+ $this->reference = null;
+
+ return $ref;
+ }
+
+ /**
+ * @param NodeInterface $node
+ * @param int $depth
+ * @param bool $root If the node is the root node
+ * @param string $namespace The namespace of the node
+ */
+ private function writeNode(NodeInterface $node, $depth = 0, $root = false, $namespace = null)
+ {
+ $rootName = ($root ? 'config' : $node->getName());
+ $rootNamespace = ($namespace ?: ($root ? 'http://example.org/schema/dic/'.$node->getName() : null));
+
+ // xml remapping
+ if ($node->getParent()) {
+ $remapping = array_filter($node->getParent()->getXmlRemappings(), function ($mapping) use ($rootName) {
+ return $rootName === $mapping[1];
+ });
+
+ if (count($remapping)) {
+ list($singular) = current($remapping);
+ $rootName = $singular;
+ }
+ }
+ $rootName = str_replace('_', '-', $rootName);
+
+ $rootAttributes = array();
+ $rootAttributeComments = array();
+ $rootChildren = array();
+ $rootComments = array();
+
+ if ($node instanceof ArrayNode) {
+ $children = $node->getChildren();
+
+ // comments about the root node
+ if ($rootInfo = $node->getInfo()) {
+ $rootComments[] = $rootInfo;
+ }
+
+ if ($rootNamespace) {
+ $rootComments[] = 'Namespace: '.$rootNamespace;
+ }
+
+ // render prototyped nodes
+ if ($node instanceof PrototypedArrayNode) {
+ array_unshift($rootComments, 'prototype');
+
+ if ($key = $node->getKeyAttribute()) {
+ $rootAttributes[$key] = str_replace('-', ' ', $rootName).' '.$key;
+ }
+
+ $prototype = $node->getPrototype();
+
+ if ($prototype instanceof ArrayNode) {
+ $children = $prototype->getChildren();
+ } else {
+ if ($prototype->hasDefaultValue()) {
+ $prototypeValue = $prototype->getDefaultValue();
+ } else {
+ switch (get_class($prototype)) {
+ case 'Symfony\Component\Config\Definition\ScalarNode':
+ $prototypeValue = 'scalar value';
+ break;
+
+ case 'Symfony\Component\Config\Definition\FloatNode':
+ case 'Symfony\Component\Config\Definition\IntegerNode':
+ $prototypeValue = 'numeric value';
+ break;
+
+ case 'Symfony\Component\Config\Definition\BooleanNode':
+ $prototypeValue = 'true|false';
+ break;
+
+ case 'Symfony\Component\Config\Definition\EnumNode':
+ $prototypeValue = implode('|', array_map('json_encode', $prototype->getValues()));
+ break;
+
+ default:
+ $prototypeValue = 'value';
+ }
+ }
+ }
+ }
+
+ // get attributes and elements
+ foreach ($children as $child) {
+ if (!$child instanceof ArrayNode) {
+ // get attributes
+
+ // metadata
+ $name = str_replace('_', '-', $child->getName());
+ $value = '%%%%not_defined%%%%'; // use a string which isn't used in the normal world
+
+ // comments
+ $comments = array();
+ if ($info = $child->getInfo()) {
+ $comments[] = $info;
+ }
+
+ if ($example = $child->getExample()) {
+ $comments[] = 'Example: '.$example;
+ }
+
+ if ($child->isRequired()) {
+ $comments[] = 'Required';
+ }
+
+ if ($child instanceof EnumNode) {
+ $comments[] = 'One of '.implode('; ', array_map('json_encode', $child->getValues()));
+ }
+
+ if (count($comments)) {
+ $rootAttributeComments[$name] = implode(";\n", $comments);
+ }
+
+ // default values
+ if ($child->hasDefaultValue()) {
+ $value = $child->getDefaultValue();
+ }
+
+ // append attribute
+ $rootAttributes[$name] = $value;
+ } else {
+ // get elements
+ $rootChildren[] = $child;
+ }
+ }
+ }
+
+ // render comments
+
+ // root node comment
+ if (count($rootComments)) {
+ foreach ($rootComments as $comment) {
+ $this->writeLine('<!-- '.$comment.' -->', $depth);
+ }
+ }
+
+ // attribute comments
+ if (count($rootAttributeComments)) {
+ foreach ($rootAttributeComments as $attrName => $comment) {
+ $commentDepth = $depth + 4 + strlen($attrName) + 2;
+ $commentLines = explode("\n", $comment);
+ $multiline = (count($commentLines) > 1);
+ $comment = implode(PHP_EOL.str_repeat(' ', $commentDepth), $commentLines);
+
+ if ($multiline) {
+ $this->writeLine('<!--', $depth);
+ $this->writeLine($attrName.': '.$comment, $depth + 4);
+ $this->writeLine('-->', $depth);
+ } else {
+ $this->writeLine('<!-- '.$attrName.': '.$comment.' -->', $depth);
+ }
+ }
+ }
+
+ // render start tag + attributes
+ $rootIsVariablePrototype = isset($prototypeValue);
+ $rootIsEmptyTag = (0 === count($rootChildren) && !$rootIsVariablePrototype);
+ $rootOpenTag = '<'.$rootName;
+ if (1 >= ($attributesCount = count($rootAttributes))) {
+ if (1 === $attributesCount) {
+ $rootOpenTag .= sprintf(' %s="%s"', current(array_keys($rootAttributes)), $this->writeValue(current($rootAttributes)));
+ }
+
+ $rootOpenTag .= $rootIsEmptyTag ? ' />' : '>';
+
+ if ($rootIsVariablePrototype) {
+ $rootOpenTag .= $prototypeValue.'</'.$rootName.'>';
+ }
+
+ $this->writeLine($rootOpenTag, $depth);
+ } else {
+ $this->writeLine($rootOpenTag, $depth);
+
+ $i = 1;
+
+ foreach ($rootAttributes as $attrName => $attrValue) {
+ $attr = sprintf('%s="%s"', $attrName, $this->writeValue($attrValue));
+
+ $this->writeLine($attr, $depth + 4);
+
+ if ($attributesCount === $i++) {
+ $this->writeLine($rootIsEmptyTag ? '/>' : '>', $depth);
+
+ if ($rootIsVariablePrototype) {
+ $rootOpenTag .= $prototypeValue.'</'.$rootName.'>';
+ }
+ }
+ }
+ }
+
+ // render children tags
+ foreach ($rootChildren as $child) {
+ $this->writeLine('');
+ $this->writeNode($child, $depth + 4);
+ }
+
+ // render end tag
+ if (!$rootIsEmptyTag && !$rootIsVariablePrototype) {
+ $this->writeLine('');
+
+ $rootEndTag = '</'.$rootName.'>';
+ $this->writeLine($rootEndTag, $depth);
+ }
+ }
+
+ /**
+ * Outputs a single config reference line
+ *
+ * @param string $text
+ * @param int $indent
+ */
+ private function writeLine($text, $indent = 0)
+ {
+ $indent = strlen($text) + $indent;
+ $format = '%'.$indent.'s';
+
+ $this->reference .= sprintf($format, $text)."\n";
+ }
+
+ /**
+ * Renders the string conversion of the value.
+ *
+ * @param mixed $value
+ *
+ * @return string
+ */
+ private function writeValue($value)
+ {
+ if ('%%%%not_defined%%%%' === $value) {
+ return '';
+ }
+
+ if (is_string($value) || is_numeric($value)) {
+ return $value;
+ }
+
+ if (false === $value) {
+ return 'false';
+ }
+
+ if (true === $value) {
+ return 'true';
+ }
+
+ if (null === $value) {
+ return 'null';
+ }
+
+ if (empty($value)) {
+ return '';
+ }
+
+ if (is_array($value)) {
+ return implode(',', $value);
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php
new file mode 100644
index 0000000..a7cd448
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php
@@ -0,0 +1,198 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Dumper;
+
+use Symfony\Component\Config\Definition\ConfigurationInterface;
+use Symfony\Component\Config\Definition\NodeInterface;
+use Symfony\Component\Config\Definition\ArrayNode;
+use Symfony\Component\Config\Definition\EnumNode;
+use Symfony\Component\Config\Definition\PrototypedArrayNode;
+use Symfony\Component\Yaml\Inline;
+
+/**
+ * Dumps a Yaml reference configuration for the given configuration/node instance.
+ *
+ * @author Kevin Bond <kevinbond@gmail.com>
+ */
+class YamlReferenceDumper
+{
+ private $reference;
+
+ public function dump(ConfigurationInterface $configuration)
+ {
+ return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree());
+ }
+
+ public function dumpNode(NodeInterface $node)
+ {
+ $this->reference = '';
+ $this->writeNode($node);
+ $ref = $this->reference;
+ $this->reference = null;
+
+ return $ref;
+ }
+
+ /**
+ * @param NodeInterface $node
+ * @param int $depth
+ */
+ private function writeNode(NodeInterface $node, $depth = 0)
+ {
+ $comments = array();
+ $default = '';
+ $defaultArray = null;
+ $children = null;
+ $example = $node->getExample();
+
+ // defaults
+ if ($node instanceof ArrayNode) {
+ $children = $node->getChildren();
+
+ if ($node instanceof PrototypedArrayNode) {
+ $prototype = $node->getPrototype();
+
+ if ($prototype instanceof ArrayNode) {
+ $children = $prototype->getChildren();
+ }
+
+ // check for attribute as key
+ if ($key = $node->getKeyAttribute()) {
+ $keyNodeClass = 'Symfony\Component\Config\Definition\\'.($prototype instanceof ArrayNode ? 'ArrayNode' : 'ScalarNode');
+ $keyNode = new $keyNodeClass($key, $node);
+ $keyNode->setInfo('Prototype');
+
+ // add children
+ foreach ($children as $childNode) {
+ $keyNode->addChild($childNode);
+ }
+ $children = array($key => $keyNode);
+ }
+ }
+
+ if (!$children) {
+ if ($node->hasDefaultValue() && count($defaultArray = $node->getDefaultValue())) {
+ $default = '';
+ } elseif (!is_array($example)) {
+ $default = '[]';
+ }
+ }
+ } elseif ($node instanceof EnumNode) {
+ $comments[] = 'One of '.implode('; ', array_map('json_encode', $node->getValues()));
+ $default = '~';
+ } else {
+ $default = '~';
+
+ if ($node->hasDefaultValue()) {
+ $default = $node->getDefaultValue();
+
+ if (is_array($default)) {
+ if (count($defaultArray = $node->getDefaultValue())) {
+ $default = '';
+ } elseif (!is_array($example)) {
+ $default = '[]';
+ }
+ } else {
+ $default = Inline::dump($default);
+ }
+ }
+ }
+
+ // required?
+ if ($node->isRequired()) {
+ $comments[] = 'Required';
+ }
+
+ // example
+ if ($example && !is_array($example)) {
+ $comments[] = 'Example: '.$example;
+ }
+
+ $default = (string) $default != '' ? ' '.$default : '';
+ $comments = count($comments) ? '# '.implode(', ', $comments) : '';
+
+ $text = rtrim(sprintf('%-20s %s %s', $node->getName().':', $default, $comments), ' ');
+
+ if ($info = $node->getInfo()) {
+ $this->writeLine('');
+ // indenting multi-line info
+ $info = str_replace("\n", sprintf("\n%".($depth * 4)."s# ", ' '), $info);
+ $this->writeLine('# '.$info, $depth * 4);
+ }
+
+ $this->writeLine($text, $depth * 4);
+
+ // output defaults
+ if ($defaultArray) {
+ $this->writeLine('');
+
+ $message = count($defaultArray) > 1 ? 'Defaults' : 'Default';
+
+ $this->writeLine('# '.$message.':', $depth * 4 + 4);
+
+ $this->writeArray($defaultArray, $depth + 1);
+ }
+
+ if (is_array($example)) {
+ $this->writeLine('');
+
+ $message = count($example) > 1 ? 'Examples' : 'Example';
+
+ $this->writeLine('# '.$message.':', $depth * 4 + 4);
+
+ $this->writeArray($example, $depth + 1);
+ }
+
+ if ($children) {
+ foreach ($children as $childNode) {
+ $this->writeNode($childNode, $depth + 1);
+ }
+ }
+ }
+
+ /**
+ * Outputs a single config reference line
+ *
+ * @param string $text
+ * @param int $indent
+ */
+ private function writeLine($text, $indent = 0)
+ {
+ $indent = strlen($text) + $indent;
+ $format = '%'.$indent.'s';
+
+ $this->reference .= sprintf($format, $text)."\n";
+ }
+
+ private function writeArray(array $array, $depth)
+ {
+ $isIndexed = array_values($array) === $array;
+
+ foreach ($array as $key => $value) {
+ if (is_array($value)) {
+ $val = '';
+ } else {
+ $val = $value;
+ }
+
+ if ($isIndexed) {
+ $this->writeLine('- '.$val, $depth * 4);
+ } else {
+ $this->writeLine(sprintf('%-20s %s', $key.':', $val), $depth * 4);
+ }
+
+ if (is_array($value)) {
+ $this->writeArray($value, $depth + 1);
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/EnumNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/EnumNode.php
new file mode 100644
index 0000000..224871a
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/EnumNode.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+
+/**
+ * Node which only allows a finite set of values.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class EnumNode extends ScalarNode
+{
+ private $values;
+
+ public function __construct($name, NodeInterface $parent = null, array $values = array())
+ {
+ $values = array_unique($values);
+ if (count($values) <= 1) {
+ throw new \InvalidArgumentException('$values must contain at least two distinct elements.');
+ }
+
+ parent::__construct($name, $parent);
+ $this->values = $values;
+ }
+
+ public function getValues()
+ {
+ return $this->values;
+ }
+
+ protected function finalizeValue($value)
+ {
+ $value = parent::finalizeValue($value);
+
+ if (!in_array($value, $this->values, true)) {
+ $ex = new InvalidConfigurationException(sprintf(
+ 'The value %s is not allowed for path "%s". Permissible values: %s',
+ json_encode($value),
+ $this->getPath(),
+ implode(', ', array_map('json_encode', $this->values))));
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ return $value;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php
new file mode 100644
index 0000000..48dd932
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Exception;
+
+/**
+ * This exception is thrown whenever the key of an array is not unique. This can
+ * only be the case if the configuration is coming from an XML file.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class DuplicateKeyException extends InvalidConfigurationException
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/Exception.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/Exception.php
new file mode 100644
index 0000000..8933a49
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/Exception.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Exception;
+
+/**
+ * Base exception for all configuration exceptions.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class Exception extends \RuntimeException
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php
new file mode 100644
index 0000000..726c07f
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Exception;
+
+/**
+ * This exception is thrown when a configuration path is overwritten from a
+ * subsequent configuration file, but the entry node specifically forbids this.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ForbiddenOverwriteException extends InvalidConfigurationException
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php
new file mode 100644
index 0000000..3dbc57b
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Exception;
+
+/**
+ * A very general exception which can be thrown whenever non of the more specific
+ * exceptions is suitable.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class InvalidConfigurationException extends Exception
+{
+ private $path;
+ private $containsHints = false;
+
+ public function setPath($path)
+ {
+ $this->path = $path;
+ }
+
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Adds extra information that is suffixed to the original exception message.
+ *
+ * @param string $hint
+ */
+ public function addHint($hint)
+ {
+ if (!$this->containsHints) {
+ $this->message .= "\nHint: ".$hint;
+ $this->containsHints = true;
+ } else {
+ $this->message .= ', '.$hint;
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php
new file mode 100644
index 0000000..98310da
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Exception;
+
+/**
+ * Thrown when an error is detected in a node Definition.
+ *
+ * @author Victor Berchet <victor.berchet@suumit.com>
+ */
+class InvalidDefinitionException extends Exception
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php
new file mode 100644
index 0000000..d7ca8c9
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Exception;
+
+/**
+ * This exception is thrown if an invalid type is encountered.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class InvalidTypeException extends InvalidConfigurationException
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php
new file mode 100644
index 0000000..863181a
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition\Exception;
+
+/**
+ * This exception is usually not encountered by the end-user, but only used
+ * internally to signal the parent scope to unset a key.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class UnsetKeyException extends Exception
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/FloatNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/FloatNode.php
new file mode 100644
index 0000000..5e1af17
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/FloatNode.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
+
+/**
+ * This node represents a float value in the config tree.
+ *
+ * @author Jeanmonod David <david.jeanmonod@gmail.com>
+ */
+class FloatNode extends NumericNode
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function validateType($value)
+ {
+ // Integers are also accepted, we just cast them
+ if (is_int($value)) {
+ $value = (float) $value;
+ }
+
+ if (!is_float($value)) {
+ $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected float, but got %s.', $this->getPath(), gettype($value)));
+ if ($hint = $this->getInfo()) {
+ $ex->addHint($hint);
+ }
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/IntegerNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/IntegerNode.php
new file mode 100644
index 0000000..ba23070
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/IntegerNode.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
+
+/**
+ * This node represents an integer value in the config tree.
+ *
+ * @author Jeanmonod David <david.jeanmonod@gmail.com>
+ */
+class IntegerNode extends NumericNode
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function validateType($value)
+ {
+ if (!is_int($value)) {
+ $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected int, but got %s.', $this->getPath(), gettype($value)));
+ if ($hint = $this->getInfo()) {
+ $ex->addHint($hint);
+ }
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/NodeInterface.php b/vendor/symfony/config/Symfony/Component/Config/Definition/NodeInterface.php
new file mode 100644
index 0000000..b9bddc4
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/NodeInterface.php
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+/**
+ * Common Interface among all nodes.
+ *
+ * In most cases, it is better to inherit from BaseNode instead of implementing
+ * this interface yourself.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface NodeInterface
+{
+ /**
+ * Returns the name of the node.
+ *
+ * @return string The name of the node
+ */
+ public function getName();
+
+ /**
+ * Returns the path of the node.
+ *
+ * @return string The node path
+ */
+ public function getPath();
+
+ /**
+ * Returns true when the node is required.
+ *
+ * @return bool If the node is required
+ */
+ public function isRequired();
+
+ /**
+ * Returns true when the node has a default value.
+ *
+ * @return bool If the node has a default value
+ */
+ public function hasDefaultValue();
+
+ /**
+ * Returns the default value of the node.
+ *
+ * @return mixed The default value
+ *
+ * @throws \RuntimeException if the node has no default value
+ */
+ public function getDefaultValue();
+
+ /**
+ * Normalizes the supplied value.
+ *
+ * @param mixed $value The value to normalize
+ *
+ * @return mixed The normalized value
+ */
+ public function normalize($value);
+
+ /**
+ * Merges two values together.
+ *
+ * @param mixed $leftSide
+ * @param mixed $rightSide
+ *
+ * @return mixed The merged values
+ */
+ public function merge($leftSide, $rightSide);
+
+ /**
+ * Finalizes a value.
+ *
+ * @param mixed $value The value to finalize
+ *
+ * @return mixed The finalized value
+ */
+ public function finalize($value);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/NumericNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/NumericNode.php
new file mode 100644
index 0000000..2304ad9
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/NumericNode.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+
+/**
+ * This node represents a numeric value in the config tree.
+ *
+ * @author David Jeanmonod <david.jeanmonod@gmail.com>
+ */
+class NumericNode extends ScalarNode
+{
+ protected $min;
+ protected $max;
+
+ public function __construct($name, NodeInterface $parent = null, $min = null, $max = null)
+ {
+ parent::__construct($name, $parent);
+ $this->min = $min;
+ $this->max = $max;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function finalizeValue($value)
+ {
+ $value = parent::finalizeValue($value);
+
+ $errorMsg = null;
+ if (isset($this->min) && $value < $this->min) {
+ $errorMsg = sprintf('The value %s is too small for path "%s". Should be greater than or equal to %s', $value, $this->getPath(), $this->min);
+ }
+ if (isset($this->max) && $value > $this->max) {
+ $errorMsg = sprintf('The value %s is too big for path "%s". Should be less than or equal to %s', $value, $this->getPath(), $this->max);
+ }
+ if (isset($errorMsg)) {
+ $ex = new InvalidConfigurationException($errorMsg);
+ $ex->setPath($this->getPath());
+ throw $ex;
+ }
+
+ return $value;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Processor.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Processor.php
new file mode 100644
index 0000000..025e693
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Processor.php
@@ -0,0 +1,97 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+/**
+ * This class is the entry point for config normalization/merging/finalization.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class Processor
+{
+ /**
+ * Processes an array of configurations.
+ *
+ * @param NodeInterface $configTree The node tree describing the configuration
+ * @param array $configs An array of configuration items to process
+ *
+ * @return array The processed configuration
+ */
+ public function process(NodeInterface $configTree, array $configs)
+ {
+ $currentConfig = array();
+ foreach ($configs as $config) {
+ $config = $configTree->normalize($config);
+ $currentConfig = $configTree->merge($currentConfig, $config);
+ }
+
+ return $configTree->finalize($currentConfig);
+ }
+
+ /**
+ * Processes an array of configurations.
+ *
+ * @param ConfigurationInterface $configuration The configuration class
+ * @param array $configs An array of configuration items to process
+ *
+ * @return array The processed configuration
+ */
+ public function processConfiguration(ConfigurationInterface $configuration, array $configs)
+ {
+ return $this->process($configuration->getConfigTreeBuilder()->buildTree(), $configs);
+ }
+
+ /**
+ * Normalizes a configuration entry.
+ *
+ * This method returns a normalize configuration array for a given key
+ * to remove the differences due to the original format (YAML and XML mainly).
+ *
+ * Here is an example.
+ *
+ * The configuration in XML:
+ *
+ * <twig:extension>twig.extension.foo</twig:extension>
+ * <twig:extension>twig.extension.bar</twig:extension>
+ *
+ * And the same configuration in YAML:
+ *
+ * extensions: ['twig.extension.foo', 'twig.extension.bar']
+ *
+ * @param array $config A config array
+ * @param string $key The key to normalize
+ * @param string $plural The plural form of the key if it is irregular
+ *
+ * @return array
+ */
+ public static function normalizeConfig($config, $key, $plural = null)
+ {
+ if (null === $plural) {
+ $plural = $key.'s';
+ }
+
+ if (isset($config[$plural])) {
+ return $config[$plural];
+ }
+
+ if (isset($config[$key])) {
+ if (is_string($config[$key]) || !is_int(key($config[$key]))) {
+ // only one
+ return array($config[$key]);
+ }
+
+ return $config[$key];
+ }
+
+ return array();
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/PrototypeNodeInterface.php b/vendor/symfony/config/Symfony/Component/Config/Definition/PrototypeNodeInterface.php
new file mode 100644
index 0000000..8bbb84d
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/PrototypeNodeInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+/**
+ * This interface must be implemented by nodes which can be used as prototypes.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface PrototypeNodeInterface extends NodeInterface
+{
+ /**
+ * Sets the name of the node.
+ *
+ * @param string $name The name of the node
+ */
+ public function setName($name);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/PrototypedArrayNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/PrototypedArrayNode.php
new file mode 100644
index 0000000..0a03d36
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/PrototypedArrayNode.php
@@ -0,0 +1,331 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+use Symfony\Component\Config\Definition\Exception\DuplicateKeyException;
+use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
+use Symfony\Component\Config\Definition\Exception\Exception;
+
+/**
+ * Represents a prototyped Array node in the config tree.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class PrototypedArrayNode extends ArrayNode
+{
+ protected $prototype;
+ protected $keyAttribute;
+ protected $removeKeyAttribute = false;
+ protected $minNumberOfElements = 0;
+ protected $defaultValue = array();
+ protected $defaultChildren;
+
+ /**
+ * Sets the minimum number of elements that a prototype based node must
+ * contain. By default this is zero, meaning no elements.
+ *
+ * @param int $number
+ */
+ public function setMinNumberOfElements($number)
+ {
+ $this->minNumberOfElements = $number;
+ }
+
+ /**
+ * Sets the attribute which value is to be used as key.
+ *
+ * This is useful when you have an indexed array that should be an
+ * associative array. You can select an item from within the array
+ * to be the key of the particular item. For example, if "id" is the
+ * "key", then:
+ *
+ * array(
+ * array('id' => 'my_name', 'foo' => 'bar'),
+ * );
+ *
+ * becomes
+ *
+ * array(
+ * 'my_name' => array('foo' => 'bar'),
+ * );
+ *
+ * If you'd like "'id' => 'my_name'" to still be present in the resulting
+ * array, then you can set the second argument of this method to false.
+ *
+ * @param string $attribute The name of the attribute which value is to be used as a key
+ * @param bool $remove Whether or not to remove the key
+ */
+ public function setKeyAttribute($attribute, $remove = true)
+ {
+ $this->keyAttribute = $attribute;
+ $this->removeKeyAttribute = $remove;
+ }
+
+ /**
+ * Retrieves the name of the attribute which value should be used as key.
+ *
+ * @return string The name of the attribute
+ */
+ public function getKeyAttribute()
+ {
+ return $this->keyAttribute;
+ }
+
+ /**
+ * Sets the default value of this node.
+ *
+ * @param string $value
+ *
+ * @throws \InvalidArgumentException if the default value is not an array
+ */
+ public function setDefaultValue($value)
+ {
+ if (!is_array($value)) {
+ throw new \InvalidArgumentException($this->getPath().': the default value of an array node has to be an array.');
+ }
+
+ $this->defaultValue = $value;
+ }
+
+ /**
+ * Checks if the node has a default value.
+ *
+ * @return bool
+ */
+ public function hasDefaultValue()
+ {
+ return true;
+ }
+
+ /**
+ * Adds default children when none are set.
+ *
+ * @param int|string|array|null $children The number of children|The child name|The children names to be added
+ */
+ public function setAddChildrenIfNoneSet($children = array('defaults'))
+ {
+ if (null === $children) {
+ $this->defaultChildren = array('defaults');
+ } else {
+ $this->defaultChildren = is_int($children) && $children > 0 ? range(1, $children) : (array) $children;
+ }
+ }
+
+ /**
+ * Retrieves the default value.
+ *
+ * The default value could be either explicited or derived from the prototype
+ * default value.
+ *
+ * @return array The default value
+ */
+ public function getDefaultValue()
+ {
+ if (null !== $this->defaultChildren) {
+ $default = $this->prototype->hasDefaultValue() ? $this->prototype->getDefaultValue() : array();
+ $defaults = array();
+ foreach (array_values($this->defaultChildren) as $i => $name) {
+ $defaults[null === $this->keyAttribute ? $i : $name] = $default;
+ }
+
+ return $defaults;
+ }
+
+ return $this->defaultValue;
+ }
+
+ /**
+ * Sets the node prototype.
+ *
+ * @param PrototypeNodeInterface $node
+ */
+ public function setPrototype(PrototypeNodeInterface $node)
+ {
+ $this->prototype = $node;
+ }
+
+ /**
+ * Retrieves the prototype.
+ *
+ * @return PrototypeNodeInterface The prototype
+ */
+ public function getPrototype()
+ {
+ return $this->prototype;
+ }
+
+ /**
+ * Disable adding concrete children for prototyped nodes.
+ *
+ * @param NodeInterface $node The child node to add
+ *
+ * @throws Exception
+ */
+ public function addChild(NodeInterface $node)
+ {
+ throw new Exception('A prototyped array node can not have concrete children.');
+ }
+
+ /**
+ * Finalizes the value of this node.
+ *
+ * @param mixed $value
+ *
+ * @return mixed The finalized value
+ *
+ * @throws UnsetKeyException
+ * @throws InvalidConfigurationException if the node doesn't have enough children
+ */
+ protected function finalizeValue($value)
+ {
+ if (false === $value) {
+ $msg = sprintf('Unsetting key for path "%s", value: %s', $this->getPath(), json_encode($value));
+ throw new UnsetKeyException($msg);
+ }
+
+ foreach ($value as $k => $v) {
+ $this->prototype->setName($k);
+ try {
+ $value[$k] = $this->prototype->finalize($v);
+ } catch (UnsetKeyException $unset) {
+ unset($value[$k]);
+ }
+ }
+
+ if (count($value) < $this->minNumberOfElements) {
+ $msg = sprintf('The path "%s" should have at least %d element(s) defined.', $this->getPath(), $this->minNumberOfElements);
+ $ex = new InvalidConfigurationException($msg);
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ return $value;
+ }
+
+ /**
+ * Normalizes the value.
+ *
+ * @param mixed $value The value to normalize
+ *
+ * @return mixed The normalized value
+ *
+ * @throws InvalidConfigurationException
+ * @throws DuplicateKeyException
+ */
+ protected function normalizeValue($value)
+ {
+ if (false === $value) {
+ return $value;
+ }
+
+ $value = $this->remapXml($value);
+
+ $isAssoc = array_keys($value) !== range(0, count($value) - 1);
+ $normalized = array();
+ foreach ($value as $k => $v) {
+ if (null !== $this->keyAttribute && is_array($v)) {
+ if (!isset($v[$this->keyAttribute]) && is_int($k) && !$isAssoc) {
+ $msg = sprintf('The attribute "%s" must be set for path "%s".', $this->keyAttribute, $this->getPath());
+ $ex = new InvalidConfigurationException($msg);
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ } elseif (isset($v[$this->keyAttribute])) {
+ $k = $v[$this->keyAttribute];
+
+ // remove the key attribute when required
+ if ($this->removeKeyAttribute) {
+ unset($v[$this->keyAttribute]);
+ }
+
+ // if only "value" is left
+ if (1 == count($v) && isset($v['value'])) {
+ $v = $v['value'];
+ }
+ }
+
+ if (array_key_exists($k, $normalized)) {
+ $msg = sprintf('Duplicate key "%s" for path "%s".', $k, $this->getPath());
+ $ex = new DuplicateKeyException($msg);
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+ }
+
+ $this->prototype->setName($k);
+ if (null !== $this->keyAttribute || $isAssoc) {
+ $normalized[$k] = $this->prototype->normalize($v);
+ } else {
+ $normalized[] = $this->prototype->normalize($v);
+ }
+ }
+
+ return $normalized;
+ }
+
+ /**
+ * Merges values together.
+ *
+ * @param mixed $leftSide The left side to merge.
+ * @param mixed $rightSide The right side to merge.
+ *
+ * @return mixed The merged values
+ *
+ * @throws InvalidConfigurationException
+ * @throws \RuntimeException
+ */
+ protected function mergeValues($leftSide, $rightSide)
+ {
+ if (false === $rightSide) {
+ // if this is still false after the last config has been merged the
+ // finalization pass will take care of removing this key entirely
+ return false;
+ }
+
+ if (false === $leftSide || !$this->performDeepMerging) {
+ return $rightSide;
+ }
+
+ foreach ($rightSide as $k => $v) {
+ // prototype, and key is irrelevant, so simply append the element
+ if (null === $this->keyAttribute) {
+ $leftSide[] = $v;
+ continue;
+ }
+
+ // no conflict
+ if (!array_key_exists($k, $leftSide)) {
+ if (!$this->allowNewKeys) {
+ $ex = new InvalidConfigurationException(sprintf(
+ 'You are not allowed to define new elements for path "%s". '.
+ 'Please define all elements for this path in one config file.',
+ $this->getPath()
+ ));
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ $leftSide[$k] = $v;
+ continue;
+ }
+
+ $this->prototype->setName($k);
+ $leftSide[$k] = $this->prototype->merge($leftSide[$k], $v);
+ }
+
+ return $leftSide;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/ReferenceDumper.php b/vendor/symfony/config/Symfony/Component/Config/Definition/ReferenceDumper.php
new file mode 100644
index 0000000..7fe336d
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/ReferenceDumper.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper;
+
+/**
+ * @deprecated Deprecated since version 2.4, to be removed in 3.0. Use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper instead.
+ */
+class ReferenceDumper extends YamlReferenceDumper
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/ScalarNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/ScalarNode.php
new file mode 100644
index 0000000..854c265
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/ScalarNode.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
+
+/**
+ * This node represents a scalar value in the config tree.
+ *
+ * The following values are considered scalars:
+ * * booleans
+ * * strings
+ * * null
+ * * integers
+ * * floats
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ScalarNode extends VariableNode
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function validateType($value)
+ {
+ if (!is_scalar($value) && null !== $value) {
+ $ex = new InvalidTypeException(sprintf(
+ 'Invalid type for path "%s". Expected scalar, but got %s.',
+ $this->getPath(),
+ gettype($value)
+ ));
+ if ($hint = $this->getInfo()) {
+ $ex->addHint($hint);
+ }
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/VariableNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/VariableNode.php
new file mode 100644
index 0000000..2ab7a45
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/VariableNode.php
@@ -0,0 +1,119 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+
+/**
+ * This node represents a value of variable type in the config tree.
+ *
+ * This node is intended for values of arbitrary type.
+ * Any PHP type is accepted as a value.
+ *
+ * @author Jeremy Mikola <jmikola@gmail.com>
+ */
+class VariableNode extends BaseNode implements PrototypeNodeInterface
+{
+ protected $defaultValueSet = false;
+ protected $defaultValue;
+ protected $allowEmptyValue = true;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDefaultValue($value)
+ {
+ $this->defaultValueSet = true;
+ $this->defaultValue = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasDefaultValue()
+ {
+ return $this->defaultValueSet;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultValue()
+ {
+ $v = $this->defaultValue;
+
+ return $v instanceof \Closure ? $v() : $v;
+ }
+
+ /**
+ * Sets if this node is allowed to have an empty value.
+ *
+ * @param bool $boolean True if this entity will accept empty values.
+ */
+ public function setAllowEmptyValue($boolean)
+ {
+ $this->allowEmptyValue = (bool) $boolean;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function validateType($value)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function finalizeValue($value)
+ {
+ if (!$this->allowEmptyValue && empty($value)) {
+ $ex = new InvalidConfigurationException(sprintf(
+ 'The path "%s" cannot contain an empty value, but got %s.',
+ $this->getPath(),
+ json_encode($value)
+ ));
+ if ($hint = $this->getInfo()) {
+ $ex->addHint($hint);
+ }
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ return $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function normalizeValue($value)
+ {
+ return $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function mergeValues($leftSide, $rightSide)
+ {
+ return $rightSide;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php b/vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php
new file mode 100644
index 0000000..6a3b01c
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Exception;
+
+/**
+ * Exception class for when a circular reference is detected when importing resources.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class FileLoaderImportCircularReferenceException extends FileLoaderLoadException
+{
+ public function __construct(array $resources, $code = null, $previous = null)
+ {
+ $message = sprintf('Circular reference detected in "%s" ("%s" > "%s").', $this->varToString($resources[0]), implode('" > "', $resources), $resources[0]);
+
+ \Exception::__construct($message, $code, $previous);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderLoadException.php b/vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderLoadException.php
new file mode 100644
index 0000000..ec825e3
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderLoadException.php
@@ -0,0 +1,100 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Exception;
+
+/**
+ * Exception class for when a resource cannot be loaded or imported.
+ *
+ * @author Ryan Weaver <ryan@thatsquality.com>
+ */
+class FileLoaderLoadException extends \Exception
+{
+ /**
+ * @param string $resource The resource that could not be imported
+ * @param string $sourceResource The original resource importing the new resource
+ * @param int $code The error code
+ * @param \Exception $previous A previous exception
+ */
+ public function __construct($resource, $sourceResource = null, $code = null, $previous = null)
+ {
+ $message = '';
+ if ($previous) {
+ // Include the previous exception, to help the user see what might be the underlying cause
+
+ // Trim the trailing period of the previous message. We only want 1 period remove so no rtrim...
+ if ('.' === substr($previous->getMessage(), -1)) {
+ $trimmedMessage = substr($previous->getMessage(), 0, -1);
+ $message .= sprintf('%s', $trimmedMessage).' in ';
+ } else {
+ $message .= sprintf('%s', $previous->getMessage()).' in ';
+ }
+ $message .= $resource.' ';
+
+ // show tweaked trace to complete the human readable sentence
+ if (null === $sourceResource) {
+ $message .= sprintf('(which is loaded in resource "%s")', $this->varToString($resource));
+ } else {
+ $message .= sprintf('(which is being imported from "%s")', $this->varToString($sourceResource));
+ }
+ $message .= '.';
+
+ // if there's no previous message, present it the default way
+ } elseif (null === $sourceResource) {
+ $message .= sprintf('Cannot load resource "%s".', $this->varToString($resource));
+ } else {
+ $message .= sprintf('Cannot import resource "%s" from "%s".', $this->varToString($resource), $this->varToString($sourceResource));
+ }
+
+ // Is the resource located inside a bundle?
+ if ('@' === $resource[0]) {
+ $parts = explode(DIRECTORY_SEPARATOR, $resource);
+ $bundle = substr($parts[0], 1);
+ $message .= ' '.sprintf('Make sure the "%s" bundle is correctly registered and loaded in the application kernel class.', $bundle);
+ }
+
+ parent::__construct($message, $code, $previous);
+ }
+
+ protected function varToString($var)
+ {
+ if (is_object($var)) {
+ return sprintf('Object(%s)', get_class($var));
+ }
+
+ if (is_array($var)) {
+ $a = array();
+ foreach ($var as $k => $v) {
+ $a[] = sprintf('%s => %s', $k, $this->varToString($v));
+ }
+
+ return sprintf('Array(%s)', implode(', ', $a));
+ }
+
+ if (is_resource($var)) {
+ return sprintf('Resource(%s)', get_resource_type($var));
+ }
+
+ if (null === $var) {
+ return 'null';
+ }
+
+ if (false === $var) {
+ return 'false';
+ }
+
+ if (true === $var) {
+ return 'true';
+ }
+
+ return (string) $var;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/FileLocator.php b/vendor/symfony/config/Symfony/Component/Config/FileLocator.php
new file mode 100644
index 0000000..71bb5ab
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/FileLocator.php
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config;
+
+/**
+ * FileLocator uses an array of pre-defined paths to find files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class FileLocator implements FileLocatorInterface
+{
+ protected $paths;
+
+ /**
+ * Constructor.
+ *
+ * @param string|array $paths A path or an array of paths where to look for resources
+ */
+ public function __construct($paths = array())
+ {
+ $this->paths = (array) $paths;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function locate($name, $currentPath = null, $first = true)
+ {
+ if ('' == $name) {
+ throw new \InvalidArgumentException('An empty file name is not valid to be located.');
+ }
+
+ if ($this->isAbsolutePath($name)) {
+ if (!file_exists($name)) {
+ throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $name));
+ }
+
+ return $name;
+ }
+
+ $filepaths = array();
+ if (null !== $currentPath && file_exists($file = $currentPath.DIRECTORY_SEPARATOR.$name)) {
+ if (true === $first) {
+ return $file;
+ }
+ $filepaths[] = $file;
+ }
+
+ foreach ($this->paths as $path) {
+ if (file_exists($file = $path.DIRECTORY_SEPARATOR.$name)) {
+ if (true === $first) {
+ return $file;
+ }
+ $filepaths[] = $file;
+ }
+ }
+
+ if (!$filepaths) {
+ throw new \InvalidArgumentException(sprintf('The file "%s" does not exist (in: %s%s).', $name, null !== $currentPath ? $currentPath.', ' : '', implode(', ', $this->paths)));
+ }
+
+ return array_values(array_unique($filepaths));
+ }
+
+ /**
+ * Returns whether the file path is an absolute path.
+ *
+ * @param string $file A file path
+ *
+ * @return bool
+ */
+ private function isAbsolutePath($file)
+ {
+ if ($file[0] === '/' || $file[0] === '\\'
+ || (strlen($file) > 3 && ctype_alpha($file[0])
+ && $file[1] === ':'
+ && ($file[2] === '\\' || $file[2] === '/')
+ )
+ || null !== parse_url($file, PHP_URL_SCHEME)
+ ) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/FileLocatorInterface.php b/vendor/symfony/config/Symfony/Component/Config/FileLocatorInterface.php
new file mode 100644
index 0000000..6605798
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/FileLocatorInterface.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface FileLocatorInterface
+{
+ /**
+ * Returns a full path for a given file name.
+ *
+ * @param string $name The file name to locate
+ * @param string|null $currentPath The current path
+ * @param bool $first Whether to return the first occurrence or an array of filenames
+ *
+ * @return string|array The full path to the file or an array of file paths
+ *
+ * @throws \InvalidArgumentException When file is not found
+ */
+ public function locate($name, $currentPath = null, $first = true);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/LICENSE b/vendor/symfony/config/Symfony/Component/Config/LICENSE
new file mode 100644
index 0000000..43028bc
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2015 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/vendor/symfony/config/Symfony/Component/Config/Loader/DelegatingLoader.php b/vendor/symfony/config/Symfony/Component/Config/Loader/DelegatingLoader.php
new file mode 100644
index 0000000..3097878
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Loader/DelegatingLoader.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Loader;
+
+use Symfony\Component\Config\Exception\FileLoaderLoadException;
+
+/**
+ * DelegatingLoader delegates loading to other loaders using a loader resolver.
+ *
+ * This loader acts as an array of LoaderInterface objects - each having
+ * a chance to load a given resource (handled by the resolver)
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class DelegatingLoader extends Loader
+{
+ /**
+ * Constructor.
+ *
+ * @param LoaderResolverInterface $resolver A LoaderResolverInterface instance
+ */
+ public function __construct(LoaderResolverInterface $resolver)
+ {
+ $this->resolver = $resolver;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function load($resource, $type = null)
+ {
+ if (false === $loader = $this->resolver->resolve($resource, $type)) {
+ throw new FileLoaderLoadException($resource);
+ }
+
+ return $loader->load($resource, $type);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return false !== $this->resolver->resolve($resource, $type);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Loader/FileLoader.php b/vendor/symfony/config/Symfony/Component/Config/Loader/FileLoader.php
new file mode 100644
index 0000000..21e4c47
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Loader/FileLoader.php
@@ -0,0 +1,124 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Loader;
+
+use Symfony\Component\Config\FileLocatorInterface;
+use Symfony\Component\Config\Exception\FileLoaderLoadException;
+use Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException;
+
+/**
+ * FileLoader is the abstract class used by all built-in loaders that are file based.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class FileLoader extends Loader
+{
+ /**
+ * @var array
+ */
+ protected static $loading = array();
+
+ /**
+ * @var FileLocatorInterface
+ */
+ protected $locator;
+
+ private $currentDir;
+
+ /**
+ * Constructor.
+ *
+ * @param FileLocatorInterface $locator A FileLocatorInterface instance
+ */
+ public function __construct(FileLocatorInterface $locator)
+ {
+ $this->locator = $locator;
+ }
+
+ /**
+ * Sets the current directory.
+ *
+ * @param string $dir
+ */
+ public function setCurrentDir($dir)
+ {
+ $this->currentDir = $dir;
+ }
+
+ /**
+ * Returns the file locator used by this loader.
+ *
+ * @return FileLocatorInterface
+ */
+ public function getLocator()
+ {
+ return $this->locator;
+ }
+
+ /**
+ * Imports a resource.
+ *
+ * @param mixed $resource A Resource
+ * @param string|null $type The resource type or null if unknown
+ * @param bool $ignoreErrors Whether to ignore import errors or not
+ * @param string|null $sourceResource The original resource importing the new resource
+ *
+ * @return mixed
+ *
+ * @throws FileLoaderLoadException
+ * @throws FileLoaderImportCircularReferenceException
+ */
+ public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
+ {
+ try {
+ $loader = $this->resolve($resource, $type);
+
+ if ($loader instanceof FileLoader && null !== $this->currentDir) {
+ // we fallback to the current locator to keep BC
+ // as some some loaders do not call the parent __construct()
+ // @deprecated should be removed in 3.0
+ $locator = $loader->getLocator() ?: $this->locator;
+ $resource = $locator->locate($resource, $this->currentDir, false);
+ }
+
+ $resources = is_array($resource) ? $resource : array($resource);
+ for ($i = 0; $i < $resourcesCount = count($resources); $i++) {
+ if (isset(self::$loading[$resources[$i]])) {
+ if ($i == $resourcesCount - 1) {
+ throw new FileLoaderImportCircularReferenceException(array_keys(self::$loading));
+ }
+ } else {
+ $resource = $resources[$i];
+ break;
+ }
+ }
+ self::$loading[$resource] = true;
+
+ $ret = $loader->load($resource, $type);
+
+ unset(self::$loading[$resource]);
+
+ return $ret;
+ } catch (FileLoaderImportCircularReferenceException $e) {
+ throw $e;
+ } catch (\Exception $e) {
+ if (!$ignoreErrors) {
+ // prevent embedded imports from nesting multiple exceptions
+ if ($e instanceof FileLoaderLoadException) {
+ throw $e;
+ }
+
+ throw new FileLoaderLoadException($resource, $sourceResource, null, $e);
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Loader/Loader.php b/vendor/symfony/config/Symfony/Component/Config/Loader/Loader.php
new file mode 100644
index 0000000..de4e127
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Loader/Loader.php
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Loader;
+
+use Symfony\Component\Config\Exception\FileLoaderLoadException;
+
+/**
+ * Loader is the abstract class used by all built-in loaders.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class Loader implements LoaderInterface
+{
+ protected $resolver;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getResolver()
+ {
+ return $this->resolver;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setResolver(LoaderResolverInterface $resolver)
+ {
+ $this->resolver = $resolver;
+ }
+
+ /**
+ * Imports a resource.
+ *
+ * @param mixed $resource A resource
+ * @param string|null $type The resource type or null if unknown
+ *
+ * @return mixed
+ */
+ public function import($resource, $type = null)
+ {
+ return $this->resolve($resource, $type)->load($resource, $type);
+ }
+
+ /**
+ * Finds a loader able to load an imported resource.
+ *
+ * @param mixed $resource A resource
+ * @param string|null $type The resource type or null if unknown
+ *
+ * @return LoaderInterface A LoaderInterface instance
+ *
+ * @throws FileLoaderLoadException If no loader is found
+ */
+ public function resolve($resource, $type = null)
+ {
+ if ($this->supports($resource, $type)) {
+ return $this;
+ }
+
+ $loader = null === $this->resolver ? false : $this->resolver->resolve($resource, $type);
+
+ if (false === $loader) {
+ throw new FileLoaderLoadException($resource);
+ }
+
+ return $loader;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderInterface.php b/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderInterface.php
new file mode 100644
index 0000000..dd0a85a
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderInterface.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Loader;
+
+/**
+ * LoaderInterface is the interface implemented by all loader classes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface LoaderInterface
+{
+ /**
+ * Loads a resource.
+ *
+ * @param mixed $resource The resource
+ * @param string|null $type The resource type or null if unknown
+ *
+ * @throws \Exception If something went wrong
+ */
+ public function load($resource, $type = null);
+
+ /**
+ * Returns whether this class supports the given resource.
+ *
+ * @param mixed $resource A resource
+ * @param string|null $type The resource type or null if unknown
+ *
+ * @return bool True if this class supports the given resource, false otherwise
+ */
+ public function supports($resource, $type = null);
+
+ /**
+ * Gets the loader resolver.
+ *
+ * @return LoaderResolverInterface A LoaderResolverInterface instance
+ */
+ public function getResolver();
+
+ /**
+ * Sets the loader resolver.
+ *
+ * @param LoaderResolverInterface $resolver A LoaderResolverInterface instance
+ */
+ public function setResolver(LoaderResolverInterface $resolver);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolver.php b/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolver.php
new file mode 100644
index 0000000..dc6846d
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolver.php
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Loader;
+
+/**
+ * LoaderResolver selects a loader for a given resource.
+ *
+ * A resource can be anything (e.g. a full path to a config file or a Closure).
+ * Each loader determines whether it can load a resource and how.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class LoaderResolver implements LoaderResolverInterface
+{
+ /**
+ * @var LoaderInterface[] An array of LoaderInterface objects
+ */
+ private $loaders = array();
+
+ /**
+ * Constructor.
+ *
+ * @param LoaderInterface[] $loaders An array of loaders
+ */
+ public function __construct(array $loaders = array())
+ {
+ foreach ($loaders as $loader) {
+ $this->addLoader($loader);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function resolve($resource, $type = null)
+ {
+ foreach ($this->loaders as $loader) {
+ if ($loader->supports($resource, $type)) {
+ return $loader;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Adds a loader.
+ *
+ * @param LoaderInterface $loader A LoaderInterface instance
+ */
+ public function addLoader(LoaderInterface $loader)
+ {
+ $this->loaders[] = $loader;
+ $loader->setResolver($this);
+ }
+
+ /**
+ * Returns the registered loaders.
+ *
+ * @return LoaderInterface[] An array of LoaderInterface instances
+ */
+ public function getLoaders()
+ {
+ return $this->loaders;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolverInterface.php b/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolverInterface.php
new file mode 100644
index 0000000..40f1a1a
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolverInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Loader;
+
+/**
+ * LoaderResolverInterface selects a loader for a given resource.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface LoaderResolverInterface
+{
+ /**
+ * Returns a loader able to load the resource.
+ *
+ * @param mixed $resource A resource
+ * @param string|null $type The resource type or null if unknown
+ *
+ * @return LoaderInterface|false The loader or false if none is able to load the resource
+ */
+ public function resolve($resource, $type = null);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/README.md b/vendor/symfony/config/Symfony/Component/Config/README.md
new file mode 100644
index 0000000..690d7d7
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/README.md
@@ -0,0 +1,17 @@
+Config Component
+================
+
+Config provides the infrastructure for loading configurations from different
+data sources and optionally monitoring these data sources for changes. There
+are additional tools for validating, normalizing and handling of defaults that
+can optionally be used to convert from different formats to arrays.
+
+Resources
+---------
+
+You can run the unit tests with the following command:
+
+ $ cd path/to/Symfony/Component/Config/
+ $ composer install
+ $ phpunit
+
diff --git a/vendor/symfony/config/Symfony/Component/Config/Resource/DirectoryResource.php b/vendor/symfony/config/Symfony/Component/Config/Resource/DirectoryResource.php
new file mode 100644
index 0000000..515fb5c
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Resource/DirectoryResource.php
@@ -0,0 +1,99 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Resource;
+
+/**
+ * DirectoryResource represents a resources stored in a subdirectory tree.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class DirectoryResource implements ResourceInterface, \Serializable
+{
+ private $resource;
+ private $pattern;
+
+ /**
+ * Constructor.
+ *
+ * @param string $resource The file path to the resource
+ * @param string|null $pattern A pattern to restrict monitored files
+ */
+ public function __construct($resource, $pattern = null)
+ {
+ $this->resource = $resource;
+ $this->pattern = $pattern;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __toString()
+ {
+ return (string) $this->resource;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getResource()
+ {
+ return $this->resource;
+ }
+
+ /**
+ * Returns the pattern to restrict monitored files.
+ *
+ * @return string|null
+ */
+ public function getPattern()
+ {
+ return $this->pattern;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isFresh($timestamp)
+ {
+ if (!is_dir($this->resource)) {
+ return false;
+ }
+
+ $newestMTime = filemtime($this->resource);
+ foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) {
+ // if regex filtering is enabled only check matching files
+ if ($this->pattern && $file->isFile() && !preg_match($this->pattern, $file->getBasename())) {
+ continue;
+ }
+
+ // always monitor directories for changes, except the .. entries
+ // (otherwise deleted files wouldn't get detected)
+ if ($file->isDir() && '/..' === substr($file, -3)) {
+ continue;
+ }
+
+ $newestMTime = max($file->getMTime(), $newestMTime);
+ }
+
+ return $newestMTime < $timestamp;
+ }
+
+ public function serialize()
+ {
+ return serialize(array($this->resource, $this->pattern));
+ }
+
+ public function unserialize($serialized)
+ {
+ list($this->resource, $this->pattern) = unserialize($serialized);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Resource/FileResource.php b/vendor/symfony/config/Symfony/Component/Config/Resource/FileResource.php
new file mode 100644
index 0000000..4c00ae4
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Resource/FileResource.php
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Resource;
+
+/**
+ * FileResource represents a resource stored on the filesystem.
+ *
+ * The resource can be a file or a directory.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class FileResource implements ResourceInterface, \Serializable
+{
+ /**
+ * @var string|false
+ */
+ private $resource;
+
+ /**
+ * Constructor.
+ *
+ * @param string $resource The file path to the resource
+ */
+ public function __construct($resource)
+ {
+ $this->resource = realpath($resource);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __toString()
+ {
+ return (string) $this->resource;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getResource()
+ {
+ return $this->resource;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isFresh($timestamp)
+ {
+ if (false === $this->resource || !file_exists($this->resource)) {
+ return false;
+ }
+
+ return filemtime($this->resource) <= $timestamp;
+ }
+
+ public function serialize()
+ {
+ return serialize($this->resource);
+ }
+
+ public function unserialize($serialized)
+ {
+ $this->resource = unserialize($serialized);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Resource/ResourceInterface.php b/vendor/symfony/config/Symfony/Component/Config/Resource/ResourceInterface.php
new file mode 100644
index 0000000..db03d12
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Resource/ResourceInterface.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Resource;
+
+/**
+ * ResourceInterface is the interface that must be implemented by all Resource classes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface ResourceInterface
+{
+ /**
+ * Returns a string representation of the Resource.
+ *
+ * @return string A string representation of the Resource
+ */
+ public function __toString();
+
+ /**
+ * Returns true if the resource has not been updated since the given timestamp.
+ *
+ * @param int $timestamp The last time the resource was loaded
+ *
+ * @return bool True if the resource has not been updated, false otherwise
+ */
+ public function isFresh($timestamp);
+
+ /**
+ * Returns the tied resource.
+ *
+ * @return mixed The resource
+ */
+ public function getResource();
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/ConfigCacheTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/ConfigCacheTest.php
new file mode 100644
index 0000000..8271885
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/ConfigCacheTest.php
@@ -0,0 +1,138 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests;
+
+use Symfony\Component\Config\ConfigCache;
+use Symfony\Component\Config\Resource\FileResource;
+
+class ConfigCacheTest extends \PHPUnit_Framework_TestCase
+{
+ private $resourceFile = null;
+
+ private $cacheFile = null;
+
+ private $metaFile = null;
+
+ protected function setUp()
+ {
+ $this->resourceFile = tempnam(sys_get_temp_dir(), '_resource');
+ $this->cacheFile = tempnam(sys_get_temp_dir(), 'config_');
+ $this->metaFile = $this->cacheFile.'.meta';
+
+ $this->makeCacheFresh();
+ $this->generateMetaFile();
+ }
+
+ protected function tearDown()
+ {
+ $files = array($this->cacheFile, $this->metaFile, $this->resourceFile);
+
+ foreach ($files as $file) {
+ if (file_exists($file)) {
+ unlink($file);
+ }
+ }
+ }
+
+ public function testToString()
+ {
+ $cache = new ConfigCache($this->cacheFile, true);
+
+ $this->assertSame($this->cacheFile, (string) $cache);
+ }
+
+ public function testCacheIsNotFreshIfFileDoesNotExist()
+ {
+ unlink($this->cacheFile);
+
+ $cache = new ConfigCache($this->cacheFile, false);
+
+ $this->assertFalse($cache->isFresh());
+ }
+
+ public function testCacheIsAlwaysFreshIfFileExistsWithDebugDisabled()
+ {
+ $this->makeCacheStale();
+
+ $cache = new ConfigCache($this->cacheFile, false);
+
+ $this->assertTrue($cache->isFresh());
+ }
+
+ public function testCacheIsNotFreshWithoutMetaFile()
+ {
+ unlink($this->metaFile);
+
+ $cache = new ConfigCache($this->cacheFile, true);
+
+ $this->assertFalse($cache->isFresh());
+ }
+
+ public function testCacheIsFreshIfResourceIsFresh()
+ {
+ $cache = new ConfigCache($this->cacheFile, true);
+
+ $this->assertTrue($cache->isFresh());
+ }
+
+ public function testCacheIsNotFreshIfOneOfTheResourcesIsNotFresh()
+ {
+ $this->makeCacheStale();
+
+ $cache = new ConfigCache($this->cacheFile, true);
+
+ $this->assertFalse($cache->isFresh());
+ }
+
+ public function testWriteDumpsFile()
+ {
+ unlink($this->cacheFile);
+ unlink($this->metaFile);
+
+ $cache = new ConfigCache($this->cacheFile, false);
+ $cache->write('FOOBAR');
+
+ $this->assertFileExists($this->cacheFile, 'Cache file is created');
+ $this->assertSame('FOOBAR', file_get_contents($this->cacheFile));
+ $this->assertFileNotExists($this->metaFile, 'Meta file is not created');
+ }
+
+ public function testWriteDumpsMetaFileWithDebugEnabled()
+ {
+ unlink($this->cacheFile);
+ unlink($this->metaFile);
+
+ $metadata = array(new FileResource($this->resourceFile));
+
+ $cache = new ConfigCache($this->cacheFile, true);
+ $cache->write('FOOBAR', $metadata);
+
+ $this->assertFileExists($this->cacheFile, 'Cache file is created');
+ $this->assertFileExists($this->metaFile, 'Meta file is created');
+ $this->assertSame(serialize($metadata), file_get_contents($this->metaFile));
+ }
+
+ private function makeCacheFresh()
+ {
+ touch($this->resourceFile, filemtime($this->cacheFile) - 3600);
+ }
+
+ private function makeCacheStale()
+ {
+ touch($this->cacheFile, filemtime($this->resourceFile) - 3600);
+ }
+
+ private function generateMetaFile()
+ {
+ file_put_contents($this->metaFile, serialize(array(new FileResource($this->resourceFile))));
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php
new file mode 100644
index 0000000..291c2fd
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php
@@ -0,0 +1,160 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\ArrayNode;
+use Symfony\Component\Config\Definition\ScalarNode;
+
+class ArrayNodeTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
+ */
+ public function testNormalizeThrowsExceptionWhenFalseIsNotAllowed()
+ {
+ $node = new ArrayNode('root');
+ $node->normalize(false);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage Unrecognized option "foo" under "root"
+ */
+ public function testExceptionThrownOnUnrecognizedChild()
+ {
+ $node = new ArrayNode('root');
+ $node->normalize(array('foo' => 'bar'));
+ }
+
+ /**
+ * Tests that no exception is thrown for an unrecognized child if the
+ * ignoreExtraKeys option is set to true.
+ *
+ * Related to testExceptionThrownOnUnrecognizedChild
+ */
+ public function testIgnoreExtraKeysNoException()
+ {
+ $node = new ArrayNode('roo');
+ $node->setIgnoreExtraKeys(true);
+
+ $node->normalize(array('foo' => 'bar'));
+ $this->assertTrue(true, 'No exception was thrown when setIgnoreExtraKeys is true');
+ }
+
+ /**
+ * @dataProvider getPreNormalizationTests
+ */
+ public function testPreNormalize($denormalized, $normalized)
+ {
+ $node = new ArrayNode('foo');
+
+ $r = new \ReflectionMethod($node, 'preNormalize');
+ $r->setAccessible(true);
+
+ $this->assertSame($normalized, $r->invoke($node, $denormalized));
+ }
+
+ public function getPreNormalizationTests()
+ {
+ return array(
+ array(
+ array('foo-bar' => 'foo'),
+ array('foo_bar' => 'foo'),
+ ),
+ array(
+ array('foo-bar_moo' => 'foo'),
+ array('foo-bar_moo' => 'foo'),
+ ),
+ array(
+ array('foo-bar' => null, 'foo_bar' => 'foo'),
+ array('foo-bar' => null, 'foo_bar' => 'foo'),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider getZeroNamedNodeExamplesData
+ */
+ public function testNodeNameCanBeZero($denormalized, $normalized)
+ {
+ $zeroNode = new ArrayNode(0);
+ $zeroNode->addChild(new ScalarNode('name'));
+ $fiveNode = new ArrayNode(5);
+ $fiveNode->addChild(new ScalarNode(0));
+ $fiveNode->addChild(new ScalarNode('new_key'));
+ $rootNode = new ArrayNode('root');
+ $rootNode->addChild($zeroNode);
+ $rootNode->addChild($fiveNode);
+ $rootNode->addChild(new ScalarNode('string_key'));
+ $r = new \ReflectionMethod($rootNode, 'normalizeValue');
+ $r->setAccessible(true);
+
+ $this->assertSame($normalized, $r->invoke($rootNode, $denormalized));
+ }
+
+ public function getZeroNamedNodeExamplesData()
+ {
+ return array(
+ array(
+ array(
+ 0 => array(
+ 'name' => 'something',
+ ),
+ 5 => array(
+ 0 => 'this won\'t work too',
+ 'new_key' => 'some other value',
+ ),
+ 'string_key' => 'just value',
+ ),
+ array(
+ 0 => array(
+ 'name' => 'something',
+ ),
+ 5 => array(
+ 0 => 'this won\'t work too',
+ 'new_key' => 'some other value',
+ ),
+ 'string_key' => 'just value',
+ ),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider getPreNormalizedNormalizedOrderedData
+ */
+ public function testChildrenOrderIsMaintainedOnNormalizeValue($prenormalized, $normalized)
+ {
+ $scalar1 = new ScalarNode('1');
+ $scalar2 = new ScalarNode('2');
+ $scalar3 = new ScalarNode('3');
+ $node = new ArrayNode('foo');
+ $node->addChild($scalar1);
+ $node->addChild($scalar3);
+ $node->addChild($scalar2);
+
+ $r = new \ReflectionMethod($node, 'normalizeValue');
+ $r->setAccessible(true);
+
+ $this->assertSame($normalized, $r->invoke($node, $prenormalized));
+ }
+
+ public function getPreNormalizedNormalizedOrderedData()
+ {
+ return array(
+ array(
+ array('2' => 'two', '1' => 'one', '3' => 'three'),
+ array('2' => 'two', '1' => 'one', '3' => 'three'),
+ ),
+ );
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php
new file mode 100644
index 0000000..0753d64
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\BooleanNode;
+
+class BooleanNodeTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getValidValues
+ */
+ public function testNormalize($value)
+ {
+ $node = new BooleanNode('test');
+ $this->assertSame($value, $node->normalize($value));
+ }
+
+ public function getValidValues()
+ {
+ return array(
+ array(false),
+ array(true),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidValues
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
+ */
+ public function testNormalizeThrowsExceptionOnInvalidValues($value)
+ {
+ $node = new BooleanNode('test');
+ $node->normalize($value);
+ }
+
+ public function getInvalidValues()
+ {
+ return array(
+ array(null),
+ array(''),
+ array('foo'),
+ array(0),
+ array(1),
+ array(0.0),
+ array(0.1),
+ array(array()),
+ array(array('foo' => 'bar')),
+ array(new \stdClass()),
+ );
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php
new file mode 100644
index 0000000..e75ed34
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php
@@ -0,0 +1,207 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\Config\Definition\Processor;
+use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
+use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
+
+class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
+{
+ public function testAppendingSomeNode()
+ {
+ $parent = new ArrayNodeDefinition('root');
+ $child = new ScalarNodeDefinition('child');
+
+ $parent
+ ->children()
+ ->scalarNode('foo')->end()
+ ->scalarNode('bar')->end()
+ ->end()
+ ->append($child);
+
+ $this->assertCount(3, $this->getField($parent, 'children'));
+ $this->assertTrue(in_array($child, $this->getField($parent, 'children')));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
+ * @dataProvider providePrototypeNodeSpecificCalls
+ */
+ public function testPrototypeNodeSpecificOption($method, $args)
+ {
+ $node = new ArrayNodeDefinition('root');
+
+ call_user_func_array(array($node, $method), $args);
+
+ $node->getNode();
+ }
+
+ public function providePrototypeNodeSpecificCalls()
+ {
+ return array(
+ array('defaultValue', array(array())),
+ array('addDefaultChildrenIfNoneSet', array()),
+ array('requiresAtLeastOneElement', array()),
+ array('useAttributeAsKey', array('foo')),
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
+ */
+ public function testConcreteNodeSpecificOption()
+ {
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->addDefaultsIfNotSet()
+ ->prototype('array')
+ ;
+ $node->getNode();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
+ */
+ public function testPrototypeNodesCantHaveADefaultValueWhenUsingDefaultChildren()
+ {
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->defaultValue(array())
+ ->addDefaultChildrenIfNoneSet('foo')
+ ->prototype('array')
+ ;
+ $node->getNode();
+ }
+
+ public function testPrototypedArrayNodeDefaultWhenUsingDefaultChildren()
+ {
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->addDefaultChildrenIfNoneSet()
+ ->prototype('array')
+ ;
+ $tree = $node->getNode();
+ $this->assertEquals(array(array()), $tree->getDefaultValue());
+ }
+
+ /**
+ * @dataProvider providePrototypedArrayNodeDefaults
+ */
+ public function testPrototypedArrayNodeDefault($args, $shouldThrowWhenUsingAttrAsKey, $shouldThrowWhenNotUsingAttrAsKey, $defaults)
+ {
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->addDefaultChildrenIfNoneSet($args)
+ ->prototype('array')
+ ;
+
+ try {
+ $tree = $node->getNode();
+ $this->assertFalse($shouldThrowWhenNotUsingAttrAsKey);
+ $this->assertEquals($defaults, $tree->getDefaultValue());
+ } catch (InvalidDefinitionException $e) {
+ $this->assertTrue($shouldThrowWhenNotUsingAttrAsKey);
+ }
+
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->useAttributeAsKey('attr')
+ ->addDefaultChildrenIfNoneSet($args)
+ ->prototype('array')
+ ;
+
+ try {
+ $tree = $node->getNode();
+ $this->assertFalse($shouldThrowWhenUsingAttrAsKey);
+ $this->assertEquals($defaults, $tree->getDefaultValue());
+ } catch (InvalidDefinitionException $e) {
+ $this->assertTrue($shouldThrowWhenUsingAttrAsKey);
+ }
+ }
+
+ public function providePrototypedArrayNodeDefaults()
+ {
+ return array(
+ array(null, true, false, array(array())),
+ array(2, true, false, array(array(), array())),
+ array('2', false, true, array('2' => array())),
+ array('foo', false, true, array('foo' => array())),
+ array(array('foo'), false, true, array('foo' => array())),
+ array(array('foo', 'bar'), false, true, array('foo' => array(), 'bar' => array())),
+ );
+ }
+
+ public function testNestedPrototypedArrayNodes()
+ {
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->addDefaultChildrenIfNoneSet()
+ ->prototype('array')
+ ->prototype('array')
+ ;
+ $node->getNode();
+ }
+
+ public function testEnabledNodeDefaults()
+ {
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->canBeEnabled()
+ ->children()
+ ->scalarNode('foo')->defaultValue('bar')->end()
+ ;
+
+ $this->assertEquals(array('enabled' => false, 'foo' => 'bar'), $node->getNode()->getDefaultValue());
+ }
+
+ /**
+ * @dataProvider getEnableableNodeFixtures
+ */
+ public function testTrueEnableEnabledNode($expected, $config, $message)
+ {
+ $processor = new Processor();
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->canBeEnabled()
+ ->children()
+ ->scalarNode('foo')->defaultValue('bar')->end()
+ ;
+
+ $this->assertEquals(
+ $expected,
+ $processor->process($node->getNode(), $config),
+ $message
+ );
+ }
+
+ public function getEnableableNodeFixtures()
+ {
+ return array(
+ array(array('enabled' => true, 'foo' => 'bar'), array(true), 'true enables an enableable node'),
+ array(array('enabled' => true, 'foo' => 'bar'), array(null), 'null enables an enableable node'),
+ array(array('enabled' => true, 'foo' => 'bar'), array(array('enabled' => true)), 'An enableable node can be enabled'),
+ array(array('enabled' => true, 'foo' => 'baz'), array(array('foo' => 'baz')), 'any configuration enables an enableable node'),
+ array(array('enabled' => false, 'foo' => 'baz'), array(array('foo' => 'baz', 'enabled' => false)), 'An enableable node can be disabled'),
+ array(array('enabled' => false, 'foo' => 'bar'), array(false), 'false disables an enableable node'),
+ );
+ }
+
+ protected function getField($object, $field)
+ {
+ $reflection = new \ReflectionProperty($object, $field);
+ $reflection->setAccessible(true);
+
+ return $reflection->getValue($object);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php
new file mode 100644
index 0000000..69f7fcf
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\EnumNodeDefinition;
+
+class EnumNodeDefinitionTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage ->values() must be called with at least two distinct values.
+ */
+ public function testNoDistinctValues()
+ {
+ $def = new EnumNodeDefinition('foo');
+ $def->values(array('foo', 'foo'));
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ * @expectedExceptionMessage You must call ->values() on enum nodes.
+ */
+ public function testNoValuesPassed()
+ {
+ $def = new EnumNodeDefinition('foo');
+ $def->getNode();
+ }
+
+ public function testGetNode()
+ {
+ $def = new EnumNodeDefinition('foo');
+ $def->values(array('foo', 'bar'));
+
+ $node = $def->getNode();
+ $this->assertEquals(array('foo', 'bar'), $node->getValues());
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php
new file mode 100644
index 0000000..147bf13
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php
@@ -0,0 +1,215 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+
+class ExprBuilderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testAlwaysExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->always($this->returnClosure('new_value'))
+ ->end();
+
+ $this->assertFinalizedValueIs('new_value', $test);
+ }
+
+ public function testIfTrueExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifTrue()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test, array('key' => true));
+
+ $test = $this->getTestBuilder()
+ ->ifTrue(function ($v) { return true; })
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test);
+
+ $test = $this->getTestBuilder()
+ ->ifTrue(function ($v) { return false; })
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('value', $test);
+ }
+
+ public function testIfStringExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifString()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test);
+
+ $test = $this->getTestBuilder()
+ ->ifString()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs(45, $test, array('key' => 45));
+ }
+
+ public function testIfNullExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifNull()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test, array('key' => null));
+
+ $test = $this->getTestBuilder()
+ ->ifNull()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('value', $test);
+ }
+
+ public function testIfArrayExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifArray()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test, array('key' => array()));
+
+ $test = $this->getTestBuilder()
+ ->ifArray()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('value', $test);
+ }
+
+ public function testIfInArrayExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifInArray(array('foo', 'bar', 'value'))
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test);
+
+ $test = $this->getTestBuilder()
+ ->ifInArray(array('foo', 'bar'))
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('value', $test);
+ }
+
+ public function testIfNotInArrayExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifNotInArray(array('foo', 'bar'))
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test);
+
+ $test = $this->getTestBuilder()
+ ->ifNotInArray(array('foo', 'bar', 'value_from_config'))
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test);
+ }
+
+ public function testThenEmptyArrayExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifString()
+ ->thenEmptyArray()
+ ->end();
+ $this->assertFinalizedValueIs(array(), $test);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ */
+ public function testThenInvalid()
+ {
+ $test = $this->getTestBuilder()
+ ->ifString()
+ ->thenInvalid('Invalid value')
+ ->end();
+ $this->finalizeTestBuilder($test);
+ }
+
+ public function testThenUnsetExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifString()
+ ->thenUnset()
+ ->end();
+ $this->assertEquals(array(), $this->finalizeTestBuilder($test));
+ }
+
+ /**
+ * Create a test treebuilder with a variable node, and init the validation.
+ *
+ * @return TreeBuilder
+ */
+ protected function getTestBuilder()
+ {
+ $builder = new TreeBuilder();
+
+ return $builder
+ ->root('test')
+ ->children()
+ ->variableNode('key')
+ ->validate()
+ ;
+ }
+
+ /**
+ * Close the validation process and finalize with the given config.
+ *
+ * @param TreeBuilder $testBuilder The tree builder to finalize
+ * @param array $config The config you want to use for the finalization, if nothing provided
+ * a simple array('key'=>'value') will be used
+ *
+ * @return array The finalized config values
+ */
+ protected function finalizeTestBuilder($testBuilder, $config = null)
+ {
+ return $testBuilder
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ->finalize(null === $config ? array('key' => 'value') : $config)
+ ;
+ }
+
+ /**
+ * Return a closure that will return the given value.
+ *
+ * @param mixed $val The value that the closure must return
+ *
+ * @return \Closure
+ */
+ protected function returnClosure($val)
+ {
+ return function ($v) use ($val) {
+ return $val;
+ };
+ }
+
+ /**
+ * Assert that the given test builder, will return the given value.
+ *
+ * @param mixed $value The value to test
+ * @param TreeBuilder $treeBuilder The tree builder to finalize
+ * @param mixed $config The config values that new to be finalized
+ */
+ protected function assertFinalizedValueIs($value, $treeBuilder, $config = null)
+ {
+ $this->assertEquals(array('key' => $value), $this->finalizeTestBuilder($treeBuilder, $config));
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php
new file mode 100644
index 0000000..22c399c
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php
@@ -0,0 +1,94 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder;
+use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition;
+
+class NodeBuilderTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testThrowsAnExceptionWhenTryingToCreateANonRegisteredNodeType()
+ {
+ $builder = new BaseNodeBuilder();
+ $builder->node('', 'foobar');
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testThrowsAnExceptionWhenTheNodeClassIsNotFound()
+ {
+ $builder = new BaseNodeBuilder();
+ $builder
+ ->setNodeClass('noclasstype', '\\foo\\bar\\noclass')
+ ->node('', 'noclasstype');
+ }
+
+ public function testAddingANewNodeType()
+ {
+ $class = __NAMESPACE__.'\\SomeNodeDefinition';
+
+ $builder = new BaseNodeBuilder();
+ $node = $builder
+ ->setNodeClass('newtype', $class)
+ ->node('', 'newtype');
+
+ $this->assertInstanceOf($class, $node);
+ }
+
+ public function testOverridingAnExistingNodeType()
+ {
+ $class = __NAMESPACE__.'\\SomeNodeDefinition';
+
+ $builder = new BaseNodeBuilder();
+ $node = $builder
+ ->setNodeClass('variable', $class)
+ ->node('', 'variable');
+
+ $this->assertInstanceOf($class, $node);
+ }
+
+ public function testNodeTypesAreNotCaseSensitive()
+ {
+ $builder = new BaseNodeBuilder();
+
+ $node1 = $builder->node('', 'VaRiAbLe');
+ $node2 = $builder->node('', 'variable');
+
+ $this->assertInstanceOf(get_class($node1), $node2);
+
+ $builder->setNodeClass('CuStOm', __NAMESPACE__.'\\SomeNodeDefinition');
+
+ $node1 = $builder->node('', 'CUSTOM');
+ $node2 = $builder->node('', 'custom');
+
+ $this->assertInstanceOf(get_class($node1), $node2);
+ }
+
+ public function testNumericNodeCreation()
+ {
+ $builder = new BaseNodeBuilder();
+
+ $node = $builder->integerNode('foo')->min(3)->max(5);
+ $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition', $node);
+
+ $node = $builder->floatNode('bar')->min(3.0)->max(5.0);
+ $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\FloatNodeDefinition', $node);
+ }
+}
+
+class SomeNodeDefinition extends BaseVariableNodeDefinition
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php
new file mode 100644
index 0000000..cf0813a
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition as NumericNodeDefinition;
+use Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition;
+use Symfony\Component\Config\Definition\Builder\FloatNodeDefinition;
+
+class NumericNodeDefinitionTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage You cannot define a min(4) as you already have a max(3)
+ */
+ public function testIncoherentMinAssertion()
+ {
+ $def = new NumericNodeDefinition('foo');
+ $def->max(3)->min(4);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage You cannot define a max(2) as you already have a min(3)
+ */
+ public function testIncoherentMaxAssertion()
+ {
+ $node = new NumericNodeDefinition('foo');
+ $node->min(3)->max(2);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage The value 4 is too small for path "foo". Should be greater than or equal to 5
+ */
+ public function testIntegerMinAssertion()
+ {
+ $def = new IntegerNodeDefinition('foo');
+ $def->min(5)->getNode()->finalize(4);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage The value 4 is too big for path "foo". Should be less than or equal to 3
+ */
+ public function testIntegerMaxAssertion()
+ {
+ $def = new IntegerNodeDefinition('foo');
+ $def->max(3)->getNode()->finalize(4);
+ }
+
+ public function testIntegerValidMinMaxAssertion()
+ {
+ $def = new IntegerNodeDefinition('foo');
+ $node = $def->min(3)->max(7)->getNode();
+ $this->assertEquals(4, $node->finalize(4));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage The value 400 is too small for path "foo". Should be greater than or equal to 500
+ */
+ public function testFloatMinAssertion()
+ {
+ $def = new FloatNodeDefinition('foo');
+ $def->min(5E2)->getNode()->finalize(4e2);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage The value 4.3 is too big for path "foo". Should be less than or equal to 0.3
+ */
+ public function testFloatMaxAssertion()
+ {
+ $def = new FloatNodeDefinition('foo');
+ $def->max(0.3)->getNode()->finalize(4.3);
+ }
+
+ public function testFloatValidMinMaxAssertion()
+ {
+ $def = new FloatNodeDefinition('foo');
+ $node = $def->min(3.0)->max(7e2)->getNode();
+ $this->assertEquals(4.5, $node->finalize(4.5));
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php
new file mode 100644
index 0000000..00e27c6
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder as CustomNodeBuilder;
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+
+require __DIR__.'/../../Fixtures/Builder/NodeBuilder.php';
+require __DIR__.'/../../Fixtures/Builder/BarNodeDefinition.php';
+require __DIR__.'/../../Fixtures/Builder/VariableNodeDefinition.php';
+
+class TreeBuilderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testUsingACustomNodeBuilder()
+ {
+ $builder = new TreeBuilder();
+ $root = $builder->root('custom', 'array', new CustomNodeBuilder());
+
+ $nodeBuilder = $root->children();
+
+ $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder', $nodeBuilder);
+
+ $nodeBuilder = $nodeBuilder->arrayNode('deeper')->children();
+
+ $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder', $nodeBuilder);
+ }
+
+ public function testOverrideABuiltInNodeType()
+ {
+ $builder = new TreeBuilder();
+ $root = $builder->root('override', 'array', new CustomNodeBuilder());
+
+ $definition = $root->children()->variableNode('variable');
+
+ $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\VariableNodeDefinition', $definition);
+ }
+
+ public function testAddANodeType()
+ {
+ $builder = new TreeBuilder();
+ $root = $builder->root('override', 'array', new CustomNodeBuilder());
+
+ $definition = $root->children()->barNode('variable');
+
+ $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\BarNodeDefinition', $definition);
+ }
+
+ public function testCreateABuiltInNodeTypeWithACustomNodeBuilder()
+ {
+ $builder = new TreeBuilder();
+ $root = $builder->root('builtin', 'array', new CustomNodeBuilder());
+
+ $definition = $root->children()->booleanNode('boolean');
+
+ $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition', $definition);
+ }
+
+ public function testPrototypedArrayNodeUseTheCustomNodeBuilder()
+ {
+ $builder = new TreeBuilder();
+ $root = $builder->root('override', 'array', new CustomNodeBuilder());
+
+ $root->prototype('bar')->end();
+ }
+
+ public function testAnExtendedNodeBuilderGetsPropagatedToTheChildren()
+ {
+ $builder = new TreeBuilder();
+
+ $builder->root('propagation')
+ ->children()
+ ->setNodeClass('extended', 'Symfony\Component\Config\Tests\Definition\Builder\VariableNodeDefinition')
+ ->node('foo', 'extended')->end()
+ ->arrayNode('child')
+ ->children()
+ ->node('foo', 'extended')
+ ->end()
+ ->end()
+ ->end()
+ ->end();
+ }
+
+ public function testDefinitionInfoGetsTransferredToNode()
+ {
+ $builder = new TreeBuilder();
+
+ $builder->root('test')->info('root info')
+ ->children()
+ ->node('child', 'variable')->info('child info')->defaultValue('default')
+ ->end()
+ ->end();
+
+ $tree = $builder->buildTree();
+ $children = $tree->getChildren();
+
+ $this->assertEquals('root info', $tree->getInfo());
+ $this->assertEquals('child info', $children['child']->getInfo());
+ }
+
+ public function testDefinitionExampleGetsTransferredToNode()
+ {
+ $builder = new TreeBuilder();
+
+ $builder->root('test')
+ ->example(array('key' => 'value'))
+ ->children()
+ ->node('child', 'variable')->info('child info')->defaultValue('default')->example('example')
+ ->end()
+ ->end();
+
+ $tree = $builder->buildTree();
+ $children = $tree->getChildren();
+
+ $this->assertTrue(is_array($tree->getExample()));
+ $this->assertEquals('example', $children['child']->getExample());
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php
new file mode 100644
index 0000000..ab6bdaa
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition\Dumper;
+
+use Symfony\Component\Config\Definition\Dumper\XmlReferenceDumper;
+use Symfony\Component\Config\Tests\Fixtures\Configuration\ExampleConfiguration;
+
+class XmlReferenceDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDumper()
+ {
+ $configuration = new ExampleConfiguration();
+
+ $dumper = new XmlReferenceDumper();
+ $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration));
+ }
+
+ public function testNamespaceDumper()
+ {
+ $configuration = new ExampleConfiguration();
+
+ $dumper = new XmlReferenceDumper();
+ $this->assertEquals(str_replace('http://example.org/schema/dic/acme_root', 'http://symfony.com/schema/dic/symfony', $this->getConfigurationAsString()), $dumper->dump($configuration, 'http://symfony.com/schema/dic/symfony'));
+ }
+
+ private function getConfigurationAsString()
+ {
+ return <<<EOL
+<!-- Namespace: http://example.org/schema/dic/acme_root -->
+<!-- scalar-required: Required -->
+<!-- enum: One of "this"; "that" -->
+<config
+ boolean="true"
+ scalar-empty=""
+ scalar-null="null"
+ scalar-true="true"
+ scalar-false="false"
+ scalar-default="default"
+ scalar-array-empty=""
+ scalar-array-defaults="elem1,elem2"
+ scalar-required=""
+ enum=""
+>
+
+ <!-- some info -->
+ <!--
+ child3: this is a long
+ multi-line info text
+ which should be indented;
+ Example: example setting
+ -->
+ <array
+ child1=""
+ child2=""
+ child3=""
+ />
+
+ <!-- prototype -->
+ <parameter name="parameter name">scalar value</parameter>
+
+ <!-- prototype -->
+ <connection
+ user=""
+ pass=""
+ />
+
+</config>
+
+EOL;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php
new file mode 100644
index 0000000..4775235
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition\Dumper;
+
+use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper;
+use Symfony\Component\Config\Tests\Fixtures\Configuration\ExampleConfiguration;
+
+class YamlReferenceDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDumper()
+ {
+ $configuration = new ExampleConfiguration();
+
+ $dumper = new YamlReferenceDumper();
+
+ $this->markTestIncomplete('The Yaml Dumper currently does not support prototyped arrays');
+ $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration));
+ }
+
+ private function getConfigurationAsString()
+ {
+ return <<<EOL
+acme_root:
+ boolean: true
+ scalar_empty: ~
+ scalar_null: ~
+ scalar_true: true
+ scalar_false: false
+ scalar_default: default
+ scalar_array_empty: []
+ scalar_array_defaults:
+
+ # Defaults:
+ - elem1
+ - elem2
+ scalar_required: ~ # Required
+ enum: ~ # One of "this"; "that"
+
+ # some info
+ array:
+ child1: ~
+ child2: ~
+
+ # this is a long
+ # multi-line info text
+ # which should be indented
+ child3: ~ # Example: example setting
+ parameters:
+
+ # Prototype
+ name: ~
+ connections:
+ # Prototype
+ - { user: ~, pass: ~ }
+
+EOL;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php
new file mode 100644
index 0000000..2b84de6
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\EnumNode;
+
+class EnumNodeTest extends \PHPUnit_Framework_TestCase
+{
+ public function testFinalizeValue()
+ {
+ $node = new EnumNode('foo', null, array('foo', 'bar'));
+ $this->assertSame('foo', $node->finalize('foo'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testConstructionWithOneValue()
+ {
+ new EnumNode('foo', null, array('foo', 'foo'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage The value "foobar" is not allowed for path "foo". Permissible values: "foo", "bar"
+ */
+ public function testFinalizeWithInvalidValue()
+ {
+ $node = new EnumNode('foo', null, array('foo', 'bar'));
+ $node->finalize('foobar');
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FinalizationTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FinalizationTest.php
new file mode 100644
index 0000000..19fc347
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FinalizationTest.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+use Symfony\Component\Config\Definition\Processor;
+use Symfony\Component\Config\Definition\NodeInterface;
+
+class FinalizationTest extends \PHPUnit_Framework_TestCase
+{
+ public function testUnsetKeyWithDeepHierarchy()
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('config', 'array')
+ ->children()
+ ->node('level1', 'array')
+ ->canBeUnset()
+ ->children()
+ ->node('level2', 'array')
+ ->canBeUnset()
+ ->children()
+ ->node('somevalue', 'scalar')->end()
+ ->node('anothervalue', 'scalar')->end()
+ ->end()
+ ->end()
+ ->node('level1_scalar', 'scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $a = array(
+ 'level1' => array(
+ 'level2' => array(
+ 'somevalue' => 'foo',
+ 'anothervalue' => 'bar',
+ ),
+ 'level1_scalar' => 'foo',
+ ),
+ );
+
+ $b = array(
+ 'level1' => array(
+ 'level2' => false,
+ ),
+ );
+
+ $this->assertEquals(array(
+ 'level1' => array(
+ 'level1_scalar' => 'foo',
+ ),
+ ), $this->process($tree, array($a, $b)));
+ }
+
+ protected function process(NodeInterface $tree, array $configs)
+ {
+ $processor = new Processor();
+
+ return $processor->process($tree, $configs);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php
new file mode 100644
index 0000000..4f308ca
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\FloatNode;
+
+class FloatNodeTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getValidValues
+ */
+ public function testNormalize($value)
+ {
+ $node = new FloatNode('test');
+ $this->assertSame($value, $node->normalize($value));
+ }
+
+ public function getValidValues()
+ {
+ return array(
+ array(1798.0),
+ array(-678.987),
+ array(12.56E45),
+ array(0.0),
+ // Integer are accepted too, they will be cast
+ array(17),
+ array(-10),
+ array(0),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidValues
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
+ */
+ public function testNormalizeThrowsExceptionOnInvalidValues($value)
+ {
+ $node = new FloatNode('test');
+ $node->normalize($value);
+ }
+
+ public function getInvalidValues()
+ {
+ return array(
+ array(null),
+ array(''),
+ array('foo'),
+ array(true),
+ array(false),
+ array(array()),
+ array(array('foo' => 'bar')),
+ array(new \stdClass()),
+ );
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php
new file mode 100644
index 0000000..1527db7
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\IntegerNode;
+
+class IntegerNodeTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getValidValues
+ */
+ public function testNormalize($value)
+ {
+ $node = new IntegerNode('test');
+ $this->assertSame($value, $node->normalize($value));
+ }
+
+ public function getValidValues()
+ {
+ return array(
+ array(1798),
+ array(-678),
+ array(0),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidValues
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
+ */
+ public function testNormalizeThrowsExceptionOnInvalidValues($value)
+ {
+ $node = new IntegerNode('test');
+ $node->normalize($value);
+ }
+
+ public function getInvalidValues()
+ {
+ return array(
+ array(null),
+ array(''),
+ array('foo'),
+ array(true),
+ array(false),
+ array(0.0),
+ array(0.1),
+ array(array()),
+ array(array('foo' => 'bar')),
+ array(new \stdClass()),
+ );
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/MergeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/MergeTest.php
new file mode 100644
index 0000000..08ddc32
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/MergeTest.php
@@ -0,0 +1,195 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+
+class MergeTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException
+ */
+ public function testForbiddenOverwrite()
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('root', 'array')
+ ->children()
+ ->node('foo', 'scalar')
+ ->cannotBeOverwritten()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $a = array(
+ 'foo' => 'bar',
+ );
+
+ $b = array(
+ 'foo' => 'moo',
+ );
+
+ $tree->merge($a, $b);
+ }
+
+ public function testUnsetKey()
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('root', 'array')
+ ->children()
+ ->node('foo', 'scalar')->end()
+ ->node('bar', 'scalar')->end()
+ ->node('unsettable', 'array')
+ ->canBeUnset()
+ ->children()
+ ->node('foo', 'scalar')->end()
+ ->node('bar', 'scalar')->end()
+ ->end()
+ ->end()
+ ->node('unsetted', 'array')
+ ->canBeUnset()
+ ->prototype('scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $a = array(
+ 'foo' => 'bar',
+ 'unsettable' => array(
+ 'foo' => 'a',
+ 'bar' => 'b',
+ ),
+ 'unsetted' => false,
+ );
+
+ $b = array(
+ 'foo' => 'moo',
+ 'bar' => 'b',
+ 'unsettable' => false,
+ 'unsetted' => array('a', 'b'),
+ );
+
+ $this->assertEquals(array(
+ 'foo' => 'moo',
+ 'bar' => 'b',
+ 'unsettable' => false,
+ 'unsetted' => array('a', 'b'),
+ ), $tree->merge($a, $b));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ */
+ public function testDoesNotAllowNewKeysInSubsequentConfigs()
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('config', 'array')
+ ->children()
+ ->node('test', 'array')
+ ->disallowNewKeysInSubsequentConfigs()
+ ->useAttributeAsKey('key')
+ ->prototype('array')
+ ->children()
+ ->node('value', 'scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree();
+
+ $a = array(
+ 'test' => array(
+ 'a' => array('value' => 'foo'),
+ ),
+ );
+
+ $b = array(
+ 'test' => array(
+ 'b' => array('value' => 'foo'),
+ ),
+ );
+
+ $tree->merge($a, $b);
+ }
+
+ public function testPerformsNoDeepMerging()
+ {
+ $tb = new TreeBuilder();
+
+ $tree = $tb
+ ->root('config', 'array')
+ ->children()
+ ->node('no_deep_merging', 'array')
+ ->performNoDeepMerging()
+ ->children()
+ ->node('foo', 'scalar')->end()
+ ->node('bar', 'scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $a = array(
+ 'no_deep_merging' => array(
+ 'foo' => 'a',
+ 'bar' => 'b',
+ ),
+ );
+
+ $b = array(
+ 'no_deep_merging' => array(
+ 'c' => 'd',
+ ),
+ );
+
+ $this->assertEquals(array(
+ 'no_deep_merging' => array(
+ 'c' => 'd',
+ ),
+ ), $tree->merge($a, $b));
+ }
+
+ public function testPrototypeWithoutAKeyAttribute()
+ {
+ $tb = new TreeBuilder();
+
+ $tree = $tb
+ ->root('config', 'array')
+ ->children()
+ ->arrayNode('append_elements')
+ ->prototype('scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $a = array(
+ 'append_elements' => array('a', 'b'),
+ );
+
+ $b = array(
+ 'append_elements' => array('c', 'd'),
+ );
+
+ $this->assertEquals(array('append_elements' => array('a', 'b', 'c', 'd')), $tree->merge($a, $b));
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/NormalizationTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/NormalizationTest.php
new file mode 100644
index 0000000..a896f96
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/NormalizationTest.php
@@ -0,0 +1,229 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\NodeInterface;
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+
+class NormalizationTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getEncoderTests
+ */
+ public function testNormalizeEncoders($denormalized)
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('root_name', 'array')
+ ->fixXmlConfig('encoder')
+ ->children()
+ ->node('encoders', 'array')
+ ->useAttributeAsKey('class')
+ ->prototype('array')
+ ->beforeNormalization()->ifString()->then(function ($v) { return array('algorithm' => $v); })->end()
+ ->children()
+ ->node('algorithm', 'scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $normalized = array(
+ 'encoders' => array(
+ 'foo' => array('algorithm' => 'plaintext'),
+ ),
+ );
+
+ $this->assertNormalized($tree, $denormalized, $normalized);
+ }
+
+ public function getEncoderTests()
+ {
+ $configs = array();
+
+ // XML
+ $configs[] = array(
+ 'encoder' => array(
+ array('class' => 'foo', 'algorithm' => 'plaintext'),
+ ),
+ );
+
+ // XML when only one element of this type
+ $configs[] = array(
+ 'encoder' => array('class' => 'foo', 'algorithm' => 'plaintext'),
+ );
+
+ // YAML/PHP
+ $configs[] = array(
+ 'encoders' => array(
+ array('class' => 'foo', 'algorithm' => 'plaintext'),
+ ),
+ );
+
+ // YAML/PHP
+ $configs[] = array(
+ 'encoders' => array(
+ 'foo' => 'plaintext',
+ ),
+ );
+
+ // YAML/PHP
+ $configs[] = array(
+ 'encoders' => array(
+ 'foo' => array('algorithm' => 'plaintext'),
+ ),
+ );
+
+ return array_map(function ($v) {
+ return array($v);
+ }, $configs);
+ }
+
+ /**
+ * @dataProvider getAnonymousKeysTests
+ */
+ public function testAnonymousKeysArray($denormalized)
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('root', 'array')
+ ->children()
+ ->node('logout', 'array')
+ ->fixXmlConfig('handler')
+ ->children()
+ ->node('handlers', 'array')
+ ->prototype('scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $normalized = array('logout' => array('handlers' => array('a', 'b', 'c')));
+
+ $this->assertNormalized($tree, $denormalized, $normalized);
+ }
+
+ public function getAnonymousKeysTests()
+ {
+ $configs = array();
+
+ $configs[] = array(
+ 'logout' => array(
+ 'handlers' => array('a', 'b', 'c'),
+ ),
+ );
+
+ $configs[] = array(
+ 'logout' => array(
+ 'handler' => array('a', 'b', 'c'),
+ ),
+ );
+
+ return array_map(function ($v) { return array($v); }, $configs);
+ }
+
+ /**
+ * @dataProvider getNumericKeysTests
+ */
+ public function testNumericKeysAsAttributes($denormalized)
+ {
+ $normalized = array(
+ 'thing' => array(42 => array('foo', 'bar'), 1337 => array('baz', 'qux')),
+ );
+
+ $this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, $normalized);
+ }
+
+ public function getNumericKeysTests()
+ {
+ $configs = array();
+
+ $configs[] = array(
+ 'thing' => array(
+ 42 => array('foo', 'bar'), 1337 => array('baz', 'qux'),
+ ),
+ );
+
+ $configs[] = array(
+ 'thing' => array(
+ array('foo', 'bar', 'id' => 42), array('baz', 'qux', 'id' => 1337),
+ ),
+ );
+
+ return array_map(function ($v) { return array($v); }, $configs);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage The attribute "id" must be set for path "root.thing".
+ */
+ public function testNonAssociativeArrayThrowsExceptionIfAttributeNotSet()
+ {
+ $denormalized = array(
+ 'thing' => array(
+ array('foo', 'bar'), array('baz', 'qux'),
+ ),
+ );
+
+ $this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, array());
+ }
+
+ public function testAssociativeArrayPreserveKeys()
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('root', 'array')
+ ->prototype('array')
+ ->children()
+ ->node('foo', 'scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $data = array('first' => array('foo' => 'bar'));
+
+ $this->assertNormalized($tree, $data, $data);
+ }
+
+ public static function assertNormalized(NodeInterface $tree, $denormalized, $normalized)
+ {
+ self::assertSame($normalized, $tree->normalize($denormalized));
+ }
+
+ private function getNumericKeysTestTree()
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('root', 'array')
+ ->children()
+ ->node('thing', 'array')
+ ->useAttributeAsKey('id')
+ ->prototype('array')
+ ->prototype('scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ return $tree;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php
new file mode 100644
index 0000000..c343fcf
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php
@@ -0,0 +1,180 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\PrototypedArrayNode;
+use Symfony\Component\Config\Definition\ArrayNode;
+use Symfony\Component\Config\Definition\ScalarNode;
+
+class PrototypedArrayNodeTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetDefaultValueReturnsAnEmptyArrayForPrototypes()
+ {
+ $node = new PrototypedArrayNode('root');
+ $prototype = new ArrayNode(null, $node);
+ $node->setPrototype($prototype);
+ $this->assertEmpty($node->getDefaultValue());
+ }
+
+ public function testGetDefaultValueReturnsDefaultValueForPrototypes()
+ {
+ $node = new PrototypedArrayNode('root');
+ $prototype = new ArrayNode(null, $node);
+ $node->setPrototype($prototype);
+ $node->setDefaultValue(array('test'));
+ $this->assertEquals(array('test'), $node->getDefaultValue());
+ }
+
+ // a remapped key (e.g. "mapping" -> "mappings") should be unset after being used
+ public function testRemappedKeysAreUnset()
+ {
+ $node = new ArrayNode('root');
+ $mappingsNode = new PrototypedArrayNode('mappings');
+ $node->addChild($mappingsNode);
+
+ // each item under mappings is just a scalar
+ $prototype = new ScalarNode(null, $mappingsNode);
+ $mappingsNode->setPrototype($prototype);
+
+ $remappings = array();
+ $remappings[] = array('mapping', 'mappings');
+ $node->setXmlRemappings($remappings);
+
+ $normalized = $node->normalize(array('mapping' => array('foo', 'bar')));
+ $this->assertEquals(array('mappings' => array('foo', 'bar')), $normalized);
+ }
+
+ /**
+ * Tests that when a key attribute is mapped, that key is removed from the array.
+ *
+ * <things>
+ * <option id="option1" value="foo">
+ * <option id="option2" value="bar">
+ * </things>
+ *
+ * The above should finally be mapped to an array that looks like this
+ * (because "id" is the key attribute).
+ *
+ * array(
+ * 'things' => array(
+ * 'option1' => 'foo',
+ * 'option2' => 'bar',
+ * )
+ * )
+ */
+ public function testMappedAttributeKeyIsRemoved()
+ {
+ $node = new PrototypedArrayNode('root');
+ $node->setKeyAttribute('id', true);
+
+ // each item under the root is an array, with one scalar item
+ $prototype = new ArrayNode(null, $node);
+ $prototype->addChild(new ScalarNode('foo'));
+ $node->setPrototype($prototype);
+
+ $children = array();
+ $children[] = array('id' => 'item_name', 'foo' => 'bar');
+ $normalized = $node->normalize($children);
+
+ $expected = array();
+ $expected['item_name'] = array('foo' => 'bar');
+ $this->assertEquals($expected, $normalized);
+ }
+
+ /**
+ * Tests the opposite of the testMappedAttributeKeyIsRemoved because
+ * the removal can be toggled with an option.
+ */
+ public function testMappedAttributeKeyNotRemoved()
+ {
+ $node = new PrototypedArrayNode('root');
+ $node->setKeyAttribute('id', false);
+
+ // each item under the root is an array, with two scalar items
+ $prototype = new ArrayNode(null, $node);
+ $prototype->addChild(new ScalarNode('foo'));
+ $prototype->addChild(new ScalarNode('id')); // the key attribute will remain
+ $node->setPrototype($prototype);
+
+ $children = array();
+ $children[] = array('id' => 'item_name', 'foo' => 'bar');
+ $normalized = $node->normalize($children);
+
+ $expected = array();
+ $expected['item_name'] = array('id' => 'item_name', 'foo' => 'bar');
+ $this->assertEquals($expected, $normalized);
+ }
+
+ public function testAddDefaultChildren()
+ {
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setAddChildrenIfNoneSet();
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue());
+
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setKeyAttribute('foobar');
+ $node->setAddChildrenIfNoneSet();
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array('defaults' => array('foo' => 'bar')), $node->getDefaultValue());
+
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setKeyAttribute('foobar');
+ $node->setAddChildrenIfNoneSet('defaultkey');
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue());
+
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setKeyAttribute('foobar');
+ $node->setAddChildrenIfNoneSet(array('defaultkey'));
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue());
+
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setKeyAttribute('foobar');
+ $node->setAddChildrenIfNoneSet(array('dk1', 'dk2'));
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array('dk1' => array('foo' => 'bar'), 'dk2' => array('foo' => 'bar')), $node->getDefaultValue());
+
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setAddChildrenIfNoneSet(array(5, 6));
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array(0 => array('foo' => 'bar'), 1 => array('foo' => 'bar')), $node->getDefaultValue());
+
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setAddChildrenIfNoneSet(2);
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array(array('foo' => 'bar'), array('foo' => 'bar')), $node->getDefaultValue());
+ }
+
+ public function testDefaultChildrenWinsOverDefaultValue()
+ {
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setAddChildrenIfNoneSet();
+ $node->setDefaultValue(array('bar' => 'foo'));
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue());
+ }
+
+ protected function getPrototypeNodeWithDefaultChildren()
+ {
+ $node = new PrototypedArrayNode('root');
+ $prototype = new ArrayNode(null, $node);
+ $child = new ScalarNode('foo');
+ $child->setDefaultValue('bar');
+ $prototype->addChild($child);
+ $prototype->setAddIfNotSet(true);
+ $node->setPrototype($prototype);
+
+ return $node;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php
new file mode 100644
index 0000000..a798410
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php
@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\ScalarNode;
+
+class ScalarNodeTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getValidValues
+ */
+ public function testNormalize($value)
+ {
+ $node = new ScalarNode('test');
+ $this->assertSame($value, $node->normalize($value));
+ }
+
+ public function getValidValues()
+ {
+ return array(
+ array(false),
+ array(true),
+ array(null),
+ array(''),
+ array('foo'),
+ array(0),
+ array(1),
+ array(0.0),
+ array(0.1),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidValues
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
+ */
+ public function testNormalizeThrowsExceptionOnInvalidValues($value)
+ {
+ $node = new ScalarNode('test');
+ $node->normalize($value);
+ }
+
+ public function getInvalidValues()
+ {
+ return array(
+ array(array()),
+ array(array('foo' => 'bar')),
+ array(new \stdClass()),
+ );
+ }
+
+ public function testNormalizeThrowsExceptionWithoutHint()
+ {
+ $node = new ScalarNode('test');
+
+ $this->setExpectedException('Symfony\Component\Config\Definition\Exception\InvalidTypeException', 'Invalid type for path "test". Expected scalar, but got array.');
+
+ $node->normalize(array());
+ }
+
+ public function testNormalizeThrowsExceptionWithErrorMessage()
+ {
+ $node = new ScalarNode('test');
+ $node->setInfo('"the test value"');
+
+ $this->setExpectedException('Symfony\Component\Config\Definition\Exception\InvalidTypeException', "Invalid type for path \"test\". Expected scalar, but got array.\nHint: \"the test value\"");
+
+ $node->normalize(array());
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Exception/FileLoaderLoadExceptionTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Exception/FileLoaderLoadExceptionTest.php
new file mode 100644
index 0000000..4d91535
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Exception/FileLoaderLoadExceptionTest.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Exception;
+
+use Symfony\Component\Config\Exception\FileLoaderLoadException;
+
+class FileLoaderLoadExceptionTest extends \PHPUnit_Framework_TestCase
+{
+ public function testMessageCannotLoadResource()
+ {
+ $exception = new FileLoaderLoadException('resource', null);
+ $this->assertEquals('Cannot load resource "resource".', $exception->getMessage());
+ }
+
+ public function testMessageCannotImportResourceFromSource()
+ {
+ $exception = new FileLoaderLoadException('resource', 'sourceResource');
+ $this->assertEquals('Cannot import resource "resource" from "sourceResource".', $exception->getMessage());
+ }
+
+ public function testMessageCannotImportBundleResource()
+ {
+ $exception = new FileLoaderLoadException('@resource', 'sourceResource');
+ $this->assertEquals(
+ 'Cannot import resource "@resource" from "sourceResource". '.
+ 'Make sure the "resource" bundle is correctly registered and loaded in the application kernel class.',
+ $exception->getMessage()
+ );
+ }
+
+ public function testMessageHasPreviousErrorWithDotAndUnableToLoad()
+ {
+ $exception = new FileLoaderLoadException(
+ 'resource',
+ null,
+ null,
+ new \Exception('There was a previous error with an ending dot.')
+ );
+ $this->assertEquals(
+ 'There was a previous error with an ending dot in resource (which is loaded in resource "resource").',
+ $exception->getMessage()
+ );
+ }
+
+ public function testMessageHasPreviousErrorWithoutDotAndUnableToLoad()
+ {
+ $exception = new FileLoaderLoadException(
+ 'resource',
+ null,
+ null,
+ new \Exception('There was a previous error with no ending dot')
+ );
+ $this->assertEquals(
+ 'There was a previous error with no ending dot in resource (which is loaded in resource "resource").',
+ $exception->getMessage()
+ );
+ }
+
+ public function testMessageHasPreviousErrorAndUnableToLoadBundle()
+ {
+ $exception = new FileLoaderLoadException(
+ '@resource',
+ null,
+ null,
+ new \Exception('There was a previous error with an ending dot.')
+ );
+ $this->assertEquals(
+ 'There was a previous error with an ending dot in @resource '.
+ '(which is loaded in resource "@resource"). '.
+ 'Make sure the "resource" bundle is correctly registered and loaded in the application kernel class.',
+ $exception->getMessage()
+ );
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/FileLocatorTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/FileLocatorTest.php
new file mode 100644
index 0000000..d479f25
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/FileLocatorTest.php
@@ -0,0 +1,119 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests;
+
+use Symfony\Component\Config\FileLocator;
+
+class FileLocatorTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getIsAbsolutePathTests
+ */
+ public function testIsAbsolutePath($path)
+ {
+ $loader = new FileLocator(array());
+ $r = new \ReflectionObject($loader);
+ $m = $r->getMethod('isAbsolutePath');
+ $m->setAccessible(true);
+
+ $this->assertTrue($m->invoke($loader, $path), '->isAbsolutePath() returns true for an absolute path');
+ }
+
+ public function getIsAbsolutePathTests()
+ {
+ return array(
+ array('/foo.xml'),
+ array('c:\\\\foo.xml'),
+ array('c:/foo.xml'),
+ array('\\server\\foo.xml'),
+ array('https://server/foo.xml'),
+ array('phar://server/foo.xml'),
+ );
+ }
+
+ public function testLocate()
+ {
+ $loader = new FileLocator(__DIR__.'/Fixtures');
+
+ $this->assertEquals(
+ __DIR__.DIRECTORY_SEPARATOR.'FileLocatorTest.php',
+ $loader->locate('FileLocatorTest.php', __DIR__),
+ '->locate() returns the absolute filename if the file exists in the given path'
+ );
+
+ $this->assertEquals(
+ __DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml',
+ $loader->locate('foo.xml', __DIR__),
+ '->locate() returns the absolute filename if the file exists in one of the paths given in the constructor'
+ );
+
+ $this->assertEquals(
+ __DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml',
+ $loader->locate(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__),
+ '->locate() returns the absolute filename if the file exists in one of the paths given in the constructor'
+ );
+
+ $loader = new FileLocator(array(__DIR__.'/Fixtures', __DIR__.'/Fixtures/Again'));
+
+ $this->assertEquals(
+ array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
+ $loader->locate('foo.xml', __DIR__, false),
+ '->locate() returns an array of absolute filenames'
+ );
+
+ $this->assertEquals(
+ array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
+ $loader->locate('foo.xml', __DIR__.'/Fixtures', false),
+ '->locate() returns an array of absolute filenames'
+ );
+
+ $loader = new FileLocator(__DIR__.'/Fixtures/Again');
+
+ $this->assertEquals(
+ array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
+ $loader->locate('foo.xml', __DIR__.'/Fixtures', false),
+ '->locate() returns an array of absolute filenames'
+ );
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The file "foobar.xml" does not exist
+ */
+ public function testLocateThrowsAnExceptionIfTheFileDoesNotExists()
+ {
+ $loader = new FileLocator(array(__DIR__.'/Fixtures'));
+
+ $loader->locate('foobar.xml', __DIR__);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testLocateThrowsAnExceptionIfTheFileDoesNotExistsInAbsolutePath()
+ {
+ $loader = new FileLocator(array(__DIR__.'/Fixtures'));
+
+ $loader->locate(__DIR__.'/Fixtures/foobar.xml', __DIR__);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage An empty file name is not valid to be located.
+ */
+ public function testLocateEmpty()
+ {
+ $loader = new FileLocator(array(__DIR__.'/Fixtures'));
+
+ $loader->locate(null, __DIR__);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php
new file mode 100644
index 0000000..47701c1
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\NodeDefinition;
+
+class BarNodeDefinition extends NodeDefinition
+{
+ protected function createNode()
+ {
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php
new file mode 100644
index 0000000..aa59863
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder;
+
+class NodeBuilder extends BaseNodeBuilder
+{
+ public function barNode($name)
+ {
+ return $this->node($name, 'bar');
+ }
+
+ protected function getNodeClass($type)
+ {
+ switch ($type) {
+ case 'variable':
+ return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition';
+ case 'bar':
+ return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition';
+ default:
+ return parent::getNodeClass($type);
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php
new file mode 100644
index 0000000..1017880
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition;
+
+class VariableNodeDefinition extends BaseVariableNodeDefinition
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php
new file mode 100644
index 0000000..df43e8b
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Fixtures\Configuration;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+use Symfony\Component\Config\Definition\ConfigurationInterface;
+
+class ExampleConfiguration implements ConfigurationInterface
+{
+ public function getConfigTreeBuilder()
+ {
+ $treeBuilder = new TreeBuilder();
+ $rootNode = $treeBuilder->root('acme_root');
+
+ $rootNode
+ ->fixXmlConfig('parameter')
+ ->fixXmlConfig('connection')
+ ->children()
+ ->booleanNode('boolean')->defaultTrue()->end()
+ ->scalarNode('scalar_empty')->end()
+ ->scalarNode('scalar_null')->defaultNull()->end()
+ ->scalarNode('scalar_true')->defaultTrue()->end()
+ ->scalarNode('scalar_false')->defaultFalse()->end()
+ ->scalarNode('scalar_default')->defaultValue('default')->end()
+ ->scalarNode('scalar_array_empty')->defaultValue(array())->end()
+ ->scalarNode('scalar_array_defaults')->defaultValue(array('elem1', 'elem2'))->end()
+ ->scalarNode('scalar_required')->isRequired()->end()
+ ->enumNode('enum')->values(array('this', 'that'))->end()
+ ->arrayNode('array')
+ ->info('some info')
+ ->canBeUnset()
+ ->children()
+ ->scalarNode('child1')->end()
+ ->scalarNode('child2')->end()
+ ->scalarNode('child3')
+ ->info(
+ "this is a long\n".
+ "multi-line info text\n".
+ 'which should be indented'
+ )
+ ->example('example setting')
+ ->end()
+ ->end()
+ ->end()
+ ->arrayNode('parameters')
+ ->useAttributeAsKey('name')
+ ->prototype('scalar')->end()
+ ->end()
+ ->arrayNode('connections')
+ ->prototype('array')
+ ->children()
+ ->scalarNode('user')->end()
+ ->scalarNode('pass')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ;
+
+ return $treeBuilder;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/document_type.xml b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/document_type.xml
new file mode 100644
index 0000000..4c25228
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/document_type.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE scan [<!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource={{ resource }}">]>
+<scan></scan>
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid.xml b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid.xml
new file mode 100644
index 0000000..a07af9f
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid_schema.xml b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid_schema.xml
new file mode 100644
index 0000000..e2725a2
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid_schema.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root2 xmlns="http://example.com/schema" />
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/schema.xsd b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/schema.xsd
new file mode 100644
index 0000000..e56820f
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/schema.xsd
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsd:schema xmlns="http://example.com/schema"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://example.com/schema"
+ elementFormDefault="qualified">
+
+ <xsd:element name="root" />
+</xsd:schema>
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/valid.xml b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/valid.xml
new file mode 100644
index 0000000..a96bb38
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/valid.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root xmlns="http://example.com/schema">
+</root>
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/foo.xml b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/foo.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/foo.xml
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php
new file mode 100644
index 0000000..7641e24
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Loader;
+
+use Symfony\Component\Config\Loader\LoaderResolver;
+use Symfony\Component\Config\Loader\DelegatingLoader;
+
+class DelegatingLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Symfony\Component\Config\Loader\DelegatingLoader::__construct
+ */
+ public function testConstructor()
+ {
+ $loader = new DelegatingLoader($resolver = new LoaderResolver());
+ $this->assertTrue(true, '__construct() takes a loader resolver as its first argument');
+ }
+
+ /**
+ * @covers Symfony\Component\Config\Loader\DelegatingLoader::getResolver
+ * @covers Symfony\Component\Config\Loader\DelegatingLoader::setResolver
+ */
+ public function testGetSetResolver()
+ {
+ $resolver = new LoaderResolver();
+ $loader = new DelegatingLoader($resolver);
+ $this->assertSame($resolver, $loader->getResolver(), '->getResolver() gets the resolver loader');
+ $loader->setResolver($resolver = new LoaderResolver());
+ $this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader');
+ }
+
+ /**
+ * @covers Symfony\Component\Config\Loader\DelegatingLoader::supports
+ */
+ public function testSupports()
+ {
+ $loader1 = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $loader1->expects($this->once())->method('supports')->will($this->returnValue(true));
+ $loader = new DelegatingLoader(new LoaderResolver(array($loader1)));
+ $this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable');
+
+ $loader1 = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $loader1->expects($this->once())->method('supports')->will($this->returnValue(false));
+ $loader = new DelegatingLoader(new LoaderResolver(array($loader1)));
+ $this->assertFalse($loader->supports('foo.foo'), '->supports() returns false if the resource is not loadable');
+ }
+
+ /**
+ * @covers Symfony\Component\Config\Loader\DelegatingLoader::load
+ */
+ public function testLoad()
+ {
+ $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $loader->expects($this->once())->method('supports')->will($this->returnValue(true));
+ $loader->expects($this->once())->method('load');
+ $resolver = new LoaderResolver(array($loader));
+ $loader = new DelegatingLoader($resolver);
+
+ $loader->load('foo');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Exception\FileLoaderLoadException
+ */
+ public function testLoadThrowsAnExceptionIfTheResourceCannotBeLoaded()
+ {
+ $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $loader->expects($this->once())->method('supports')->will($this->returnValue(false));
+ $resolver = new LoaderResolver(array($loader));
+ $loader = new DelegatingLoader($resolver);
+
+ $loader->load('foo');
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php
new file mode 100644
index 0000000..1442e94
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php
@@ -0,0 +1,106 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Loader;
+
+use Symfony\Component\Config\Loader\FileLoader;
+use Symfony\Component\Config\Loader\LoaderResolver;
+
+class FileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Symfony\Component\Config\Loader\FileLoader
+ */
+ public function testImportWithFileLocatorDelegation()
+ {
+ $locatorMock = $this->getMock('Symfony\Component\Config\FileLocatorInterface');
+
+ $locatorMockForAdditionalLoader = $this->getMock('Symfony\Component\Config\FileLocatorInterface');
+ $locatorMockForAdditionalLoader->expects($this->any())->method('locate')->will($this->onConsecutiveCalls(
+ array('path/to/file1'), // Default
+ array('path/to/file1', 'path/to/file2'), // First is imported
+ array('path/to/file1', 'path/to/file2'), // Second is imported
+ array('path/to/file1'), // Exception
+ array('path/to/file1', 'path/to/file2') // Exception
+ ));
+
+ $fileLoader = new TestFileLoader($locatorMock);
+ $fileLoader->setSupports(false);
+ $fileLoader->setCurrentDir('.');
+
+ $additionalLoader = new TestFileLoader($locatorMockForAdditionalLoader);
+ $additionalLoader->setCurrentDir('.');
+
+ $fileLoader->setResolver($loaderResolver = new LoaderResolver(array($fileLoader, $additionalLoader)));
+
+ // Default case
+ $this->assertSame('path/to/file1', $fileLoader->import('my_resource'));
+
+ // Check first file is imported if not already loading
+ $this->assertSame('path/to/file1', $fileLoader->import('my_resource'));
+
+ // Check second file is imported if first is already loading
+ $fileLoader->addLoading('path/to/file1');
+ $this->assertSame('path/to/file2', $fileLoader->import('my_resource'));
+
+ // Check exception throws if first (and only available) file is already loading
+ try {
+ $fileLoader->import('my_resource');
+ $this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
+ }
+
+ // Check exception throws if all files are already loading
+ try {
+ $fileLoader->addLoading('path/to/file2');
+ $fileLoader->import('my_resource');
+ $this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
+ }
+ }
+}
+
+class TestFileLoader extends FileLoader
+{
+ private $supports = true;
+
+ public function load($resource, $type = null)
+ {
+ return $resource;
+ }
+
+ public function supports($resource, $type = null)
+ {
+ return $this->supports;
+ }
+
+ public function addLoading($resource)
+ {
+ self::$loading[$resource] = true;
+ }
+
+ public function removeLoading($resource)
+ {
+ unset(self::$loading[$resource]);
+ }
+
+ public function clearLoading()
+ {
+ self::$loading = array();
+ }
+
+ public function setSupports($supports)
+ {
+ $this->supports = $supports;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php
new file mode 100644
index 0000000..8ee276b
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Loader;
+
+use Symfony\Component\Config\Loader\LoaderResolver;
+
+class LoaderResolverTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Symfony\Component\Config\Loader\LoaderResolver::__construct
+ */
+ public function testConstructor()
+ {
+ $resolver = new LoaderResolver(array(
+ $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface'),
+ ));
+
+ $this->assertEquals(array($loader), $resolver->getLoaders(), '__construct() takes an array of loaders as its first argument');
+ }
+
+ /**
+ * @covers Symfony\Component\Config\Loader\LoaderResolver::resolve
+ */
+ public function testResolve()
+ {
+ $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $resolver = new LoaderResolver(array($loader));
+ $this->assertFalse($resolver->resolve('foo.foo'), '->resolve() returns false if no loader is able to load the resource');
+
+ $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $loader->expects($this->once())->method('supports')->will($this->returnValue(true));
+ $resolver = new LoaderResolver(array($loader));
+ $this->assertEquals($loader, $resolver->resolve(function () {}), '->resolve() returns the loader for the given resource');
+ }
+
+ /**
+ * @covers Symfony\Component\Config\Loader\LoaderResolver::getLoaders
+ * @covers Symfony\Component\Config\Loader\LoaderResolver::addLoader
+ */
+ public function testLoaders()
+ {
+ $resolver = new LoaderResolver();
+ $resolver->addLoader($loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface'));
+
+ $this->assertEquals(array($loader), $resolver->getLoaders(), 'addLoader() adds a loader');
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderTest.php
new file mode 100644
index 0000000..e938a4b
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderTest.php
@@ -0,0 +1,117 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Loader;
+
+use Symfony\Component\Config\Loader\Loader;
+
+class LoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetSetResolver()
+ {
+ $resolver = $this->getMock('Symfony\Component\Config\Loader\LoaderResolverInterface');
+
+ $loader = new ProjectLoader1();
+ $loader->setResolver($resolver);
+
+ $this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader');
+ }
+
+ public function testResolve()
+ {
+ $resolvedLoader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+
+ $resolver = $this->getMock('Symfony\Component\Config\Loader\LoaderResolverInterface');
+ $resolver->expects($this->once())
+ ->method('resolve')
+ ->with('foo.xml')
+ ->will($this->returnValue($resolvedLoader));
+
+ $loader = new ProjectLoader1();
+ $loader->setResolver($resolver);
+
+ $this->assertSame($loader, $loader->resolve('foo.foo'), '->resolve() finds a loader');
+ $this->assertSame($resolvedLoader, $loader->resolve('foo.xml'), '->resolve() finds a loader');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Exception\FileLoaderLoadException
+ */
+ public function testResolveWhenResolverCannotFindLoader()
+ {
+ $resolver = $this->getMock('Symfony\Component\Config\Loader\LoaderResolverInterface');
+ $resolver->expects($this->once())
+ ->method('resolve')
+ ->with('FOOBAR')
+ ->will($this->returnValue(false));
+
+ $loader = new ProjectLoader1();
+ $loader->setResolver($resolver);
+
+ $loader->resolve('FOOBAR');
+ }
+
+ public function testImport()
+ {
+ $resolvedLoader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $resolvedLoader->expects($this->once())
+ ->method('load')
+ ->with('foo')
+ ->will($this->returnValue('yes'));
+
+ $resolver = $this->getMock('Symfony\Component\Config\Loader\LoaderResolverInterface');
+ $resolver->expects($this->once())
+ ->method('resolve')
+ ->with('foo')
+ ->will($this->returnValue($resolvedLoader));
+
+ $loader = new ProjectLoader1();
+ $loader->setResolver($resolver);
+
+ $this->assertEquals('yes', $loader->import('foo'));
+ }
+
+ public function testImportWithType()
+ {
+ $resolvedLoader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $resolvedLoader->expects($this->once())
+ ->method('load')
+ ->with('foo', 'bar')
+ ->will($this->returnValue('yes'));
+
+ $resolver = $this->getMock('Symfony\Component\Config\Loader\LoaderResolverInterface');
+ $resolver->expects($this->once())
+ ->method('resolve')
+ ->with('foo', 'bar')
+ ->will($this->returnValue($resolvedLoader));
+
+ $loader = new ProjectLoader1();
+ $loader->setResolver($resolver);
+
+ $this->assertEquals('yes', $loader->import('foo', 'bar'));
+ }
+}
+
+class ProjectLoader1 extends Loader
+{
+ public function load($resource, $type = null)
+ {
+ }
+
+ public function supports($resource, $type = null)
+ {
+ return is_string($resource) && 'foo' === pathinfo($resource, PATHINFO_EXTENSION);
+ }
+
+ public function getType()
+ {
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php
new file mode 100644
index 0000000..d78e0cf
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Resource;
+
+use Symfony\Component\Config\Resource\DirectoryResource;
+
+class DirectoryResourceTest extends \PHPUnit_Framework_TestCase
+{
+ protected $directory;
+
+ protected function setUp()
+ {
+ $this->directory = sys_get_temp_dir().'/symfonyDirectoryIterator';
+ if (!file_exists($this->directory)) {
+ mkdir($this->directory);
+ }
+ touch($this->directory.'/tmp.xml');
+ }
+
+ protected function tearDown()
+ {
+ if (!is_dir($this->directory)) {
+ return;
+ }
+ $this->removeDirectory($this->directory);
+ }
+
+ protected function removeDirectory($directory)
+ {
+ $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory), \RecursiveIteratorIterator::CHILD_FIRST);
+ foreach ($iterator as $path) {
+ if (preg_match('#[/\\\\]\.\.?$#', $path->__toString())) {
+ continue;
+ }
+ if ($path->isDir()) {
+ rmdir($path->__toString());
+ } else {
+ unlink($path->__toString());
+ }
+ }
+ rmdir($directory);
+ }
+
+ public function testGetResource()
+ {
+ $resource = new DirectoryResource($this->directory);
+ $this->assertSame($this->directory, $resource->getResource(), '->getResource() returns the path to the resource');
+ $this->assertSame($this->directory, (string) $resource, '->__toString() returns the path to the resource');
+ }
+
+ public function testGetPattern()
+ {
+ $resource = new DirectoryResource('foo', 'bar');
+ $this->assertEquals('bar', $resource->getPattern());
+ }
+
+ public function testIsFresh()
+ {
+ $resource = new DirectoryResource($this->directory);
+ $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if the resource has not changed');
+ $this->assertFalse($resource->isFresh(time() - 86400), '->isFresh() returns false if the resource has been updated');
+
+ $resource = new DirectoryResource('/____foo/foobar'.rand(1, 999999));
+ $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist');
+ }
+
+ public function testIsFreshUpdateFile()
+ {
+ $resource = new DirectoryResource($this->directory);
+ touch($this->directory.'/tmp.xml', time() + 20);
+ $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an existing file is modified');
+ }
+
+ public function testIsFreshNewFile()
+ {
+ $resource = new DirectoryResource($this->directory);
+ touch($this->directory.'/new.xml', time() + 20);
+ $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file is added');
+ }
+
+ public function testIsFreshDeleteFile()
+ {
+ $resource = new DirectoryResource($this->directory);
+ unlink($this->directory.'/tmp.xml');
+ $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if an existing file is removed');
+ }
+
+ public function testIsFreshDeleteDirectory()
+ {
+ $resource = new DirectoryResource($this->directory);
+ $this->removeDirectory($this->directory);
+ $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the whole resource is removed');
+ }
+
+ public function testIsFreshCreateFileInSubdirectory()
+ {
+ $subdirectory = $this->directory.'/subdirectory';
+ mkdir($subdirectory);
+
+ $resource = new DirectoryResource($this->directory);
+ $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if an unmodified subdirectory exists');
+
+ touch($subdirectory.'/newfile.xml', time() + 20);
+ $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file in a subdirectory is added');
+ }
+
+ public function testIsFreshModifySubdirectory()
+ {
+ $resource = new DirectoryResource($this->directory);
+
+ $subdirectory = $this->directory.'/subdirectory';
+ mkdir($subdirectory);
+ touch($subdirectory, time() + 20);
+
+ $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a subdirectory is modified (e.g. a file gets deleted)');
+ }
+
+ public function testFilterRegexListNoMatch()
+ {
+ $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');
+
+ touch($this->directory.'/new.bar', time() + 20);
+ $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if a new file not matching the filter regex is created');
+ }
+
+ public function testFilterRegexListMatch()
+ {
+ $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');
+
+ touch($this->directory.'/new.xml', time() + 20);
+ $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an new file matching the filter regex is created ');
+ }
+
+ public function testSerializeUnserialize()
+ {
+ $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');
+
+ $unserialized = unserialize(serialize($resource));
+
+ $this->assertSame($this->directory, $resource->getResource());
+ $this->assertSame('/\.(foo|xml)$/', $resource->getPattern());
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Resource/FileResourceTest.php
new file mode 100644
index 0000000..d152806
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Resource/FileResourceTest.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Resource;
+
+use Symfony\Component\Config\Resource\FileResource;
+
+class FileResourceTest extends \PHPUnit_Framework_TestCase
+{
+ protected $resource;
+ protected $file;
+ protected $time;
+
+ protected function setUp()
+ {
+ $this->file = realpath(sys_get_temp_dir()).'/tmp.xml';
+ $this->time = time();
+ touch($this->file, $this->time);
+ $this->resource = new FileResource($this->file);
+ }
+
+ protected function tearDown()
+ {
+ unlink($this->file);
+ }
+
+ public function testGetResource()
+ {
+ $this->assertSame(realpath($this->file), $this->resource->getResource(), '->getResource() returns the path to the resource');
+ }
+
+ public function testToString()
+ {
+ $this->assertSame(realpath($this->file), (string) $this->resource);
+ }
+
+ public function testIsFresh()
+ {
+ $this->assertTrue($this->resource->isFresh($this->time), '->isFresh() returns true if the resource has not changed in same second');
+ $this->assertTrue($this->resource->isFresh($this->time + 10), '->isFresh() returns true if the resource has not changed');
+ $this->assertFalse($this->resource->isFresh($this->time - 86400), '->isFresh() returns false if the resource has been updated');
+
+ $resource = new FileResource('/____foo/foobar'.rand(1, 999999));
+ $this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource does not exist');
+ }
+
+ public function testSerializeUnserialize()
+ {
+ $unserialized = unserialize(serialize($this->resource));
+
+ $this->assertSame(realpath($this->file), $this->resource->getResource());
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php
new file mode 100644
index 0000000..f9d3d14
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php
@@ -0,0 +1,197 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Tests\Loader;
+
+use Symfony\Component\Config\Util\XmlUtils;
+
+class XmlUtilsTest extends \PHPUnit_Framework_TestCase
+{
+ public function testLoadFile()
+ {
+ $fixtures = __DIR__.'/../Fixtures/Util/';
+
+ try {
+ XmlUtils::loadFile($fixtures.'invalid.xml');
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertContains('ERROR 77', $e->getMessage());
+ }
+
+ try {
+ XmlUtils::loadFile($fixtures.'document_type.xml');
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertContains('Document types are not allowed', $e->getMessage());
+ }
+
+ try {
+ XmlUtils::loadFile($fixtures.'invalid_schema.xml', $fixtures.'schema.xsd');
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertContains('ERROR 1845', $e->getMessage());
+ }
+
+ try {
+ XmlUtils::loadFile($fixtures.'invalid_schema.xml', 'invalid_callback_or_file');
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertContains('XSD file or callable', $e->getMessage());
+ }
+
+ $mock = $this->getMock(__NAMESPACE__.'\Validator');
+ $mock->expects($this->exactly(2))->method('validate')->will($this->onConsecutiveCalls(false, true));
+
+ try {
+ XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate'));
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertContains('is not valid', $e->getMessage());
+ }
+
+ $this->assertInstanceOf('DOMDocument', XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate')));
+ $this->assertSame(array(), libxml_get_errors());
+ }
+
+ public function testLoadFileWithInternalErrorsEnabled()
+ {
+ libxml_use_internal_errors(true);
+
+ $this->assertSame(array(), libxml_get_errors());
+ $this->assertInstanceOf('DOMDocument', XmlUtils::loadFile(__DIR__.'/../Fixtures/Util/invalid_schema.xml'));
+ $this->assertSame(array(), libxml_get_errors());
+ }
+
+ /**
+ * @dataProvider getDataForConvertDomToArray
+ */
+ public function testConvertDomToArray($expected, $xml, $root = false, $checkPrefix = true)
+ {
+ $dom = new \DOMDocument();
+ $dom->loadXML($root ? $xml : '<root>'.$xml.'</root>');
+
+ $this->assertSame($expected, XmlUtils::convertDomElementToArray($dom->documentElement, $checkPrefix));
+ }
+
+ public function getDataForConvertDomToArray()
+ {
+ return array(
+ array(null, ''),
+ array('bar', 'bar'),
+ array(array('bar' => 'foobar'), '<foo bar="foobar" />', true),
+ array(array('foo' => null), '<foo />'),
+ array(array('foo' => 'bar'), '<foo>bar</foo>'),
+ array(array('foo' => array('foo' => 'bar')), '<foo foo="bar"/>'),
+ array(array('foo' => array('foo' => 0)), '<foo><foo>0</foo></foo>'),
+ array(array('foo' => array('foo' => 'bar')), '<foo><foo>bar</foo></foo>'),
+ array(array('foo' => array('foo' => 'bar', 'value' => 'text')), '<foo foo="bar">text</foo>'),
+ array(array('foo' => array('attr' => 'bar', 'foo' => 'text')), '<foo attr="bar"><foo>text</foo></foo>'),
+ array(array('foo' => array('bar', 'text')), '<foo>bar</foo><foo>text</foo>'),
+ array(array('foo' => array(array('foo' => 'bar'), array('foo' => 'text'))), '<foo foo="bar"/><foo foo="text" />'),
+ array(array('foo' => array('foo' => array('bar', 'text'))), '<foo foo="bar"><foo>text</foo></foo>'),
+ array(array('foo' => 'bar'), '<foo><!-- Comment -->bar</foo>'),
+ array(array('foo' => 'text'), '<foo xmlns:h="http://www.example.org/bar" h:bar="bar">text</foo>'),
+ array(array('foo' => array('bar' => 'bar', 'value' => 'text')), '<foo xmlns:h="http://www.example.org/bar" h:bar="bar">text</foo>', false, false),
+ array(array('attr' => 1, 'b' => 'hello'), '<foo:a xmlns:foo="http://www.example.org/foo" xmlns:h="http://www.example.org/bar" attr="1" h:bar="bar"><foo:b>hello</foo:b><h:c>2</h:c></foo:a>', true),
+ );
+ }
+
+ /**
+ * @dataProvider getDataForPhpize
+ */
+ public function testPhpize($expected, $value)
+ {
+ $this->assertSame($expected, XmlUtils::phpize($value));
+ }
+
+ public function getDataForPhpize()
+ {
+ return array(
+ array('', ''),
+ array(null, 'null'),
+ array(true, 'true'),
+ array(false, 'false'),
+ array(null, 'Null'),
+ array(true, 'True'),
+ array(false, 'False'),
+ array(0, '0'),
+ array(1, '1'),
+ array(-1, '-1'),
+ array(0777, '0777'),
+ array(255, '0xFF'),
+ array(100.0, '1e2'),
+ array(-120.0, '-1.2E2'),
+ array(-10100.1, '-10100.1'),
+ array('-10,100.1', '-10,100.1'),
+ array('1234 5678 9101 1121 3141', '1234 5678 9101 1121 3141'),
+ array('1,2,3,4', '1,2,3,4'),
+ array('11,22,33,44', '11,22,33,44'),
+ array('11,222,333,4', '11,222,333,4'),
+ array('1,222,333,444', '1,222,333,444'),
+ array('11,222,333,444', '11,222,333,444'),
+ array('111,222,333,444', '111,222,333,444'),
+ array('1111,2222,3333,4444,5555', '1111,2222,3333,4444,5555'),
+ array('foo', 'foo'),
+ array(6, '0b0110'),
+ );
+ }
+
+ public function testLoadEmptyXmlFile()
+ {
+ $file = __DIR__.'/../Fixtures/foo.xml';
+ $this->setExpectedException('InvalidArgumentException', 'File '.$file.' does not contain valid XML, it is empty.');
+ XmlUtils::loadFile($file);
+ }
+
+ // test for issue https://github.com/symfony/symfony/issues/9731
+ public function testLoadWrongEmptyXMLWithErrorHandler()
+ {
+ $originalDisableEntities = libxml_disable_entity_loader(false);
+ $errorReporting = error_reporting(-1);
+
+ set_error_handler(function ($errno, $errstr) {
+ throw new \Exception($errstr, $errno);
+ });
+
+ $file = __DIR__.'/../Fixtures/foo.xml';
+ try {
+ try {
+ XmlUtils::loadFile($file);
+ $this->fail('An exception should have been raised');
+ } catch (\InvalidArgumentException $e) {
+ $this->assertEquals(sprintf('File %s does not contain valid XML, it is empty.', $file), $e->getMessage());
+ }
+ } catch (\Exception $e) {
+ restore_error_handler();
+ error_reporting($errorReporting);
+
+ throw $e;
+ }
+
+ restore_error_handler();
+ error_reporting($errorReporting);
+
+ $disableEntities = libxml_disable_entity_loader(true);
+ libxml_disable_entity_loader($disableEntities);
+
+ libxml_disable_entity_loader($originalDisableEntities);
+
+ $this->assertFalse($disableEntities);
+
+ // should not throw an exception
+ XmlUtils::loadFile(__DIR__.'/../Fixtures/Util/valid.xml', __DIR__.'/../Fixtures/Util/schema.xsd');
+ }
+}
+
+interface Validator
+{
+ public function validate();
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Util/XmlUtils.php b/vendor/symfony/config/Symfony/Component/Config/Util/XmlUtils.php
new file mode 100644
index 0000000..2ef881d
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Util/XmlUtils.php
@@ -0,0 +1,238 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Config\Util;
+
+/**
+ * XMLUtils is a bunch of utility methods to XML operations.
+ *
+ * This class contains static methods only and is not meant to be instantiated.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Martin Hasoň <martin.hason@gmail.com>
+ */
+class XmlUtils
+{
+ /**
+ * This class should not be instantiated.
+ */
+ private function __construct()
+ {
+ }
+
+ /**
+ * Loads an XML file.
+ *
+ * @param string $file An XML file path
+ * @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation
+ *
+ * @return \DOMDocument
+ *
+ * @throws \InvalidArgumentException When loading of XML file returns error
+ */
+ public static function loadFile($file, $schemaOrCallable = null)
+ {
+ $content = @file_get_contents($file);
+ if ('' === trim($content)) {
+ throw new \InvalidArgumentException(sprintf('File %s does not contain valid XML, it is empty.', $file));
+ }
+
+ $internalErrors = libxml_use_internal_errors(true);
+ $disableEntities = libxml_disable_entity_loader(true);
+ libxml_clear_errors();
+
+ $dom = new \DOMDocument();
+ $dom->validateOnParse = true;
+ if (!$dom->loadXML($content, LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) {
+ libxml_disable_entity_loader($disableEntities);
+
+ throw new \InvalidArgumentException(implode("\n", static::getXmlErrors($internalErrors)));
+ }
+
+ $dom->normalizeDocument();
+
+ libxml_use_internal_errors($internalErrors);
+ libxml_disable_entity_loader($disableEntities);
+
+ foreach ($dom->childNodes as $child) {
+ if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
+ throw new \InvalidArgumentException('Document types are not allowed.');
+ }
+ }
+
+ if (null !== $schemaOrCallable) {
+ $internalErrors = libxml_use_internal_errors(true);
+ libxml_clear_errors();
+
+ $e = null;
+ if (is_callable($schemaOrCallable)) {
+ try {
+ $valid = call_user_func($schemaOrCallable, $dom, $internalErrors);
+ } catch (\Exception $e) {
+ $valid = false;
+ }
+ } elseif (!is_array($schemaOrCallable) && is_file((string) $schemaOrCallable)) {
+ $schemaSource = file_get_contents((string) $schemaOrCallable);
+ $valid = @$dom->schemaValidateSource($schemaSource);
+ } else {
+ libxml_use_internal_errors($internalErrors);
+
+ throw new \InvalidArgumentException('The schemaOrCallable argument has to be a valid path to XSD file or callable.');
+ }
+
+ if (!$valid) {
+ $messages = static::getXmlErrors($internalErrors);
+ if (empty($messages)) {
+ $messages = array(sprintf('The XML file "%s" is not valid.', $file));
+ }
+ throw new \InvalidArgumentException(implode("\n", $messages), 0, $e);
+ }
+ }
+
+ libxml_clear_errors();
+ libxml_use_internal_errors($internalErrors);
+
+ return $dom;
+ }
+
+ /**
+ * Converts a \DomElement object to a PHP array.
+ *
+ * The following rules applies during the conversion:
+ *
+ * * Each tag is converted to a key value or an array
+ * if there is more than one "value"
+ *
+ * * The content of a tag is set under a "value" key (<foo>bar</foo>)
+ * if the tag also has some nested tags
+ *
+ * * The attributes are converted to keys (<foo foo="bar"/>)
+ *
+ * * The nested-tags are converted to keys (<foo><foo>bar</foo></foo>)
+ *
+ * @param \DomElement $element A \DomElement instance
+ * @param bool $checkPrefix Check prefix in an element or an attribute name
+ *
+ * @return array A PHP array
+ */
+ public static function convertDomElementToArray(\DomElement $element, $checkPrefix = true)
+ {
+ $prefix = (string) $element->prefix;
+ $empty = true;
+ $config = array();
+ foreach ($element->attributes as $name => $node) {
+ if ($checkPrefix && !in_array((string) $node->prefix, array('', $prefix), true)) {
+ continue;
+ }
+ $config[$name] = static::phpize($node->value);
+ $empty = false;
+ }
+
+ $nodeValue = false;
+ foreach ($element->childNodes as $node) {
+ if ($node instanceof \DOMText) {
+ if ('' !== trim($node->nodeValue)) {
+ $nodeValue = trim($node->nodeValue);
+ $empty = false;
+ }
+ } elseif ($checkPrefix && $prefix != (string) $node->prefix) {
+ continue;
+ } elseif (!$node instanceof \DOMComment) {
+ $value = static::convertDomElementToArray($node, $checkPrefix);
+
+ $key = $node->localName;
+ if (isset($config[$key])) {
+ if (!is_array($config[$key]) || !is_int(key($config[$key]))) {
+ $config[$key] = array($config[$key]);
+ }
+ $config[$key][] = $value;
+ } else {
+ $config[$key] = $value;
+ }
+
+ $empty = false;
+ }
+ }
+
+ if (false !== $nodeValue) {
+ $value = static::phpize($nodeValue);
+ if (count($config)) {
+ $config['value'] = $value;
+ } else {
+ $config = $value;
+ }
+ }
+
+ return !$empty ? $config : null;
+ }
+
+ /**
+ * Converts an xml value to a PHP type.
+ *
+ * @param mixed $value
+ *
+ * @return mixed
+ */
+ public static function phpize($value)
+ {
+ $value = (string) $value;
+ $lowercaseValue = strtolower($value);
+
+ switch (true) {
+ case 'null' === $lowercaseValue:
+ return;
+ case ctype_digit($value):
+ $raw = $value;
+ $cast = (int) $value;
+
+ return '0' == $value[0] ? octdec($value) : (((string) $raw === (string) $cast) ? $cast : $raw);
+ case isset($value[1]) && '-' === $value[0] && ctype_digit(substr($value, 1)):
+ $raw = $value;
+ $cast = intval($value);
+
+ return '0' == $value[1] ? octdec($value) : (((string) $raw === (string) $cast) ? $cast : $raw);
+ case 'true' === $lowercaseValue:
+ return true;
+ case 'false' === $lowercaseValue:
+ return false;
+ case isset($value[1]) && '0b' == $value[0].$value[1]:
+ return bindec($value);
+ case is_numeric($value):
+ return '0x' === $value[0].$value[1] ? hexdec($value) : (float) $value;
+ case preg_match('/^0x[0-9a-f]++$/i', $value):
+ return hexdec($value);
+ case preg_match('/^(-|\+)?[0-9]+(\.[0-9]+)?$/', $value):
+ return (float) $value;
+ default:
+ return $value;
+ }
+ }
+
+ protected static function getXmlErrors($internalErrors)
+ {
+ $errors = array();
+ foreach (libxml_get_errors() as $error) {
+ $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
+ LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
+ $error->code,
+ trim($error->message),
+ $error->file ?: 'n/a',
+ $error->line,
+ $error->column
+ );
+ }
+
+ libxml_clear_errors();
+ libxml_use_internal_errors($internalErrors);
+
+ return $errors;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/composer.json b/vendor/symfony/config/Symfony/Component/Config/composer.json
new file mode 100644
index 0000000..3b2542a
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/composer.json
@@ -0,0 +1,35 @@
+{
+ "name": "symfony/config",
+ "type": "library",
+ "description": "Symfony Config Component",
+ "keywords": [],
+ "homepage": "http://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3",
+ "symfony/filesystem": "~2.3"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7"
+ },
+ "autoload": {
+ "psr-0": { "Symfony\\Component\\Config\\": "" }
+ },
+ "target-dir": "Symfony/Component/Config",
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/phpunit.xml.dist b/vendor/symfony/config/Symfony/Component/Config/phpunit.xml.dist
new file mode 100644
index 0000000..2156534
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/phpunit.xml.dist
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+ <testsuites>
+ <testsuite name="Symfony Config Component Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Resources</directory>
+ <directory>./Tests</directory>
+ <directory>./vendor</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/symfony/console/Symfony/Component/Console/.gitignore b/vendor/symfony/console/Symfony/Component/Console/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/vendor/symfony/console/Symfony/Component/Console/Application.php b/vendor/symfony/console/Symfony/Component/Console/Application.php
new file mode 100644
index 0000000..093dd2f
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Application.php
@@ -0,0 +1,1173 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console;
+
+use Symfony\Component\Console\Descriptor\TextDescriptor;
+use Symfony\Component\Console\Descriptor\XmlDescriptor;
+use Symfony\Component\Console\Helper\DebugFormatterHelper;
+use Symfony\Component\Console\Helper\ProcessHelper;
+use Symfony\Component\Console\Helper\QuestionHelper;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\ArgvInput;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputAwareInterface;
+use Symfony\Component\Console\Output\BufferedOutput;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Console\Output\ConsoleOutputInterface;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Command\HelpCommand;
+use Symfony\Component\Console\Command\ListCommand;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Helper\FormatterHelper;
+use Symfony\Component\Console\Helper\DialogHelper;
+use Symfony\Component\Console\Helper\ProgressHelper;
+use Symfony\Component\Console\Helper\TableHelper;
+use Symfony\Component\Console\Event\ConsoleCommandEvent;
+use Symfony\Component\Console\Event\ConsoleExceptionEvent;
+use Symfony\Component\Console\Event\ConsoleTerminateEvent;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * An Application is the container for a collection of commands.
+ *
+ * It is the main entry point of a Console application.
+ *
+ * This class is optimized for a standard CLI environment.
+ *
+ * Usage:
+ *
+ * $app = new Application('myapp', '1.0 (stable)');
+ * $app->add(new SimpleCommand());
+ * $app->run();
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class Application
+{
+ private $commands = array();
+ private $wantHelps = false;
+ private $runningCommand;
+ private $name;
+ private $version;
+ private $catchExceptions = true;
+ private $autoExit = true;
+ private $definition;
+ private $helperSet;
+ private $dispatcher;
+ private $terminalDimensions;
+ private $defaultCommand;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of the application
+ * @param string $version The version of the application
+ *
+ * @api
+ */
+ public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
+ {
+ $this->name = $name;
+ $this->version = $version;
+ $this->defaultCommand = 'list';
+ $this->helperSet = $this->getDefaultHelperSet();
+ $this->definition = $this->getDefaultInputDefinition();
+
+ foreach ($this->getDefaultCommands() as $command) {
+ $this->add($command);
+ }
+ }
+
+ public function setDispatcher(EventDispatcherInterface $dispatcher)
+ {
+ $this->dispatcher = $dispatcher;
+ }
+
+ /**
+ * Runs the current application.
+ *
+ * @param InputInterface $input An Input instance
+ * @param OutputInterface $output An Output instance
+ *
+ * @return int 0 if everything went fine, or an error code
+ *
+ * @throws \Exception When doRun returns Exception
+ *
+ * @api
+ */
+ public function run(InputInterface $input = null, OutputInterface $output = null)
+ {
+ if (null === $input) {
+ $input = new ArgvInput();
+ }
+
+ if (null === $output) {
+ $output = new ConsoleOutput();
+ }
+
+ $this->configureIO($input, $output);
+
+ try {
+ $exitCode = $this->doRun($input, $output);
+ } catch (\Exception $e) {
+ if (!$this->catchExceptions) {
+ throw $e;
+ }
+
+ if ($output instanceof ConsoleOutputInterface) {
+ $this->renderException($e, $output->getErrorOutput());
+ } else {
+ $this->renderException($e, $output);
+ }
+
+ $exitCode = $e->getCode();
+ if (is_numeric($exitCode)) {
+ $exitCode = (int) $exitCode;
+ if (0 === $exitCode) {
+ $exitCode = 1;
+ }
+ } else {
+ $exitCode = 1;
+ }
+ }
+
+ if ($this->autoExit) {
+ if ($exitCode > 255) {
+ $exitCode = 255;
+ }
+
+ exit($exitCode);
+ }
+
+ return $exitCode;
+ }
+
+ /**
+ * Runs the current application.
+ *
+ * @param InputInterface $input An Input instance
+ * @param OutputInterface $output An Output instance
+ *
+ * @return int 0 if everything went fine, or an error code
+ */
+ public function doRun(InputInterface $input, OutputInterface $output)
+ {
+ if (true === $input->hasParameterOption(array('--version', '-V'))) {
+ $output->writeln($this->getLongVersion());
+
+ return 0;
+ }
+
+ $name = $this->getCommandName($input);
+ if (true === $input->hasParameterOption(array('--help', '-h'))) {
+ if (!$name) {
+ $name = 'help';
+ $input = new ArrayInput(array('command' => 'help'));
+ } else {
+ $this->wantHelps = true;
+ }
+ }
+
+ if (!$name) {
+ $name = $this->defaultCommand;
+ $input = new ArrayInput(array('command' => $this->defaultCommand));
+ }
+
+ // the command name MUST be the first element of the input
+ $command = $this->find($name);
+
+ $this->runningCommand = $command;
+ $exitCode = $this->doRunCommand($command, $input, $output);
+ $this->runningCommand = null;
+
+ return $exitCode;
+ }
+
+ /**
+ * Set a helper set to be used with the command.
+ *
+ * @param HelperSet $helperSet The helper set
+ *
+ * @api
+ */
+ public function setHelperSet(HelperSet $helperSet)
+ {
+ $this->helperSet = $helperSet;
+ }
+
+ /**
+ * Get the helper set associated with the command.
+ *
+ * @return HelperSet The HelperSet instance associated with this command
+ *
+ * @api
+ */
+ public function getHelperSet()
+ {
+ return $this->helperSet;
+ }
+
+ /**
+ * Set an input definition set to be used with this application.
+ *
+ * @param InputDefinition $definition The input definition
+ *
+ * @api
+ */
+ public function setDefinition(InputDefinition $definition)
+ {
+ $this->definition = $definition;
+ }
+
+ /**
+ * Gets the InputDefinition related to this Application.
+ *
+ * @return InputDefinition The InputDefinition instance
+ */
+ public function getDefinition()
+ {
+ return $this->definition;
+ }
+
+ /**
+ * Gets the help message.
+ *
+ * @return string A help message.
+ */
+ public function getHelp()
+ {
+ return $this->getLongVersion();
+ }
+
+ /**
+ * Sets whether to catch exceptions or not during commands execution.
+ *
+ * @param bool $boolean Whether to catch exceptions or not during commands execution
+ *
+ * @api
+ */
+ public function setCatchExceptions($boolean)
+ {
+ $this->catchExceptions = (bool) $boolean;
+ }
+
+ /**
+ * Sets whether to automatically exit after a command execution or not.
+ *
+ * @param bool $boolean Whether to automatically exit after a command execution or not
+ *
+ * @api
+ */
+ public function setAutoExit($boolean)
+ {
+ $this->autoExit = (bool) $boolean;
+ }
+
+ /**
+ * Gets the name of the application.
+ *
+ * @return string The application name
+ *
+ * @api
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Sets the application name.
+ *
+ * @param string $name The application name
+ *
+ * @api
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Gets the application version.
+ *
+ * @return string The application version
+ *
+ * @api
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Sets the application version.
+ *
+ * @param string $version The application version
+ *
+ * @api
+ */
+ public function setVersion($version)
+ {
+ $this->version = $version;
+ }
+
+ /**
+ * Returns the long version of the application.
+ *
+ * @return string The long application version
+ *
+ * @api
+ */
+ public function getLongVersion()
+ {
+ if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) {
+ return sprintf('<info>%s</info> version <comment>%s</comment>', $this->getName(), $this->getVersion());
+ }
+
+ return '<info>Console Tool</info>';
+ }
+
+ /**
+ * Registers a new command.
+ *
+ * @param string $name The command name
+ *
+ * @return Command The newly created command
+ *
+ * @api
+ */
+ public function register($name)
+ {
+ return $this->add(new Command($name));
+ }
+
+ /**
+ * Adds an array of command objects.
+ *
+ * @param Command[] $commands An array of commands
+ *
+ * @api
+ */
+ public function addCommands(array $commands)
+ {
+ foreach ($commands as $command) {
+ $this->add($command);
+ }
+ }
+
+ /**
+ * Adds a command object.
+ *
+ * If a command with the same name already exists, it will be overridden.
+ *
+ * @param Command $command A Command object
+ *
+ * @return Command The registered command
+ *
+ * @api
+ */
+ public function add(Command $command)
+ {
+ $command->setApplication($this);
+
+ if (!$command->isEnabled()) {
+ $command->setApplication(null);
+
+ return;
+ }
+
+ if (null === $command->getDefinition()) {
+ throw new \LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command)));
+ }
+
+ $this->commands[$command->getName()] = $command;
+
+ foreach ($command->getAliases() as $alias) {
+ $this->commands[$alias] = $command;
+ }
+
+ return $command;
+ }
+
+ /**
+ * Returns a registered command by name or alias.
+ *
+ * @param string $name The command name or alias
+ *
+ * @return Command A Command object
+ *
+ * @throws \InvalidArgumentException When command name given does not exist
+ *
+ * @api
+ */
+ public function get($name)
+ {
+ if (!isset($this->commands[$name])) {
+ throw new \InvalidArgumentException(sprintf('The command "%s" does not exist.', $name));
+ }
+
+ $command = $this->commands[$name];
+
+ if ($this->wantHelps) {
+ $this->wantHelps = false;
+
+ $helpCommand = $this->get('help');
+ $helpCommand->setCommand($command);
+
+ return $helpCommand;
+ }
+
+ return $command;
+ }
+
+ /**
+ * Returns true if the command exists, false otherwise.
+ *
+ * @param string $name The command name or alias
+ *
+ * @return bool true if the command exists, false otherwise
+ *
+ * @api
+ */
+ public function has($name)
+ {
+ return isset($this->commands[$name]);
+ }
+
+ /**
+ * Returns an array of all unique namespaces used by currently registered commands.
+ *
+ * It does not returns the global namespace which always exists.
+ *
+ * @return array An array of namespaces
+ */
+ public function getNamespaces()
+ {
+ $namespaces = array();
+ foreach ($this->commands as $command) {
+ $namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
+
+ foreach ($command->getAliases() as $alias) {
+ $namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias));
+ }
+ }
+
+ return array_values(array_unique(array_filter($namespaces)));
+ }
+
+ /**
+ * Finds a registered namespace by a name or an abbreviation.
+ *
+ * @param string $namespace A namespace or abbreviation to search for
+ *
+ * @return string A registered namespace
+ *
+ * @throws \InvalidArgumentException When namespace is incorrect or ambiguous
+ */
+ public function findNamespace($namespace)
+ {
+ $allNamespaces = $this->getNamespaces();
+ $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $namespace);
+ $namespaces = preg_grep('{^'.$expr.'}', $allNamespaces);
+
+ if (empty($namespaces)) {
+ $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace);
+
+ if ($alternatives = $this->findAlternatives($namespace, $allNamespaces, array())) {
+ if (1 == count($alternatives)) {
+ $message .= "\n\nDid you mean this?\n ";
+ } else {
+ $message .= "\n\nDid you mean one of these?\n ";
+ }
+
+ $message .= implode("\n ", $alternatives);
+ }
+
+ throw new \InvalidArgumentException($message);
+ }
+
+ $exact = in_array($namespace, $namespaces, true);
+ if (count($namespaces) > 1 && !$exact) {
+ throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))));
+ }
+
+ return $exact ? $namespace : reset($namespaces);
+ }
+
+ /**
+ * Finds a command by name or alias.
+ *
+ * Contrary to get, this command tries to find the best
+ * match if you give it an abbreviation of a name or alias.
+ *
+ * @param string $name A command name or a command alias
+ *
+ * @return Command A Command instance
+ *
+ * @throws \InvalidArgumentException When command name is incorrect or ambiguous
+ *
+ * @api
+ */
+ public function find($name)
+ {
+ $allCommands = array_keys($this->commands);
+ $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
+ $commands = preg_grep('{^'.$expr.'}', $allCommands);
+
+ if (empty($commands) || count(preg_grep('{^'.$expr.'$}', $commands)) < 1) {
+ if (false !== $pos = strrpos($name, ':')) {
+ // check if a namespace exists and contains commands
+ $this->findNamespace(substr($name, 0, $pos));
+ }
+
+ $message = sprintf('Command "%s" is not defined.', $name);
+
+ if ($alternatives = $this->findAlternatives($name, $allCommands, array())) {
+ if (1 == count($alternatives)) {
+ $message .= "\n\nDid you mean this?\n ";
+ } else {
+ $message .= "\n\nDid you mean one of these?\n ";
+ }
+ $message .= implode("\n ", $alternatives);
+ }
+
+ throw new \InvalidArgumentException($message);
+ }
+
+ // filter out aliases for commands which are already on the list
+ if (count($commands) > 1) {
+ $commandList = $this->commands;
+ $commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) {
+ $commandName = $commandList[$nameOrAlias]->getName();
+
+ return $commandName === $nameOrAlias || !in_array($commandName, $commands);
+ });
+ }
+
+ $exact = in_array($name, $commands, true);
+ if (count($commands) > 1 && !$exact) {
+ $suggestions = $this->getAbbreviationSuggestions(array_values($commands));
+
+ throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions));
+ }
+
+ return $this->get($exact ? $name : reset($commands));
+ }
+
+ /**
+ * Gets the commands (registered in the given namespace if provided).
+ *
+ * The array keys are the full names and the values the command instances.
+ *
+ * @param string $namespace A namespace name
+ *
+ * @return Command[] An array of Command instances
+ *
+ * @api
+ */
+ public function all($namespace = null)
+ {
+ if (null === $namespace) {
+ return $this->commands;
+ }
+
+ $commands = array();
+ foreach ($this->commands as $name => $command) {
+ if ($namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) {
+ $commands[$name] = $command;
+ }
+ }
+
+ return $commands;
+ }
+
+ /**
+ * Returns an array of possible abbreviations given a set of names.
+ *
+ * @param array $names An array of names
+ *
+ * @return array An array of abbreviations
+ */
+ public static function getAbbreviations($names)
+ {
+ $abbrevs = array();
+ foreach ($names as $name) {
+ for ($len = strlen($name); $len > 0; --$len) {
+ $abbrev = substr($name, 0, $len);
+ $abbrevs[$abbrev][] = $name;
+ }
+ }
+
+ return $abbrevs;
+ }
+
+ /**
+ * Returns a text representation of the Application.
+ *
+ * @param string $namespace An optional namespace name
+ * @param bool $raw Whether to return raw command list
+ *
+ * @return string A string representing the Application
+ *
+ * @deprecated Deprecated since version 2.3, to be removed in 3.0.
+ */
+ public function asText($namespace = null, $raw = false)
+ {
+ $descriptor = new TextDescriptor();
+ $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, !$raw);
+ $descriptor->describe($output, $this, array('namespace' => $namespace, 'raw_output' => true));
+
+ return $output->fetch();
+ }
+
+ /**
+ * Returns an XML representation of the Application.
+ *
+ * @param string $namespace An optional namespace name
+ * @param bool $asDom Whether to return a DOM or an XML string
+ *
+ * @return string|\DOMDocument An XML string representing the Application
+ *
+ * @deprecated Deprecated since version 2.3, to be removed in 3.0.
+ */
+ public function asXml($namespace = null, $asDom = false)
+ {
+ $descriptor = new XmlDescriptor();
+
+ if ($asDom) {
+ return $descriptor->getApplicationDocument($this, $namespace);
+ }
+
+ $output = new BufferedOutput();
+ $descriptor->describe($output, $this, array('namespace' => $namespace));
+
+ return $output->fetch();
+ }
+
+ /**
+ * Renders a caught exception.
+ *
+ * @param \Exception $e An exception instance
+ * @param OutputInterface $output An OutputInterface instance
+ */
+ public function renderException($e, $output)
+ {
+ do {
+ $title = sprintf(' [%s] ', get_class($e));
+
+ $len = $this->stringWidth($title);
+
+ $width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX;
+ // HHVM only accepts 32 bits integer in str_split, even when PHP_INT_MAX is a 64 bit integer: https://github.com/facebook/hhvm/issues/1327
+ if (defined('HHVM_VERSION') && $width > 1 << 31) {
+ $width = 1 << 31;
+ }
+ $formatter = $output->getFormatter();
+ $lines = array();
+ foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) {
+ foreach ($this->splitStringByWidth($line, $width - 4) as $line) {
+ // pre-format lines to get the right string length
+ $lineLength = $this->stringWidth(preg_replace('/\[[^m]*m/', '', $formatter->format($line))) + 4;
+ $lines[] = array($line, $lineLength);
+
+ $len = max($lineLength, $len);
+ }
+ }
+
+ $messages = array('', '');
+ $messages[] = $emptyLine = $formatter->format(sprintf('<error>%s</error>', str_repeat(' ', $len)));
+ $messages[] = $formatter->format(sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title)))));
+ foreach ($lines as $line) {
+ $messages[] = $formatter->format(sprintf('<error> %s %s</error>', $line[0], str_repeat(' ', $len - $line[1])));
+ }
+ $messages[] = $emptyLine;
+ $messages[] = '';
+ $messages[] = '';
+
+ $output->writeln($messages, OutputInterface::OUTPUT_RAW);
+
+ if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
+ $output->writeln('<comment>Exception trace:</comment>');
+
+ // exception related properties
+ $trace = $e->getTrace();
+ array_unshift($trace, array(
+ 'function' => '',
+ 'file' => $e->getFile() !== null ? $e->getFile() : 'n/a',
+ 'line' => $e->getLine() !== null ? $e->getLine() : 'n/a',
+ 'args' => array(),
+ ));
+
+ for ($i = 0, $count = count($trace); $i < $count; $i++) {
+ $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
+ $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
+ $function = $trace[$i]['function'];
+ $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a';
+ $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a';
+
+ $output->writeln(sprintf(' %s%s%s() at <info>%s:%s</info>', $class, $type, $function, $file, $line));
+ }
+
+ $output->writeln('');
+ $output->writeln('');
+ }
+ } while ($e = $e->getPrevious());
+
+ if (null !== $this->runningCommand) {
+ $output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())));
+ $output->writeln('');
+ $output->writeln('');
+ }
+ }
+
+ /**
+ * Tries to figure out the terminal width in which this application runs.
+ *
+ * @return int|null
+ */
+ protected function getTerminalWidth()
+ {
+ $dimensions = $this->getTerminalDimensions();
+
+ return $dimensions[0];
+ }
+
+ /**
+ * Tries to figure out the terminal height in which this application runs.
+ *
+ * @return int|null
+ */
+ protected function getTerminalHeight()
+ {
+ $dimensions = $this->getTerminalDimensions();
+
+ return $dimensions[1];
+ }
+
+ /**
+ * Tries to figure out the terminal dimensions based on the current environment.
+ *
+ * @return array Array containing width and height
+ */
+ public function getTerminalDimensions()
+ {
+ if ($this->terminalDimensions) {
+ return $this->terminalDimensions;
+ }
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ // extract [w, H] from "wxh (WxH)"
+ if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) {
+ return array((int) $matches[1], (int) $matches[2]);
+ }
+ // extract [w, h] from "wxh"
+ if (preg_match('/^(\d+)x(\d+)$/', $this->getConsoleMode(), $matches)) {
+ return array((int) $matches[1], (int) $matches[2]);
+ }
+ }
+
+ if ($sttyString = $this->getSttyColumns()) {
+ // extract [w, h] from "rows h; columns w;"
+ if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
+ return array((int) $matches[2], (int) $matches[1]);
+ }
+ // extract [w, h] from "; h rows; w columns"
+ if (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
+ return array((int) $matches[2], (int) $matches[1]);
+ }
+ }
+
+ return array(null, null);
+ }
+
+ /**
+ * Sets terminal dimensions.
+ *
+ * Can be useful to force terminal dimensions for functional tests.
+ *
+ * @param int $width The width
+ * @param int $height The height
+ *
+ * @return Application The current application
+ */
+ public function setTerminalDimensions($width, $height)
+ {
+ $this->terminalDimensions = array($width, $height);
+
+ return $this;
+ }
+
+ /**
+ * Configures the input and output instances based on the user arguments and options.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ */
+ protected function configureIO(InputInterface $input, OutputInterface $output)
+ {
+ if (true === $input->hasParameterOption(array('--ansi'))) {
+ $output->setDecorated(true);
+ } elseif (true === $input->hasParameterOption(array('--no-ansi'))) {
+ $output->setDecorated(false);
+ }
+
+ if (true === $input->hasParameterOption(array('--no-interaction', '-n'))) {
+ $input->setInteractive(false);
+ } elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('question')) {
+ $inputStream = $this->getHelperSet()->get('question')->getInputStream();
+ if (!@posix_isatty($inputStream)) {
+ $input->setInteractive(false);
+ }
+ }
+
+ if (true === $input->hasParameterOption(array('--quiet', '-q'))) {
+ $output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
+ } else {
+ if ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || $input->getParameterOption('--verbose') === 3) {
+ $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
+ } elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2') || $input->getParameterOption('--verbose') === 2) {
+ $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
+ } elseif ($input->hasParameterOption('-v') || $input->hasParameterOption('--verbose=1') || $input->hasParameterOption('--verbose') || $input->getParameterOption('--verbose')) {
+ $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
+ }
+ }
+ }
+
+ /**
+ * Runs the current command.
+ *
+ * If an event dispatcher has been attached to the application,
+ * events are also dispatched during the life-cycle of the command.
+ *
+ * @param Command $command A Command instance
+ * @param InputInterface $input An Input instance
+ * @param OutputInterface $output An Output instance
+ *
+ * @return int 0 if everything went fine, or an error code
+ *
+ * @throws \Exception when the command being run threw an exception
+ */
+ protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output)
+ {
+ foreach ($command->getHelperSet() as $helper) {
+ if ($helper instanceof InputAwareInterface) {
+ $helper->setInput($input);
+ }
+ }
+
+ if (null === $this->dispatcher) {
+ return $command->run($input, $output);
+ }
+
+ $event = new ConsoleCommandEvent($command, $input, $output);
+ $this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
+
+ if ($event->commandShouldRun()) {
+ try {
+ $exitCode = $command->run($input, $output);
+ } catch (\Exception $e) {
+ $event = new ConsoleTerminateEvent($command, $input, $output, $e->getCode());
+ $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
+
+ $event = new ConsoleExceptionEvent($command, $input, $output, $e, $event->getExitCode());
+ $this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event);
+
+ throw $event->getException();
+ }
+ } else {
+ $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
+ }
+
+ $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode);
+ $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
+
+ return $event->getExitCode();
+ }
+
+ /**
+ * Gets the name of the command based on input.
+ *
+ * @param InputInterface $input The input interface
+ *
+ * @return string The command name
+ */
+ protected function getCommandName(InputInterface $input)
+ {
+ return $input->getFirstArgument();
+ }
+
+ /**
+ * Gets the default input definition.
+ *
+ * @return InputDefinition An InputDefinition instance
+ */
+ protected function getDefaultInputDefinition()
+ {
+ return new InputDefinition(array(
+ new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),
+
+ new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message'),
+ new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'),
+ new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'),
+ new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version'),
+ new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'),
+ new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'),
+ new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'),
+ ));
+ }
+
+ /**
+ * Gets the default commands that should always be available.
+ *
+ * @return Command[] An array of default Command instances
+ */
+ protected function getDefaultCommands()
+ {
+ return array(new HelpCommand(), new ListCommand());
+ }
+
+ /**
+ * Gets the default helper set with the helpers that should always be available.
+ *
+ * @return HelperSet A HelperSet instance
+ */
+ protected function getDefaultHelperSet()
+ {
+ return new HelperSet(array(
+ new FormatterHelper(),
+ new DialogHelper(),
+ new ProgressHelper(),
+ new TableHelper(),
+ new DebugFormatterHelper(),
+ new ProcessHelper(),
+ new QuestionHelper(),
+ ));
+ }
+
+ /**
+ * Runs and parses stty -a if it's available, suppressing any error output.
+ *
+ * @return string
+ */
+ private function getSttyColumns()
+ {
+ if (!function_exists('proc_open')) {
+ return;
+ }
+
+ $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
+ $process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
+ if (is_resource($process)) {
+ $info = stream_get_contents($pipes[1]);
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+ proc_close($process);
+
+ return $info;
+ }
+ }
+
+ /**
+ * Runs and parses mode CON if it's available, suppressing any error output.
+ *
+ * @return string <width>x<height> or null if it could not be parsed
+ */
+ private function getConsoleMode()
+ {
+ if (!function_exists('proc_open')) {
+ return;
+ }
+
+ $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
+ $process = proc_open('mode CON', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
+ if (is_resource($process)) {
+ $info = stream_get_contents($pipes[1]);
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+ proc_close($process);
+
+ if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
+ return $matches[2].'x'.$matches[1];
+ }
+ }
+ }
+
+ /**
+ * Returns abbreviated suggestions in string format.
+ *
+ * @param array $abbrevs Abbreviated suggestions to convert
+ *
+ * @return string A formatted string of abbreviated suggestions
+ */
+ private function getAbbreviationSuggestions($abbrevs)
+ {
+ return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '');
+ }
+
+ /**
+ * Returns the namespace part of the command name.
+ *
+ * This method is not part of public API and should not be used directly.
+ *
+ * @param string $name The full name of the command
+ * @param string $limit The maximum number of parts of the namespace
+ *
+ * @return string The namespace of the command
+ */
+ public function extractNamespace($name, $limit = null)
+ {
+ $parts = explode(':', $name);
+ array_pop($parts);
+
+ return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit));
+ }
+
+ /**
+ * Finds alternative of $name among $collection,
+ * if nothing is found in $collection, try in $abbrevs.
+ *
+ * @param string $name The string
+ * @param array|\Traversable $collection The collection
+ *
+ * @return array A sorted array of similar string
+ */
+ private function findAlternatives($name, $collection)
+ {
+ $threshold = 1e3;
+ $alternatives = array();
+
+ $collectionParts = array();
+ foreach ($collection as $item) {
+ $collectionParts[$item] = explode(':', $item);
+ }
+
+ foreach (explode(':', $name) as $i => $subname) {
+ foreach ($collectionParts as $collectionName => $parts) {
+ $exists = isset($alternatives[$collectionName]);
+ if (!isset($parts[$i]) && $exists) {
+ $alternatives[$collectionName] += $threshold;
+ continue;
+ } elseif (!isset($parts[$i])) {
+ continue;
+ }
+
+ $lev = levenshtein($subname, $parts[$i]);
+ if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) {
+ $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev;
+ } elseif ($exists) {
+ $alternatives[$collectionName] += $threshold;
+ }
+ }
+ }
+
+ foreach ($collection as $item) {
+ $lev = levenshtein($name, $item);
+ if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
+ $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev;
+ }
+ }
+
+ $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2*$threshold; });
+ asort($alternatives);
+
+ return array_keys($alternatives);
+ }
+
+ /**
+ * Sets the default Command name.
+ *
+ * @param string $commandName The Command name
+ */
+ public function setDefaultCommand($commandName)
+ {
+ $this->defaultCommand = $commandName;
+ }
+
+ private function stringWidth($string)
+ {
+ if (!function_exists('mb_strwidth')) {
+ return strlen($string);
+ }
+
+ if (false === $encoding = mb_detect_encoding($string)) {
+ return strlen($string);
+ }
+
+ return mb_strwidth($string, $encoding);
+ }
+
+ private function splitStringByWidth($string, $width)
+ {
+ // str_split is not suitable for multi-byte characters, we should use preg_split to get char array properly.
+ // additionally, array_slice() is not enough as some character has doubled width.
+ // we need a function to split string not by character count but by string width
+
+ if (!function_exists('mb_strwidth')) {
+ return str_split($string, $width);
+ }
+
+ if (false === $encoding = mb_detect_encoding($string)) {
+ return str_split($string, $width);
+ }
+
+ $utf8String = mb_convert_encoding($string, 'utf8', $encoding);
+ $lines = array();
+ $line = '';
+ foreach (preg_split('//u', $utf8String) as $char) {
+ // test if $char could be appended to current line
+ if (mb_strwidth($line.$char, 'utf8') <= $width) {
+ $line .= $char;
+ continue;
+ }
+ // if not, push current line to array and make new line
+ $lines[] = str_pad($line, $width);
+ $line = $char;
+ }
+ if (strlen($line)) {
+ $lines[] = count($lines) ? str_pad($line, $width) : $line;
+ }
+
+ mb_convert_variables($encoding, 'utf8', $lines);
+
+ return $lines;
+ }
+
+ /**
+ * Returns all namespaces of the command name.
+ *
+ * @param string $name The full name of the command
+ *
+ * @return array The namespaces of the command
+ */
+ private function extractAllNamespaces($name)
+ {
+ // -1 as third argument is needed to skip the command short name when exploding
+ $parts = explode(':', $name, -1);
+ $namespaces = array();
+
+ foreach ($parts as $part) {
+ if (count($namespaces)) {
+ $namespaces[] = end($namespaces).':'.$part;
+ } else {
+ $namespaces[] = $part;
+ }
+ }
+
+ return $namespaces;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/CHANGELOG.md b/vendor/symfony/console/Symfony/Component/Console/CHANGELOG.md
new file mode 100644
index 0000000..07254c6
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/CHANGELOG.md
@@ -0,0 +1,62 @@
+CHANGELOG
+=========
+
+2.6.0
+-----
+
+ * added a Process helper
+ * added a DebugFormatter helper
+
+2.5.0
+-----
+
+ * deprecated the dialog helper (use the question helper instead)
+ * deprecated TableHelper in favor of Table
+ * deprecated ProgressHelper in favor of ProgressBar
+ * added ConsoleLogger
+ * added a question helper
+ * added a way to set the process name of a command
+ * added a way to set a default command instead of `ListCommand`
+
+2.4.0
+-----
+
+ * added a way to force terminal dimensions
+ * added a convenient method to detect verbosity level
+ * [BC BREAK] made descriptors use output instead of returning a string
+
+2.3.0
+-----
+
+ * added multiselect support to the select dialog helper
+ * added Table Helper for tabular data rendering
+ * added support for events in `Application`
+ * added a way to normalize EOLs in `ApplicationTester::getDisplay()` and `CommandTester::getDisplay()`
+ * added a way to set the progress bar progress via the `setCurrent` method
+ * added support for multiple InputOption shortcuts, written as `'-a|-b|-c'`
+ * added two additional verbosity levels, VERBOSITY_VERY_VERBOSE and VERBOSITY_DEBUG
+
+2.2.0
+-----
+
+ * added support for colorization on Windows via ConEmu
+ * add a method to Dialog Helper to ask for a question and hide the response
+ * added support for interactive selections in console (DialogHelper::select())
+ * added support for autocompletion as you type in Dialog Helper
+
+2.1.0
+-----
+
+ * added ConsoleOutputInterface
+ * added the possibility to disable a command (Command::isEnabled())
+ * added suggestions when a command does not exist
+ * added a --raw option to the list command
+ * added support for STDERR in the console output class (errors are now sent
+ to STDERR)
+ * made the defaults (helper set, commands, input definition) in Application
+ more easily customizable
+ * added support for the shell even if readline is not available
+ * added support for process isolation in Symfony shell via
+ `--process-isolation` switch
+ * added support for `--`, which disables options parsing after that point
+ (tokens will be parsed as arguments)
diff --git a/vendor/symfony/console/Symfony/Component/Console/Command/Command.php b/vendor/symfony/console/Symfony/Component/Console/Command/Command.php
new file mode 100644
index 0000000..20dd85b
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Command/Command.php
@@ -0,0 +1,661 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Command;
+
+use Symfony\Component\Console\Descriptor\TextDescriptor;
+use Symfony\Component\Console\Descriptor\XmlDescriptor;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\BufferedOutput;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Helper\HelperSet;
+
+/**
+ * Base class for all commands.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class Command
+{
+ private $application;
+ private $name;
+ private $processTitle;
+ private $aliases = array();
+ private $definition;
+ private $help;
+ private $description;
+ private $ignoreValidationErrors = false;
+ private $applicationDefinitionMerged = false;
+ private $applicationDefinitionMergedWithArgs = false;
+ private $code;
+ private $synopsis;
+ private $helperSet;
+
+ /**
+ * Constructor.
+ *
+ * @param string|null $name The name of the command; passing null means it must be set in configure()
+ *
+ * @throws \LogicException When the command name is empty
+ *
+ * @api
+ */
+ public function __construct($name = null)
+ {
+ $this->definition = new InputDefinition();
+
+ if (null !== $name) {
+ $this->setName($name);
+ }
+
+ $this->configure();
+
+ if (!$this->name) {
+ throw new \LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($this)));
+ }
+ }
+
+ /**
+ * Ignores validation errors.
+ *
+ * This is mainly useful for the help command.
+ */
+ public function ignoreValidationErrors()
+ {
+ $this->ignoreValidationErrors = true;
+ }
+
+ /**
+ * Sets the application instance for this command.
+ *
+ * @param Application $application An Application instance
+ *
+ * @api
+ */
+ public function setApplication(Application $application = null)
+ {
+ $this->application = $application;
+ if ($application) {
+ $this->setHelperSet($application->getHelperSet());
+ } else {
+ $this->helperSet = null;
+ }
+ }
+
+ /**
+ * Sets the helper set.
+ *
+ * @param HelperSet $helperSet A HelperSet instance
+ */
+ public function setHelperSet(HelperSet $helperSet)
+ {
+ $this->helperSet = $helperSet;
+ }
+
+ /**
+ * Gets the helper set.
+ *
+ * @return HelperSet A HelperSet instance
+ */
+ public function getHelperSet()
+ {
+ return $this->helperSet;
+ }
+
+ /**
+ * Gets the application instance for this command.
+ *
+ * @return Application An Application instance
+ *
+ * @api
+ */
+ public function getApplication()
+ {
+ return $this->application;
+ }
+
+ /**
+ * Checks whether the command is enabled or not in the current environment.
+ *
+ * Override this to check for x or y and return false if the command can not
+ * run properly under the current conditions.
+ *
+ * @return bool
+ */
+ public function isEnabled()
+ {
+ return true;
+ }
+
+ /**
+ * Configures the current command.
+ */
+ protected function configure()
+ {
+ }
+
+ /**
+ * Executes the current command.
+ *
+ * This method is not abstract because you can use this class
+ * as a concrete class. In this case, instead of defining the
+ * execute() method, you set the code to execute by passing
+ * a Closure to the setCode() method.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ *
+ * @return null|int null or 0 if everything went fine, or an error code
+ *
+ * @throws \LogicException When this abstract method is not implemented
+ *
+ * @see setCode()
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ throw new \LogicException('You must override the execute() method in the concrete command class.');
+ }
+
+ /**
+ * Interacts with the user.
+ *
+ * This method is executed before the InputDefinition is validated.
+ * This means that this is the only place where the command can
+ * interactively ask for values of missing required arguments.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ */
+ protected function interact(InputInterface $input, OutputInterface $output)
+ {
+ }
+
+ /**
+ * Initializes the command just after the input has been validated.
+ *
+ * This is mainly useful when a lot of commands extends one main command
+ * where some things need to be initialized based on the input arguments and options.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ */
+ protected function initialize(InputInterface $input, OutputInterface $output)
+ {
+ }
+
+ /**
+ * Runs the command.
+ *
+ * The code to execute is either defined directly with the
+ * setCode() method or by overriding the execute() method
+ * in a sub-class.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ *
+ * @return int The command exit code
+ *
+ * @throws \Exception
+ *
+ * @see setCode()
+ * @see execute()
+ *
+ * @api
+ */
+ public function run(InputInterface $input, OutputInterface $output)
+ {
+ // force the creation of the synopsis before the merge with the app definition
+ $this->getSynopsis();
+
+ // add the application arguments and options
+ $this->mergeApplicationDefinition();
+
+ // bind the input against the command specific arguments/options
+ try {
+ $input->bind($this->definition);
+ } catch (\Exception $e) {
+ if (!$this->ignoreValidationErrors) {
+ throw $e;
+ }
+ }
+
+ $this->initialize($input, $output);
+
+ if (null !== $this->processTitle) {
+ if (function_exists('cli_set_process_title')) {
+ cli_set_process_title($this->processTitle);
+ } elseif (function_exists('setproctitle')) {
+ setproctitle($this->processTitle);
+ } elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) {
+ $output->writeln('<comment>Install the proctitle PECL to be able to change the process title.</comment>');
+ }
+ }
+
+ if ($input->isInteractive()) {
+ $this->interact($input, $output);
+ }
+
+ $input->validate();
+
+ if ($this->code) {
+ $statusCode = call_user_func($this->code, $input, $output);
+ } else {
+ $statusCode = $this->execute($input, $output);
+ }
+
+ return is_numeric($statusCode) ? (int) $statusCode : 0;
+ }
+
+ /**
+ * Sets the code to execute when running this command.
+ *
+ * If this method is used, it overrides the code defined
+ * in the execute() method.
+ *
+ * @param callable $code A callable(InputInterface $input, OutputInterface $output)
+ *
+ * @return Command The current instance
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @see execute()
+ *
+ * @api
+ */
+ public function setCode($code)
+ {
+ if (!is_callable($code)) {
+ throw new \InvalidArgumentException('Invalid callable provided to Command::setCode.');
+ }
+
+ $this->code = $code;
+
+ return $this;
+ }
+
+ /**
+ * Merges the application definition with the command definition.
+ *
+ * This method is not part of public API and should not be used directly.
+ *
+ * @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments
+ */
+ public function mergeApplicationDefinition($mergeArgs = true)
+ {
+ if (null === $this->application || (true === $this->applicationDefinitionMerged && ($this->applicationDefinitionMergedWithArgs || !$mergeArgs))) {
+ return;
+ }
+
+ if ($mergeArgs) {
+ $currentArguments = $this->definition->getArguments();
+ $this->definition->setArguments($this->application->getDefinition()->getArguments());
+ $this->definition->addArguments($currentArguments);
+ }
+
+ $this->definition->addOptions($this->application->getDefinition()->getOptions());
+
+ $this->applicationDefinitionMerged = true;
+ if ($mergeArgs) {
+ $this->applicationDefinitionMergedWithArgs = true;
+ }
+ }
+
+ /**
+ * Sets an array of argument and option instances.
+ *
+ * @param array|InputDefinition $definition An array of argument and option instances or a definition instance
+ *
+ * @return Command The current instance
+ *
+ * @api
+ */
+ public function setDefinition($definition)
+ {
+ if ($definition instanceof InputDefinition) {
+ $this->definition = $definition;
+ } else {
+ $this->definition->setDefinition($definition);
+ }
+
+ $this->applicationDefinitionMerged = false;
+
+ return $this;
+ }
+
+ /**
+ * Gets the InputDefinition attached to this Command.
+ *
+ * @return InputDefinition An InputDefinition instance
+ *
+ * @api
+ */
+ public function getDefinition()
+ {
+ return $this->definition;
+ }
+
+ /**
+ * Gets the InputDefinition to be used to create XML and Text representations of this Command.
+ *
+ * Can be overridden to provide the original command representation when it would otherwise
+ * be changed by merging with the application InputDefinition.
+ *
+ * This method is not part of public API and should not be used directly.
+ *
+ * @return InputDefinition An InputDefinition instance
+ */
+ public function getNativeDefinition()
+ {
+ return $this->getDefinition();
+ }
+
+ /**
+ * Adds an argument.
+ *
+ * @param string $name The argument name
+ * @param int $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
+ * @param string $description A description text
+ * @param mixed $default The default value (for InputArgument::OPTIONAL mode only)
+ *
+ * @return Command The current instance
+ *
+ * @api
+ */
+ public function addArgument($name, $mode = null, $description = '', $default = null)
+ {
+ $this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
+
+ return $this;
+ }
+
+ /**
+ * Adds an option.
+ *
+ * @param string $name The option name
+ * @param string $shortcut The shortcut (can be null)
+ * @param int $mode The option mode: One of the InputOption::VALUE_* constants
+ * @param string $description A description text
+ * @param mixed $default The default value (must be null for InputOption::VALUE_REQUIRED or InputOption::VALUE_NONE)
+ *
+ * @return Command The current instance
+ *
+ * @api
+ */
+ public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
+ {
+ $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
+
+ return $this;
+ }
+
+ /**
+ * Sets the name of the command.
+ *
+ * This method can set both the namespace and the name if
+ * you separate them by a colon (:)
+ *
+ * $command->setName('foo:bar');
+ *
+ * @param string $name The command name
+ *
+ * @return Command The current instance
+ *
+ * @throws \InvalidArgumentException When the name is invalid
+ *
+ * @api
+ */
+ public function setName($name)
+ {
+ $this->validateName($name);
+
+ $this->name = $name;
+
+ return $this;
+ }
+
+ /**
+ * Sets the process title of the command.
+ *
+ * This feature should be used only when creating a long process command,
+ * like a daemon.
+ *
+ * PHP 5.5+ or the proctitle PECL library is required
+ *
+ * @param string $title The process title
+ *
+ * @return Command The current instance
+ */
+ public function setProcessTitle($title)
+ {
+ $this->processTitle = $title;
+
+ return $this;
+ }
+
+ /**
+ * Returns the command name.
+ *
+ * @return string The command name
+ *
+ * @api
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Sets the description for the command.
+ *
+ * @param string $description The description for the command
+ *
+ * @return Command The current instance
+ *
+ * @api
+ */
+ public function setDescription($description)
+ {
+ $this->description = $description;
+
+ return $this;
+ }
+
+ /**
+ * Returns the description for the command.
+ *
+ * @return string The description for the command
+ *
+ * @api
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ /**
+ * Sets the help for the command.
+ *
+ * @param string $help The help for the command
+ *
+ * @return Command The current instance
+ *
+ * @api
+ */
+ public function setHelp($help)
+ {
+ $this->help = $help;
+
+ return $this;
+ }
+
+ /**
+ * Returns the help for the command.
+ *
+ * @return string The help for the command
+ *
+ * @api
+ */
+ public function getHelp()
+ {
+ return $this->help;
+ }
+
+ /**
+ * Returns the processed help for the command replacing the %command.name% and
+ * %command.full_name% patterns with the real values dynamically.
+ *
+ * @return string The processed help for the command
+ */
+ public function getProcessedHelp()
+ {
+ $name = $this->name;
+
+ $placeholders = array(
+ '%command.name%',
+ '%command.full_name%',
+ );
+ $replacements = array(
+ $name,
+ $_SERVER['PHP_SELF'].' '.$name,
+ );
+
+ return str_replace($placeholders, $replacements, $this->getHelp());
+ }
+
+ /**
+ * Sets the aliases for the command.
+ *
+ * @param string[] $aliases An array of aliases for the command
+ *
+ * @return Command The current instance
+ *
+ * @throws \InvalidArgumentException When an alias is invalid
+ *
+ * @api
+ */
+ public function setAliases($aliases)
+ {
+ if (!is_array($aliases) && !$aliases instanceof \Traversable) {
+ throw new \InvalidArgumentException('$aliases must be an array or an instance of \Traversable');
+ }
+
+ foreach ($aliases as $alias) {
+ $this->validateName($alias);
+ }
+
+ $this->aliases = $aliases;
+
+ return $this;
+ }
+
+ /**
+ * Returns the aliases for the command.
+ *
+ * @return array An array of aliases for the command
+ *
+ * @api
+ */
+ public function getAliases()
+ {
+ return $this->aliases;
+ }
+
+ /**
+ * Returns the synopsis for the command.
+ *
+ * @return string The synopsis
+ */
+ public function getSynopsis()
+ {
+ if (null === $this->synopsis) {
+ $this->synopsis = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis()));
+ }
+
+ return $this->synopsis;
+ }
+
+ /**
+ * Gets a helper instance by name.
+ *
+ * @param string $name The helper name
+ *
+ * @return mixed The helper value
+ *
+ * @throws \InvalidArgumentException if the helper is not defined
+ *
+ * @api
+ */
+ public function getHelper($name)
+ {
+ return $this->helperSet->get($name);
+ }
+
+ /**
+ * Returns a text representation of the command.
+ *
+ * @return string A string representing the command
+ *
+ * @deprecated Deprecated since version 2.3, to be removed in 3.0.
+ */
+ public function asText()
+ {
+ $descriptor = new TextDescriptor();
+ $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
+ $descriptor->describe($output, $this, array('raw_output' => true));
+
+ return $output->fetch();
+ }
+
+ /**
+ * Returns an XML representation of the command.
+ *
+ * @param bool $asDom Whether to return a DOM or an XML string
+ *
+ * @return string|\DOMDocument An XML string representing the command
+ *
+ * @deprecated Deprecated since version 2.3, to be removed in 3.0.
+ */
+ public function asXml($asDom = false)
+ {
+ $descriptor = new XmlDescriptor();
+
+ if ($asDom) {
+ return $descriptor->getCommandDocument($this);
+ }
+
+ $output = new BufferedOutput();
+ $descriptor->describe($output, $this);
+
+ return $output->fetch();
+ }
+
+ /**
+ * Validates a command name.
+ *
+ * It must be non-empty and parts can optionally be separated by ":".
+ *
+ * @param string $name
+ *
+ * @throws \InvalidArgumentException When the name is invalid
+ */
+ private function validateName($name)
+ {
+ if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) {
+ throw new \InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));
+ }
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Command/HelpCommand.php b/vendor/symfony/console/Symfony/Component/Console/Command/HelpCommand.php
new file mode 100644
index 0000000..4cf9362
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Command/HelpCommand.php
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Command;
+
+use Symfony\Component\Console\Helper\DescriptorHelper;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * HelpCommand displays the help for a given command.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class HelpCommand extends Command
+{
+ private $command;
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function configure()
+ {
+ $this->ignoreValidationErrors();
+
+ $this
+ ->setName('help')
+ ->setDefinition(array(
+ new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'),
+ new InputOption('xml', null, InputOption::VALUE_NONE, 'To output help as XML'),
+ new InputOption('format', null, InputOption::VALUE_REQUIRED, 'To output help in other formats', 'txt'),
+ new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'),
+ ))
+ ->setDescription('Displays help for a command')
+ ->setHelp(<<<EOF
+The <info>%command.name%</info> command displays help for a given command:
+
+ <info>php %command.full_name% list</info>
+
+You can also output the help in other formats by using the <comment>--format</comment> option:
+
+ <info>php %command.full_name% --format=xml list</info>
+
+To display the list of available commands, please use the <info>list</info> command.
+EOF
+ )
+ ;
+ }
+
+ /**
+ * Sets the command.
+ *
+ * @param Command $command The command to set
+ */
+ public function setCommand(Command $command)
+ {
+ $this->command = $command;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ if (null === $this->command) {
+ $this->command = $this->getApplication()->find($input->getArgument('command_name'));
+ }
+
+ if ($input->getOption('xml')) {
+ $input->setOption('format', 'xml');
+ }
+
+ $helper = new DescriptorHelper();
+ $helper->describe($output, $this->command, array(
+ 'format' => $input->getOption('format'),
+ 'raw_text' => $input->getOption('raw'),
+ ));
+
+ $this->command = null;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Command/ListCommand.php b/vendor/symfony/console/Symfony/Component/Console/Command/ListCommand.php
new file mode 100644
index 0000000..58868e4
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Command/ListCommand.php
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Command;
+
+use Symfony\Component\Console\Helper\DescriptorHelper;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputDefinition;
+
+/**
+ * ListCommand displays the list of all available commands for the application.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ListCommand extends Command
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function configure()
+ {
+ $this
+ ->setName('list')
+ ->setDefinition($this->createDefinition())
+ ->setDescription('Lists commands')
+ ->setHelp(<<<EOF
+The <info>%command.name%</info> command lists all commands:
+
+ <info>php %command.full_name%</info>
+
+You can also display the commands for a specific namespace:
+
+ <info>php %command.full_name% test</info>
+
+You can also output the information in other formats by using the <comment>--format</comment> option:
+
+ <info>php %command.full_name% --format=xml</info>
+
+It's also possible to get raw list of commands (useful for embedding command runner):
+
+ <info>php %command.full_name% --raw</info>
+EOF
+ )
+ ;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getNativeDefinition()
+ {
+ return $this->createDefinition();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ if ($input->getOption('xml')) {
+ $input->setOption('format', 'xml');
+ }
+
+ $helper = new DescriptorHelper();
+ $helper->describe($output, $this->getApplication(), array(
+ 'format' => $input->getOption('format'),
+ 'raw_text' => $input->getOption('raw'),
+ 'namespace' => $input->getArgument('namespace'),
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ private function createDefinition()
+ {
+ return new InputDefinition(array(
+ new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'),
+ new InputOption('xml', null, InputOption::VALUE_NONE, 'To output list as XML'),
+ new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'),
+ new InputOption('format', null, InputOption::VALUE_REQUIRED, 'To output list in other formats', 'txt'),
+ ));
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/ConsoleEvents.php b/vendor/symfony/console/Symfony/Component/Console/ConsoleEvents.php
new file mode 100644
index 0000000..1ed41b7
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/ConsoleEvents.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console;
+
+/**
+ * Contains all events dispatched by an Application.
+ *
+ * @author Francesco Levorato <git@flevour.net>
+ */
+final class ConsoleEvents
+{
+ /**
+ * The COMMAND event allows you to attach listeners before any command is
+ * executed by the console. It also allows you to modify the command, input and output
+ * before they are handled to the command.
+ *
+ * The event listener method receives a Symfony\Component\Console\Event\ConsoleCommandEvent
+ * instance.
+ *
+ * @Event
+ *
+ * @var string
+ */
+ const COMMAND = 'console.command';
+
+ /**
+ * The TERMINATE event allows you to attach listeners after a command is
+ * executed by the console.
+ *
+ * The event listener method receives a Symfony\Component\Console\Event\ConsoleTerminateEvent
+ * instance.
+ *
+ * @Event
+ *
+ * @var string
+ */
+ const TERMINATE = 'console.terminate';
+
+ /**
+ * The EXCEPTION event occurs when an uncaught exception appears.
+ *
+ * This event allows you to deal with the exception or
+ * to modify the thrown exception. The event listener method receives
+ * a Symfony\Component\Console\Event\ConsoleExceptionEvent
+ * instance.
+ *
+ * @Event
+ *
+ * @var string
+ */
+ const EXCEPTION = 'console.exception';
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Descriptor/ApplicationDescription.php b/vendor/symfony/console/Symfony/Component/Console/Descriptor/ApplicationDescription.php
new file mode 100644
index 0000000..a0a5df2
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Descriptor/ApplicationDescription.php
@@ -0,0 +1,155 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+
+/**
+ * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
+ *
+ * @internal
+ */
+class ApplicationDescription
+{
+ const GLOBAL_NAMESPACE = '_global';
+
+ /**
+ * @var Application
+ */
+ private $application;
+
+ /**
+ * @var null|string
+ */
+ private $namespace;
+
+ /**
+ * @var array
+ */
+ private $namespaces;
+
+ /**
+ * @var Command[]
+ */
+ private $commands;
+
+ /**
+ * @var Command[]
+ */
+ private $aliases;
+
+ /**
+ * Constructor.
+ *
+ * @param Application $application
+ * @param string|null $namespace
+ */
+ public function __construct(Application $application, $namespace = null)
+ {
+ $this->application = $application;
+ $this->namespace = $namespace;
+ }
+
+ /**
+ * @return array
+ */
+ public function getNamespaces()
+ {
+ if (null === $this->namespaces) {
+ $this->inspectApplication();
+ }
+
+ return $this->namespaces;
+ }
+
+ /**
+ * @return Command[]
+ */
+ public function getCommands()
+ {
+ if (null === $this->commands) {
+ $this->inspectApplication();
+ }
+
+ return $this->commands;
+ }
+
+ /**
+ * @param string $name
+ *
+ * @return Command
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function getCommand($name)
+ {
+ if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {
+ throw new \InvalidArgumentException(sprintf('Command %s does not exist.', $name));
+ }
+
+ return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name];
+ }
+
+ private function inspectApplication()
+ {
+ $this->commands = array();
+ $this->namespaces = array();
+
+ $all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null);
+ foreach ($this->sortCommands($all) as $namespace => $commands) {
+ $names = array();
+
+ /** @var Command $command */
+ foreach ($commands as $name => $command) {
+ if (!$command->getName()) {
+ continue;
+ }
+
+ if ($command->getName() === $name) {
+ $this->commands[$name] = $command;
+ } else {
+ $this->aliases[$name] = $command;
+ }
+
+ $names[] = $name;
+ }
+
+ $this->namespaces[$namespace] = array('id' => $namespace, 'commands' => $names);
+ }
+ }
+
+ /**
+ * @param array $commands
+ *
+ * @return array
+ */
+ private function sortCommands(array $commands)
+ {
+ $namespacedCommands = array();
+ foreach ($commands as $name => $command) {
+ $key = $this->application->extractNamespace($name, 1);
+ if (!$key) {
+ $key = '_global';
+ }
+
+ $namespacedCommands[$key][$name] = $command;
+ }
+ ksort($namespacedCommands);
+
+ foreach ($namespacedCommands as &$commands) {
+ ksort($commands);
+ }
+
+ return $namespacedCommands;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.php b/vendor/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.php
new file mode 100644
index 0000000..49e2193
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.php
@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
+ *
+ * @internal
+ */
+abstract class Descriptor implements DescriptorInterface
+{
+ /**
+ * @var OutputInterface
+ */
+ private $output;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function describe(OutputInterface $output, $object, array $options = array())
+ {
+ $this->output = $output;
+
+ switch (true) {
+ case $object instanceof InputArgument:
+ $this->describeInputArgument($object, $options);
+ break;
+ case $object instanceof InputOption:
+ $this->describeInputOption($object, $options);
+ break;
+ case $object instanceof InputDefinition:
+ $this->describeInputDefinition($object, $options);
+ break;
+ case $object instanceof Command:
+ $this->describeCommand($object, $options);
+ break;
+ case $object instanceof Application:
+ $this->describeApplication($object, $options);
+ break;
+ default:
+ throw new \InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object)));
+ }
+ }
+
+ /**
+ * Writes content to output.
+ *
+ * @param string $content
+ * @param bool $decorated
+ */
+ protected function write($content, $decorated = false)
+ {
+ $this->output->write($content, false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW);
+ }
+
+ /**
+ * Describes an InputArgument instance.
+ *
+ * @param InputArgument $argument
+ * @param array $options
+ *
+ * @return string|mixed
+ */
+ abstract protected function describeInputArgument(InputArgument $argument, array $options = array());
+
+ /**
+ * Describes an InputOption instance.
+ *
+ * @param InputOption $option
+ * @param array $options
+ *
+ * @return string|mixed
+ */
+ abstract protected function describeInputOption(InputOption $option, array $options = array());
+
+ /**
+ * Describes an InputDefinition instance.
+ *
+ * @param InputDefinition $definition
+ * @param array $options
+ *
+ * @return string|mixed
+ */
+ abstract protected function describeInputDefinition(InputDefinition $definition, array $options = array());
+
+ /**
+ * Describes a Command instance.
+ *
+ * @param Command $command
+ * @param array $options
+ *
+ * @return string|mixed
+ */
+ abstract protected function describeCommand(Command $command, array $options = array());
+
+ /**
+ * Describes an Application instance.
+ *
+ * @param Application $application
+ * @param array $options
+ *
+ * @return string|mixed
+ */
+ abstract protected function describeApplication(Application $application, array $options = array());
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.php b/vendor/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.php
new file mode 100644
index 0000000..3929b6d
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Descriptor interface.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+interface DescriptorInterface
+{
+ /**
+ * Describes an InputArgument instance.
+ *
+ * @param OutputInterface $output
+ * @param object $object
+ * @param array $options
+ */
+ public function describe(OutputInterface $output, $object, array $options = array());
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php b/vendor/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php
new file mode 100644
index 0000000..13785a4
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php
@@ -0,0 +1,167 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * JSON descriptor.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ *
+ * @internal
+ */
+class JsonDescriptor extends Descriptor
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputArgument(InputArgument $argument, array $options = array())
+ {
+ $this->writeData($this->getInputArgumentData($argument), $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputOption(InputOption $option, array $options = array())
+ {
+ $this->writeData($this->getInputOptionData($option), $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputDefinition(InputDefinition $definition, array $options = array())
+ {
+ $this->writeData($this->getInputDefinitionData($definition), $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeCommand(Command $command, array $options = array())
+ {
+ $this->writeData($this->getCommandData($command), $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeApplication(Application $application, array $options = array())
+ {
+ $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
+ $description = new ApplicationDescription($application, $describedNamespace);
+ $commands = array();
+
+ foreach ($description->getCommands() as $command) {
+ $commands[] = $this->getCommandData($command);
+ }
+
+ $data = $describedNamespace
+ ? array('commands' => $commands, 'namespace' => $describedNamespace)
+ : array('commands' => $commands, 'namespaces' => array_values($description->getNamespaces()));
+
+ $this->writeData($data, $options);
+ }
+
+ /**
+ * Writes data as json.
+ *
+ * @param array $data
+ * @param array $options
+ *
+ * @return array|string
+ */
+ private function writeData(array $data, array $options)
+ {
+ $this->write(json_encode($data, isset($options['json_encoding']) ? $options['json_encoding'] : 0));
+ }
+
+ /**
+ * @param InputArgument $argument
+ *
+ * @return array
+ */
+ private function getInputArgumentData(InputArgument $argument)
+ {
+ return array(
+ 'name' => $argument->getName(),
+ 'is_required' => $argument->isRequired(),
+ 'is_array' => $argument->isArray(),
+ 'description' => $argument->getDescription(),
+ 'default' => $argument->getDefault(),
+ );
+ }
+
+ /**
+ * @param InputOption $option
+ *
+ * @return array
+ */
+ private function getInputOptionData(InputOption $option)
+ {
+ return array(
+ 'name' => '--'.$option->getName(),
+ 'shortcut' => $option->getShortcut() ? '-'.implode('|-', explode('|', $option->getShortcut())) : '',
+ 'accept_value' => $option->acceptValue(),
+ 'is_value_required' => $option->isValueRequired(),
+ 'is_multiple' => $option->isArray(),
+ 'description' => $option->getDescription(),
+ 'default' => $option->getDefault(),
+ );
+ }
+
+ /**
+ * @param InputDefinition $definition
+ *
+ * @return array
+ */
+ private function getInputDefinitionData(InputDefinition $definition)
+ {
+ $inputArguments = array();
+ foreach ($definition->getArguments() as $name => $argument) {
+ $inputArguments[$name] = $this->getInputArgumentData($argument);
+ }
+
+ $inputOptions = array();
+ foreach ($definition->getOptions() as $name => $option) {
+ $inputOptions[$name] = $this->getInputOptionData($option);
+ }
+
+ return array('arguments' => $inputArguments, 'options' => $inputOptions);
+ }
+
+ /**
+ * @param Command $command
+ *
+ * @return array
+ */
+ private function getCommandData(Command $command)
+ {
+ $command->getSynopsis();
+ $command->mergeApplicationDefinition(false);
+
+ return array(
+ 'name' => $command->getName(),
+ 'usage' => $command->getSynopsis(),
+ 'description' => $command->getDescription(),
+ 'help' => $command->getProcessedHelp(),
+ 'aliases' => $command->getAliases(),
+ 'definition' => $this->getInputDefinitionData($command->getNativeDefinition()),
+ );
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php b/vendor/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php
new file mode 100644
index 0000000..78d48b9
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php
@@ -0,0 +1,141 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * Markdown descriptor.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ *
+ * @internal
+ */
+class MarkdownDescriptor extends Descriptor
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputArgument(InputArgument $argument, array $options = array())
+ {
+ $this->write(
+ '**'.$argument->getName().':**'."\n\n"
+ .'* Name: '.($argument->getName() ?: '<none>')."\n"
+ .'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n"
+ .'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n"
+ .'* Description: '.($argument->getDescription() ?: '<none>')."\n"
+ .'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputOption(InputOption $option, array $options = array())
+ {
+ $this->write(
+ '**'.$option->getName().':**'."\n\n"
+ .'* Name: `--'.$option->getName().'`'."\n"
+ .'* Shortcut: '.($option->getShortcut() ? '`-'.implode('|-', explode('|', $option->getShortcut())).'`' : '<none>')."\n"
+ .'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n"
+ .'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n"
+ .'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n"
+ .'* Description: '.($option->getDescription() ?: '<none>')."\n"
+ .'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputDefinition(InputDefinition $definition, array $options = array())
+ {
+ if ($showArguments = count($definition->getArguments()) > 0) {
+ $this->write('### Arguments:');
+ foreach ($definition->getArguments() as $argument) {
+ $this->write("\n\n");
+ $this->write($this->describeInputArgument($argument));
+ }
+ }
+
+ if (count($definition->getOptions()) > 0) {
+ if ($showArguments) {
+ $this->write("\n\n");
+ }
+
+ $this->write('### Options:');
+ foreach ($definition->getOptions() as $option) {
+ $this->write("\n\n");
+ $this->write($this->describeInputOption($option));
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeCommand(Command $command, array $options = array())
+ {
+ $command->getSynopsis();
+ $command->mergeApplicationDefinition(false);
+
+ $this->write(
+ $command->getName()."\n"
+ .str_repeat('-', strlen($command->getName()))."\n\n"
+ .'* Description: '.($command->getDescription() ?: '<none>')."\n"
+ .'* Usage: `'.$command->getSynopsis().'`'."\n"
+ .'* Aliases: '.(count($command->getAliases()) ? '`'.implode('`, `', $command->getAliases()).'`' : '<none>')
+ );
+
+ if ($help = $command->getProcessedHelp()) {
+ $this->write("\n\n");
+ $this->write($help);
+ }
+
+ if ($command->getNativeDefinition()) {
+ $this->write("\n\n");
+ $this->describeInputDefinition($command->getNativeDefinition());
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeApplication(Application $application, array $options = array())
+ {
+ $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
+ $description = new ApplicationDescription($application, $describedNamespace);
+
+ $this->write($application->getName()."\n".str_repeat('=', strlen($application->getName())));
+
+ foreach ($description->getNamespaces() as $namespace) {
+ if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
+ $this->write("\n\n");
+ $this->write('**'.$namespace['id'].':**');
+ }
+
+ $this->write("\n\n");
+ $this->write(implode("\n", array_map(function ($commandName) {
+ return '* '.$commandName;
+ }, $namespace['commands'])));
+ }
+
+ foreach ($description->getCommands() as $command) {
+ $this->write("\n\n");
+ $this->write($this->describeCommand($command));
+ }
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php b/vendor/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php
new file mode 100644
index 0000000..0b3dd5a
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php
@@ -0,0 +1,255 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * Text descriptor.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ *
+ * @internal
+ */
+class TextDescriptor extends Descriptor
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputArgument(InputArgument $argument, array $options = array())
+ {
+ if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) {
+ $default = sprintf('<comment> (default: %s)</comment>', $this->formatDefaultValue($argument->getDefault()));
+ } else {
+ $default = '';
+ }
+
+ $nameWidth = isset($options['name_width']) ? $options['name_width'] : strlen($argument->getName());
+
+ $this->writeText(sprintf(" <info>%-${nameWidth}s</info> %s%s",
+ $argument->getName(),
+ str_replace("\n", "\n".str_repeat(' ', $nameWidth + 2), $argument->getDescription()),
+ $default
+ ), $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputOption(InputOption $option, array $options = array())
+ {
+ if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) {
+ $default = sprintf('<comment> (default: %s)</comment>', $this->formatDefaultValue($option->getDefault()));
+ } else {
+ $default = '';
+ }
+
+ $nameWidth = isset($options['name_width']) ? $options['name_width'] : strlen($option->getName());
+ $nameWithShortcutWidth = $nameWidth - strlen($option->getName()) - 2;
+
+ $this->writeText(sprintf(" <info>%s</info> %-${nameWithShortcutWidth}s%s%s%s",
+ '--'.$option->getName(),
+ $option->getShortcut() ? sprintf('(-%s) ', $option->getShortcut()) : '',
+ str_replace("\n", "\n".str_repeat(' ', $nameWidth + 2), $option->getDescription()),
+ $default,
+ $option->isArray() ? '<comment> (multiple values allowed)</comment>' : ''
+ ), $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputDefinition(InputDefinition $definition, array $options = array())
+ {
+ $nameWidth = 0;
+ foreach ($definition->getOptions() as $option) {
+ $nameLength = strlen($option->getName()) + 2;
+ if ($option->getShortcut()) {
+ $nameLength += strlen($option->getShortcut()) + 3;
+ }
+ $nameWidth = max($nameWidth, $nameLength);
+ }
+ foreach ($definition->getArguments() as $argument) {
+ $nameWidth = max($nameWidth, strlen($argument->getName()));
+ }
+ ++$nameWidth;
+
+ if ($definition->getArguments()) {
+ $this->writeText('<comment>Arguments:</comment>', $options);
+ $this->writeText("\n");
+ foreach ($definition->getArguments() as $argument) {
+ $this->describeInputArgument($argument, array_merge($options, array('name_width' => $nameWidth)));
+ $this->writeText("\n");
+ }
+ }
+
+ if ($definition->getArguments() && $definition->getOptions()) {
+ $this->writeText("\n");
+ }
+
+ if ($definition->getOptions()) {
+ $this->writeText('<comment>Options:</comment>', $options);
+ $this->writeText("\n");
+ foreach ($definition->getOptions() as $option) {
+ $this->describeInputOption($option, array_merge($options, array('name_width' => $nameWidth)));
+ $this->writeText("\n");
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeCommand(Command $command, array $options = array())
+ {
+ $command->getSynopsis();
+ $command->mergeApplicationDefinition(false);
+
+ $this->writeText('<comment>Usage:</comment>', $options);
+ $this->writeText("\n");
+ $this->writeText(' '.$command->getSynopsis(), $options);
+ $this->writeText("\n");
+
+ if (count($command->getAliases()) > 0) {
+ $this->writeText("\n");
+ $this->writeText('<comment>Aliases:</comment> <info>'.implode(', ', $command->getAliases()).'</info>', $options);
+ }
+
+ if ($definition = $command->getNativeDefinition()) {
+ $this->writeText("\n");
+ $this->describeInputDefinition($definition, $options);
+ }
+
+ $this->writeText("\n");
+
+ if ($help = $command->getProcessedHelp()) {
+ $this->writeText('<comment>Help:</comment>', $options);
+ $this->writeText("\n");
+ $this->writeText(' '.str_replace("\n", "\n ", $help), $options);
+ $this->writeText("\n");
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeApplication(Application $application, array $options = array())
+ {
+ $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
+ $description = new ApplicationDescription($application, $describedNamespace);
+
+ if (isset($options['raw_text']) && $options['raw_text']) {
+ $width = $this->getColumnWidth($description->getCommands());
+
+ foreach ($description->getCommands() as $command) {
+ $this->writeText(sprintf("%-${width}s %s", $command->getName(), $command->getDescription()), $options);
+ $this->writeText("\n");
+ }
+ } else {
+ if ('' != $help = $application->getHelp()) {
+ $this->writeText("$help\n\n", $options);
+ }
+
+ $this->writeText("<comment>Usage:</comment>\n", $options);
+ $this->writeText(" command [options] [arguments]\n\n", $options);
+ $this->writeText('<comment>Options:</comment>', $options);
+
+ $inputOptions = $application->getDefinition()->getOptions();
+
+ $width = 0;
+ foreach ($inputOptions as $option) {
+ $nameLength = strlen($option->getName()) + 2;
+ if ($option->getShortcut()) {
+ $nameLength += strlen($option->getShortcut()) + 3;
+ }
+ $width = max($width, $nameLength);
+ }
+ ++$width;
+
+ foreach ($inputOptions as $option) {
+ $this->writeText("\n", $options);
+ $this->describeInputOption($option, array_merge($options, array('name_width' => $width)));
+ }
+
+ $this->writeText("\n\n", $options);
+
+ $width = $this->getColumnWidth($description->getCommands());
+
+ if ($describedNamespace) {
+ $this->writeText(sprintf("<comment>Available commands for the \"%s\" namespace:</comment>", $describedNamespace), $options);
+ } else {
+ $this->writeText('<comment>Available commands:</comment>', $options);
+ }
+
+ // add commands by namespace
+ foreach ($description->getNamespaces() as $namespace) {
+ if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
+ $this->writeText("\n");
+ $this->writeText('<comment>'.$namespace['id'].'</comment>', $options);
+ }
+
+ foreach ($namespace['commands'] as $name) {
+ $this->writeText("\n");
+ $this->writeText(sprintf(" <info>%-${width}s</info> %s", $name, $description->getCommand($name)->getDescription()), $options);
+ }
+ }
+
+ $this->writeText("\n");
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ private function writeText($content, array $options = array())
+ {
+ $this->write(
+ isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content,
+ isset($options['raw_output']) ? !$options['raw_output'] : true
+ );
+ }
+
+ /**
+ * Formats input option/argument default value.
+ *
+ * @param mixed $default
+ *
+ * @return string
+ */
+ private function formatDefaultValue($default)
+ {
+ if (PHP_VERSION_ID < 50400) {
+ return str_replace('\/', '/', json_encode($default));
+ }
+
+ return json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
+ }
+
+ /**
+ * @param Command[] $commands
+ *
+ * @return int
+ */
+ private function getColumnWidth(array $commands)
+ {
+ $width = 0;
+ foreach ($commands as $command) {
+ $width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width;
+ }
+
+ return $width + 2;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php b/vendor/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php
new file mode 100644
index 0000000..5054686
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php
@@ -0,0 +1,266 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * XML descriptor.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ *
+ * @internal
+ */
+class XmlDescriptor extends Descriptor
+{
+ /**
+ * @param InputDefinition $definition
+ *
+ * @return \DOMDocument
+ */
+ public function getInputDefinitionDocument(InputDefinition $definition)
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->appendChild($definitionXML = $dom->createElement('definition'));
+
+ $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments'));
+ foreach ($definition->getArguments() as $argument) {
+ $this->appendDocument($argumentsXML, $this->getInputArgumentDocument($argument));
+ }
+
+ $definitionXML->appendChild($optionsXML = $dom->createElement('options'));
+ foreach ($definition->getOptions() as $option) {
+ $this->appendDocument($optionsXML, $this->getInputOptionDocument($option));
+ }
+
+ return $dom;
+ }
+
+ /**
+ * @param Command $command
+ *
+ * @return \DOMDocument
+ */
+ public function getCommandDocument(Command $command)
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->appendChild($commandXML = $dom->createElement('command'));
+
+ $command->getSynopsis();
+ $command->mergeApplicationDefinition(false);
+
+ $commandXML->setAttribute('id', $command->getName());
+ $commandXML->setAttribute('name', $command->getName());
+
+ $commandXML->appendChild($usageXML = $dom->createElement('usage'));
+ $usageXML->appendChild($dom->createTextNode(sprintf($command->getSynopsis(), '')));
+
+ $commandXML->appendChild($descriptionXML = $dom->createElement('description'));
+ $descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getDescription())));
+
+ $commandXML->appendChild($helpXML = $dom->createElement('help'));
+ $helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getProcessedHelp())));
+
+ $commandXML->appendChild($aliasesXML = $dom->createElement('aliases'));
+ foreach ($command->getAliases() as $alias) {
+ $aliasesXML->appendChild($aliasXML = $dom->createElement('alias'));
+ $aliasXML->appendChild($dom->createTextNode($alias));
+ }
+
+ $definitionXML = $this->getInputDefinitionDocument($command->getNativeDefinition());
+ $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0));
+
+ return $dom;
+ }
+
+ /**
+ * @param Application $application
+ * @param string|null $namespace
+ *
+ * @return \DOMDocument
+ */
+ public function getApplicationDocument(Application $application, $namespace = null)
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->appendChild($rootXml = $dom->createElement('symfony'));
+
+ if ($application->getName() !== 'UNKNOWN') {
+ $rootXml->setAttribute('name', $application->getName());
+ if ($application->getVersion() !== 'UNKNOWN') {
+ $rootXml->setAttribute('version', $application->getVersion());
+ }
+ }
+
+ $rootXml->appendChild($commandsXML = $dom->createElement('commands'));
+
+ $description = new ApplicationDescription($application, $namespace);
+
+ if ($namespace) {
+ $commandsXML->setAttribute('namespace', $namespace);
+ }
+
+ foreach ($description->getCommands() as $command) {
+ $this->appendDocument($commandsXML, $this->getCommandDocument($command));
+ }
+
+ if (!$namespace) {
+ $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces'));
+
+ foreach ($description->getNamespaces() as $namespaceDescription) {
+ $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace'));
+ $namespaceArrayXML->setAttribute('id', $namespaceDescription['id']);
+
+ foreach ($namespaceDescription['commands'] as $name) {
+ $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command'));
+ $commandXML->appendChild($dom->createTextNode($name));
+ }
+ }
+ }
+
+ return $dom;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputArgument(InputArgument $argument, array $options = array())
+ {
+ $this->writeDocument($this->getInputArgumentDocument($argument));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputOption(InputOption $option, array $options = array())
+ {
+ $this->writeDocument($this->getInputOptionDocument($option));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputDefinition(InputDefinition $definition, array $options = array())
+ {
+ $this->writeDocument($this->getInputDefinitionDocument($definition));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeCommand(Command $command, array $options = array())
+ {
+ $this->writeDocument($this->getCommandDocument($command));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeApplication(Application $application, array $options = array())
+ {
+ $this->writeDocument($this->getApplicationDocument($application, isset($options['namespace']) ? $options['namespace'] : null));
+ }
+
+ /**
+ * Appends document children to parent node.
+ *
+ * @param \DOMNode $parentNode
+ * @param \DOMNode $importedParent
+ */
+ private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent)
+ {
+ foreach ($importedParent->childNodes as $childNode) {
+ $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, true));
+ }
+ }
+
+ /**
+ * Writes DOM document.
+ *
+ * @param \DOMDocument $dom
+ *
+ * @return \DOMDocument|string
+ */
+ private function writeDocument(\DOMDocument $dom)
+ {
+ $dom->formatOutput = true;
+ $this->write($dom->saveXML());
+ }
+
+ /**
+ * @param InputArgument $argument
+ *
+ * @return \DOMDocument
+ */
+ private function getInputArgumentDocument(InputArgument $argument)
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+
+ $dom->appendChild($objectXML = $dom->createElement('argument'));
+ $objectXML->setAttribute('name', $argument->getName());
+ $objectXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0);
+ $objectXML->setAttribute('is_array', $argument->isArray() ? 1 : 0);
+ $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
+ $descriptionXML->appendChild($dom->createTextNode($argument->getDescription()));
+
+ $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
+ $defaults = is_array($argument->getDefault()) ? $argument->getDefault() : (is_bool($argument->getDefault()) ? array(var_export($argument->getDefault(), true)) : ($argument->getDefault() ? array($argument->getDefault()) : array()));
+ foreach ($defaults as $default) {
+ $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
+ $defaultXML->appendChild($dom->createTextNode($default));
+ }
+
+ return $dom;
+ }
+
+ /**
+ * @param InputOption $option
+ *
+ * @return \DOMDocument
+ */
+ private function getInputOptionDocument(InputOption $option)
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+
+ $dom->appendChild($objectXML = $dom->createElement('option'));
+ $objectXML->setAttribute('name', '--'.$option->getName());
+ $pos = strpos($option->getShortcut(), '|');
+ if (false !== $pos) {
+ $objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos));
+ $objectXML->setAttribute('shortcuts', '-'.implode('|-', explode('|', $option->getShortcut())));
+ } else {
+ $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : '');
+ }
+ $objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0);
+ $objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0);
+ $objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0);
+ $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
+ $descriptionXML->appendChild($dom->createTextNode($option->getDescription()));
+
+ if ($option->acceptValue()) {
+ $defaults = is_array($option->getDefault()) ? $option->getDefault() : (is_bool($option->getDefault()) ? array(var_export($option->getDefault(), true)) : ($option->getDefault() ? array($option->getDefault()) : array()));
+ $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
+
+ if (!empty($defaults)) {
+ foreach ($defaults as $default) {
+ $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
+ $defaultXML->appendChild($dom->createTextNode($default));
+ }
+ }
+ }
+
+ return $dom;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleCommandEvent.php b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleCommandEvent.php
new file mode 100644
index 0000000..56f5526
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleCommandEvent.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Event;
+
+/**
+ * Allows to do things before the command is executed, like skipping the command or changing the input.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ConsoleCommandEvent extends ConsoleEvent
+{
+ /**
+ * The return code for skipped commands, this will also be passed into the terminate event
+ */
+ const RETURN_CODE_DISABLED = 113;
+
+ /**
+ * Indicates if the command should be run or skipped
+ *
+ * @var bool
+ */
+ private $commandShouldRun = true;
+
+ /**
+ * Disables the command, so it won't be run
+ *
+ * @return bool
+ */
+ public function disableCommand()
+ {
+ return $this->commandShouldRun = false;
+ }
+
+ /**
+ * Enables the command
+ *
+ * @return bool
+ */
+ public function enableCommand()
+ {
+ return $this->commandShouldRun = true;
+ }
+
+ /**
+ * Returns true if the command is runnable, false otherwise
+ *
+ * @return bool
+ */
+ public function commandShouldRun()
+ {
+ return $this->commandShouldRun;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleEvent.php b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleEvent.php
new file mode 100644
index 0000000..ab620c4
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleEvent.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Event;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Allows to inspect input and output of a command.
+ *
+ * @author Francesco Levorato <git@flevour.net>
+ */
+class ConsoleEvent extends Event
+{
+ protected $command;
+
+ private $input;
+ private $output;
+
+ public function __construct(Command $command, InputInterface $input, OutputInterface $output)
+ {
+ $this->command = $command;
+ $this->input = $input;
+ $this->output = $output;
+ }
+
+ /**
+ * Gets the command that is executed.
+ *
+ * @return Command A Command instance
+ */
+ public function getCommand()
+ {
+ return $this->command;
+ }
+
+ /**
+ * Gets the input instance.
+ *
+ * @return InputInterface An InputInterface instance
+ */
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ /**
+ * Gets the output instance.
+ *
+ * @return OutputInterface An OutputInterface instance
+ */
+ public function getOutput()
+ {
+ return $this->output;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php
new file mode 100644
index 0000000..603b7ee
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Event;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Allows to handle exception thrown in a command.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ConsoleExceptionEvent extends ConsoleEvent
+{
+ private $exception;
+ private $exitCode;
+
+ public function __construct(Command $command, InputInterface $input, OutputInterface $output, \Exception $exception, $exitCode)
+ {
+ parent::__construct($command, $input, $output);
+
+ $this->setException($exception);
+ $this->exitCode = (int) $exitCode;
+ }
+
+ /**
+ * Returns the thrown exception.
+ *
+ * @return \Exception The thrown exception
+ */
+ public function getException()
+ {
+ return $this->exception;
+ }
+
+ /**
+ * Replaces the thrown exception.
+ *
+ * This exception will be thrown if no response is set in the event.
+ *
+ * @param \Exception $exception The thrown exception
+ */
+ public function setException(\Exception $exception)
+ {
+ $this->exception = $exception;
+ }
+
+ /**
+ * Gets the exit code.
+ *
+ * @return int The command exit code
+ */
+ public function getExitCode()
+ {
+ return $this->exitCode;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleTerminateEvent.php b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleTerminateEvent.php
new file mode 100644
index 0000000..b6a5d7c
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleTerminateEvent.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Event;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Allows to manipulate the exit code of a command after its execution.
+ *
+ * @author Francesco Levorato <git@flevour.net>
+ */
+class ConsoleTerminateEvent extends ConsoleEvent
+{
+ /**
+ * The exit code of the command.
+ *
+ * @var int
+ */
+ private $exitCode;
+
+ public function __construct(Command $command, InputInterface $input, OutputInterface $output, $exitCode)
+ {
+ parent::__construct($command, $input, $output);
+
+ $this->setExitCode($exitCode);
+ }
+
+ /**
+ * Sets the exit code.
+ *
+ * @param int $exitCode The command exit code
+ */
+ public function setExitCode($exitCode)
+ {
+ $this->exitCode = (int) $exitCode;
+ }
+
+ /**
+ * Gets the exit code.
+ *
+ * @return int The command exit code
+ */
+ public function getExitCode()
+ {
+ return $this->exitCode;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatter.php b/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatter.php
new file mode 100644
index 0000000..90b1970
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatter.php
@@ -0,0 +1,241 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter class for console output.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @api
+ */
+class OutputFormatter implements OutputFormatterInterface
+{
+ private $decorated;
+ private $styles = array();
+ private $styleStack;
+
+ /**
+ * Escapes "<" special char in given text.
+ *
+ * @param string $text Text to escape
+ *
+ * @return string Escaped text
+ */
+ public static function escape($text)
+ {
+ return preg_replace('/([^\\\\]?)</is', '$1\\<', $text);
+ }
+
+ /**
+ * Initializes console output formatter.
+ *
+ * @param bool $decorated Whether this formatter should actually decorate strings
+ * @param OutputFormatterStyleInterface[] $styles Array of "name => FormatterStyle" instances
+ *
+ * @api
+ */
+ public function __construct($decorated = false, array $styles = array())
+ {
+ $this->decorated = (bool) $decorated;
+
+ $this->setStyle('error', new OutputFormatterStyle('white', 'red'));
+ $this->setStyle('info', new OutputFormatterStyle('green'));
+ $this->setStyle('comment', new OutputFormatterStyle('yellow'));
+ $this->setStyle('question', new OutputFormatterStyle('black', 'cyan'));
+
+ foreach ($styles as $name => $style) {
+ $this->setStyle($name, $style);
+ }
+
+ $this->styleStack = new OutputFormatterStyleStack();
+ }
+
+ /**
+ * Sets the decorated flag.
+ *
+ * @param bool $decorated Whether to decorate the messages or not
+ *
+ * @api
+ */
+ public function setDecorated($decorated)
+ {
+ $this->decorated = (bool) $decorated;
+ }
+
+ /**
+ * Gets the decorated flag.
+ *
+ * @return bool true if the output will decorate messages, false otherwise
+ *
+ * @api
+ */
+ public function isDecorated()
+ {
+ return $this->decorated;
+ }
+
+ /**
+ * Sets a new style.
+ *
+ * @param string $name The style name
+ * @param OutputFormatterStyleInterface $style The style instance
+ *
+ * @api
+ */
+ public function setStyle($name, OutputFormatterStyleInterface $style)
+ {
+ $this->styles[strtolower($name)] = $style;
+ }
+
+ /**
+ * Checks if output formatter has style with specified name.
+ *
+ * @param string $name
+ *
+ * @return bool
+ *
+ * @api
+ */
+ public function hasStyle($name)
+ {
+ return isset($this->styles[strtolower($name)]);
+ }
+
+ /**
+ * Gets style options from style with specified name.
+ *
+ * @param string $name
+ *
+ * @return OutputFormatterStyleInterface
+ *
+ * @throws \InvalidArgumentException When style isn't defined
+ *
+ * @api
+ */
+ public function getStyle($name)
+ {
+ if (!$this->hasStyle($name)) {
+ throw new \InvalidArgumentException(sprintf('Undefined style: %s', $name));
+ }
+
+ return $this->styles[strtolower($name)];
+ }
+
+ /**
+ * Formats a message according to the given styles.
+ *
+ * @param string $message The message to style
+ *
+ * @return string The styled message
+ *
+ * @api
+ */
+ public function format($message)
+ {
+ $offset = 0;
+ $output = '';
+ $tagRegex = '[a-z][a-z0-9_=;-]*';
+ preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#isx", $message, $matches, PREG_OFFSET_CAPTURE);
+ foreach ($matches[0] as $i => $match) {
+ $pos = $match[1];
+ $text = $match[0];
+
+ if (0 != $pos && '\\' == $message[$pos - 1]) {
+ continue;
+ }
+
+ // add the text up to the next tag
+ $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset));
+ $offset = $pos + strlen($text);
+
+ // opening tag?
+ if ($open = '/' != $text[1]) {
+ $tag = $matches[1][$i][0];
+ } else {
+ $tag = isset($matches[3][$i][0]) ? $matches[3][$i][0] : '';
+ }
+
+ if (!$open && !$tag) {
+ // </>
+ $this->styleStack->pop();
+ } elseif (false === $style = $this->createStyleFromString(strtolower($tag))) {
+ $output .= $this->applyCurrentStyle($text);
+ } elseif ($open) {
+ $this->styleStack->push($style);
+ } else {
+ $this->styleStack->pop($style);
+ }
+ }
+
+ $output .= $this->applyCurrentStyle(substr($message, $offset));
+
+ return str_replace('\\<', '<', $output);
+ }
+
+ /**
+ * @return OutputFormatterStyleStack
+ */
+ public function getStyleStack()
+ {
+ return $this->styleStack;
+ }
+
+ /**
+ * Tries to create new style instance from string.
+ *
+ * @param string $string
+ *
+ * @return OutputFormatterStyle|bool false if string is not format string
+ */
+ private function createStyleFromString($string)
+ {
+ if (isset($this->styles[$string])) {
+ return $this->styles[$string];
+ }
+
+ if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) {
+ return false;
+ }
+
+ $style = new OutputFormatterStyle();
+ foreach ($matches as $match) {
+ array_shift($match);
+
+ if ('fg' == $match[0]) {
+ $style->setForeground($match[1]);
+ } elseif ('bg' == $match[0]) {
+ $style->setBackground($match[1]);
+ } else {
+ try {
+ $style->setOption($match[1]);
+ } catch (\InvalidArgumentException $e) {
+ return false;
+ }
+ }
+ }
+
+ return $style;
+ }
+
+ /**
+ * Applies current style from stack to text, if must be applied.
+ *
+ * @param string $text Input text
+ *
+ * @return string Styled text
+ */
+ private function applyCurrentStyle($text)
+ {
+ return $this->isDecorated() && strlen($text) > 0 ? $this->styleStack->getCurrent()->apply($text) : $text;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterInterface.php b/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterInterface.php
new file mode 100644
index 0000000..52efa31
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterInterface.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter interface for console output.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @api
+ */
+interface OutputFormatterInterface
+{
+ /**
+ * Sets the decorated flag.
+ *
+ * @param bool $decorated Whether to decorate the messages or not
+ *
+ * @api
+ */
+ public function setDecorated($decorated);
+
+ /**
+ * Gets the decorated flag.
+ *
+ * @return bool true if the output will decorate messages, false otherwise
+ *
+ * @api
+ */
+ public function isDecorated();
+
+ /**
+ * Sets a new style.
+ *
+ * @param string $name The style name
+ * @param OutputFormatterStyleInterface $style The style instance
+ *
+ * @api
+ */
+ public function setStyle($name, OutputFormatterStyleInterface $style);
+
+ /**
+ * Checks if output formatter has style with specified name.
+ *
+ * @param string $name
+ *
+ * @return bool
+ *
+ * @api
+ */
+ public function hasStyle($name);
+
+ /**
+ * Gets style options from style with specified name.
+ *
+ * @param string $name
+ *
+ * @return OutputFormatterStyleInterface
+ *
+ * @api
+ */
+ public function getStyle($name);
+
+ /**
+ * Formats a message according to the given styles.
+ *
+ * @param string $message The message to style
+ *
+ * @return string The styled message
+ *
+ * @api
+ */
+ public function format($message);
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyle.php b/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyle.php
new file mode 100644
index 0000000..b3f274a
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyle.php
@@ -0,0 +1,227 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter style class for defining styles.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @api
+ */
+class OutputFormatterStyle implements OutputFormatterStyleInterface
+{
+ private static $availableForegroundColors = array(
+ 'black' => array('set' => 30, 'unset' => 39),
+ 'red' => array('set' => 31, 'unset' => 39),
+ 'green' => array('set' => 32, 'unset' => 39),
+ 'yellow' => array('set' => 33, 'unset' => 39),
+ 'blue' => array('set' => 34, 'unset' => 39),
+ 'magenta' => array('set' => 35, 'unset' => 39),
+ 'cyan' => array('set' => 36, 'unset' => 39),
+ 'white' => array('set' => 37, 'unset' => 39),
+ );
+ private static $availableBackgroundColors = array(
+ 'black' => array('set' => 40, 'unset' => 49),
+ 'red' => array('set' => 41, 'unset' => 49),
+ 'green' => array('set' => 42, 'unset' => 49),
+ 'yellow' => array('set' => 43, 'unset' => 49),
+ 'blue' => array('set' => 44, 'unset' => 49),
+ 'magenta' => array('set' => 45, 'unset' => 49),
+ 'cyan' => array('set' => 46, 'unset' => 49),
+ 'white' => array('set' => 47, 'unset' => 49),
+ );
+ private static $availableOptions = array(
+ 'bold' => array('set' => 1, 'unset' => 22),
+ 'underscore' => array('set' => 4, 'unset' => 24),
+ 'blink' => array('set' => 5, 'unset' => 25),
+ 'reverse' => array('set' => 7, 'unset' => 27),
+ 'conceal' => array('set' => 8, 'unset' => 28),
+ );
+
+ private $foreground;
+ private $background;
+ private $options = array();
+
+ /**
+ * Initializes output formatter style.
+ *
+ * @param string|null $foreground The style foreground color name
+ * @param string|null $background The style background color name
+ * @param array $options The style options
+ *
+ * @api
+ */
+ public function __construct($foreground = null, $background = null, array $options = array())
+ {
+ if (null !== $foreground) {
+ $this->setForeground($foreground);
+ }
+ if (null !== $background) {
+ $this->setBackground($background);
+ }
+ if (count($options)) {
+ $this->setOptions($options);
+ }
+ }
+
+ /**
+ * Sets style foreground color.
+ *
+ * @param string|null $color The color name
+ *
+ * @throws \InvalidArgumentException When the color name isn't defined
+ *
+ * @api
+ */
+ public function setForeground($color = null)
+ {
+ if (null === $color) {
+ $this->foreground = null;
+
+ return;
+ }
+
+ if (!isset(static::$availableForegroundColors[$color])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'Invalid foreground color specified: "%s". Expected one of (%s)',
+ $color,
+ implode(', ', array_keys(static::$availableForegroundColors))
+ ));
+ }
+
+ $this->foreground = static::$availableForegroundColors[$color];
+ }
+
+ /**
+ * Sets style background color.
+ *
+ * @param string|null $color The color name
+ *
+ * @throws \InvalidArgumentException When the color name isn't defined
+ *
+ * @api
+ */
+ public function setBackground($color = null)
+ {
+ if (null === $color) {
+ $this->background = null;
+
+ return;
+ }
+
+ if (!isset(static::$availableBackgroundColors[$color])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'Invalid background color specified: "%s". Expected one of (%s)',
+ $color,
+ implode(', ', array_keys(static::$availableBackgroundColors))
+ ));
+ }
+
+ $this->background = static::$availableBackgroundColors[$color];
+ }
+
+ /**
+ * Sets some specific style option.
+ *
+ * @param string $option The option name
+ *
+ * @throws \InvalidArgumentException When the option name isn't defined
+ *
+ * @api
+ */
+ public function setOption($option)
+ {
+ if (!isset(static::$availableOptions[$option])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'Invalid option specified: "%s". Expected one of (%s)',
+ $option,
+ implode(', ', array_keys(static::$availableOptions))
+ ));
+ }
+
+ if (!in_array(static::$availableOptions[$option], $this->options)) {
+ $this->options[] = static::$availableOptions[$option];
+ }
+ }
+
+ /**
+ * Unsets some specific style option.
+ *
+ * @param string $option The option name
+ *
+ * @throws \InvalidArgumentException When the option name isn't defined
+ */
+ public function unsetOption($option)
+ {
+ if (!isset(static::$availableOptions[$option])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'Invalid option specified: "%s". Expected one of (%s)',
+ $option,
+ implode(', ', array_keys(static::$availableOptions))
+ ));
+ }
+
+ $pos = array_search(static::$availableOptions[$option], $this->options);
+ if (false !== $pos) {
+ unset($this->options[$pos]);
+ }
+ }
+
+ /**
+ * Sets multiple style options at once.
+ *
+ * @param array $options
+ */
+ public function setOptions(array $options)
+ {
+ $this->options = array();
+
+ foreach ($options as $option) {
+ $this->setOption($option);
+ }
+ }
+
+ /**
+ * Applies the style to a given text.
+ *
+ * @param string $text The text to style
+ *
+ * @return string
+ */
+ public function apply($text)
+ {
+ $setCodes = array();
+ $unsetCodes = array();
+
+ if (null !== $this->foreground) {
+ $setCodes[] = $this->foreground['set'];
+ $unsetCodes[] = $this->foreground['unset'];
+ }
+ if (null !== $this->background) {
+ $setCodes[] = $this->background['set'];
+ $unsetCodes[] = $this->background['unset'];
+ }
+ if (count($this->options)) {
+ foreach ($this->options as $option) {
+ $setCodes[] = $option['set'];
+ $unsetCodes[] = $option['unset'];
+ }
+ }
+
+ if (0 === count($setCodes)) {
+ return $text;
+ }
+
+ return sprintf("\033[%sm%s\033[%sm", implode(';', $setCodes), $text, implode(';', $unsetCodes));
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php b/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php
new file mode 100644
index 0000000..e8642b3
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter style interface for defining styles.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * @api
+ */
+interface OutputFormatterStyleInterface
+{
+ /**
+ * Sets style foreground color.
+ *
+ * @param string $color The color name
+ *
+ * @api
+ */
+ public function setForeground($color = null);
+
+ /**
+ * Sets style background color.
+ *
+ * @param string $color The color name
+ *
+ * @api
+ */
+ public function setBackground($color = null);
+
+ /**
+ * Sets some specific style option.
+ *
+ * @param string $option The option name
+ *
+ * @api
+ */
+ public function setOption($option);
+
+ /**
+ * Unsets some specific style option.
+ *
+ * @param string $option The option name
+ */
+ public function unsetOption($option);
+
+ /**
+ * Sets multiple style options at once.
+ *
+ * @param array $options
+ */
+ public function setOptions(array $options);
+
+ /**
+ * Applies the style to a given text.
+ *
+ * @param string $text The text to style
+ *
+ * @return string
+ */
+ public function apply($text);
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php b/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php
new file mode 100644
index 0000000..b64c87f
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Formatter/OutputFormatterStyleStack.php
@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class OutputFormatterStyleStack
+{
+ /**
+ * @var OutputFormatterStyleInterface[]
+ */
+ private $styles;
+
+ /**
+ * @var OutputFormatterStyleInterface
+ */
+ private $emptyStyle;
+
+ /**
+ * Constructor.
+ *
+ * @param OutputFormatterStyleInterface|null $emptyStyle
+ */
+ public function __construct(OutputFormatterStyleInterface $emptyStyle = null)
+ {
+ $this->emptyStyle = $emptyStyle ?: new OutputFormatterStyle();
+ $this->reset();
+ }
+
+ /**
+ * Resets stack (ie. empty internal arrays).
+ */
+ public function reset()
+ {
+ $this->styles = array();
+ }
+
+ /**
+ * Pushes a style in the stack.
+ *
+ * @param OutputFormatterStyleInterface $style
+ */
+ public function push(OutputFormatterStyleInterface $style)
+ {
+ $this->styles[] = $style;
+ }
+
+ /**
+ * Pops a style from the stack.
+ *
+ * @param OutputFormatterStyleInterface|null $style
+ *
+ * @return OutputFormatterStyleInterface
+ *
+ * @throws \InvalidArgumentException When style tags incorrectly nested
+ */
+ public function pop(OutputFormatterStyleInterface $style = null)
+ {
+ if (empty($this->styles)) {
+ return $this->emptyStyle;
+ }
+
+ if (null === $style) {
+ return array_pop($this->styles);
+ }
+
+ foreach (array_reverse($this->styles, true) as $index => $stackedStyle) {
+ if ($style->apply('') === $stackedStyle->apply('')) {
+ $this->styles = array_slice($this->styles, 0, $index);
+
+ return $stackedStyle;
+ }
+ }
+
+ throw new \InvalidArgumentException('Incorrectly nested style tag found.');
+ }
+
+ /**
+ * Computes current style with stacks top codes.
+ *
+ * @return OutputFormatterStyle
+ */
+ public function getCurrent()
+ {
+ if (empty($this->styles)) {
+ return $this->emptyStyle;
+ }
+
+ return $this->styles[count($this->styles) - 1];
+ }
+
+ /**
+ * @param OutputFormatterStyleInterface $emptyStyle
+ *
+ * @return OutputFormatterStyleStack
+ */
+ public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle)
+ {
+ $this->emptyStyle = $emptyStyle;
+
+ return $this;
+ }
+
+ /**
+ * @return OutputFormatterStyleInterface
+ */
+ public function getEmptyStyle()
+ {
+ return $this->emptyStyle;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/DebugFormatterHelper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/DebugFormatterHelper.php
new file mode 100644
index 0000000..cdb620d
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/DebugFormatterHelper.php
@@ -0,0 +1,127 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+/**
+ * Helps outputting debug information when running an external program from a command.
+ *
+ * An external program can be a Process, an HTTP request, or anything else.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class DebugFormatterHelper extends Helper
+{
+ private $colors = array('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white');
+ private $started = array();
+ private $count = -1;
+
+ /**
+ * Starts a debug formatting session
+ *
+ * @param string $id The id of the formatting session
+ * @param string $message The message to display
+ * @param string $prefix The prefix to use
+ *
+ * @return string
+ */
+ public function start($id, $message, $prefix = 'RUN')
+ {
+ $this->started[$id] = array('border' => ++$this->count % count($this->colors));
+
+ return sprintf("%s<bg=blue;fg=white> %s </> <fg=blue>%s</>\n", $this->getBorder($id), $prefix, $message);
+ }
+
+ /**
+ * Adds progress to a formatting session
+ *
+ * @param string $id The id of the formatting session
+ * @param string $buffer The message to display
+ * @param bool $error Whether to consider the buffer as error
+ * @param string $prefix The prefix for output
+ * @param string $errorPrefix The prefix for error output
+ *
+ * @return string
+ */
+ public function progress($id, $buffer, $error = false, $prefix = 'OUT', $errorPrefix = 'ERR')
+ {
+ $message = '';
+
+ if ($error) {
+ if (isset($this->started[$id]['out'])) {
+ $message .= "\n";
+ unset($this->started[$id]['out']);
+ }
+ if (!isset($this->started[$id]['err'])) {
+ $message .= sprintf("%s<bg=red;fg=white> %s </> ", $this->getBorder($id), $errorPrefix);
+ $this->started[$id]['err'] = true;
+ }
+
+ $message .= str_replace("\n", sprintf("\n%s<bg=red;fg=white> %s </> ", $this->getBorder($id), $errorPrefix), $buffer);
+ } else {
+ if (isset($this->started[$id]['err'])) {
+ $message .= "\n";
+ unset($this->started[$id]['err']);
+ }
+ if (!isset($this->started[$id]['out'])) {
+ $message .= sprintf("%s<bg=green;fg=white> %s </> ", $this->getBorder($id), $prefix);
+ $this->started[$id]['out'] = true;
+ }
+
+ $message .= str_replace("\n", sprintf("\n%s<bg=green;fg=white> %s </> ", $this->getBorder($id), $prefix), $buffer);
+ }
+
+ return $message;
+ }
+
+ /**
+ * Stops a formatting session
+ *
+ * @param string $id The id of the formatting session
+ * @param string $message The message to display
+ * @param bool $successful Whether to consider the result as success
+ * @param string $prefix The prefix for the end output
+ *
+ * @return string
+ */
+ public function stop($id, $message, $successful, $prefix = 'RES')
+ {
+ $trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : '';
+
+ if ($successful) {
+ return sprintf("%s%s<bg=green;fg=white> %s </> <fg=green>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
+ }
+
+ $message = sprintf("%s%s<bg=red;fg=white> %s </> <fg=red>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
+
+ unset($this->started[$id]['out'], $this->started[$id]['err']);
+
+ return $message;
+ }
+
+ /**
+ * @param string $id The id of the formatting session
+ *
+ * @return string
+ */
+ private function getBorder($id)
+ {
+ return sprintf('<bg=%s> </>', $this->colors[$this->started[$id]['border']]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'debug_formatter';
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php
new file mode 100644
index 0000000..c324c99
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php
@@ -0,0 +1,96 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Descriptor\DescriptorInterface;
+use Symfony\Component\Console\Descriptor\JsonDescriptor;
+use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
+use Symfony\Component\Console\Descriptor\TextDescriptor;
+use Symfony\Component\Console\Descriptor\XmlDescriptor;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * This class adds helper method to describe objects in various formats.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class DescriptorHelper extends Helper
+{
+ /**
+ * @var DescriptorInterface[]
+ */
+ private $descriptors = array();
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ $this
+ ->register('txt', new TextDescriptor())
+ ->register('xml', new XmlDescriptor())
+ ->register('json', new JsonDescriptor())
+ ->register('md', new MarkdownDescriptor())
+ ;
+ }
+
+ /**
+ * Describes an object if supported.
+ *
+ * Available options are:
+ * * format: string, the output format name
+ * * raw_text: boolean, sets output type as raw
+ *
+ * @param OutputInterface $output
+ * @param object $object
+ * @param array $options
+ *
+ * @throws \InvalidArgumentException when the given format is not supported
+ */
+ public function describe(OutputInterface $output, $object, array $options = array())
+ {
+ $options = array_merge(array(
+ 'raw_text' => false,
+ 'format' => 'txt',
+ ), $options);
+
+ if (!isset($this->descriptors[$options['format']])) {
+ throw new \InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format']));
+ }
+
+ $descriptor = $this->descriptors[$options['format']];
+ $descriptor->describe($output, $object, $options);
+ }
+
+ /**
+ * Registers a descriptor.
+ *
+ * @param string $format
+ * @param DescriptorInterface $descriptor
+ *
+ * @return DescriptorHelper
+ */
+ public function register($format, DescriptorInterface $descriptor)
+ {
+ $this->descriptors[$format] = $descriptor;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'descriptor';
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/DialogHelper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/DialogHelper.php
new file mode 100644
index 0000000..c5f0aa7
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/DialogHelper.php
@@ -0,0 +1,476 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+
+/**
+ * The Dialog class provides helpers to interact with the user.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in 3.0.
+ * Use the question helper instead.
+ */
+class DialogHelper extends InputAwareHelper
+{
+ private $inputStream;
+ private static $shell;
+ private static $stty;
+
+ /**
+ * Asks the user to select a value.
+ *
+ * @param OutputInterface $output An Output instance
+ * @param string|array $question The question to ask
+ * @param array $choices List of choices to pick from
+ * @param bool|string $default The default answer if the user enters nothing
+ * @param bool|int $attempts Max number of times to ask before giving up (false by default, which means infinite)
+ * @param string $errorMessage Message which will be shown if invalid value from choice list would be picked
+ * @param bool $multiselect Select more than one value separated by comma
+ *
+ * @return int|string|array The selected value or values (the key of the choices array)
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function select(OutputInterface $output, $question, $choices, $default = null, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false)
+ {
+ $width = max(array_map('strlen', array_keys($choices)));
+
+ $messages = (array) $question;
+ foreach ($choices as $key => $value) {
+ $messages[] = sprintf(" [<info>%-${width}s</info>] %s", $key, $value);
+ }
+
+ $output->writeln($messages);
+
+ $result = $this->askAndValidate($output, '> ', function ($picked) use ($choices, $errorMessage, $multiselect) {
+ // Collapse all spaces.
+ $selectedChoices = str_replace(' ', '', $picked);
+
+ if ($multiselect) {
+ // Check for a separated comma values
+ if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
+ throw new \InvalidArgumentException(sprintf($errorMessage, $picked));
+ }
+ $selectedChoices = explode(',', $selectedChoices);
+ } else {
+ $selectedChoices = array($picked);
+ }
+
+ $multiselectChoices = array();
+
+ foreach ($selectedChoices as $value) {
+ if (empty($choices[$value])) {
+ throw new \InvalidArgumentException(sprintf($errorMessage, $value));
+ }
+ array_push($multiselectChoices, $value);
+ }
+
+ if ($multiselect) {
+ return $multiselectChoices;
+ }
+
+ return $picked;
+ }, $attempts, $default);
+
+ return $result;
+ }
+
+ /**
+ * Asks a question to the user.
+ *
+ * @param OutputInterface $output An Output instance
+ * @param string|array $question The question to ask
+ * @param string $default The default answer if none is given by the user
+ * @param array $autocomplete List of values to autocomplete
+ *
+ * @return string The user answer
+ *
+ * @throws \RuntimeException If there is no data to read in the input stream
+ */
+ public function ask(OutputInterface $output, $question, $default = null, array $autocomplete = null)
+ {
+ if ($this->input && !$this->input->isInteractive()) {
+ return $default;
+ }
+
+ $output->write($question);
+
+ $inputStream = $this->inputStream ?: STDIN;
+
+ if (null === $autocomplete || !$this->hasSttyAvailable()) {
+ $ret = fgets($inputStream, 4096);
+ if (false === $ret) {
+ throw new \RuntimeException('Aborted');
+ }
+ $ret = trim($ret);
+ } else {
+ $ret = '';
+
+ $i = 0;
+ $ofs = -1;
+ $matches = $autocomplete;
+ $numMatches = count($matches);
+
+ $sttyMode = shell_exec('stty -g');
+
+ // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead)
+ shell_exec('stty -icanon -echo');
+
+ // Add highlighted text style
+ $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));
+
+ // Read a keypress
+ while (!feof($inputStream)) {
+ $c = fread($inputStream, 1);
+
+ // Backspace Character
+ if ("\177" === $c) {
+ if (0 === $numMatches && 0 !== $i) {
+ $i--;
+ // Move cursor backwards
+ $output->write("\033[1D");
+ }
+
+ if ($i === 0) {
+ $ofs = -1;
+ $matches = $autocomplete;
+ $numMatches = count($matches);
+ } else {
+ $numMatches = 0;
+ }
+
+ // Pop the last character off the end of our string
+ $ret = substr($ret, 0, $i);
+ } elseif ("\033" === $c) {
+ // Did we read an escape sequence?
+ $c .= fread($inputStream, 2);
+
+ // A = Up Arrow. B = Down Arrow
+ if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
+ if ('A' === $c[2] && -1 === $ofs) {
+ $ofs = 0;
+ }
+
+ if (0 === $numMatches) {
+ continue;
+ }
+
+ $ofs += ('A' === $c[2]) ? -1 : 1;
+ $ofs = ($numMatches + $ofs) % $numMatches;
+ }
+ } elseif (ord($c) < 32) {
+ if ("\t" === $c || "\n" === $c) {
+ if ($numMatches > 0 && -1 !== $ofs) {
+ $ret = $matches[$ofs];
+ // Echo out remaining chars for current match
+ $output->write(substr($ret, $i));
+ $i = strlen($ret);
+ }
+
+ if ("\n" === $c) {
+ $output->write($c);
+ break;
+ }
+
+ $numMatches = 0;
+ }
+
+ continue;
+ } else {
+ $output->write($c);
+ $ret .= $c;
+ $i++;
+
+ $numMatches = 0;
+ $ofs = 0;
+
+ foreach ($autocomplete as $value) {
+ // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
+ if (0 === strpos($value, $ret) && $i !== strlen($value)) {
+ $matches[$numMatches++] = $value;
+ }
+ }
+ }
+
+ // Erase characters from cursor to end of line
+ $output->write("\033[K");
+
+ if ($numMatches > 0 && -1 !== $ofs) {
+ // Save cursor position
+ $output->write("\0337");
+ // Write highlighted text
+ $output->write('<hl>'.substr($matches[$ofs], $i).'</hl>');
+ // Restore cursor position
+ $output->write("\0338");
+ }
+ }
+
+ // Reset stty so it behaves normally again
+ shell_exec(sprintf('stty %s', $sttyMode));
+ }
+
+ return strlen($ret) > 0 ? $ret : $default;
+ }
+
+ /**
+ * Asks a confirmation to the user.
+ *
+ * The question will be asked until the user answers by nothing, yes, or no.
+ *
+ * @param OutputInterface $output An Output instance
+ * @param string|array $question The question to ask
+ * @param bool $default The default answer if the user enters nothing
+ *
+ * @return bool true if the user has confirmed, false otherwise
+ */
+ public function askConfirmation(OutputInterface $output, $question, $default = true)
+ {
+ $answer = 'z';
+ while ($answer && !in_array(strtolower($answer[0]), array('y', 'n'))) {
+ $answer = $this->ask($output, $question);
+ }
+
+ if (false === $default) {
+ return $answer && 'y' == strtolower($answer[0]);
+ }
+
+ return !$answer || 'y' == strtolower($answer[0]);
+ }
+
+ /**
+ * Asks a question to the user, the response is hidden.
+ *
+ * @param OutputInterface $output An Output instance
+ * @param string|array $question The question
+ * @param bool $fallback In case the response can not be hidden, whether to fallback on non-hidden question or not
+ *
+ * @return string The answer
+ *
+ * @throws \RuntimeException In case the fallback is deactivated and the response can not be hidden
+ */
+ public function askHiddenResponse(OutputInterface $output, $question, $fallback = true)
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $exe = __DIR__.'/../Resources/bin/hiddeninput.exe';
+
+ // handle code running from a phar
+ if ('phar:' === substr(__FILE__, 0, 5)) {
+ $tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
+ copy($exe, $tmpExe);
+ $exe = $tmpExe;
+ }
+
+ $output->write($question);
+ $value = rtrim(shell_exec($exe));
+ $output->writeln('');
+
+ if (isset($tmpExe)) {
+ unlink($tmpExe);
+ }
+
+ return $value;
+ }
+
+ if ($this->hasSttyAvailable()) {
+ $output->write($question);
+
+ $sttyMode = shell_exec('stty -g');
+
+ shell_exec('stty -echo');
+ $value = fgets($this->inputStream ?: STDIN, 4096);
+ shell_exec(sprintf('stty %s', $sttyMode));
+
+ if (false === $value) {
+ throw new \RuntimeException('Aborted');
+ }
+
+ $value = trim($value);
+ $output->writeln('');
+
+ return $value;
+ }
+
+ if (false !== $shell = $this->getShell()) {
+ $output->write($question);
+ $readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword';
+ $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
+ $value = rtrim(shell_exec($command));
+ $output->writeln('');
+
+ return $value;
+ }
+
+ if ($fallback) {
+ return $this->ask($output, $question);
+ }
+
+ throw new \RuntimeException('Unable to hide the response');
+ }
+
+ /**
+ * Asks for a value and validates the response.
+ *
+ * The validator receives the data to validate. It must return the
+ * validated data when the data is valid and throw an exception
+ * otherwise.
+ *
+ * @param OutputInterface $output An Output instance
+ * @param string|array $question The question to ask
+ * @param callable $validator A PHP callback
+ * @param int|false $attempts Max number of times to ask before giving up (false by default, which means infinite)
+ * @param string $default The default answer if none is given by the user
+ * @param array $autocomplete List of values to autocomplete
+ *
+ * @return mixed
+ *
+ * @throws \Exception When any of the validators return an error
+ */
+ public function askAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $default = null, array $autocomplete = null)
+ {
+ $that = $this;
+
+ $interviewer = function () use ($output, $question, $default, $autocomplete, $that) {
+ return $that->ask($output, $question, $default, $autocomplete);
+ };
+
+ return $this->validateAttempts($interviewer, $output, $validator, $attempts);
+ }
+
+ /**
+ * Asks for a value, hide and validates the response.
+ *
+ * The validator receives the data to validate. It must return the
+ * validated data when the data is valid and throw an exception
+ * otherwise.
+ *
+ * @param OutputInterface $output An Output instance
+ * @param string|array $question The question to ask
+ * @param callable $validator A PHP callback
+ * @param int|false $attempts Max number of times to ask before giving up (false by default, which means infinite)
+ * @param bool $fallback In case the response can not be hidden, whether to fallback on non-hidden question or not
+ *
+ * @return string The response
+ *
+ * @throws \Exception When any of the validators return an error
+ * @throws \RuntimeException In case the fallback is deactivated and the response can not be hidden
+ */
+ public function askHiddenResponseAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $fallback = true)
+ {
+ $that = $this;
+
+ $interviewer = function () use ($output, $question, $fallback, $that) {
+ return $that->askHiddenResponse($output, $question, $fallback);
+ };
+
+ return $this->validateAttempts($interviewer, $output, $validator, $attempts);
+ }
+
+ /**
+ * Sets the input stream to read from when interacting with the user.
+ *
+ * This is mainly useful for testing purpose.
+ *
+ * @param resource $stream The input stream
+ */
+ public function setInputStream($stream)
+ {
+ $this->inputStream = $stream;
+ }
+
+ /**
+ * Returns the helper's input stream.
+ *
+ * @return string
+ */
+ public function getInputStream()
+ {
+ return $this->inputStream;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'dialog';
+ }
+
+ /**
+ * Return a valid Unix shell.
+ *
+ * @return string|bool The valid shell name, false in case no valid shell is found
+ */
+ private function getShell()
+ {
+ if (null !== self::$shell) {
+ return self::$shell;
+ }
+
+ self::$shell = false;
+
+ if (file_exists('/usr/bin/env')) {
+ // handle other OSs with bash/zsh/ksh/csh if available to hide the answer
+ $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
+ foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) {
+ if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
+ self::$shell = $sh;
+ break;
+ }
+ }
+ }
+
+ return self::$shell;
+ }
+
+ private function hasSttyAvailable()
+ {
+ if (null !== self::$stty) {
+ return self::$stty;
+ }
+
+ exec('stty 2>&1', $output, $exitcode);
+
+ return self::$stty = $exitcode === 0;
+ }
+
+ /**
+ * Validate an attempt.
+ *
+ * @param callable $interviewer A callable that will ask for a question and return the result
+ * @param OutputInterface $output An Output instance
+ * @param callable $validator A PHP callback
+ * @param int|false $attempts Max number of times to ask before giving up ; false will ask infinitely
+ *
+ * @return string The validated response
+ *
+ * @throws \Exception In case the max number of attempts has been reached and no valid response has been given
+ */
+ private function validateAttempts($interviewer, OutputInterface $output, $validator, $attempts)
+ {
+ $error = null;
+ while (false === $attempts || $attempts--) {
+ if (null !== $error) {
+ $output->writeln($this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error'));
+ }
+
+ try {
+ return call_user_func($validator, $interviewer());
+ } catch (\Exception $error) {
+ }
+ }
+
+ throw $error;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/FormatterHelper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/FormatterHelper.php
new file mode 100644
index 0000000..ac736f9
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/FormatterHelper.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Formatter\OutputFormatter;
+
+/**
+ * The Formatter class provides helpers to format messages.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class FormatterHelper extends Helper
+{
+ /**
+ * Formats a message within a section.
+ *
+ * @param string $section The section name
+ * @param string $message The message
+ * @param string $style The style to apply to the section
+ *
+ * @return string The format section
+ */
+ public function formatSection($section, $message, $style = 'info')
+ {
+ return sprintf('<%s>[%s]</%s> %s', $style, $section, $style, $message);
+ }
+
+ /**
+ * Formats a message as a block of text.
+ *
+ * @param string|array $messages The message to write in the block
+ * @param string $style The style to apply to the whole block
+ * @param bool $large Whether to return a large block
+ *
+ * @return string The formatter message
+ */
+ public function formatBlock($messages, $style, $large = false)
+ {
+ if (!is_array($messages)) {
+ $messages = array($messages);
+ }
+
+ $len = 0;
+ $lines = array();
+ foreach ($messages as $message) {
+ $message = OutputFormatter::escape($message);
+ $lines[] = sprintf($large ? ' %s ' : ' %s ', $message);
+ $len = max($this->strlen($message) + ($large ? 4 : 2), $len);
+ }
+
+ $messages = $large ? array(str_repeat(' ', $len)) : array();
+ for ($i = 0; isset($lines[$i]); ++$i) {
+ $messages[] = $lines[$i].str_repeat(' ', $len - $this->strlen($lines[$i]));
+ }
+ if ($large) {
+ $messages[] = str_repeat(' ', $len);
+ }
+
+ for ($i = 0; isset($messages[$i]); ++$i) {
+ $messages[$i] = sprintf('<%s>%s</%s>', $style, $messages[$i], $style);
+ }
+
+ return implode("\n", $messages);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'formatter';
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/Helper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/Helper.php
new file mode 100644
index 0000000..b288d44
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/Helper.php
@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * Helper is the base class for all helper classes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class Helper implements HelperInterface
+{
+ protected $helperSet = null;
+
+ /**
+ * Sets the helper set associated with this helper.
+ *
+ * @param HelperSet $helperSet A HelperSet instance
+ */
+ public function setHelperSet(HelperSet $helperSet = null)
+ {
+ $this->helperSet = $helperSet;
+ }
+
+ /**
+ * Gets the helper set associated with this helper.
+ *
+ * @return HelperSet A HelperSet instance
+ */
+ public function getHelperSet()
+ {
+ return $this->helperSet;
+ }
+
+ /**
+ * Returns the length of a string, using mb_strwidth if it is available.
+ *
+ * @param string $string The string to check its length
+ *
+ * @return int The length of the string
+ */
+ public static function strlen($string)
+ {
+ if (!function_exists('mb_strwidth')) {
+ return strlen($string);
+ }
+
+ if (false === $encoding = mb_detect_encoding($string)) {
+ return strlen($string);
+ }
+
+ return mb_strwidth($string, $encoding);
+ }
+
+ public static function formatTime($secs)
+ {
+ static $timeFormats = array(
+ array(0, '< 1 sec'),
+ array(2, '1 sec'),
+ array(59, 'secs', 1),
+ array(60, '1 min'),
+ array(3600, 'mins', 60),
+ array(5400, '1 hr'),
+ array(86400, 'hrs', 3600),
+ array(129600, '1 day'),
+ array(604800, 'days', 86400),
+ );
+
+ foreach ($timeFormats as $format) {
+ if ($secs >= $format[0]) {
+ continue;
+ }
+
+ if (2 == count($format)) {
+ return $format[1];
+ }
+
+ return ceil($secs / $format[2]).' '.$format[1];
+ }
+ }
+
+ public static function formatMemory($memory)
+ {
+ if ($memory >= 1024 * 1024 * 1024) {
+ return sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024);
+ }
+
+ if ($memory >= 1024 * 1024) {
+ return sprintf('%.1f MiB', $memory / 1024 / 1024);
+ }
+
+ if ($memory >= 1024) {
+ return sprintf('%d KiB', $memory / 1024);
+ }
+
+ return sprintf('%d B', $memory);
+ }
+
+ public static function strlenWithoutDecoration(OutputFormatterInterface $formatter, $string)
+ {
+ $isDecorated = $formatter->isDecorated();
+ $formatter->setDecorated(false);
+ // remove <...> formatting
+ $string = $formatter->format($string);
+ // remove already formatted characters
+ $string = preg_replace("/\033\[[^m]*m/", '', $string);
+ $formatter->setDecorated($isDecorated);
+
+ return self::strlen($string);
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/HelperInterface.php b/vendor/symfony/console/Symfony/Component/Console/Helper/HelperInterface.php
new file mode 100644
index 0000000..6d39449
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/HelperInterface.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+/**
+ * HelperInterface is the interface all helpers must implement.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface HelperInterface
+{
+ /**
+ * Sets the helper set associated with this helper.
+ *
+ * @param HelperSet $helperSet A HelperSet instance
+ *
+ * @api
+ */
+ public function setHelperSet(HelperSet $helperSet = null);
+
+ /**
+ * Gets the helper set associated with this helper.
+ *
+ * @return HelperSet A HelperSet instance
+ *
+ * @api
+ */
+ public function getHelperSet();
+
+ /**
+ * Returns the canonical name of this helper.
+ *
+ * @return string The canonical name
+ *
+ * @api
+ */
+ public function getName();
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/HelperSet.php b/vendor/symfony/console/Symfony/Component/Console/Helper/HelperSet.php
new file mode 100644
index 0000000..467be86
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/HelperSet.php
@@ -0,0 +1,108 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Command\Command;
+
+/**
+ * HelperSet represents a set of helpers to be used with a command.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class HelperSet implements \IteratorAggregate
+{
+ private $helpers = array();
+ private $command;
+
+ /**
+ * Constructor.
+ *
+ * @param Helper[] $helpers An array of helper.
+ */
+ public function __construct(array $helpers = array())
+ {
+ foreach ($helpers as $alias => $helper) {
+ $this->set($helper, is_int($alias) ? null : $alias);
+ }
+ }
+
+ /**
+ * Sets a helper.
+ *
+ * @param HelperInterface $helper The helper instance
+ * @param string $alias An alias
+ */
+ public function set(HelperInterface $helper, $alias = null)
+ {
+ $this->helpers[$helper->getName()] = $helper;
+ if (null !== $alias) {
+ $this->helpers[$alias] = $helper;
+ }
+
+ $helper->setHelperSet($this);
+ }
+
+ /**
+ * Returns true if the helper if defined.
+ *
+ * @param string $name The helper name
+ *
+ * @return bool true if the helper is defined, false otherwise
+ */
+ public function has($name)
+ {
+ return isset($this->helpers[$name]);
+ }
+
+ /**
+ * Gets a helper value.
+ *
+ * @param string $name The helper name
+ *
+ * @return HelperInterface The helper instance
+ *
+ * @throws \InvalidArgumentException if the helper is not defined
+ */
+ public function get($name)
+ {
+ if (!$this->has($name)) {
+ throw new \InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
+ }
+
+ return $this->helpers[$name];
+ }
+
+ /**
+ * Sets the command associated with this helper set.
+ *
+ * @param Command $command A Command instance
+ */
+ public function setCommand(Command $command = null)
+ {
+ $this->command = $command;
+ }
+
+ /**
+ * Gets the command associated with this helper set.
+ *
+ * @return Command A Command instance
+ */
+ public function getCommand()
+ {
+ return $this->command;
+ }
+
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->helpers);
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/InputAwareHelper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/InputAwareHelper.php
new file mode 100644
index 0000000..4261767
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/InputAwareHelper.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputAwareInterface;
+
+/**
+ * An implementation of InputAwareInterface for Helpers.
+ *
+ * @author Wouter J <waldio.webdesign@gmail.com>
+ */
+abstract class InputAwareHelper extends Helper implements InputAwareInterface
+{
+ protected $input;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setInput(InputInterface $input)
+ {
+ $this->input = $input;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/ProcessHelper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/ProcessHelper.php
new file mode 100644
index 0000000..0c9da73
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/ProcessHelper.php
@@ -0,0 +1,142 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Process\Exception\ProcessFailedException;
+use Symfony\Component\Process\Process;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * The ProcessHelper class provides helpers to run external processes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ProcessHelper extends Helper
+{
+ /**
+ * Runs an external process.
+ *
+ * @param OutputInterface $output An OutputInterface instance
+ * @param string|array|Process $cmd An instance of Process or an array of arguments to escape and run or a command to run
+ * @param string|null $error An error message that must be displayed if something went wrong
+ * @param callable|null $callback A PHP callback to run whenever there is some
+ * output available on STDOUT or STDERR
+ * @param int $verbosity The threshold for verbosity
+ *
+ * @return Process The process that ran
+ */
+ public function run(OutputInterface $output, $cmd, $error = null, $callback = null, $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE)
+ {
+ $formatter = $this->getHelperSet()->get('debug_formatter');
+
+ if (is_array($cmd)) {
+ $process = ProcessBuilder::create($cmd)->getProcess();
+ } elseif ($cmd instanceof Process) {
+ $process = $cmd;
+ } else {
+ $process = new Process($cmd);
+ }
+
+ if ($verbosity <= $output->getVerbosity()) {
+ $output->write($formatter->start(spl_object_hash($process), $this->escapeString($process->getCommandLine())));
+ }
+
+ if ($output->isDebug()) {
+ $callback = $this->wrapCallback($output, $process, $callback);
+ }
+
+ $process->run($callback);
+
+ if ($verbosity <= $output->getVerbosity()) {
+ $message = $process->isSuccessful() ? 'Command ran successfully' : sprintf('%s Command did not run successfully', $process->getExitCode());
+ $output->write($formatter->stop(spl_object_hash($process), $message, $process->isSuccessful()));
+ }
+
+ if (!$process->isSuccessful() && null !== $error) {
+ $output->writeln(sprintf('<error>%s</error>', $this->escapeString($error)));
+ }
+
+ return $process;
+ }
+
+ /**
+ * Runs the process.
+ *
+ * This is identical to run() except that an exception is thrown if the process
+ * exits with a non-zero exit code.
+ *
+ * @param OutputInterface $output An OutputInterface instance
+ * @param string|Process $cmd An instance of Process or a command to run
+ * @param string|null $error An error message that must be displayed if something went wrong
+ * @param callable|null $callback A PHP callback to run whenever there is some
+ * output available on STDOUT or STDERR
+ *
+ * @return Process The process that ran
+ *
+ * @throws ProcessFailedException
+ *
+ * @see run()
+ */
+ public function mustRun(OutputInterface $output, $cmd, $error = null, $callback = null)
+ {
+ $process = $this->run($output, $cmd, $error, $callback);
+
+ if (!$process->isSuccessful()) {
+ throw new ProcessFailedException($process);
+ }
+
+ return $process;
+ }
+
+ /**
+ * Wraps a Process callback to add debugging output.
+ *
+ * @param OutputInterface $output An OutputInterface interface
+ * @param Process $process The Process
+ * @param callable|null $callback A PHP callable
+ *
+ * @return callable
+ */
+ public function wrapCallback(OutputInterface $output, Process $process, $callback = null)
+ {
+ $formatter = $this->getHelperSet()->get('debug_formatter');
+
+ $that = $this;
+
+ return function ($type, $buffer) use ($output, $process, $callback, $formatter, $that) {
+ $output->write($formatter->progress(spl_object_hash($process), $that->escapeString($buffer), Process::ERR === $type));
+
+ if (null !== $callback) {
+ call_user_func($callback, $type, $buffer);
+ }
+ };
+ }
+
+ /**
+ * This method is public for PHP 5.3 compatibility, it should be private.
+ *
+ * @internal
+ */
+ public function escapeString($str)
+ {
+ return str_replace('<', '\\<', $str);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'process';
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/ProgressBar.php b/vendor/symfony/console/Symfony/Component/Console/Helper/ProgressBar.php
new file mode 100644
index 0000000..893664e
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/ProgressBar.php
@@ -0,0 +1,611 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * The ProgressBar provides helpers to display progress output.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Chris Jones <leeked@gmail.com>
+ */
+class ProgressBar
+{
+ // options
+ private $barWidth = 28;
+ private $barChar;
+ private $emptyBarChar = '-';
+ private $progressChar = '>';
+ private $format = null;
+ private $redrawFreq = 1;
+
+ /**
+ * @var OutputInterface
+ */
+ private $output;
+ private $step = 0;
+ private $max;
+ private $startTime;
+ private $stepWidth;
+ private $percent = 0.0;
+ private $lastMessagesLength = 0;
+ private $formatLineCount;
+ private $messages;
+ private $overwrite = true;
+
+ private static $formatters;
+ private static $formats;
+
+ /**
+ * Constructor.
+ *
+ * @param OutputInterface $output An OutputInterface instance
+ * @param int $max Maximum steps (0 if unknown)
+ */
+ public function __construct(OutputInterface $output, $max = 0)
+ {
+ $this->output = $output;
+ $this->setMaxSteps($max);
+
+ if (!$this->output->isDecorated()) {
+ // disable overwrite when output does not support ANSI codes.
+ $this->overwrite = false;
+
+ if ($this->max > 10) {
+ // set a reasonable redraw frequency so output isn't flooded
+ $this->setRedrawFrequency($max / 10);
+ }
+ }
+
+ $this->setFormat($this->determineBestFormat());
+
+ $this->startTime = time();
+ }
+
+ /**
+ * Sets a placeholder formatter for a given name.
+ *
+ * This method also allow you to override an existing placeholder.
+ *
+ * @param string $name The placeholder name (including the delimiter char like %)
+ * @param callable $callable A PHP callable
+ */
+ public static function setPlaceholderFormatterDefinition($name, $callable)
+ {
+ if (!self::$formatters) {
+ self::$formatters = self::initPlaceholderFormatters();
+ }
+
+ self::$formatters[$name] = $callable;
+ }
+
+ /**
+ * Gets the placeholder formatter for a given name.
+ *
+ * @param string $name The placeholder name (including the delimiter char like %)
+ *
+ * @return callable|null A PHP callable
+ */
+ public static function getPlaceholderFormatterDefinition($name)
+ {
+ if (!self::$formatters) {
+ self::$formatters = self::initPlaceholderFormatters();
+ }
+
+ return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
+ }
+
+ /**
+ * Sets a format for a given name.
+ *
+ * This method also allow you to override an existing format.
+ *
+ * @param string $name The format name
+ * @param string $format A format string
+ */
+ public static function setFormatDefinition($name, $format)
+ {
+ if (!self::$formats) {
+ self::$formats = self::initFormats();
+ }
+
+ self::$formats[$name] = $format;
+ }
+
+ /**
+ * Gets the format for a given name.
+ *
+ * @param string $name The format name
+ *
+ * @return string|null A format string
+ */
+ public static function getFormatDefinition($name)
+ {
+ if (!self::$formats) {
+ self::$formats = self::initFormats();
+ }
+
+ return isset(self::$formats[$name]) ? self::$formats[$name] : null;
+ }
+
+ public function setMessage($message, $name = 'message')
+ {
+ $this->messages[$name] = $message;
+ }
+
+ public function getMessage($name = 'message')
+ {
+ return $this->messages[$name];
+ }
+
+ /**
+ * Gets the progress bar start time.
+ *
+ * @return int The progress bar start time
+ */
+ public function getStartTime()
+ {
+ return $this->startTime;
+ }
+
+ /**
+ * Gets the progress bar maximal steps.
+ *
+ * @return int The progress bar max steps
+ */
+ public function getMaxSteps()
+ {
+ return $this->max;
+ }
+
+ /**
+ * Gets the progress bar step.
+ *
+ * @deprecated since 2.6, to be removed in 3.0. Use {@link getProgress()} instead.
+ *
+ * @return int The progress bar step
+ */
+ public function getStep()
+ {
+ return $this->getProgress();
+ }
+
+ /**
+ * Gets the current step position.
+ *
+ * @return int The progress bar step
+ */
+ public function getProgress()
+ {
+ return $this->step;
+ }
+
+ /**
+ * Gets the progress bar step width.
+ *
+ * @internal This method is public for PHP 5.3 compatibility, it should not be used.
+ *
+ * @return int The progress bar step width
+ */
+ public function getStepWidth()
+ {
+ return $this->stepWidth;
+ }
+
+ /**
+ * Gets the current progress bar percent.
+ *
+ * @return float The current progress bar percent
+ */
+ public function getProgressPercent()
+ {
+ return $this->percent;
+ }
+
+ /**
+ * Sets the progress bar width.
+ *
+ * @param int $size The progress bar size
+ */
+ public function setBarWidth($size)
+ {
+ $this->barWidth = (int) $size;
+ }
+
+ /**
+ * Gets the progress bar width.
+ *
+ * @return int The progress bar size
+ */
+ public function getBarWidth()
+ {
+ return $this->barWidth;
+ }
+
+ /**
+ * Sets the bar character.
+ *
+ * @param string $char A character
+ */
+ public function setBarCharacter($char)
+ {
+ $this->barChar = $char;
+ }
+
+ /**
+ * Gets the bar character.
+ *
+ * @return string A character
+ */
+ public function getBarCharacter()
+ {
+ if (null === $this->barChar) {
+ return $this->max ? '=' : $this->emptyBarChar;
+ }
+
+ return $this->barChar;
+ }
+
+ /**
+ * Sets the empty bar character.
+ *
+ * @param string $char A character
+ */
+ public function setEmptyBarCharacter($char)
+ {
+ $this->emptyBarChar = $char;
+ }
+
+ /**
+ * Gets the empty bar character.
+ *
+ * @return string A character
+ */
+ public function getEmptyBarCharacter()
+ {
+ return $this->emptyBarChar;
+ }
+
+ /**
+ * Sets the progress bar character.
+ *
+ * @param string $char A character
+ */
+ public function setProgressCharacter($char)
+ {
+ $this->progressChar = $char;
+ }
+
+ /**
+ * Gets the progress bar character.
+ *
+ * @return string A character
+ */
+ public function getProgressCharacter()
+ {
+ return $this->progressChar;
+ }
+
+ /**
+ * Sets the progress bar format.
+ *
+ * @param string $format The format
+ */
+ public function setFormat($format)
+ {
+ // try to use the _nomax variant if available
+ if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
+ $this->format = self::getFormatDefinition($format.'_nomax');
+ } elseif (null !== self::getFormatDefinition($format)) {
+ $this->format = self::getFormatDefinition($format);
+ } else {
+ $this->format = $format;
+ }
+
+ $this->formatLineCount = substr_count($this->format, "\n");
+ }
+
+ /**
+ * Sets the redraw frequency.
+ *
+ * @param int $freq The frequency in steps
+ */
+ public function setRedrawFrequency($freq)
+ {
+ $this->redrawFreq = (int) $freq;
+ }
+
+ /**
+ * Starts the progress output.
+ *
+ * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
+ */
+ public function start($max = null)
+ {
+ $this->startTime = time();
+ $this->step = 0;
+ $this->percent = 0.0;
+
+ if (null !== $max) {
+ $this->setMaxSteps($max);
+ }
+
+ $this->display();
+ }
+
+ /**
+ * Advances the progress output X steps.
+ *
+ * @param int $step Number of steps to advance
+ *
+ * @throws \LogicException
+ */
+ public function advance($step = 1)
+ {
+ $this->setProgress($this->step + $step);
+ }
+
+ /**
+ * Sets the current progress.
+ *
+ * @deprecated since 2.6, to be removed in 3.0. Use {@link setProgress()} instead.
+ *
+ * @param int $step The current progress
+ *
+ * @throws \LogicException
+ */
+ public function setCurrent($step)
+ {
+ $this->setProgress($step);
+ }
+
+ /**
+ * Sets whether to overwrite the progressbar, false for new line
+ *
+ * @param bool $overwrite
+ */
+ public function setOverwrite($overwrite)
+ {
+ $this->overwrite = (bool) $overwrite;
+ }
+
+ /**
+ * Sets the current progress.
+ *
+ * @param int $step The current progress
+ *
+ * @throws \LogicException
+ */
+ public function setProgress($step)
+ {
+ $step = (int) $step;
+ if ($step < $this->step) {
+ throw new \LogicException('You can\'t regress the progress bar.');
+ }
+
+ if ($this->max && $step > $this->max) {
+ $this->max = $step;
+ }
+
+ $prevPeriod = intval($this->step / $this->redrawFreq);
+ $currPeriod = intval($step / $this->redrawFreq);
+ $this->step = $step;
+ $this->percent = $this->max ? (float) $this->step / $this->max : 0;
+ if ($prevPeriod !== $currPeriod || $this->max === $step) {
+ $this->display();
+ }
+ }
+
+ /**
+ * Finishes the progress output.
+ */
+ public function finish()
+ {
+ if (!$this->max) {
+ $this->max = $this->step;
+ }
+
+ if ($this->step === $this->max && !$this->overwrite) {
+ // prevent double 100% output
+ return;
+ }
+
+ $this->setProgress($this->max);
+ }
+
+ /**
+ * Outputs the current progress string.
+ */
+ public function display()
+ {
+ if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
+ return;
+ }
+
+ // these 3 variables can be removed in favor of using $this in the closure when support for PHP 5.3 will be dropped.
+ $self = $this;
+ $output = $this->output;
+ $messages = $this->messages;
+ $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self, $output, $messages) {
+ if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
+ $text = call_user_func($formatter, $self, $output);
+ } elseif (isset($messages[$matches[1]])) {
+ $text = $messages[$matches[1]];
+ } else {
+ return $matches[0];
+ }
+
+ if (isset($matches[2])) {
+ $text = sprintf('%'.$matches[2], $text);
+ }
+
+ return $text;
+ }, $this->format));
+ }
+
+ /**
+ * Removes the progress bar from the current line.
+ *
+ * This is useful if you wish to write some output
+ * while a progress bar is running.
+ * Call display() to show the progress bar again.
+ */
+ public function clear()
+ {
+ if (!$this->overwrite) {
+ return;
+ }
+
+ $this->overwrite(str_repeat("\n", $this->formatLineCount));
+ }
+
+ /**
+ * Sets the progress bar maximal steps.
+ *
+ * @param int The progress bar max steps
+ */
+ private function setMaxSteps($max)
+ {
+ $this->max = max(0, (int) $max);
+ $this->stepWidth = $this->max ? Helper::strlen($this->max) : 4;
+ }
+
+ /**
+ * Overwrites a previous message to the output.
+ *
+ * @param string $message The message
+ */
+ private function overwrite($message)
+ {
+ $lines = explode("\n", $message);
+
+ // append whitespace to match the line's length
+ if (null !== $this->lastMessagesLength) {
+ foreach ($lines as $i => $line) {
+ if ($this->lastMessagesLength > Helper::strlenWithoutDecoration($this->output->getFormatter(), $line)) {
+ $lines[$i] = str_pad($line, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
+ }
+ }
+ }
+
+ if ($this->overwrite) {
+ // move back to the beginning of the progress bar before redrawing it
+ $this->output->write("\x0D");
+ } elseif ($this->step > 0) {
+ // move to new line
+ $this->output->writeln('');
+ }
+
+ if ($this->formatLineCount) {
+ $this->output->write(sprintf("\033[%dA", $this->formatLineCount));
+ }
+ $this->output->write(implode("\n", $lines));
+
+ $this->lastMessagesLength = 0;
+ foreach ($lines as $line) {
+ $len = Helper::strlenWithoutDecoration($this->output->getFormatter(), $line);
+ if ($len > $this->lastMessagesLength) {
+ $this->lastMessagesLength = $len;
+ }
+ }
+ }
+
+ private function determineBestFormat()
+ {
+ switch ($this->output->getVerbosity()) {
+ // OutputInterface::VERBOSITY_QUIET: display is disabled anyway
+ case OutputInterface::VERBOSITY_VERBOSE:
+ return $this->max ? 'verbose' : 'verbose_nomax';
+ case OutputInterface::VERBOSITY_VERY_VERBOSE:
+ return $this->max ? 'very_verbose' : 'very_verbose_nomax';
+ case OutputInterface::VERBOSITY_DEBUG:
+ return $this->max ? 'debug' : 'debug_nomax';
+ default:
+ return $this->max ? 'normal' : 'normal_nomax';
+ }
+ }
+
+ private static function initPlaceholderFormatters()
+ {
+ return array(
+ 'bar' => function (ProgressBar $bar, OutputInterface $output) {
+ $completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getProgress() % $bar->getBarWidth());
+ $display = str_repeat($bar->getBarCharacter(), $completeBars);
+ if ($completeBars < $bar->getBarWidth()) {
+ $emptyBars = $bar->getBarWidth() - $completeBars - Helper::strlenWithoutDecoration($output->getFormatter(), $bar->getProgressCharacter());
+ $display .= $bar->getProgressCharacter().str_repeat($bar->getEmptyBarCharacter(), $emptyBars);
+ }
+
+ return $display;
+ },
+ 'elapsed' => function (ProgressBar $bar) {
+ return Helper::formatTime(time() - $bar->getStartTime());
+ },
+ 'remaining' => function (ProgressBar $bar) {
+ if (!$bar->getMaxSteps()) {
+ throw new \LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
+ }
+
+ if (!$bar->getProgress()) {
+ $remaining = 0;
+ } else {
+ $remaining = round((time() - $bar->getStartTime()) / $bar->getProgress() * ($bar->getMaxSteps() - $bar->getProgress()));
+ }
+
+ return Helper::formatTime($remaining);
+ },
+ 'estimated' => function (ProgressBar $bar) {
+ if (!$bar->getMaxSteps()) {
+ throw new \LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
+ }
+
+ if (!$bar->getProgress()) {
+ $estimated = 0;
+ } else {
+ $estimated = round((time() - $bar->getStartTime()) / $bar->getProgress() * $bar->getMaxSteps());
+ }
+
+ return Helper::formatTime($estimated);
+ },
+ 'memory' => function (ProgressBar $bar) {
+ return Helper::formatMemory(memory_get_usage(true));
+ },
+ 'current' => function (ProgressBar $bar) {
+ return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', STR_PAD_LEFT);
+ },
+ 'max' => function (ProgressBar $bar) {
+ return $bar->getMaxSteps();
+ },
+ 'percent' => function (ProgressBar $bar) {
+ return floor($bar->getProgressPercent() * 100);
+ },
+ );
+ }
+
+ private static function initFormats()
+ {
+ return array(
+ 'normal' => ' %current%/%max% [%bar%] %percent:3s%%',
+ 'normal_nomax' => ' %current% [%bar%]',
+
+ 'verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%',
+ 'verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
+
+ 'very_verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%',
+ 'very_verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
+
+ 'debug' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%',
+ 'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%',
+ );
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/ProgressHelper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/ProgressHelper.php
new file mode 100644
index 0000000..b82486d
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/ProgressHelper.php
@@ -0,0 +1,457 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Output\NullOutput;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * The Progress class provides helpers to display progress output.
+ *
+ * @author Chris Jones <leeked@gmail.com>
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @deprecated Deprecated since 2.5, to be removed in 3.0; use ProgressBar instead.
+ */
+class ProgressHelper extends Helper
+{
+ const FORMAT_QUIET = ' %percent%%';
+ const FORMAT_NORMAL = ' %current%/%max% [%bar%] %percent%%';
+ const FORMAT_VERBOSE = ' %current%/%max% [%bar%] %percent%% Elapsed: %elapsed%';
+ const FORMAT_QUIET_NOMAX = ' %current%';
+ const FORMAT_NORMAL_NOMAX = ' %current% [%bar%]';
+ const FORMAT_VERBOSE_NOMAX = ' %current% [%bar%] Elapsed: %elapsed%';
+
+ // options
+ private $barWidth = 28;
+ private $barChar = '=';
+ private $emptyBarChar = '-';
+ private $progressChar = '>';
+ private $format = null;
+ private $redrawFreq = 1;
+
+ private $lastMessagesLength;
+ private $barCharOriginal;
+
+ /**
+ * @var OutputInterface
+ */
+ private $output;
+
+ /**
+ * Current step.
+ *
+ * @var int
+ */
+ private $current;
+
+ /**
+ * Maximum number of steps.
+ *
+ * @var int
+ */
+ private $max;
+
+ /**
+ * Start time of the progress bar.
+ *
+ * @var int
+ */
+ private $startTime;
+
+ /**
+ * List of formatting variables.
+ *
+ * @var array
+ */
+ private $defaultFormatVars = array(
+ 'current',
+ 'max',
+ 'bar',
+ 'percent',
+ 'elapsed',
+ );
+
+ /**
+ * Available formatting variables.
+ *
+ * @var array
+ */
+ private $formatVars;
+
+ /**
+ * Stored format part widths (used for padding).
+ *
+ * @var array
+ */
+ private $widths = array(
+ 'current' => 4,
+ 'max' => 4,
+ 'percent' => 3,
+ 'elapsed' => 6,
+ );
+
+ /**
+ * Various time formats.
+ *
+ * @var array
+ */
+ private $timeFormats = array(
+ array(0, '???'),
+ array(2, '1 sec'),
+ array(59, 'secs', 1),
+ array(60, '1 min'),
+ array(3600, 'mins', 60),
+ array(5400, '1 hr'),
+ array(86400, 'hrs', 3600),
+ array(129600, '1 day'),
+ array(604800, 'days', 86400),
+ );
+
+ /**
+ * Sets the progress bar width.
+ *
+ * @param int $size The progress bar size
+ */
+ public function setBarWidth($size)
+ {
+ $this->barWidth = (int) $size;
+ }
+
+ /**
+ * Sets the bar character.
+ *
+ * @param string $char A character
+ */
+ public function setBarCharacter($char)
+ {
+ $this->barChar = $char;
+ }
+
+ /**
+ * Sets the empty bar character.
+ *
+ * @param string $char A character
+ */
+ public function setEmptyBarCharacter($char)
+ {
+ $this->emptyBarChar = $char;
+ }
+
+ /**
+ * Sets the progress bar character.
+ *
+ * @param string $char A character
+ */
+ public function setProgressCharacter($char)
+ {
+ $this->progressChar = $char;
+ }
+
+ /**
+ * Sets the progress bar format.
+ *
+ * @param string $format The format
+ */
+ public function setFormat($format)
+ {
+ $this->format = $format;
+ }
+
+ /**
+ * Sets the redraw frequency.
+ *
+ * @param int $freq The frequency in steps
+ */
+ public function setRedrawFrequency($freq)
+ {
+ $this->redrawFreq = (int) $freq;
+ }
+
+ /**
+ * Starts the progress output.
+ *
+ * @param OutputInterface $output An Output instance
+ * @param int|null $max Maximum steps
+ */
+ public function start(OutputInterface $output, $max = null)
+ {
+ $this->startTime = time();
+ $this->current = 0;
+ $this->max = (int) $max;
+
+ // Disabling output when it does not support ANSI codes as it would result in a broken display anyway.
+ $this->output = $output->isDecorated() ? $output : new NullOutput();
+ $this->lastMessagesLength = 0;
+ $this->barCharOriginal = '';
+
+ if (null === $this->format) {
+ switch ($output->getVerbosity()) {
+ case OutputInterface::VERBOSITY_QUIET:
+ $this->format = self::FORMAT_QUIET_NOMAX;
+ if ($this->max > 0) {
+ $this->format = self::FORMAT_QUIET;
+ }
+ break;
+ case OutputInterface::VERBOSITY_VERBOSE:
+ case OutputInterface::VERBOSITY_VERY_VERBOSE:
+ case OutputInterface::VERBOSITY_DEBUG:
+ $this->format = self::FORMAT_VERBOSE_NOMAX;
+ if ($this->max > 0) {
+ $this->format = self::FORMAT_VERBOSE;
+ }
+ break;
+ default:
+ $this->format = self::FORMAT_NORMAL_NOMAX;
+ if ($this->max > 0) {
+ $this->format = self::FORMAT_NORMAL;
+ }
+ break;
+ }
+ }
+
+ $this->initialize();
+ }
+
+ /**
+ * Advances the progress output X steps.
+ *
+ * @param int $step Number of steps to advance
+ * @param bool $redraw Whether to redraw or not
+ *
+ * @throws \LogicException
+ */
+ public function advance($step = 1, $redraw = false)
+ {
+ $this->setCurrent($this->current + $step, $redraw);
+ }
+
+ /**
+ * Sets the current progress.
+ *
+ * @param int $current The current progress
+ * @param bool $redraw Whether to redraw or not
+ *
+ * @throws \LogicException
+ */
+ public function setCurrent($current, $redraw = false)
+ {
+ if (null === $this->startTime) {
+ throw new \LogicException('You must start the progress bar before calling setCurrent().');
+ }
+
+ $current = (int) $current;
+
+ if ($current < $this->current) {
+ throw new \LogicException('You can\'t regress the progress bar');
+ }
+
+ if (0 === $this->current) {
+ $redraw = true;
+ }
+
+ $prevPeriod = (int) ($this->current / $this->redrawFreq);
+
+ $this->current = $current;
+
+ $currPeriod = (int) ($this->current / $this->redrawFreq);
+ if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) {
+ $this->display();
+ }
+ }
+
+ /**
+ * Outputs the current progress string.
+ *
+ * @param bool $finish Forces the end result
+ *
+ * @throws \LogicException
+ */
+ public function display($finish = false)
+ {
+ if (null === $this->startTime) {
+ throw new \LogicException('You must start the progress bar before calling display().');
+ }
+
+ $message = $this->format;
+ foreach ($this->generate($finish) as $name => $value) {
+ $message = str_replace("%{$name}%", $value, $message);
+ }
+ $this->overwrite($this->output, $message);
+ }
+
+ /**
+ * Removes the progress bar from the current line.
+ *
+ * This is useful if you wish to write some output
+ * while a progress bar is running.
+ * Call display() to show the progress bar again.
+ */
+ public function clear()
+ {
+ $this->overwrite($this->output, '');
+ }
+
+ /**
+ * Finishes the progress output.
+ */
+ public function finish()
+ {
+ if (null === $this->startTime) {
+ throw new \LogicException('You must start the progress bar before calling finish().');
+ }
+
+ if (null !== $this->startTime) {
+ if (!$this->max) {
+ $this->barChar = $this->barCharOriginal;
+ $this->display(true);
+ }
+ $this->startTime = null;
+ $this->output->writeln('');
+ $this->output = null;
+ }
+ }
+
+ /**
+ * Initializes the progress helper.
+ */
+ private function initialize()
+ {
+ $this->formatVars = array();
+ foreach ($this->defaultFormatVars as $var) {
+ if (false !== strpos($this->format, "%{$var}%")) {
+ $this->formatVars[$var] = true;
+ }
+ }
+
+ if ($this->max > 0) {
+ $this->widths['max'] = $this->strlen($this->max);
+ $this->widths['current'] = $this->widths['max'];
+ } else {
+ $this->barCharOriginal = $this->barChar;
+ $this->barChar = $this->emptyBarChar;
+ }
+ }
+
+ /**
+ * Generates the array map of format variables to values.
+ *
+ * @param bool $finish Forces the end result
+ *
+ * @return array Array of format vars and values
+ */
+ private function generate($finish = false)
+ {
+ $vars = array();
+ $percent = 0;
+ if ($this->max > 0) {
+ $percent = (float) $this->current / $this->max;
+ }
+
+ if (isset($this->formatVars['bar'])) {
+ $completeBars = 0;
+
+ if ($this->max > 0) {
+ $completeBars = floor($percent * $this->barWidth);
+ } else {
+ if (!$finish) {
+ $completeBars = floor($this->current % $this->barWidth);
+ } else {
+ $completeBars = $this->barWidth;
+ }
+ }
+
+ $emptyBars = $this->barWidth - $completeBars - $this->strlen($this->progressChar);
+ $bar = str_repeat($this->barChar, $completeBars);
+ if ($completeBars < $this->barWidth) {
+ $bar .= $this->progressChar;
+ $bar .= str_repeat($this->emptyBarChar, $emptyBars);
+ }
+
+ $vars['bar'] = $bar;
+ }
+
+ if (isset($this->formatVars['elapsed'])) {
+ $elapsed = time() - $this->startTime;
+ $vars['elapsed'] = str_pad($this->humaneTime($elapsed), $this->widths['elapsed'], ' ', STR_PAD_LEFT);
+ }
+
+ if (isset($this->formatVars['current'])) {
+ $vars['current'] = str_pad($this->current, $this->widths['current'], ' ', STR_PAD_LEFT);
+ }
+
+ if (isset($this->formatVars['max'])) {
+ $vars['max'] = $this->max;
+ }
+
+ if (isset($this->formatVars['percent'])) {
+ $vars['percent'] = str_pad(floor($percent * 100), $this->widths['percent'], ' ', STR_PAD_LEFT);
+ }
+
+ return $vars;
+ }
+
+ /**
+ * Converts seconds into human-readable format.
+ *
+ * @param int $secs Number of seconds
+ *
+ * @return string Time in readable format
+ */
+ private function humaneTime($secs)
+ {
+ $text = '';
+ foreach ($this->timeFormats as $format) {
+ if ($secs < $format[0]) {
+ if (count($format) == 2) {
+ $text = $format[1];
+ break;
+ } else {
+ $text = ceil($secs / $format[2]).' '.$format[1];
+ break;
+ }
+ }
+ }
+
+ return $text;
+ }
+
+ /**
+ * Overwrites a previous message to the output.
+ *
+ * @param OutputInterface $output An Output instance
+ * @param string $message The message
+ */
+ private function overwrite(OutputInterface $output, $message)
+ {
+ $length = $this->strlen($message);
+
+ // append whitespace to match the last line's length
+ if (null !== $this->lastMessagesLength && $this->lastMessagesLength > $length) {
+ $message = str_pad($message, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
+ }
+
+ // carriage return
+ $output->write("\x0D");
+ $output->write($message);
+
+ $this->lastMessagesLength = $this->strlen($message);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'progress';
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/QuestionHelper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/QuestionHelper.php
new file mode 100644
index 0000000..caa0914
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/QuestionHelper.php
@@ -0,0 +1,418 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+use Symfony\Component\Console\Question\Question;
+use Symfony\Component\Console\Question\ChoiceQuestion;
+
+/**
+ * The QuestionHelper class provides helpers to interact with the user.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class QuestionHelper extends Helper
+{
+ private $inputStream;
+ private static $shell;
+ private static $stty;
+
+ /**
+ * Asks a question to the user.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ * @param Question $question The question to ask
+ *
+ * @return string The user answer
+ *
+ * @throws \RuntimeException If there is no data to read in the input stream
+ */
+ public function ask(InputInterface $input, OutputInterface $output, Question $question)
+ {
+ if (!$input->isInteractive()) {
+ return $question->getDefault();
+ }
+
+ if (!$question->getValidator()) {
+ return $this->doAsk($output, $question);
+ }
+
+ $that = $this;
+
+ $interviewer = function () use ($output, $question, $that) {
+ return $that->doAsk($output, $question);
+ };
+
+ return $this->validateAttempts($interviewer, $output, $question);
+ }
+
+ /**
+ * Sets the input stream to read from when interacting with the user.
+ *
+ * This is mainly useful for testing purpose.
+ *
+ * @param resource $stream The input stream
+ *
+ * @throws \InvalidArgumentException In case the stream is not a resource
+ */
+ public function setInputStream($stream)
+ {
+ if (!is_resource($stream)) {
+ throw new \InvalidArgumentException('Input stream must be a valid resource.');
+ }
+
+ $this->inputStream = $stream;
+ }
+
+ /**
+ * Returns the helper's input stream
+ *
+ * @return resource
+ */
+ public function getInputStream()
+ {
+ return $this->inputStream;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'question';
+ }
+
+ /**
+ * Asks the question to the user.
+ *
+ * This method is public for PHP 5.3 compatibility, it should be private.
+ *
+ * @param OutputInterface $output
+ * @param Question $question
+ *
+ * @return bool|mixed|null|string
+ *
+ * @throws \Exception
+ * @throws \RuntimeException
+ */
+ public function doAsk(OutputInterface $output, Question $question)
+ {
+ $inputStream = $this->inputStream ?: STDIN;
+
+ $message = $question->getQuestion();
+ if ($question instanceof ChoiceQuestion) {
+ $width = max(array_map('strlen', array_keys($question->getChoices())));
+
+ $messages = (array) $question->getQuestion();
+ foreach ($question->getChoices() as $key => $value) {
+ $messages[] = sprintf(" [<info>%-${width}s</info>] %s", $key, $value);
+ }
+
+ $output->writeln($messages);
+
+ $message = $question->getPrompt();
+ }
+
+ $output->write($message);
+
+ $autocomplete = $question->getAutocompleterValues();
+ if (null === $autocomplete || !$this->hasSttyAvailable()) {
+ $ret = false;
+ if ($question->isHidden()) {
+ try {
+ $ret = trim($this->getHiddenResponse($output, $inputStream));
+ } catch (\RuntimeException $e) {
+ if (!$question->isHiddenFallback()) {
+ throw $e;
+ }
+ }
+ }
+
+ if (false === $ret) {
+ $ret = fgets($inputStream, 4096);
+ if (false === $ret) {
+ throw new \RuntimeException('Aborted');
+ }
+ $ret = trim($ret);
+ }
+ } else {
+ $ret = trim($this->autocomplete($output, $question, $inputStream));
+ }
+
+ $ret = strlen($ret) > 0 ? $ret : $question->getDefault();
+
+ if ($normalizer = $question->getNormalizer()) {
+ return $normalizer($ret);
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Autocompletes a question.
+ *
+ * @param OutputInterface $output
+ * @param Question $question
+ *
+ * @return string
+ */
+ private function autocomplete(OutputInterface $output, Question $question, $inputStream)
+ {
+ $autocomplete = $question->getAutocompleterValues();
+ $ret = '';
+
+ $i = 0;
+ $ofs = -1;
+ $matches = $autocomplete;
+ $numMatches = count($matches);
+
+ $sttyMode = shell_exec('stty -g');
+
+ // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead)
+ shell_exec('stty -icanon -echo');
+
+ // Add highlighted text style
+ $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));
+
+ // Read a keypress
+ while (!feof($inputStream)) {
+ $c = fread($inputStream, 1);
+
+ // Backspace Character
+ if ("\177" === $c) {
+ if (0 === $numMatches && 0 !== $i) {
+ $i--;
+ // Move cursor backwards
+ $output->write("\033[1D");
+ }
+
+ if ($i === 0) {
+ $ofs = -1;
+ $matches = $autocomplete;
+ $numMatches = count($matches);
+ } else {
+ $numMatches = 0;
+ }
+
+ // Pop the last character off the end of our string
+ $ret = substr($ret, 0, $i);
+ } elseif ("\033" === $c) {
+ // Did we read an escape sequence?
+ $c .= fread($inputStream, 2);
+
+ // A = Up Arrow. B = Down Arrow
+ if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
+ if ('A' === $c[2] && -1 === $ofs) {
+ $ofs = 0;
+ }
+
+ if (0 === $numMatches) {
+ continue;
+ }
+
+ $ofs += ('A' === $c[2]) ? -1 : 1;
+ $ofs = ($numMatches + $ofs) % $numMatches;
+ }
+ } elseif (ord($c) < 32) {
+ if ("\t" === $c || "\n" === $c) {
+ if ($numMatches > 0 && -1 !== $ofs) {
+ $ret = $matches[$ofs];
+ // Echo out remaining chars for current match
+ $output->write(substr($ret, $i));
+ $i = strlen($ret);
+ }
+
+ if ("\n" === $c) {
+ $output->write($c);
+ break;
+ }
+
+ $numMatches = 0;
+ }
+
+ continue;
+ } else {
+ $output->write($c);
+ $ret .= $c;
+ $i++;
+
+ $numMatches = 0;
+ $ofs = 0;
+
+ foreach ($autocomplete as $value) {
+ // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
+ if (0 === strpos($value, $ret) && $i !== strlen($value)) {
+ $matches[$numMatches++] = $value;
+ }
+ }
+ }
+
+ // Erase characters from cursor to end of line
+ $output->write("\033[K");
+
+ if ($numMatches > 0 && -1 !== $ofs) {
+ // Save cursor position
+ $output->write("\0337");
+ // Write highlighted text
+ $output->write('<hl>'.substr($matches[$ofs], $i).'</hl>');
+ // Restore cursor position
+ $output->write("\0338");
+ }
+ }
+
+ // Reset stty so it behaves normally again
+ shell_exec(sprintf('stty %s', $sttyMode));
+
+ return $ret;
+ }
+
+ /**
+ * Gets a hidden response from user.
+ *
+ * @param OutputInterface $output An Output instance
+ *
+ * @return string The answer
+ *
+ * @throws \RuntimeException In case the fallback is deactivated and the response cannot be hidden
+ */
+ private function getHiddenResponse(OutputInterface $output, $inputStream)
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $exe = __DIR__.'/../Resources/bin/hiddeninput.exe';
+
+ // handle code running from a phar
+ if ('phar:' === substr(__FILE__, 0, 5)) {
+ $tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
+ copy($exe, $tmpExe);
+ $exe = $tmpExe;
+ }
+
+ $value = rtrim(shell_exec($exe));
+ $output->writeln('');
+
+ if (isset($tmpExe)) {
+ unlink($tmpExe);
+ }
+
+ return $value;
+ }
+
+ if ($this->hasSttyAvailable()) {
+ $sttyMode = shell_exec('stty -g');
+
+ shell_exec('stty -echo');
+ $value = fgets($inputStream, 4096);
+ shell_exec(sprintf('stty %s', $sttyMode));
+
+ if (false === $value) {
+ throw new \RuntimeException('Aborted');
+ }
+
+ $value = trim($value);
+ $output->writeln('');
+
+ return $value;
+ }
+
+ if (false !== $shell = $this->getShell()) {
+ $readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword';
+ $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
+ $value = rtrim(shell_exec($command));
+ $output->writeln('');
+
+ return $value;
+ }
+
+ throw new \RuntimeException('Unable to hide the response.');
+ }
+
+ /**
+ * Validates an attempt.
+ *
+ * @param callable $interviewer A callable that will ask for a question and return the result
+ * @param OutputInterface $output An Output instance
+ * @param Question $question A Question instance
+ *
+ * @return string The validated response
+ *
+ * @throws \Exception In case the max number of attempts has been reached and no valid response has been given
+ */
+ private function validateAttempts($interviewer, OutputInterface $output, Question $question)
+ {
+ $error = null;
+ $attempts = $question->getMaxAttempts();
+ while (null === $attempts || $attempts--) {
+ if (null !== $error) {
+ if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) {
+ $message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error');
+ } else {
+ $message = '<error>'.$error->getMessage().'</error>';
+ }
+
+ $output->writeln($message);
+ }
+
+ try {
+ return call_user_func($question->getValidator(), $interviewer());
+ } catch (\Exception $error) {
+ }
+ }
+
+ throw $error;
+ }
+
+ /**
+ * Returns a valid unix shell.
+ *
+ * @return string|bool The valid shell name, false in case no valid shell is found
+ */
+ private function getShell()
+ {
+ if (null !== self::$shell) {
+ return self::$shell;
+ }
+
+ self::$shell = false;
+
+ if (file_exists('/usr/bin/env')) {
+ // handle other OSs with bash/zsh/ksh/csh if available to hide the answer
+ $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
+ foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) {
+ if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
+ self::$shell = $sh;
+ break;
+ }
+ }
+ }
+
+ return self::$shell;
+ }
+
+ /**
+ * Returns whether Stty is available or not.
+ *
+ * @return bool
+ */
+ private function hasSttyAvailable()
+ {
+ if (null !== self::$stty) {
+ return self::$stty;
+ }
+
+ exec('stty 2>&1', $output, $exitcode);
+
+ return self::$stty = $exitcode === 0;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/Table.php b/vendor/symfony/console/Symfony/Component/Console/Helper/Table.php
new file mode 100644
index 0000000..67cfbb5
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/Table.php
@@ -0,0 +1,410 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Provides helpers to display a table.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Саша Стаменковић <umpirsky@gmail.com>
+ */
+class Table
+{
+ /**
+ * Table headers.
+ *
+ * @var array
+ */
+ private $headers = array();
+
+ /**
+ * Table rows.
+ *
+ * @var array
+ */
+ private $rows = array();
+
+ /**
+ * Column widths cache.
+ *
+ * @var array
+ */
+ private $columnWidths = array();
+
+ /**
+ * Number of columns cache.
+ *
+ * @var array
+ */
+ private $numberOfColumns;
+
+ /**
+ * @var OutputInterface
+ */
+ private $output;
+
+ /**
+ * @var TableStyle
+ */
+ private $style;
+
+ private static $styles;
+
+ public function __construct(OutputInterface $output)
+ {
+ $this->output = $output;
+
+ if (!self::$styles) {
+ self::$styles = self::initStyles();
+ }
+
+ $this->setStyle('default');
+ }
+
+ /**
+ * Sets a style definition.
+ *
+ * @param string $name The style name
+ * @param TableStyle $style A TableStyle instance
+ */
+ public static function setStyleDefinition($name, TableStyle $style)
+ {
+ if (!self::$styles) {
+ self::$styles = self::initStyles();
+ }
+
+ self::$styles[$name] = $style;
+ }
+
+ /**
+ * Gets a style definition by name.
+ *
+ * @param string $name The style name
+ *
+ * @return TableStyle A TableStyle instance
+ */
+ public static function getStyleDefinition($name)
+ {
+ if (!self::$styles) {
+ self::$styles = self::initStyles();
+ }
+
+ if (!self::$styles[$name]) {
+ throw new \InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
+ }
+
+ return self::$styles[$name];
+ }
+
+ /**
+ * Sets table style.
+ *
+ * @param TableStyle|string $name The style name or a TableStyle instance
+ *
+ * @return Table
+ */
+ public function setStyle($name)
+ {
+ if ($name instanceof TableStyle) {
+ $this->style = $name;
+ } elseif (isset(self::$styles[$name])) {
+ $this->style = self::$styles[$name];
+ } else {
+ throw new \InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
+ }
+
+ return $this;
+ }
+
+ /**
+ * Gets the current table style.
+ *
+ * @return TableStyle
+ */
+ public function getStyle()
+ {
+ return $this->style;
+ }
+
+ public function setHeaders(array $headers)
+ {
+ $this->headers = array_values($headers);
+
+ return $this;
+ }
+
+ public function setRows(array $rows)
+ {
+ $this->rows = array();
+
+ return $this->addRows($rows);
+ }
+
+ public function addRows(array $rows)
+ {
+ foreach ($rows as $row) {
+ $this->addRow($row);
+ }
+
+ return $this;
+ }
+
+ public function addRow($row)
+ {
+ if ($row instanceof TableSeparator) {
+ $this->rows[] = $row;
+
+ return;
+ }
+
+ if (!is_array($row)) {
+ throw new \InvalidArgumentException('A row must be an array or a TableSeparator instance.');
+ }
+
+ $this->rows[] = array_values($row);
+
+ end($this->rows);
+ $rowKey = key($this->rows);
+ reset($this->rows);
+
+ foreach ($row as $key => $cellValue) {
+ if (!strstr($cellValue, "\n")) {
+ continue;
+ }
+
+ $lines = explode("\n", $cellValue);
+ $this->rows[$rowKey][$key] = $lines[0];
+ unset($lines[0]);
+
+ foreach ($lines as $lineKey => $line) {
+ $nextRowKey = $rowKey + $lineKey + 1;
+
+ if (isset($this->rows[$nextRowKey])) {
+ $this->rows[$nextRowKey][$key] = $line;
+ } else {
+ $this->rows[$nextRowKey] = array($key => $line);
+ }
+ }
+ }
+
+ return $this;
+ }
+
+ public function setRow($column, array $row)
+ {
+ $this->rows[$column] = $row;
+
+ return $this;
+ }
+
+ /**
+ * Renders table to output.
+ *
+ * Example:
+ * +---------------+-----------------------+------------------+
+ * | ISBN | Title | Author |
+ * +---------------+-----------------------+------------------+
+ * | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+ * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+ * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+ * +---------------+-----------------------+------------------+
+ */
+ public function render()
+ {
+ $this->renderRowSeparator();
+ $this->renderRow($this->headers, $this->style->getCellHeaderFormat());
+ if (!empty($this->headers)) {
+ $this->renderRowSeparator();
+ }
+ foreach ($this->rows as $row) {
+ if ($row instanceof TableSeparator) {
+ $this->renderRowSeparator();
+ } else {
+ $this->renderRow($row, $this->style->getCellRowFormat());
+ }
+ }
+ if (!empty($this->rows)) {
+ $this->renderRowSeparator();
+ }
+
+ $this->cleanup();
+ }
+
+ /**
+ * Renders horizontal header separator.
+ *
+ * Example: +-----+-----------+-------+
+ */
+ private function renderRowSeparator()
+ {
+ if (0 === $count = $this->getNumberOfColumns()) {
+ return;
+ }
+
+ if (!$this->style->getHorizontalBorderChar() && !$this->style->getCrossingChar()) {
+ return;
+ }
+
+ $markup = $this->style->getCrossingChar();
+ for ($column = 0; $column < $count; $column++) {
+ $markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->getColumnWidth($column)).$this->style->getCrossingChar();
+ }
+
+ $this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
+ }
+
+ /**
+ * Renders vertical column separator.
+ */
+ private function renderColumnSeparator()
+ {
+ $this->output->write(sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar()));
+ }
+
+ /**
+ * Renders table row.
+ *
+ * Example: | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+ *
+ * @param array $row
+ * @param string $cellFormat
+ */
+ private function renderRow(array $row, $cellFormat)
+ {
+ if (empty($row)) {
+ return;
+ }
+
+ $this->renderColumnSeparator();
+ for ($column = 0, $count = $this->getNumberOfColumns(); $column < $count; $column++) {
+ $this->renderCell($row, $column, $cellFormat);
+ $this->renderColumnSeparator();
+ }
+ $this->output->writeln('');
+ }
+
+ /**
+ * Renders table cell with padding.
+ *
+ * @param array $row
+ * @param int $column
+ * @param string $cellFormat
+ */
+ private function renderCell(array $row, $column, $cellFormat)
+ {
+ $cell = isset($row[$column]) ? $row[$column] : '';
+ $width = $this->getColumnWidth($column);
+
+ // str_pad won't work properly with multi-byte strings, we need to fix the padding
+ if (function_exists('mb_strwidth') && false !== $encoding = mb_detect_encoding($cell)) {
+ $width += strlen($cell) - mb_strwidth($cell, $encoding);
+ }
+
+ $width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
+
+ $content = sprintf($this->style->getCellRowContentFormat(), $cell);
+
+ $this->output->write(sprintf($cellFormat, str_pad($content, $width, $this->style->getPaddingChar(), $this->style->getPadType())));
+ }
+
+ /**
+ * Gets number of columns for this table.
+ *
+ * @return int
+ */
+ private function getNumberOfColumns()
+ {
+ if (null !== $this->numberOfColumns) {
+ return $this->numberOfColumns;
+ }
+
+ $columns = array(count($this->headers));
+ foreach ($this->rows as $row) {
+ $columns[] = count($row);
+ }
+
+ return $this->numberOfColumns = max($columns);
+ }
+
+ /**
+ * Gets column width.
+ *
+ * @param int $column
+ *
+ * @return int
+ */
+ private function getColumnWidth($column)
+ {
+ if (isset($this->columnWidths[$column])) {
+ return $this->columnWidths[$column];
+ }
+
+ $lengths = array($this->getCellWidth($this->headers, $column));
+ foreach ($this->rows as $row) {
+ if ($row instanceof TableSeparator) {
+ continue;
+ }
+
+ $lengths[] = $this->getCellWidth($row, $column);
+ }
+
+ return $this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
+ }
+
+ /**
+ * Gets cell width.
+ *
+ * @param array $row
+ * @param int $column
+ *
+ * @return int
+ */
+ private function getCellWidth(array $row, $column)
+ {
+ return isset($row[$column]) ? Helper::strlenWithoutDecoration($this->output->getFormatter(), $row[$column]) : 0;
+ }
+
+ /**
+ * Called after rendering to cleanup cache data.
+ */
+ private function cleanup()
+ {
+ $this->columnWidths = array();
+ $this->numberOfColumns = null;
+ }
+
+ private static function initStyles()
+ {
+ $borderless = new TableStyle();
+ $borderless
+ ->setHorizontalBorderChar('=')
+ ->setVerticalBorderChar(' ')
+ ->setCrossingChar(' ')
+ ;
+
+ $compact = new TableStyle();
+ $compact
+ ->setHorizontalBorderChar('')
+ ->setVerticalBorderChar(' ')
+ ->setCrossingChar('')
+ ->setCellRowContentFormat('%s')
+ ;
+
+ return array(
+ 'default' => new TableStyle(),
+ 'borderless' => $borderless,
+ 'compact' => $compact,
+ );
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/TableHelper.php b/vendor/symfony/console/Symfony/Component/Console/Helper/TableHelper.php
new file mode 100644
index 0000000..fc6861c
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/TableHelper.php
@@ -0,0 +1,263 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\NullOutput;
+
+/**
+ * Provides helpers to display table output.
+ *
+ * @author Саша Стаменковић <umpirsky@gmail.com>
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @deprecated Deprecated since 2.5, to be removed in 3.0; use Table instead.
+ */
+class TableHelper extends Helper
+{
+ const LAYOUT_DEFAULT = 0;
+ const LAYOUT_BORDERLESS = 1;
+ const LAYOUT_COMPACT = 2;
+
+ /**
+ * @var Table
+ */
+ private $table;
+
+ public function __construct()
+ {
+ $this->table = new Table(new NullOutput());
+ }
+
+ /**
+ * Sets table layout type.
+ *
+ * @param int $layout self::LAYOUT_*
+ *
+ * @return TableHelper
+ *
+ * @throws \InvalidArgumentException when the table layout is not known
+ */
+ public function setLayout($layout)
+ {
+ switch ($layout) {
+ case self::LAYOUT_BORDERLESS:
+ $this->table->setStyle('borderless');
+ break;
+
+ case self::LAYOUT_COMPACT:
+ $this->table->setStyle('compact');
+ break;
+
+ case self::LAYOUT_DEFAULT:
+ $this->table->setStyle('default');
+ break;
+
+ default:
+ throw new \InvalidArgumentException(sprintf('Invalid table layout "%s".', $layout));
+ };
+
+ return $this;
+ }
+
+ public function setHeaders(array $headers)
+ {
+ $this->table->setHeaders($headers);
+
+ return $this;
+ }
+
+ public function setRows(array $rows)
+ {
+ $this->table->setRows($rows);
+
+ return $this;
+ }
+
+ public function addRows(array $rows)
+ {
+ $this->table->addRows($rows);
+
+ return $this;
+ }
+
+ public function addRow(array $row)
+ {
+ $this->table->addRow($row);
+
+ return $this;
+ }
+
+ public function setRow($column, array $row)
+ {
+ $this->table->setRow($column, $row);
+
+ return $this;
+ }
+
+ /**
+ * Sets padding character, used for cell padding.
+ *
+ * @param string $paddingChar
+ *
+ * @return TableHelper
+ */
+ public function setPaddingChar($paddingChar)
+ {
+ $this->table->getStyle()->setPaddingChar($paddingChar);
+
+ return $this;
+ }
+
+ /**
+ * Sets horizontal border character.
+ *
+ * @param string $horizontalBorderChar
+ *
+ * @return TableHelper
+ */
+ public function setHorizontalBorderChar($horizontalBorderChar)
+ {
+ $this->table->getStyle()->setHorizontalBorderChar($horizontalBorderChar);
+
+ return $this;
+ }
+
+ /**
+ * Sets vertical border character.
+ *
+ * @param string $verticalBorderChar
+ *
+ * @return TableHelper
+ */
+ public function setVerticalBorderChar($verticalBorderChar)
+ {
+ $this->table->getStyle()->setVerticalBorderChar($verticalBorderChar);
+
+ return $this;
+ }
+
+ /**
+ * Sets crossing character.
+ *
+ * @param string $crossingChar
+ *
+ * @return TableHelper
+ */
+ public function setCrossingChar($crossingChar)
+ {
+ $this->table->getStyle()->setCrossingChar($crossingChar);
+
+ return $this;
+ }
+
+ /**
+ * Sets header cell format.
+ *
+ * @param string $cellHeaderFormat
+ *
+ * @return TableHelper
+ */
+ public function setCellHeaderFormat($cellHeaderFormat)
+ {
+ $this->table->getStyle()->setCellHeaderFormat($cellHeaderFormat);
+
+ return $this;
+ }
+
+ /**
+ * Sets row cell format.
+ *
+ * @param string $cellRowFormat
+ *
+ * @return TableHelper
+ */
+ public function setCellRowFormat($cellRowFormat)
+ {
+ $this->table->getStyle()->setCellHeaderFormat($cellRowFormat);
+
+ return $this;
+ }
+
+ /**
+ * Sets row cell content format.
+ *
+ * @param string $cellRowContentFormat
+ *
+ * @return TableHelper
+ */
+ public function setCellRowContentFormat($cellRowContentFormat)
+ {
+ $this->table->getStyle()->setCellRowContentFormat($cellRowContentFormat);
+
+ return $this;
+ }
+
+ /**
+ * Sets table border format.
+ *
+ * @param string $borderFormat
+ *
+ * @return TableHelper
+ */
+ public function setBorderFormat($borderFormat)
+ {
+ $this->table->getStyle()->setBorderFormat($borderFormat);
+
+ return $this;
+ }
+
+ /**
+ * Sets cell padding type.
+ *
+ * @param int $padType STR_PAD_*
+ *
+ * @return TableHelper
+ */
+ public function setPadType($padType)
+ {
+ $this->table->getStyle()->setPadType($padType);
+
+ return $this;
+ }
+
+ /**
+ * Renders table to output.
+ *
+ * Example:
+ * +---------------+-----------------------+------------------+
+ * | ISBN | Title | Author |
+ * +---------------+-----------------------+------------------+
+ * | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+ * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+ * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+ * +---------------+-----------------------+------------------+
+ *
+ * @param OutputInterface $output
+ */
+ public function render(OutputInterface $output)
+ {
+ $p = new \ReflectionProperty($this->table, 'output');
+ $p->setAccessible(true);
+ $p->setValue($this->table, $output);
+
+ $this->table->render();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'table';
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/TableSeparator.php b/vendor/symfony/console/Symfony/Component/Console/Helper/TableSeparator.php
new file mode 100644
index 0000000..1f6981b
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/TableSeparator.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+/**
+ * Marks a row as being a separator.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class TableSeparator
+{
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Helper/TableStyle.php b/vendor/symfony/console/Symfony/Component/Console/Helper/TableStyle.php
new file mode 100644
index 0000000..580f9ab
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Helper/TableStyle.php
@@ -0,0 +1,251 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+/**
+ * Defines the styles for a Table.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Саша Стаменковић <umpirsky@gmail.com>
+ */
+class TableStyle
+{
+ private $paddingChar = ' ';
+ private $horizontalBorderChar = '-';
+ private $verticalBorderChar = '|';
+ private $crossingChar = '+';
+ private $cellHeaderFormat = '<info>%s</info>';
+ private $cellRowFormat = '%s';
+ private $cellRowContentFormat = ' %s ';
+ private $borderFormat = '%s';
+ private $padType = STR_PAD_RIGHT;
+
+ /**
+ * Sets padding character, used for cell padding.
+ *
+ * @param string $paddingChar
+ *
+ * @return TableStyle
+ */
+ public function setPaddingChar($paddingChar)
+ {
+ if (!$paddingChar) {
+ throw new \LogicException('The padding char must not be empty');
+ }
+
+ $this->paddingChar = $paddingChar;
+
+ return $this;
+ }
+
+ /**
+ * Gets padding character, used for cell padding.
+ *
+ * @return string
+ */
+ public function getPaddingChar()
+ {
+ return $this->paddingChar;
+ }
+
+ /**
+ * Sets horizontal border character.
+ *
+ * @param string $horizontalBorderChar
+ *
+ * @return TableStyle
+ */
+ public function setHorizontalBorderChar($horizontalBorderChar)
+ {
+ $this->horizontalBorderChar = $horizontalBorderChar;
+
+ return $this;
+ }
+
+ /**
+ * Gets horizontal border character.
+ *
+ * @return string
+ */
+ public function getHorizontalBorderChar()
+ {
+ return $this->horizontalBorderChar;
+ }
+
+ /**
+ * Sets vertical border character.
+ *
+ * @param string $verticalBorderChar
+ *
+ * @return TableStyle
+ */
+ public function setVerticalBorderChar($verticalBorderChar)
+ {
+ $this->verticalBorderChar = $verticalBorderChar;
+
+ return $this;
+ }
+
+ /**
+ * Gets vertical border character.
+ *
+ * @return string
+ */
+ public function getVerticalBorderChar()
+ {
+ return $this->verticalBorderChar;
+ }
+
+ /**
+ * Sets crossing character.
+ *
+ * @param string $crossingChar
+ *
+ * @return TableStyle
+ */
+ public function setCrossingChar($crossingChar)
+ {
+ $this->crossingChar = $crossingChar;
+
+ return $this;
+ }
+
+ /**
+ * Gets crossing character.
+ *
+ * @return string $crossingChar
+ */
+ public function getCrossingChar()
+ {
+ return $this->crossingChar;
+ }
+
+ /**
+ * Sets header cell format.
+ *
+ * @param string $cellHeaderFormat
+ *
+ * @return TableStyle
+ */
+ public function setCellHeaderFormat($cellHeaderFormat)
+ {
+ $this->cellHeaderFormat = $cellHeaderFormat;
+
+ return $this;
+ }
+
+ /**
+ * Gets header cell format.
+ *
+ * @return string
+ */
+ public function getCellHeaderFormat()
+ {
+ return $this->cellHeaderFormat;
+ }
+
+ /**
+ * Sets row cell format.
+ *
+ * @param string $cellRowFormat
+ *
+ * @return TableStyle
+ */
+ public function setCellRowFormat($cellRowFormat)
+ {
+ $this->cellRowFormat = $cellRowFormat;
+
+ return $this;
+ }
+
+ /**
+ * Gets row cell format.
+ *
+ * @return string
+ */
+ public function getCellRowFormat()
+ {
+ return $this->cellRowFormat;
+ }
+
+ /**
+ * Sets row cell content format.
+ *
+ * @param string $cellRowContentFormat
+ *
+ * @return TableStyle
+ */
+ public function setCellRowContentFormat($cellRowContentFormat)
+ {
+ $this->cellRowContentFormat = $cellRowContentFormat;
+
+ return $this;
+ }
+
+ /**
+ * Gets row cell content format.
+ *
+ * @return string
+ */
+ public function getCellRowContentFormat()
+ {
+ return $this->cellRowContentFormat;
+ }
+
+ /**
+ * Sets table border format.
+ *
+ * @param string $borderFormat
+ *
+ * @return TableStyle
+ */
+ public function setBorderFormat($borderFormat)
+ {
+ $this->borderFormat = $borderFormat;
+
+ return $this;
+ }
+
+ /**
+ * Gets table border format.
+ *
+ * @return string
+ */
+ public function getBorderFormat()
+ {
+ return $this->borderFormat;
+ }
+
+ /**
+ * Sets cell padding type.
+ *
+ * @param int $padType STR_PAD_*
+ *
+ * @return TableStyle
+ */
+ public function setPadType($padType)
+ {
+ $this->padType = $padType;
+
+ return $this;
+ }
+
+ /**
+ * Gets cell padding type.
+ *
+ * @return int
+ */
+ public function getPadType()
+ {
+ return $this->padType;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Input/ArgvInput.php b/vendor/symfony/console/Symfony/Component/Console/Input/ArgvInput.php
new file mode 100644
index 0000000..f5cc5d1
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Input/ArgvInput.php
@@ -0,0 +1,353 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * ArgvInput represents an input coming from the CLI arguments.
+ *
+ * Usage:
+ *
+ * $input = new ArgvInput();
+ *
+ * By default, the `$_SERVER['argv']` array is used for the input values.
+ *
+ * This can be overridden by explicitly passing the input values in the constructor:
+ *
+ * $input = new ArgvInput($_SERVER['argv']);
+ *
+ * If you pass it yourself, don't forget that the first element of the array
+ * is the name of the running application.
+ *
+ * When passing an argument to the constructor, be sure that it respects
+ * the same rules as the argv one. It's almost always better to use the
+ * `StringInput` when you want to provide your own input.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
+ * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
+ *
+ * @api
+ */
+class ArgvInput extends Input
+{
+ private $tokens;
+ private $parsed;
+
+ /**
+ * Constructor.
+ *
+ * @param array $argv An array of parameters from the CLI (in the argv format)
+ * @param InputDefinition $definition A InputDefinition instance
+ *
+ * @api
+ */
+ public function __construct(array $argv = null, InputDefinition $definition = null)
+ {
+ if (null === $argv) {
+ $argv = $_SERVER['argv'];
+ }
+
+ // strip the application name
+ array_shift($argv);
+
+ $this->tokens = $argv;
+
+ parent::__construct($definition);
+ }
+
+ protected function setTokens(array $tokens)
+ {
+ $this->tokens = $tokens;
+ }
+
+ /**
+ * Processes command line arguments.
+ */
+ protected function parse()
+ {
+ $parseOptions = true;
+ $this->parsed = $this->tokens;
+ while (null !== $token = array_shift($this->parsed)) {
+ if ($parseOptions && '' == $token) {
+ $this->parseArgument($token);
+ } elseif ($parseOptions && '--' == $token) {
+ $parseOptions = false;
+ } elseif ($parseOptions && 0 === strpos($token, '--')) {
+ $this->parseLongOption($token);
+ } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {
+ $this->parseShortOption($token);
+ } else {
+ $this->parseArgument($token);
+ }
+ }
+ }
+
+ /**
+ * Parses a short option.
+ *
+ * @param string $token The current token.
+ */
+ private function parseShortOption($token)
+ {
+ $name = substr($token, 1);
+
+ if (strlen($name) > 1) {
+ if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
+ // an option with a value (with no space)
+ $this->addShortOption($name[0], substr($name, 1));
+ } else {
+ $this->parseShortOptionSet($name);
+ }
+ } else {
+ $this->addShortOption($name, null);
+ }
+ }
+
+ /**
+ * Parses a short option set.
+ *
+ * @param string $name The current token
+ *
+ * @throws \RuntimeException When option given doesn't exist
+ */
+ private function parseShortOptionSet($name)
+ {
+ $len = strlen($name);
+ for ($i = 0; $i < $len; $i++) {
+ if (!$this->definition->hasShortcut($name[$i])) {
+ throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i]));
+ }
+
+ $option = $this->definition->getOptionForShortcut($name[$i]);
+ if ($option->acceptValue()) {
+ $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));
+
+ break;
+ } else {
+ $this->addLongOption($option->getName(), null);
+ }
+ }
+ }
+
+ /**
+ * Parses a long option.
+ *
+ * @param string $token The current token
+ */
+ private function parseLongOption($token)
+ {
+ $name = substr($token, 2);
+
+ if (false !== $pos = strpos($name, '=')) {
+ $this->addLongOption(substr($name, 0, $pos), substr($name, $pos + 1));
+ } else {
+ $this->addLongOption($name, null);
+ }
+ }
+
+ /**
+ * Parses an argument.
+ *
+ * @param string $token The current token
+ *
+ * @throws \RuntimeException When too many arguments are given
+ */
+ private function parseArgument($token)
+ {
+ $c = count($this->arguments);
+
+ // if input is expecting another argument, add it
+ if ($this->definition->hasArgument($c)) {
+ $arg = $this->definition->getArgument($c);
+ $this->arguments[$arg->getName()] = $arg->isArray() ? array($token) : $token;
+
+ // if last argument isArray(), append token to last argument
+ } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
+ $arg = $this->definition->getArgument($c - 1);
+ $this->arguments[$arg->getName()][] = $token;
+
+ // unexpected argument
+ } else {
+ throw new \RuntimeException('Too many arguments.');
+ }
+ }
+
+ /**
+ * Adds a short option value.
+ *
+ * @param string $shortcut The short option key
+ * @param mixed $value The value for the option
+ *
+ * @throws \RuntimeException When option given doesn't exist
+ */
+ private function addShortOption($shortcut, $value)
+ {
+ if (!$this->definition->hasShortcut($shortcut)) {
+ throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
+ }
+
+ $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
+ }
+
+ /**
+ * Adds a long option value.
+ *
+ * @param string $name The long option key
+ * @param mixed $value The value for the option
+ *
+ * @throws \RuntimeException When option given doesn't exist
+ */
+ private function addLongOption($name, $value)
+ {
+ if (!$this->definition->hasOption($name)) {
+ throw new \RuntimeException(sprintf('The "--%s" option does not exist.', $name));
+ }
+
+ $option = $this->definition->getOption($name);
+
+ // Convert false values (from a previous call to substr()) to null
+ if (false === $value) {
+ $value = null;
+ }
+
+ if (null !== $value && !$option->acceptValue()) {
+ throw new \RuntimeException(sprintf('The "--%s" option does not accept a value.', $name, $value));
+ }
+
+ if (null === $value && $option->acceptValue() && count($this->parsed)) {
+ // if option accepts an optional or mandatory argument
+ // let's see if there is one provided
+ $next = array_shift($this->parsed);
+ if (isset($next[0]) && '-' !== $next[0]) {
+ $value = $next;
+ } elseif (empty($next)) {
+ $value = '';
+ } else {
+ array_unshift($this->parsed, $next);
+ }
+ }
+
+ if (null === $value) {
+ if ($option->isValueRequired()) {
+ throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name));
+ }
+
+ if (!$option->isArray()) {
+ $value = $option->isValueOptional() ? $option->getDefault() : true;
+ }
+ }
+
+ if ($option->isArray()) {
+ $this->options[$name][] = $value;
+ } else {
+ $this->options[$name] = $value;
+ }
+ }
+
+ /**
+ * Returns the first argument from the raw parameters (not parsed).
+ *
+ * @return string The value of the first argument or null otherwise
+ */
+ public function getFirstArgument()
+ {
+ foreach ($this->tokens as $token) {
+ if ($token && '-' === $token[0]) {
+ continue;
+ }
+
+ return $token;
+ }
+ }
+
+ /**
+ * Returns true if the raw parameters (not parsed) contain a value.
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+ *
+ * @return bool true if the value is contained in the raw parameters
+ */
+ public function hasParameterOption($values)
+ {
+ $values = (array) $values;
+
+ foreach ($this->tokens as $token) {
+ foreach ($values as $value) {
+ if ($token === $value || 0 === strpos($token, $value.'=')) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the value of a raw option (not parsed).
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+ * @param mixed $default The default value to return if no result is found
+ *
+ * @return mixed The option value
+ */
+ public function getParameterOption($values, $default = false)
+ {
+ $values = (array) $values;
+ $tokens = $this->tokens;
+
+ while (0 < count($tokens)) {
+ $token = array_shift($tokens);
+
+ foreach ($values as $value) {
+ if ($token === $value || 0 === strpos($token, $value.'=')) {
+ if (false !== $pos = strpos($token, '=')) {
+ return substr($token, $pos + 1);
+ }
+
+ return array_shift($tokens);
+ }
+ }
+ }
+
+ return $default;
+ }
+
+ /**
+ * Returns a stringified representation of the args passed to the command.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $self = $this;
+ $tokens = array_map(function ($token) use ($self) {
+ if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) {
+ return $match[1].$self->escapeToken($match[2]);
+ }
+
+ if ($token && $token[0] !== '-') {
+ return $self->escapeToken($token);
+ }
+
+ return $token;
+ }, $this->tokens);
+
+ return implode(' ', $tokens);
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Input/ArrayInput.php b/vendor/symfony/console/Symfony/Component/Console/Input/ArrayInput.php
new file mode 100644
index 0000000..5743bb8
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Input/ArrayInput.php
@@ -0,0 +1,211 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * ArrayInput represents an input provided as an array.
+ *
+ * Usage:
+ *
+ * $input = new ArrayInput(array('name' => 'foo', '--bar' => 'foobar'));
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class ArrayInput extends Input
+{
+ private $parameters;
+
+ /**
+ * Constructor.
+ *
+ * @param array $parameters An array of parameters
+ * @param InputDefinition $definition A InputDefinition instance
+ *
+ * @api
+ */
+ public function __construct(array $parameters, InputDefinition $definition = null)
+ {
+ $this->parameters = $parameters;
+
+ parent::__construct($definition);
+ }
+
+ /**
+ * Returns the first argument from the raw parameters (not parsed).
+ *
+ * @return string The value of the first argument or null otherwise
+ */
+ public function getFirstArgument()
+ {
+ foreach ($this->parameters as $key => $value) {
+ if ($key && '-' === $key[0]) {
+ continue;
+ }
+
+ return $value;
+ }
+ }
+
+ /**
+ * Returns true if the raw parameters (not parsed) contain a value.
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The values to look for in the raw parameters (can be an array)
+ *
+ * @return bool true if the value is contained in the raw parameters
+ */
+ public function hasParameterOption($values)
+ {
+ $values = (array) $values;
+
+ foreach ($this->parameters as $k => $v) {
+ if (!is_int($k)) {
+ $v = $k;
+ }
+
+ if (in_array($v, $values)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the value of a raw option (not parsed).
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+ * @param mixed $default The default value to return if no result is found
+ *
+ * @return mixed The option value
+ */
+ public function getParameterOption($values, $default = false)
+ {
+ $values = (array) $values;
+
+ foreach ($this->parameters as $k => $v) {
+ if (is_int($k)) {
+ if (in_array($v, $values)) {
+ return true;
+ }
+ } elseif (in_array($k, $values)) {
+ return $v;
+ }
+ }
+
+ return $default;
+ }
+
+ /**
+ * Returns a stringified representation of the args passed to the command.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $params = array();
+ foreach ($this->parameters as $param => $val) {
+ if ($param && '-' === $param[0]) {
+ $params[] = $param.('' != $val ? '='.$this->escapeToken($val) : '');
+ } else {
+ $params[] = $this->escapeToken($val);
+ }
+ }
+
+ return implode(' ', $params);
+ }
+
+ /**
+ * Processes command line arguments.
+ */
+ protected function parse()
+ {
+ foreach ($this->parameters as $key => $value) {
+ if (0 === strpos($key, '--')) {
+ $this->addLongOption(substr($key, 2), $value);
+ } elseif ('-' === $key[0]) {
+ $this->addShortOption(substr($key, 1), $value);
+ } else {
+ $this->addArgument($key, $value);
+ }
+ }
+ }
+
+ /**
+ * Adds a short option value.
+ *
+ * @param string $shortcut The short option key
+ * @param mixed $value The value for the option
+ *
+ * @throws \InvalidArgumentException When option given doesn't exist
+ */
+ private function addShortOption($shortcut, $value)
+ {
+ if (!$this->definition->hasShortcut($shortcut)) {
+ throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
+ }
+
+ $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
+ }
+
+ /**
+ * Adds a long option value.
+ *
+ * @param string $name The long option key
+ * @param mixed $value The value for the option
+ *
+ * @throws \InvalidArgumentException When option given doesn't exist
+ * @throws \InvalidArgumentException When a required value is missing
+ */
+ private function addLongOption($name, $value)
+ {
+ if (!$this->definition->hasOption($name)) {
+ throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
+ }
+
+ $option = $this->definition->getOption($name);
+
+ if (null === $value) {
+ if ($option->isValueRequired()) {
+ throw new \InvalidArgumentException(sprintf('The "--%s" option requires a value.', $name));
+ }
+
+ $value = $option->isValueOptional() ? $option->getDefault() : true;
+ }
+
+ $this->options[$name] = $value;
+ }
+
+ /**
+ * Adds an argument value.
+ *
+ * @param string $name The argument name
+ * @param mixed $value The value for the argument
+ *
+ * @throws \InvalidArgumentException When argument given doesn't exist
+ */
+ private function addArgument($name, $value)
+ {
+ if (!$this->definition->hasArgument($name)) {
+ throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+ }
+
+ $this->arguments[$name] = $value;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Input/Input.php b/vendor/symfony/console/Symfony/Component/Console/Input/Input.php
new file mode 100644
index 0000000..5e7c140
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Input/Input.php
@@ -0,0 +1,226 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * Input is the base class for all concrete Input classes.
+ *
+ * Three concrete classes are provided by default:
+ *
+ * * `ArgvInput`: The input comes from the CLI arguments (argv)
+ * * `StringInput`: The input is provided as a string
+ * * `ArrayInput`: The input is provided as an array
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class Input implements InputInterface
+{
+ /**
+ * @var InputDefinition
+ */
+ protected $definition;
+ protected $options = array();
+ protected $arguments = array();
+ protected $interactive = true;
+
+ /**
+ * Constructor.
+ *
+ * @param InputDefinition $definition A InputDefinition instance
+ */
+ public function __construct(InputDefinition $definition = null)
+ {
+ if (null === $definition) {
+ $this->definition = new InputDefinition();
+ } else {
+ $this->bind($definition);
+ $this->validate();
+ }
+ }
+
+ /**
+ * Binds the current Input instance with the given arguments and options.
+ *
+ * @param InputDefinition $definition A InputDefinition instance
+ */
+ public function bind(InputDefinition $definition)
+ {
+ $this->arguments = array();
+ $this->options = array();
+ $this->definition = $definition;
+
+ $this->parse();
+ }
+
+ /**
+ * Processes command line arguments.
+ */
+ abstract protected function parse();
+
+ /**
+ * Validates the input.
+ *
+ * @throws \RuntimeException When not enough arguments are given
+ */
+ public function validate()
+ {
+ if (count($this->arguments) < $this->definition->getArgumentRequiredCount()) {
+ throw new \RuntimeException('Not enough arguments.');
+ }
+ }
+
+ /**
+ * Checks if the input is interactive.
+ *
+ * @return bool Returns true if the input is interactive
+ */
+ public function isInteractive()
+ {
+ return $this->interactive;
+ }
+
+ /**
+ * Sets the input interactivity.
+ *
+ * @param bool $interactive If the input should be interactive
+ */
+ public function setInteractive($interactive)
+ {
+ $this->interactive = (bool) $interactive;
+ }
+
+ /**
+ * Returns the argument values.
+ *
+ * @return array An array of argument values
+ */
+ public function getArguments()
+ {
+ return array_merge($this->definition->getArgumentDefaults(), $this->arguments);
+ }
+
+ /**
+ * Returns the argument value for a given argument name.
+ *
+ * @param string $name The argument name
+ *
+ * @return mixed The argument value
+ *
+ * @throws \InvalidArgumentException When argument given doesn't exist
+ */
+ public function getArgument($name)
+ {
+ if (!$this->definition->hasArgument($name)) {
+ throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+ }
+
+ return isset($this->arguments[$name]) ? $this->arguments[$name] : $this->definition->getArgument($name)->getDefault();
+ }
+
+ /**
+ * Sets an argument value by name.
+ *
+ * @param string $name The argument name
+ * @param string $value The argument value
+ *
+ * @throws \InvalidArgumentException When argument given doesn't exist
+ */
+ public function setArgument($name, $value)
+ {
+ if (!$this->definition->hasArgument($name)) {
+ throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+ }
+
+ $this->arguments[$name] = $value;
+ }
+
+ /**
+ * Returns true if an InputArgument object exists by name or position.
+ *
+ * @param string|int $name The InputArgument name or position
+ *
+ * @return bool true if the InputArgument object exists, false otherwise
+ */
+ public function hasArgument($name)
+ {
+ return $this->definition->hasArgument($name);
+ }
+
+ /**
+ * Returns the options values.
+ *
+ * @return array An array of option values
+ */
+ public function getOptions()
+ {
+ return array_merge($this->definition->getOptionDefaults(), $this->options);
+ }
+
+ /**
+ * Returns the option value for a given option name.
+ *
+ * @param string $name The option name
+ *
+ * @return mixed The option value
+ *
+ * @throws \InvalidArgumentException When option given doesn't exist
+ */
+ public function getOption($name)
+ {
+ if (!$this->definition->hasOption($name)) {
+ throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
+ }
+
+ return isset($this->options[$name]) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
+ }
+
+ /**
+ * Sets an option value by name.
+ *
+ * @param string $name The option name
+ * @param string|bool $value The option value
+ *
+ * @throws \InvalidArgumentException When option given doesn't exist
+ */
+ public function setOption($name, $value)
+ {
+ if (!$this->definition->hasOption($name)) {
+ throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
+ }
+
+ $this->options[$name] = $value;
+ }
+
+ /**
+ * Returns true if an InputOption object exists by name.
+ *
+ * @param string $name The InputOption name
+ *
+ * @return bool true if the InputOption object exists, false otherwise
+ */
+ public function hasOption($name)
+ {
+ return $this->definition->hasOption($name);
+ }
+
+ /**
+ * Escapes a token through escapeshellarg if it contains unsafe chars.
+ *
+ * @param string $token
+ *
+ * @return string
+ */
+ public function escapeToken($token)
+ {
+ return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token);
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Input/InputArgument.php b/vendor/symfony/console/Symfony/Component/Console/Input/InputArgument.php
new file mode 100644
index 0000000..1167da9
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Input/InputArgument.php
@@ -0,0 +1,132 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * Represents a command line argument.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class InputArgument
+{
+ const REQUIRED = 1;
+ const OPTIONAL = 2;
+ const IS_ARRAY = 4;
+
+ private $name;
+ private $mode;
+ private $default;
+ private $description;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The argument name
+ * @param int $mode The argument mode: self::REQUIRED or self::OPTIONAL
+ * @param string $description A description text
+ * @param mixed $default The default value (for self::OPTIONAL mode only)
+ *
+ * @throws \InvalidArgumentException When argument mode is not valid
+ *
+ * @api
+ */
+ public function __construct($name, $mode = null, $description = '', $default = null)
+ {
+ if (null === $mode) {
+ $mode = self::OPTIONAL;
+ } elseif (!is_int($mode) || $mode > 7 || $mode < 1) {
+ throw new \InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode));
+ }
+
+ $this->name = $name;
+ $this->mode = $mode;
+ $this->description = $description;
+
+ $this->setDefault($default);
+ }
+
+ /**
+ * Returns the argument name.
+ *
+ * @return string The argument name
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Returns true if the argument is required.
+ *
+ * @return bool true if parameter mode is self::REQUIRED, false otherwise
+ */
+ public function isRequired()
+ {
+ return self::REQUIRED === (self::REQUIRED & $this->mode);
+ }
+
+ /**
+ * Returns true if the argument can take multiple values.
+ *
+ * @return bool true if mode is self::IS_ARRAY, false otherwise
+ */
+ public function isArray()
+ {
+ return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);
+ }
+
+ /**
+ * Sets the default value.
+ *
+ * @param mixed $default The default value
+ *
+ * @throws \LogicException When incorrect default value is given
+ */
+ public function setDefault($default = null)
+ {
+ if (self::REQUIRED === $this->mode && null !== $default) {
+ throw new \LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
+ }
+
+ if ($this->isArray()) {
+ if (null === $default) {
+ $default = array();
+ } elseif (!is_array($default)) {
+ throw new \LogicException('A default value for an array argument must be an array.');
+ }
+ }
+
+ $this->default = $default;
+ }
+
+ /**
+ * Returns the default value.
+ *
+ * @return mixed The default value
+ */
+ public function getDefault()
+ {
+ return $this->default;
+ }
+
+ /**
+ * Returns the description text.
+ *
+ * @return string The description text
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Input/InputAwareInterface.php b/vendor/symfony/console/Symfony/Component/Console/Input/InputAwareInterface.php
new file mode 100644
index 0000000..d0f11e9
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Input/InputAwareInterface.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * InputAwareInterface should be implemented by classes that depends on the
+ * Console Input.
+ *
+ * @author Wouter J <waldio.webdesign@gmail.com>
+ */
+interface InputAwareInterface
+{
+ /**
+ * Sets the Console Input.
+ *
+ * @param InputInterface
+ */
+ public function setInput(InputInterface $input);
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Input/InputDefinition.php b/vendor/symfony/console/Symfony/Component/Console/Input/InputDefinition.php
new file mode 100644
index 0000000..48edb16
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Input/InputDefinition.php
@@ -0,0 +1,453 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+use Symfony\Component\Console\Descriptor\TextDescriptor;
+use Symfony\Component\Console\Descriptor\XmlDescriptor;
+use Symfony\Component\Console\Output\BufferedOutput;
+
+/**
+ * A InputDefinition represents a set of valid command line arguments and options.
+ *
+ * Usage:
+ *
+ * $definition = new InputDefinition(array(
+ * new InputArgument('name', InputArgument::REQUIRED),
+ * new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
+ * ));
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class InputDefinition
+{
+ private $arguments;
+ private $requiredCount;
+ private $hasAnArrayArgument = false;
+ private $hasOptional;
+ private $options;
+ private $shortcuts;
+
+ /**
+ * Constructor.
+ *
+ * @param array $definition An array of InputArgument and InputOption instance
+ *
+ * @api
+ */
+ public function __construct(array $definition = array())
+ {
+ $this->setDefinition($definition);
+ }
+
+ /**
+ * Sets the definition of the input.
+ *
+ * @param array $definition The definition array
+ *
+ * @api
+ */
+ public function setDefinition(array $definition)
+ {
+ $arguments = array();
+ $options = array();
+ foreach ($definition as $item) {
+ if ($item instanceof InputOption) {
+ $options[] = $item;
+ } else {
+ $arguments[] = $item;
+ }
+ }
+
+ $this->setArguments($arguments);
+ $this->setOptions($options);
+ }
+
+ /**
+ * Sets the InputArgument objects.
+ *
+ * @param InputArgument[] $arguments An array of InputArgument objects
+ *
+ * @api
+ */
+ public function setArguments($arguments = array())
+ {
+ $this->arguments = array();
+ $this->requiredCount = 0;
+ $this->hasOptional = false;
+ $this->hasAnArrayArgument = false;
+ $this->addArguments($arguments);
+ }
+
+ /**
+ * Adds an array of InputArgument objects.
+ *
+ * @param InputArgument[] $arguments An array of InputArgument objects
+ *
+ * @api
+ */
+ public function addArguments($arguments = array())
+ {
+ if (null !== $arguments) {
+ foreach ($arguments as $argument) {
+ $this->addArgument($argument);
+ }
+ }
+ }
+
+ /**
+ * Adds an InputArgument object.
+ *
+ * @param InputArgument $argument An InputArgument object
+ *
+ * @throws \LogicException When incorrect argument is given
+ *
+ * @api
+ */
+ public function addArgument(InputArgument $argument)
+ {
+ if (isset($this->arguments[$argument->getName()])) {
+ throw new \LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName()));
+ }
+
+ if ($this->hasAnArrayArgument) {
+ throw new \LogicException('Cannot add an argument after an array argument.');
+ }
+
+ if ($argument->isRequired() && $this->hasOptional) {
+ throw new \LogicException('Cannot add a required argument after an optional one.');
+ }
+
+ if ($argument->isArray()) {
+ $this->hasAnArrayArgument = true;
+ }
+
+ if ($argument->isRequired()) {
+ ++$this->requiredCount;
+ } else {
+ $this->hasOptional = true;
+ }
+
+ $this->arguments[$argument->getName()] = $argument;
+ }
+
+ /**
+ * Returns an InputArgument by name or by position.
+ *
+ * @param string|int $name The InputArgument name or position
+ *
+ * @return InputArgument An InputArgument object
+ *
+ * @throws \InvalidArgumentException When argument given doesn't exist
+ *
+ * @api
+ */
+ public function getArgument($name)
+ {
+ if (!$this->hasArgument($name)) {
+ throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+ }
+
+ $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
+
+ return $arguments[$name];
+ }
+
+ /**
+ * Returns true if an InputArgument object exists by name or position.
+ *
+ * @param string|int $name The InputArgument name or position
+ *
+ * @return bool true if the InputArgument object exists, false otherwise
+ *
+ * @api
+ */
+ public function hasArgument($name)
+ {
+ $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
+
+ return isset($arguments[$name]);
+ }
+
+ /**
+ * Gets the array of InputArgument objects.
+ *
+ * @return InputArgument[] An array of InputArgument objects
+ *
+ * @api
+ */
+ public function getArguments()
+ {
+ return $this->arguments;
+ }
+
+ /**
+ * Returns the number of InputArguments.
+ *
+ * @return int The number of InputArguments
+ */
+ public function getArgumentCount()
+ {
+ return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments);
+ }
+
+ /**
+ * Returns the number of required InputArguments.
+ *
+ * @return int The number of required InputArguments
+ */
+ public function getArgumentRequiredCount()
+ {
+ return $this->requiredCount;
+ }
+
+ /**
+ * Gets the default values.
+ *
+ * @return array An array of default values
+ */
+ public function getArgumentDefaults()
+ {
+ $values = array();
+ foreach ($this->arguments as $argument) {
+ $values[$argument->getName()] = $argument->getDefault();
+ }
+
+ return $values;
+ }
+
+ /**
+ * Sets the InputOption objects.
+ *
+ * @param InputOption[] $options An array of InputOption objects
+ *
+ * @api
+ */
+ public function setOptions($options = array())
+ {
+ $this->options = array();
+ $this->shortcuts = array();
+ $this->addOptions($options);
+ }
+
+ /**
+ * Adds an array of InputOption objects.
+ *
+ * @param InputOption[] $options An array of InputOption objects
+ *
+ * @api
+ */
+ public function addOptions($options = array())
+ {
+ foreach ($options as $option) {
+ $this->addOption($option);
+ }
+ }
+
+ /**
+ * Adds an InputOption object.
+ *
+ * @param InputOption $option An InputOption object
+ *
+ * @throws \LogicException When option given already exist
+ *
+ * @api
+ */
+ public function addOption(InputOption $option)
+ {
+ if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
+ throw new \LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
+ }
+
+ if ($option->getShortcut()) {
+ foreach (explode('|', $option->getShortcut()) as $shortcut) {
+ if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) {
+ throw new \LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut));
+ }
+ }
+ }
+
+ $this->options[$option->getName()] = $option;
+ if ($option->getShortcut()) {
+ foreach (explode('|', $option->getShortcut()) as $shortcut) {
+ $this->shortcuts[$shortcut] = $option->getName();
+ }
+ }
+ }
+
+ /**
+ * Returns an InputOption by name.
+ *
+ * @param string $name The InputOption name
+ *
+ * @return InputOption A InputOption object
+ *
+ * @throws \InvalidArgumentException When option given doesn't exist
+ *
+ * @api
+ */
+ public function getOption($name)
+ {
+ if (!$this->hasOption($name)) {
+ throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
+ }
+
+ return $this->options[$name];
+ }
+
+ /**
+ * Returns true if an InputOption object exists by name.
+ *
+ * @param string $name The InputOption name
+ *
+ * @return bool true if the InputOption object exists, false otherwise
+ *
+ * @api
+ */
+ public function hasOption($name)
+ {
+ return isset($this->options[$name]);
+ }
+
+ /**
+ * Gets the array of InputOption objects.
+ *
+ * @return InputOption[] An array of InputOption objects
+ *
+ * @api
+ */
+ public function getOptions()
+ {
+ return $this->options;
+ }
+
+ /**
+ * Returns true if an InputOption object exists by shortcut.
+ *
+ * @param string $name The InputOption shortcut
+ *
+ * @return bool true if the InputOption object exists, false otherwise
+ */
+ public function hasShortcut($name)
+ {
+ return isset($this->shortcuts[$name]);
+ }
+
+ /**
+ * Gets an InputOption by shortcut.
+ *
+ * @param string $shortcut the Shortcut name
+ *
+ * @return InputOption An InputOption object
+ */
+ public function getOptionForShortcut($shortcut)
+ {
+ return $this->getOption($this->shortcutToName($shortcut));
+ }
+
+ /**
+ * Gets an array of default values.
+ *
+ * @return array An array of all default values
+ */
+ public function getOptionDefaults()
+ {
+ $values = array();
+ foreach ($this->options as $option) {
+ $values[$option->getName()] = $option->getDefault();
+ }
+
+ return $values;
+ }
+
+ /**
+ * Returns the InputOption name given a shortcut.
+ *
+ * @param string $shortcut The shortcut
+ *
+ * @return string The InputOption name
+ *
+ * @throws \InvalidArgumentException When option given does not exist
+ */
+ private function shortcutToName($shortcut)
+ {
+ if (!isset($this->shortcuts[$shortcut])) {
+ throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
+ }
+
+ return $this->shortcuts[$shortcut];
+ }
+
+ /**
+ * Gets the synopsis.
+ *
+ * @return string The synopsis
+ */
+ public function getSynopsis()
+ {
+ $elements = array();
+ foreach ($this->getOptions() as $option) {
+ $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';
+ $elements[] = sprintf('['.($option->isValueRequired() ? '%s--%s="..."' : ($option->isValueOptional() ? '%s--%s[="..."]' : '%s--%s')).']', $shortcut, $option->getName());
+ }
+
+ foreach ($this->getArguments() as $argument) {
+ $elements[] = sprintf($argument->isRequired() ? '%s' : '[%s]', $argument->getName().($argument->isArray() ? '1' : ''));
+
+ if ($argument->isArray()) {
+ $elements[] = sprintf('... [%sN]', $argument->getName());
+ }
+ }
+
+ return implode(' ', $elements);
+ }
+
+ /**
+ * Returns a textual representation of the InputDefinition.
+ *
+ * @return string A string representing the InputDefinition
+ *
+ * @deprecated Deprecated since version 2.3, to be removed in 3.0.
+ */
+ public function asText()
+ {
+ $descriptor = new TextDescriptor();
+ $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
+ $descriptor->describe($output, $this, array('raw_output' => true));
+
+ return $output->fetch();
+ }
+
+ /**
+ * Returns an XML representation of the InputDefinition.
+ *
+ * @param bool $asDom Whether to return a DOM or an XML string
+ *
+ * @return string|\DOMDocument An XML string representing the InputDefinition
+ *
+ * @deprecated Deprecated since version 2.3, to be removed in 3.0.
+ */
+ public function asXml($asDom = false)
+ {
+ $descriptor = new XmlDescriptor();
+
+ if ($asDom) {
+ return $descriptor->getInputDefinitionDocument($this);
+ }
+
+ $output = new BufferedOutput();
+ $descriptor->describe($output, $this);
+
+ return $output->fetch();
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Input/InputInterface.php b/vendor/symfony/console/Symfony/Component/Console/Input/InputInterface.php
new file mode 100644
index 0000000..6ef2f26
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Input/InputInterface.php
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * InputInterface is the interface implemented by all input classes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface InputInterface
+{
+ /**
+ * Returns the first argument from the raw parameters (not parsed).
+ *
+ * @return string The value of the first argument or null otherwise
+ */
+ public function getFirstArgument();
+
+ /**
+ * Returns true if the raw parameters (not parsed) contain a value.
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The values to look for in the raw parameters (can be an array)
+ *
+ * @return bool true if the value is contained in the raw parameters
+ */
+ public function hasParameterOption($values);
+
+ /**
+ * Returns the value of a raw option (not parsed).
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+ * @param mixed $default The default value to return if no result is found
+ *
+ * @return mixed The option value
+ */
+ public function getParameterOption($values, $default = false);
+
+ /**
+ * Binds the current Input instance with the given arguments and options.
+ *
+ * @param InputDefinition $definition A InputDefinition instance
+ */
+ public function bind(InputDefinition $definition);
+
+ /**
+ * Validates if arguments given are correct.
+ *
+ * Throws an exception when not enough arguments are given.
+ *
+ * @throws \RuntimeException
+ */
+ public function validate();
+
+ /**
+ * Returns all the given arguments merged with the default values.
+ *
+ * @return array
+ */
+ public function getArguments();
+
+ /**
+ * Gets argument by name.
+ *
+ * @param string $name The name of the argument
+ *
+ * @return mixed
+ */
+ public function getArgument($name);
+
+ /**
+ * Sets an argument value by name.
+ *
+ * @param string $name The argument name
+ * @param string $value The argument value
+ *
+ * @throws \InvalidArgumentException When argument given doesn't exist
+ */
+ public function setArgument($name, $value);
+
+ /**
+ * Returns true if an InputArgument object exists by name or position.
+ *
+ * @param string|int $name The InputArgument name or position
+ *
+ * @return bool true if the InputArgument object exists, false otherwise
+ */
+ public function hasArgument($name);
+
+ /**
+ * Returns all the given options merged with the default values.
+ *
+ * @return array
+ */
+ public function getOptions();
+
+ /**
+ * Gets an option by name.
+ *
+ * @param string $name The name of the option
+ *
+ * @return mixed
+ */
+ public function getOption($name);
+
+ /**
+ * Sets an option value by name.
+ *
+ * @param string $name The option name
+ * @param string|bool $value The option value
+ *
+ * @throws \InvalidArgumentException When option given doesn't exist
+ */
+ public function setOption($name, $value);
+
+ /**
+ * Returns true if an InputOption object exists by name.
+ *
+ * @param string $name The InputOption name
+ *
+ * @return bool true if the InputOption object exists, false otherwise
+ */
+ public function hasOption($name);
+
+ /**
+ * Is this input means interactive?
+ *
+ * @return bool
+ */
+ public function isInteractive();
+
+ /**
+ * Sets the input interactivity.
+ *
+ * @param bool $interactive If the input should be interactive
+ */
+ public function setInteractive($interactive);
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Input/InputOption.php b/vendor/symfony/console/Symfony/Component/Console/Input/InputOption.php
new file mode 100644
index 0000000..3a48ca3
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Input/InputOption.php
@@ -0,0 +1,213 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * Represents a command line option.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class InputOption
+{
+ const VALUE_NONE = 1;
+ const VALUE_REQUIRED = 2;
+ const VALUE_OPTIONAL = 4;
+ const VALUE_IS_ARRAY = 8;
+
+ private $name;
+ private $shortcut;
+ private $mode;
+ private $default;
+ private $description;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The option name
+ * @param string|array $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
+ * @param int $mode The option mode: One of the VALUE_* constants
+ * @param string $description A description text
+ * @param mixed $default The default value (must be null for self::VALUE_REQUIRED or self::VALUE_NONE)
+ *
+ * @throws \InvalidArgumentException If option mode is invalid or incompatible
+ *
+ * @api
+ */
+ public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null)
+ {
+ if (0 === strpos($name, '--')) {
+ $name = substr($name, 2);
+ }
+
+ if (empty($name)) {
+ throw new \InvalidArgumentException('An option name cannot be empty.');
+ }
+
+ if (empty($shortcut)) {
+ $shortcut = null;
+ }
+
+ if (null !== $shortcut) {
+ if (is_array($shortcut)) {
+ $shortcut = implode('|', $shortcut);
+ }
+ $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-'));
+ $shortcuts = array_filter($shortcuts);
+ $shortcut = implode('|', $shortcuts);
+
+ if (empty($shortcut)) {
+ throw new \InvalidArgumentException('An option shortcut cannot be empty.');
+ }
+ }
+
+ if (null === $mode) {
+ $mode = self::VALUE_NONE;
+ } elseif (!is_int($mode) || $mode > 15 || $mode < 1) {
+ throw new \InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode));
+ }
+
+ $this->name = $name;
+ $this->shortcut = $shortcut;
+ $this->mode = $mode;
+ $this->description = $description;
+
+ if ($this->isArray() && !$this->acceptValue()) {
+ throw new \InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.');
+ }
+
+ $this->setDefault($default);
+ }
+
+ /**
+ * Returns the option shortcut.
+ *
+ * @return string The shortcut
+ */
+ public function getShortcut()
+ {
+ return $this->shortcut;
+ }
+
+ /**
+ * Returns the option name.
+ *
+ * @return string The name
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Returns true if the option accepts a value.
+ *
+ * @return bool true if value mode is not self::VALUE_NONE, false otherwise
+ */
+ public function acceptValue()
+ {
+ return $this->isValueRequired() || $this->isValueOptional();
+ }
+
+ /**
+ * Returns true if the option requires a value.
+ *
+ * @return bool true if value mode is self::VALUE_REQUIRED, false otherwise
+ */
+ public function isValueRequired()
+ {
+ return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode);
+ }
+
+ /**
+ * Returns true if the option takes an optional value.
+ *
+ * @return bool true if value mode is self::VALUE_OPTIONAL, false otherwise
+ */
+ public function isValueOptional()
+ {
+ return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode);
+ }
+
+ /**
+ * Returns true if the option can take multiple values.
+ *
+ * @return bool true if mode is self::VALUE_IS_ARRAY, false otherwise
+ */
+ public function isArray()
+ {
+ return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode);
+ }
+
+ /**
+ * Sets the default value.
+ *
+ * @param mixed $default The default value
+ *
+ * @throws \LogicException When incorrect default value is given
+ */
+ public function setDefault($default = null)
+ {
+ if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {
+ throw new \LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.');
+ }
+
+ if ($this->isArray()) {
+ if (null === $default) {
+ $default = array();
+ } elseif (!is_array($default)) {
+ throw new \LogicException('A default value for an array option must be an array.');
+ }
+ }
+
+ $this->default = $this->acceptValue() ? $default : false;
+ }
+
+ /**
+ * Returns the default value.
+ *
+ * @return mixed The default value
+ */
+ public function getDefault()
+ {
+ return $this->default;
+ }
+
+ /**
+ * Returns the description text.
+ *
+ * @return string The description text
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ /**
+ * Checks whether the given option equals this one.
+ *
+ * @param InputOption $option option to compare
+ *
+ * @return bool
+ */
+ public function equals(InputOption $option)
+ {
+ return $option->getName() === $this->getName()
+ && $option->getShortcut() === $this->getShortcut()
+ && $option->getDefault() === $this->getDefault()
+ && $option->isArray() === $this->isArray()
+ && $option->isValueRequired() === $this->isValueRequired()
+ && $option->isValueOptional() === $this->isValueOptional()
+ ;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Input/StringInput.php b/vendor/symfony/console/Symfony/Component/Console/Input/StringInput.php
new file mode 100644
index 0000000..6537e27
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Input/StringInput.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * StringInput represents an input provided as a string.
+ *
+ * Usage:
+ *
+ * $input = new StringInput('foo --bar="foobar"');
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class StringInput extends ArgvInput
+{
+ const REGEX_STRING = '([^\s]+?)(?:\s|(?<!\\\\)"|(?<!\\\\)\'|$)';
+ const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
+
+ /**
+ * Constructor.
+ *
+ * @param string $input An array of parameters from the CLI (in the argv format)
+ * @param InputDefinition $definition A InputDefinition instance
+ *
+ * @deprecated The second argument is deprecated as it does not work (will be removed in 3.0), use 'bind' method instead
+ *
+ * @api
+ */
+ public function __construct($input, InputDefinition $definition = null)
+ {
+ parent::__construct(array(), null);
+
+ $this->setTokens($this->tokenize($input));
+
+ if (null !== $definition) {
+ $this->bind($definition);
+ }
+ }
+
+ /**
+ * Tokenizes a string.
+ *
+ * @param string $input The input to tokenize
+ *
+ * @return array An array of tokens
+ *
+ * @throws \InvalidArgumentException When unable to parse input (should never happen)
+ */
+ private function tokenize($input)
+ {
+ $tokens = array();
+ $length = strlen($input);
+ $cursor = 0;
+ while ($cursor < $length) {
+ if (preg_match('/\s+/A', $input, $match, null, $cursor)) {
+ } elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, null, $cursor)) {
+ $tokens[] = $match[1].$match[2].stripcslashes(str_replace(array('"\'', '\'"', '\'\'', '""'), '', substr($match[3], 1, strlen($match[3]) - 2)));
+ } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, null, $cursor)) {
+ $tokens[] = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2));
+ } elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, null, $cursor)) {
+ $tokens[] = stripcslashes($match[1]);
+ } else {
+ // should never happen
+ throw new \InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10)));
+ }
+
+ $cursor += strlen($match[0]);
+ }
+
+ return $tokens;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/LICENSE b/vendor/symfony/console/Symfony/Component/Console/LICENSE
new file mode 100644
index 0000000..43028bc
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2015 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/vendor/symfony/console/Symfony/Component/Console/Logger/ConsoleLogger.php b/vendor/symfony/console/Symfony/Component/Console/Logger/ConsoleLogger.php
new file mode 100644
index 0000000..cf5d49c
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Logger/ConsoleLogger.php
@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Logger;
+
+use Psr\Log\AbstractLogger;
+use Psr\Log\InvalidArgumentException;
+use Psr\Log\LogLevel;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\ConsoleOutputInterface;
+
+/**
+ * PSR-3 compliant console logger
+ *
+ * @author Kévin Dunglas <dunglas@gmail.com>
+ * @link http://www.php-fig.org/psr/psr-3/
+ */
+class ConsoleLogger extends AbstractLogger
+{
+ const INFO = 'info';
+ const ERROR = 'error';
+
+ /**
+ * @var OutputInterface
+ */
+ private $output;
+ /**
+ * @var array
+ */
+ private $verbosityLevelMap = array(
+ LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::NOTICE => OutputInterface::VERBOSITY_VERBOSE,
+ LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE,
+ LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG,
+ );
+ /**
+ * @var array
+ */
+ private $formatLevelMap = array(
+ LogLevel::EMERGENCY => self::ERROR,
+ LogLevel::ALERT => self::ERROR,
+ LogLevel::CRITICAL => self::ERROR,
+ LogLevel::ERROR => self::ERROR,
+ LogLevel::WARNING => self::INFO,
+ LogLevel::NOTICE => self::INFO,
+ LogLevel::INFO => self::INFO,
+ LogLevel::DEBUG => self::INFO,
+ );
+
+ /**
+ * @param OutputInterface $output
+ * @param array $verbosityLevelMap
+ * @param array $formatLevelMap
+ */
+ public function __construct(OutputInterface $output, array $verbosityLevelMap = array(), array $formatLevelMap = array())
+ {
+ $this->output = $output;
+ $this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap;
+ $this->formatLevelMap = $formatLevelMap + $this->formatLevelMap;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function log($level, $message, array $context = array())
+ {
+ if (!isset($this->verbosityLevelMap[$level])) {
+ throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level));
+ }
+
+ // Write to the error output if necessary and available
+ if ($this->formatLevelMap[$level] === self::ERROR && $this->output instanceof ConsoleOutputInterface) {
+ $output = $this->output->getErrorOutput();
+ } else {
+ $output = $this->output;
+ }
+
+ if ($output->getVerbosity() >= $this->verbosityLevelMap[$level]) {
+ $output->writeln(sprintf('<%1$s>[%2$s] %3$s</%1$s>', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context)));
+ }
+ }
+
+ /**
+ * Interpolates context values into the message placeholders
+ *
+ * @author PHP Framework Interoperability Group
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return string
+ */
+ private function interpolate($message, array $context)
+ {
+ // build a replacement array with braces around the context keys
+ $replace = array();
+ foreach ($context as $key => $val) {
+ if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
+ $replace[sprintf('{%s}', $key)] = $val;
+ }
+ }
+
+ // interpolate replacement values into the message and return
+ return strtr($message, $replace);
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Output/BufferedOutput.php b/vendor/symfony/console/Symfony/Component/Console/Output/BufferedOutput.php
new file mode 100644
index 0000000..5682fc2
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Output/BufferedOutput.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class BufferedOutput extends Output
+{
+ /**
+ * @var string
+ */
+ private $buffer = '';
+
+ /**
+ * Empties buffer and returns its content.
+ *
+ * @return string
+ */
+ public function fetch()
+ {
+ $content = $this->buffer;
+ $this->buffer = '';
+
+ return $content;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doWrite($message, $newline)
+ {
+ $this->buffer .= $message;
+
+ if ($newline) {
+ $this->buffer .= "\n";
+ }
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutput.php b/vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutput.php
new file mode 100644
index 0000000..3560f1c
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutput.php
@@ -0,0 +1,113 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * ConsoleOutput is the default class for all CLI output. It uses STDOUT.
+ *
+ * This class is a convenient wrapper around `StreamOutput`.
+ *
+ * $output = new ConsoleOutput();
+ *
+ * This is equivalent to:
+ *
+ * $output = new StreamOutput(fopen('php://stdout', 'w'));
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
+{
+ private $stderr;
+
+ /**
+ * Constructor.
+ *
+ * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
+ * @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
+ * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
+ *
+ * @api
+ */
+ public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
+ {
+ $outputStream = 'php://stdout';
+ if (!$this->hasStdoutSupport()) {
+ $outputStream = 'php://output';
+ }
+
+ parent::__construct(fopen($outputStream, 'w'), $verbosity, $decorated, $formatter);
+
+ $this->stderr = new StreamOutput(fopen('php://stderr', 'w'), $verbosity, $decorated, $this->getFormatter());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDecorated($decorated)
+ {
+ parent::setDecorated($decorated);
+ $this->stderr->setDecorated($decorated);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setFormatter(OutputFormatterInterface $formatter)
+ {
+ parent::setFormatter($formatter);
+ $this->stderr->setFormatter($formatter);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setVerbosity($level)
+ {
+ parent::setVerbosity($level);
+ $this->stderr->setVerbosity($level);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getErrorOutput()
+ {
+ return $this->stderr;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setErrorOutput(OutputInterface $error)
+ {
+ $this->stderr = $error;
+ }
+
+ /**
+ * Returns true if current environment supports writing console output to
+ * STDOUT.
+ *
+ * IBM iSeries (OS400) exhibits character-encoding issues when writing to
+ * STDOUT and doesn't properly convert ASCII to EBCDIC, resulting in garbage
+ * output.
+ *
+ * @return bool
+ */
+ protected function hasStdoutSupport()
+ {
+ return ('OS400' != php_uname('s'));
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutputInterface.php b/vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutputInterface.php
new file mode 100644
index 0000000..5eb4fc7
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Output/ConsoleOutputInterface.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+/**
+ * ConsoleOutputInterface is the interface implemented by ConsoleOutput class.
+ * This adds information about stderr output stream.
+ *
+ * @author Dariusz Górecki <darek.krk@gmail.com>
+ */
+interface ConsoleOutputInterface extends OutputInterface
+{
+ /**
+ * Gets the OutputInterface for errors.
+ *
+ * @return OutputInterface
+ */
+ public function getErrorOutput();
+
+ /**
+ * Sets the OutputInterface used for errors.
+ *
+ * @param OutputInterface $error
+ */
+ public function setErrorOutput(OutputInterface $error);
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Output/NullOutput.php b/vendor/symfony/console/Symfony/Component/Console/Output/NullOutput.php
new file mode 100644
index 0000000..557f8af
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Output/NullOutput.php
@@ -0,0 +1,113 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatter;
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * NullOutput suppresses all output.
+ *
+ * $output = new NullOutput();
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Tobias Schultze <http://tobion.de>
+ *
+ * @api
+ */
+class NullOutput implements OutputInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function setFormatter(OutputFormatterInterface $formatter)
+ {
+ // do nothing
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormatter()
+ {
+ // to comply with the interface we must return a OutputFormatterInterface
+ return new OutputFormatter();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDecorated($decorated)
+ {
+ // do nothing
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isDecorated()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setVerbosity($level)
+ {
+ // do nothing
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getVerbosity()
+ {
+ return self::VERBOSITY_QUIET;
+ }
+
+ public function isQuiet()
+ {
+ return true;
+ }
+
+ public function isVerbose()
+ {
+ return false;
+ }
+
+ public function isVeryVerbose()
+ {
+ return false;
+ }
+
+ public function isDebug()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function writeln($messages, $type = self::OUTPUT_NORMAL)
+ {
+ // do nothing
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
+ {
+ // do nothing
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Output/Output.php b/vendor/symfony/console/Symfony/Component/Console/Output/Output.php
new file mode 100644
index 0000000..cb0e40d
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Output/Output.php
@@ -0,0 +1,165 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+use Symfony\Component\Console\Formatter\OutputFormatter;
+
+/**
+ * Base class for output classes.
+ *
+ * There are five levels of verbosity:
+ *
+ * * normal: no option passed (normal output)
+ * * verbose: -v (more output)
+ * * very verbose: -vv (highly extended output)
+ * * debug: -vvv (all debug output)
+ * * quiet: -q (no output)
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+abstract class Output implements OutputInterface
+{
+ private $verbosity;
+ private $formatter;
+
+ /**
+ * Constructor.
+ *
+ * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
+ * @param bool $decorated Whether to decorate messages
+ * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
+ *
+ * @api
+ */
+ public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = false, OutputFormatterInterface $formatter = null)
+ {
+ $this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity;
+ $this->formatter = $formatter ?: new OutputFormatter();
+ $this->formatter->setDecorated($decorated);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setFormatter(OutputFormatterInterface $formatter)
+ {
+ $this->formatter = $formatter;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormatter()
+ {
+ return $this->formatter;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDecorated($decorated)
+ {
+ $this->formatter->setDecorated($decorated);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isDecorated()
+ {
+ return $this->formatter->isDecorated();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setVerbosity($level)
+ {
+ $this->verbosity = (int) $level;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getVerbosity()
+ {
+ return $this->verbosity;
+ }
+
+ public function isQuiet()
+ {
+ return self::VERBOSITY_QUIET === $this->verbosity;
+ }
+
+ public function isVerbose()
+ {
+ return self::VERBOSITY_VERBOSE <= $this->verbosity;
+ }
+
+ public function isVeryVerbose()
+ {
+ return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
+ }
+
+ public function isDebug()
+ {
+ return self::VERBOSITY_DEBUG <= $this->verbosity;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function writeln($messages, $type = self::OUTPUT_NORMAL)
+ {
+ $this->write($messages, true, $type);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
+ {
+ if (self::VERBOSITY_QUIET === $this->verbosity) {
+ return;
+ }
+
+ $messages = (array) $messages;
+
+ foreach ($messages as $message) {
+ switch ($type) {
+ case OutputInterface::OUTPUT_NORMAL:
+ $message = $this->formatter->format($message);
+ break;
+ case OutputInterface::OUTPUT_RAW:
+ break;
+ case OutputInterface::OUTPUT_PLAIN:
+ $message = strip_tags($this->formatter->format($message));
+ break;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown output type given (%s)', $type));
+ }
+
+ $this->doWrite($message, $newline);
+ }
+ }
+
+ /**
+ * Writes a message to the output.
+ *
+ * @param string $message A message to write to the output
+ * @param bool $newline Whether to add a newline or not
+ */
+ abstract protected function doWrite($message, $newline);
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Output/OutputInterface.php b/vendor/symfony/console/Symfony/Component/Console/Output/OutputInterface.php
new file mode 100644
index 0000000..f7f3063
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Output/OutputInterface.php
@@ -0,0 +1,113 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * OutputInterface is the interface implemented by all Output classes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface OutputInterface
+{
+ const VERBOSITY_QUIET = 0;
+ const VERBOSITY_NORMAL = 1;
+ const VERBOSITY_VERBOSE = 2;
+ const VERBOSITY_VERY_VERBOSE = 3;
+ const VERBOSITY_DEBUG = 4;
+
+ const OUTPUT_NORMAL = 0;
+ const OUTPUT_RAW = 1;
+ const OUTPUT_PLAIN = 2;
+
+ /**
+ * Writes a message to the output.
+ *
+ * @param string|array $messages The message as an array of lines or a single string
+ * @param bool $newline Whether to add a newline
+ * @param int $type The type of output (one of the OUTPUT constants)
+ *
+ * @throws \InvalidArgumentException When unknown output type is given
+ *
+ * @api
+ */
+ public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL);
+
+ /**
+ * Writes a message to the output and adds a newline at the end.
+ *
+ * @param string|array $messages The message as an array of lines of a single string
+ * @param int $type The type of output (one of the OUTPUT constants)
+ *
+ * @throws \InvalidArgumentException When unknown output type is given
+ *
+ * @api
+ */
+ public function writeln($messages, $type = self::OUTPUT_NORMAL);
+
+ /**
+ * Sets the verbosity of the output.
+ *
+ * @param int $level The level of verbosity (one of the VERBOSITY constants)
+ *
+ * @api
+ */
+ public function setVerbosity($level);
+
+ /**
+ * Gets the current verbosity of the output.
+ *
+ * @return int The current level of verbosity (one of the VERBOSITY constants)
+ *
+ * @api
+ */
+ public function getVerbosity();
+
+ /**
+ * Sets the decorated flag.
+ *
+ * @param bool $decorated Whether to decorate the messages
+ *
+ * @api
+ */
+ public function setDecorated($decorated);
+
+ /**
+ * Gets the decorated flag.
+ *
+ * @return bool true if the output will decorate messages, false otherwise
+ *
+ * @api
+ */
+ public function isDecorated();
+
+ /**
+ * Sets output formatter.
+ *
+ * @param OutputFormatterInterface $formatter
+ *
+ * @api
+ */
+ public function setFormatter(OutputFormatterInterface $formatter);
+
+ /**
+ * Returns current output formatter instance.
+ *
+ * @return OutputFormatterInterface
+ *
+ * @api
+ */
+ public function getFormatter();
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Output/StreamOutput.php b/vendor/symfony/console/Symfony/Component/Console/Output/StreamOutput.php
new file mode 100644
index 0000000..8de10b4
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Output/StreamOutput.php
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * StreamOutput writes the output to a given stream.
+ *
+ * Usage:
+ *
+ * $output = new StreamOutput(fopen('php://stdout', 'w'));
+ *
+ * As `StreamOutput` can use any stream, you can also use a file:
+ *
+ * $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class StreamOutput extends Output
+{
+ private $stream;
+
+ /**
+ * Constructor.
+ *
+ * @param mixed $stream A stream resource
+ * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
+ * @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
+ * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
+ *
+ * @throws \InvalidArgumentException When first argument is not a real stream
+ *
+ * @api
+ */
+ public function __construct($stream, $verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
+ {
+ if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) {
+ throw new \InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
+ }
+
+ $this->stream = $stream;
+
+ if (null === $decorated) {
+ $decorated = $this->hasColorSupport();
+ }
+
+ parent::__construct($verbosity, $decorated, $formatter);
+ }
+
+ /**
+ * Gets the stream attached to this StreamOutput instance.
+ *
+ * @return resource A stream resource
+ */
+ public function getStream()
+ {
+ return $this->stream;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doWrite($message, $newline)
+ {
+ if (false === @fwrite($this->stream, $message.($newline ? PHP_EOL : ''))) {
+ // should never happen
+ throw new \RuntimeException('Unable to write output.');
+ }
+
+ fflush($this->stream);
+ }
+
+ /**
+ * Returns true if the stream supports colorization.
+ *
+ * Colorization is disabled if not supported by the stream:
+ *
+ * - Windows without Ansicon and ConEmu
+ * - non tty consoles
+ *
+ * @return bool true if the stream supports colorization, false otherwise
+ */
+ protected function hasColorSupport()
+ {
+ if (DIRECTORY_SEPARATOR == '\\') {
+ return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI');
+ }
+
+ return function_exists('posix_isatty') && @posix_isatty($this->stream);
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Question/ChoiceQuestion.php b/vendor/symfony/console/Symfony/Component/Console/Question/ChoiceQuestion.php
new file mode 100644
index 0000000..e1da7a8
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Question/ChoiceQuestion.php
@@ -0,0 +1,150 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Question;
+
+/**
+ * Represents a choice question.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ChoiceQuestion extends Question
+{
+ private $choices;
+ private $multiselect = false;
+ private $prompt = ' > ';
+ private $errorMessage = 'Value "%s" is invalid';
+
+ /**
+ * Constructor.
+ *
+ * @param string $question The question to ask to the user
+ * @param array $choices The list of available choices
+ * @param mixed $default The default answer to return
+ */
+ public function __construct($question, array $choices, $default = null)
+ {
+ parent::__construct($question, $default);
+
+ $this->choices = $choices;
+ $this->setValidator($this->getDefaultValidator());
+ $this->setAutocompleterValues(array_keys($choices));
+ }
+
+ /**
+ * Returns available choices.
+ *
+ * @return array
+ */
+ public function getChoices()
+ {
+ return $this->choices;
+ }
+
+ /**
+ * Sets multiselect option.
+ *
+ * When multiselect is set to true, multiple choices can be answered.
+ *
+ * @param bool $multiselect
+ *
+ * @return ChoiceQuestion The current instance
+ */
+ public function setMultiselect($multiselect)
+ {
+ $this->multiselect = $multiselect;
+ $this->setValidator($this->getDefaultValidator());
+
+ return $this;
+ }
+
+ /**
+ * Gets the prompt for choices.
+ *
+ * @return string
+ */
+ public function getPrompt()
+ {
+ return $this->prompt;
+ }
+
+ /**
+ * Sets the prompt for choices.
+ *
+ * @param string $prompt
+ *
+ * @return ChoiceQuestion The current instance
+ */
+ public function setPrompt($prompt)
+ {
+ $this->prompt = $prompt;
+
+ return $this;
+ }
+
+ /**
+ * Sets the error message for invalid values.
+ *
+ * The error message has a string placeholder (%s) for the invalid value.
+ *
+ * @param string $errorMessage
+ *
+ * @return ChoiceQuestion The current instance
+ */
+ public function setErrorMessage($errorMessage)
+ {
+ $this->errorMessage = $errorMessage;
+ $this->setValidator($this->getDefaultValidator());
+
+ return $this;
+ }
+
+ /**
+ * Returns the default answer validator.
+ *
+ * @return callable
+ */
+ private function getDefaultValidator()
+ {
+ $choices = $this->choices;
+ $errorMessage = $this->errorMessage;
+ $multiselect = $this->multiselect;
+
+ return function ($selected) use ($choices, $errorMessage, $multiselect) {
+ // Collapse all spaces.
+ $selectedChoices = str_replace(' ', '', $selected);
+
+ if ($multiselect) {
+ // Check for a separated comma values
+ if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
+ throw new \InvalidArgumentException(sprintf($errorMessage, $selected));
+ }
+ $selectedChoices = explode(',', $selectedChoices);
+ } else {
+ $selectedChoices = array($selected);
+ }
+
+ $multiselectChoices = array();
+ foreach ($selectedChoices as $value) {
+ if (empty($choices[$value])) {
+ throw new \InvalidArgumentException(sprintf($errorMessage, $value));
+ }
+ array_push($multiselectChoices, $choices[$value]);
+ }
+
+ if ($multiselect) {
+ return $multiselectChoices;
+ }
+
+ return $choices[$selected];
+ };
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Question/ConfirmationQuestion.php b/vendor/symfony/console/Symfony/Component/Console/Question/ConfirmationQuestion.php
new file mode 100644
index 0000000..09ac74f
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Question/ConfirmationQuestion.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Question;
+
+/**
+ * Represents a yes/no question.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ConfirmationQuestion extends Question
+{
+ /**
+ * Constructor.
+ *
+ * @param string $question The question to ask to the user
+ * @param bool $default The default answer to return, true or false
+ */
+ public function __construct($question, $default = true)
+ {
+ parent::__construct($question, (bool) $default);
+
+ $this->setNormalizer($this->getDefaultNormalizer());
+ }
+
+ /**
+ * Returns the default answer normalizer.
+ *
+ * @return callable
+ */
+ private function getDefaultNormalizer()
+ {
+ $default = $this->getDefault();
+
+ return function ($answer) use ($default) {
+ if (is_bool($answer)) {
+ return $answer;
+ }
+
+ if (false === $default) {
+ return $answer && 'y' === strtolower($answer[0]);
+ }
+
+ return !$answer || 'y' === strtolower($answer[0]);
+ };
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Question/Question.php b/vendor/symfony/console/Symfony/Component/Console/Question/Question.php
new file mode 100644
index 0000000..9f776d5
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Question/Question.php
@@ -0,0 +1,238 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Question;
+
+/**
+ * Represents a Question.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Question
+{
+ private $question;
+ private $attempts;
+ private $hidden = false;
+ private $hiddenFallback = true;
+ private $autocompleterValues;
+ private $validator;
+ private $default;
+ private $normalizer;
+
+ /**
+ * Constructor.
+ *
+ * @param string $question The question to ask to the user
+ * @param mixed $default The default answer to return if the user enters nothing
+ */
+ public function __construct($question, $default = null)
+ {
+ $this->question = $question;
+ $this->default = $default;
+ }
+
+ /**
+ * Returns the question.
+ *
+ * @return string
+ */
+ public function getQuestion()
+ {
+ return $this->question;
+ }
+
+ /**
+ * Returns the default answer.
+ *
+ * @return mixed
+ */
+ public function getDefault()
+ {
+ return $this->default;
+ }
+
+ /**
+ * Returns whether the user response must be hidden.
+ *
+ * @return bool
+ */
+ public function isHidden()
+ {
+ return $this->hidden;
+ }
+
+ /**
+ * Sets whether the user response must be hidden or not.
+ *
+ * @param bool $hidden
+ *
+ * @return Question The current instance
+ *
+ * @throws \LogicException In case the autocompleter is also used
+ */
+ public function setHidden($hidden)
+ {
+ if ($this->autocompleterValues) {
+ throw new \LogicException('A hidden question cannot use the autocompleter.');
+ }
+
+ $this->hidden = (bool) $hidden;
+
+ return $this;
+ }
+
+ /**
+ * In case the response can not be hidden, whether to fallback on non-hidden question or not.
+ *
+ * @return bool
+ */
+ public function isHiddenFallback()
+ {
+ return $this->hiddenFallback;
+ }
+
+ /**
+ * Sets whether to fallback on non-hidden question if the response can not be hidden.
+ *
+ * @param bool $fallback
+ *
+ * @return Question The current instance
+ */
+ public function setHiddenFallback($fallback)
+ {
+ $this->hiddenFallback = (bool) $fallback;
+
+ return $this;
+ }
+
+ /**
+ * Gets values for the autocompleter.
+ *
+ * @return null|array|\Traversable
+ */
+ public function getAutocompleterValues()
+ {
+ return $this->autocompleterValues;
+ }
+
+ /**
+ * Sets values for the autocompleter.
+ *
+ * @param null|array|\Traversable $values
+ *
+ * @return Question The current instance
+ *
+ * @throws \InvalidArgumentException
+ * @throws \LogicException
+ */
+ public function setAutocompleterValues($values)
+ {
+ if (null !== $values && !is_array($values)) {
+ if (!$values instanceof \Traversable || $values instanceof \Countable) {
+ throw new \InvalidArgumentException('Autocompleter values can be either an array, `null` or an object implementing both `Countable` and `Traversable` interfaces.');
+ }
+ }
+
+ if ($this->hidden) {
+ throw new \LogicException('A hidden question cannot use the autocompleter.');
+ }
+
+ $this->autocompleterValues = $values;
+
+ return $this;
+ }
+
+ /**
+ * Sets a validator for the question.
+ *
+ * @param null|callable $validator
+ *
+ * @return Question The current instance
+ */
+ public function setValidator($validator)
+ {
+ $this->validator = $validator;
+
+ return $this;
+ }
+
+ /**
+ * Gets the validator for the question.
+ *
+ * @return null|callable
+ */
+ public function getValidator()
+ {
+ return $this->validator;
+ }
+
+ /**
+ * Sets the maximum number of attempts.
+ *
+ * Null means an unlimited number of attempts.
+ *
+ * @param null|int $attempts
+ *
+ * @return Question The current instance
+ *
+ * @throws \InvalidArgumentException In case the number of attempts is invalid.
+ */
+ public function setMaxAttempts($attempts)
+ {
+ if (null !== $attempts && $attempts < 1) {
+ throw new \InvalidArgumentException('Maximum number of attempts must be a positive value.');
+ }
+
+ $this->attempts = $attempts;
+
+ return $this;
+ }
+
+ /**
+ * Gets the maximum number of attempts.
+ *
+ * Null means an unlimited number of attempts.
+ *
+ * @return null|int
+ */
+ public function getMaxAttempts()
+ {
+ return $this->attempts;
+ }
+
+ /**
+ * Sets a normalizer for the response.
+ *
+ * The normalizer can be a callable (a string), a closure or a class implementing __invoke.
+ *
+ * @param string|\Closure $normalizer
+ *
+ * @return Question The current instance
+ */
+ public function setNormalizer($normalizer)
+ {
+ $this->normalizer = $normalizer;
+
+ return $this;
+ }
+
+ /**
+ * Gets the normalizer for the response.
+ *
+ * The normalizer can ba a callable (a string), a closure or a class implementing __invoke.
+ *
+ * @return string|\Closure
+ */
+ public function getNormalizer()
+ {
+ return $this->normalizer;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/README.md b/vendor/symfony/console/Symfony/Component/Console/README.md
new file mode 100644
index 0000000..9804144
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/README.md
@@ -0,0 +1,67 @@
+Console Component
+=================
+
+Console eases the creation of beautiful and testable command line interfaces.
+
+The Application object manages the CLI application:
+
+```php
+use Symfony\Component\Console\Application;
+
+$console = new Application();
+$console->run();
+```
+
+The ``run()`` method parses the arguments and options passed on the command
+line and executes the right command.
+
+Registering a new command can easily be done via the ``register()`` method,
+which returns a ``Command`` instance:
+
+```php
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+$console
+ ->register('ls')
+ ->setDefinition(array(
+ new InputArgument('dir', InputArgument::REQUIRED, 'Directory name'),
+ ))
+ ->setDescription('Displays the files in the given directory')
+ ->setCode(function (InputInterface $input, OutputInterface $output) {
+ $dir = $input->getArgument('dir');
+
+ $output->writeln(sprintf('Dir listing for <info>%s</info>', $dir));
+ })
+;
+```
+
+You can also register new commands via classes.
+
+The component provides a lot of features like output coloring, input and
+output abstractions (so that you can easily unit-test your commands),
+validation, automatic help messages, ...
+
+Tests
+-----
+
+You can run the unit tests with the following command:
+
+ $ cd path/to/Symfony/Component/Console/
+ $ composer install
+ $ phpunit
+
+Third Party
+-----------
+
+`Resources/bin/hiddeninput.exe` is a third party binary provided within this
+component. Find sources and license at https://github.com/Seldaek/hidden-input.
+
+Resources
+---------
+
+[The Console Component](http://symfony.com/doc/current/components/console.html)
+
+[How to create a Console Command](http://symfony.com/doc/current/cookbook/console/console_command.html)
diff --git a/vendor/symfony/console/Symfony/Component/Console/Resources/bin/hiddeninput.exe b/vendor/symfony/console/Symfony/Component/Console/Resources/bin/hiddeninput.exe
new file mode 100644
index 0000000..c8cf65e
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Resources/bin/hiddeninput.exe
Binary files differ
diff --git a/vendor/symfony/console/Symfony/Component/Console/Shell.php b/vendor/symfony/console/Symfony/Component/Console/Shell.php
new file mode 100644
index 0000000..4167746
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Shell.php
@@ -0,0 +1,228 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console;
+
+use Symfony\Component\Console\Input\StringInput;
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Process\ProcessBuilder;
+use Symfony\Component\Process\PhpExecutableFinder;
+
+/**
+ * A Shell wraps an Application to add shell capabilities to it.
+ *
+ * Support for history and completion only works with a PHP compiled
+ * with readline support (either --with-readline or --with-libedit)
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Martin Hasoň <martin.hason@gmail.com>
+ */
+class Shell
+{
+ private $application;
+ private $history;
+ private $output;
+ private $hasReadline;
+ private $processIsolation = false;
+
+ /**
+ * Constructor.
+ *
+ * If there is no readline support for the current PHP executable
+ * a \RuntimeException exception is thrown.
+ *
+ * @param Application $application An application instance
+ */
+ public function __construct(Application $application)
+ {
+ $this->hasReadline = function_exists('readline');
+ $this->application = $application;
+ $this->history = getenv('HOME').'/.history_'.$application->getName();
+ $this->output = new ConsoleOutput();
+ }
+
+ /**
+ * Runs the shell.
+ */
+ public function run()
+ {
+ $this->application->setAutoExit(false);
+ $this->application->setCatchExceptions(true);
+
+ if ($this->hasReadline) {
+ readline_read_history($this->history);
+ readline_completion_function(array($this, 'autocompleter'));
+ }
+
+ $this->output->writeln($this->getHeader());
+ $php = null;
+ if ($this->processIsolation) {
+ $finder = new PhpExecutableFinder();
+ $php = $finder->find();
+ $this->output->writeln(<<<EOF
+<info>Running with process isolation, you should consider this:</info>
+ * each command is executed as separate process,
+ * commands don't support interactivity, all params must be passed explicitly,
+ * commands output is not colorized.
+
+EOF
+ );
+ }
+
+ while (true) {
+ $command = $this->readline();
+
+ if (false === $command) {
+ $this->output->writeln("\n");
+
+ break;
+ }
+
+ if ($this->hasReadline) {
+ readline_add_history($command);
+ readline_write_history($this->history);
+ }
+
+ if ($this->processIsolation) {
+ $pb = new ProcessBuilder();
+
+ $process = $pb
+ ->add($php)
+ ->add($_SERVER['argv'][0])
+ ->add($command)
+ ->inheritEnvironmentVariables(true)
+ ->getProcess()
+ ;
+
+ $output = $this->output;
+ $process->run(function ($type, $data) use ($output) {
+ $output->writeln($data);
+ });
+
+ $ret = $process->getExitCode();
+ } else {
+ $ret = $this->application->run(new StringInput($command), $this->output);
+ }
+
+ if (0 !== $ret) {
+ $this->output->writeln(sprintf('<error>The command terminated with an error status (%s)</error>', $ret));
+ }
+ }
+ }
+
+ /**
+ * Returns the shell header.
+ *
+ * @return string The header string
+ */
+ protected function getHeader()
+ {
+ return <<<EOF
+
+Welcome to the <info>{$this->application->getName()}</info> shell (<comment>{$this->application->getVersion()}</comment>).
+
+At the prompt, type <comment>help</comment> for some help,
+or <comment>list</comment> to get a list of available commands.
+
+To exit the shell, type <comment>^D</comment>.
+
+EOF;
+ }
+
+ /**
+ * Renders a prompt.
+ *
+ * @return string The prompt
+ */
+ protected function getPrompt()
+ {
+ // using the formatter here is required when using readline
+ return $this->output->getFormatter()->format($this->application->getName().' > ');
+ }
+
+ protected function getOutput()
+ {
+ return $this->output;
+ }
+
+ protected function getApplication()
+ {
+ return $this->application;
+ }
+
+ /**
+ * Tries to return autocompletion for the current entered text.
+ *
+ * @param string $text The last segment of the entered text
+ *
+ * @return bool|array A list of guessed strings or true
+ */
+ private function autocompleter($text)
+ {
+ $info = readline_info();
+ $text = substr($info['line_buffer'], 0, $info['end']);
+
+ if ($info['point'] !== $info['end']) {
+ return true;
+ }
+
+ // task name?
+ if (false === strpos($text, ' ') || !$text) {
+ return array_keys($this->application->all());
+ }
+
+ // options and arguments?
+ try {
+ $command = $this->application->find(substr($text, 0, strpos($text, ' ')));
+ } catch (\Exception $e) {
+ return true;
+ }
+
+ $list = array('--help');
+ foreach ($command->getDefinition()->getOptions() as $option) {
+ $list[] = '--'.$option->getName();
+ }
+
+ return $list;
+ }
+
+ /**
+ * Reads a single line from standard input.
+ *
+ * @return string The single line from standard input
+ */
+ private function readline()
+ {
+ if ($this->hasReadline) {
+ $line = readline($this->getPrompt());
+ } else {
+ $this->output->write($this->getPrompt());
+ $line = fgets(STDIN, 1024);
+ $line = (!$line && strlen($line) == 0) ? false : rtrim($line);
+ }
+
+ return $line;
+ }
+
+ public function getProcessIsolation()
+ {
+ return $this->processIsolation;
+ }
+
+ public function setProcessIsolation($processIsolation)
+ {
+ $this->processIsolation = (bool) $processIsolation;
+
+ if ($this->processIsolation && !class_exists('Symfony\\Component\\Process\\Process')) {
+ throw new \RuntimeException('Unable to isolate processes as the Symfony Process Component is not installed.');
+ }
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php b/vendor/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php
new file mode 100644
index 0000000..da8a19c
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tester/ApplicationTester.php
@@ -0,0 +1,128 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tester;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\StreamOutput;
+
+/**
+ * Eases the testing of console applications.
+ *
+ * When testing an application, don't forget to disable the auto exit flag:
+ *
+ * $application = new Application();
+ * $application->setAutoExit(false);
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ApplicationTester
+{
+ private $application;
+ private $input;
+ private $output;
+ private $statusCode;
+
+ /**
+ * Constructor.
+ *
+ * @param Application $application An Application instance to test.
+ */
+ public function __construct(Application $application)
+ {
+ $this->application = $application;
+ }
+
+ /**
+ * Executes the application.
+ *
+ * Available options:
+ *
+ * * interactive: Sets the input interactive flag
+ * * decorated: Sets the output decorated flag
+ * * verbosity: Sets the output verbosity flag
+ *
+ * @param array $input An array of arguments and options
+ * @param array $options An array of options
+ *
+ * @return int The command exit code
+ */
+ public function run(array $input, $options = array())
+ {
+ $this->input = new ArrayInput($input);
+ if (isset($options['interactive'])) {
+ $this->input->setInteractive($options['interactive']);
+ }
+
+ $this->output = new StreamOutput(fopen('php://memory', 'w', false));
+ if (isset($options['decorated'])) {
+ $this->output->setDecorated($options['decorated']);
+ }
+ if (isset($options['verbosity'])) {
+ $this->output->setVerbosity($options['verbosity']);
+ }
+
+ return $this->statusCode = $this->application->run($this->input, $this->output);
+ }
+
+ /**
+ * Gets the display returned by the last execution of the application.
+ *
+ * @param bool $normalize Whether to normalize end of lines to \n or not
+ *
+ * @return string The display
+ */
+ public function getDisplay($normalize = false)
+ {
+ rewind($this->output->getStream());
+
+ $display = stream_get_contents($this->output->getStream());
+
+ if ($normalize) {
+ $display = str_replace(PHP_EOL, "\n", $display);
+ }
+
+ return $display;
+ }
+
+ /**
+ * Gets the input instance used by the last execution of the application.
+ *
+ * @return InputInterface The current input instance
+ */
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ /**
+ * Gets the output instance used by the last execution of the application.
+ *
+ * @return OutputInterface The current output instance
+ */
+ public function getOutput()
+ {
+ return $this->output;
+ }
+
+ /**
+ * Gets the status code returned by the last execution of the application.
+ *
+ * @return int The status code
+ */
+ public function getStatusCode()
+ {
+ return $this->statusCode;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tester/CommandTester.php b/vendor/symfony/console/Symfony/Component/Console/Tester/CommandTester.php
new file mode 100644
index 0000000..a6d5359
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tester/CommandTester.php
@@ -0,0 +1,132 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tester;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Output\StreamOutput;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Eases the testing of console commands.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class CommandTester
+{
+ private $command;
+ private $input;
+ private $output;
+ private $statusCode;
+
+ /**
+ * Constructor.
+ *
+ * @param Command $command A Command instance to test.
+ */
+ public function __construct(Command $command)
+ {
+ $this->command = $command;
+ }
+
+ /**
+ * Executes the command.
+ *
+ * Available execution options:
+ *
+ * * interactive: Sets the input interactive flag
+ * * decorated: Sets the output decorated flag
+ * * verbosity: Sets the output verbosity flag
+ *
+ * @param array $input An array of command arguments and options
+ * @param array $options An array of execution options
+ *
+ * @return int The command exit code
+ */
+ public function execute(array $input, array $options = array())
+ {
+ // set the command name automatically if the application requires
+ // this argument and no command name was passed
+ if (!isset($input['command'])
+ && (null !== $application = $this->command->getApplication())
+ && $application->getDefinition()->hasArgument('command')
+ ) {
+ $input['command'] = $this->command->getName();
+ }
+
+ $this->input = new ArrayInput($input);
+ if (isset($options['interactive'])) {
+ $this->input->setInteractive($options['interactive']);
+ }
+
+ $this->output = new StreamOutput(fopen('php://memory', 'w', false));
+ if (isset($options['decorated'])) {
+ $this->output->setDecorated($options['decorated']);
+ }
+ if (isset($options['verbosity'])) {
+ $this->output->setVerbosity($options['verbosity']);
+ }
+
+ return $this->statusCode = $this->command->run($this->input, $this->output);
+ }
+
+ /**
+ * Gets the display returned by the last execution of the command.
+ *
+ * @param bool $normalize Whether to normalize end of lines to \n or not
+ *
+ * @return string The display
+ */
+ public function getDisplay($normalize = false)
+ {
+ rewind($this->output->getStream());
+
+ $display = stream_get_contents($this->output->getStream());
+
+ if ($normalize) {
+ $display = str_replace(PHP_EOL, "\n", $display);
+ }
+
+ return $display;
+ }
+
+ /**
+ * Gets the input instance used by the last execution of the command.
+ *
+ * @return InputInterface The current input instance
+ */
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ /**
+ * Gets the output instance used by the last execution of the command.
+ *
+ * @return OutputInterface The current output instance
+ */
+ public function getOutput()
+ {
+ return $this->output;
+ }
+
+ /**
+ * Gets the status code returned by the last execution of the application.
+ *
+ * @return int The status code
+ */
+ public function getStatusCode()
+ {
+ return $this->statusCode;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/ApplicationTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/ApplicationTest.php
new file mode 100644
index 0000000..1fa6c64
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/ApplicationTest.php
@@ -0,0 +1,1060 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Helper\FormatterHelper;
+use Symfony\Component\Console\Input\ArgvInput;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\NullOutput;
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\StreamOutput;
+use Symfony\Component\Console\Tester\ApplicationTester;
+use Symfony\Component\Console\Event\ConsoleCommandEvent;
+use Symfony\Component\Console\Event\ConsoleExceptionEvent;
+use Symfony\Component\Console\Event\ConsoleTerminateEvent;
+use Symfony\Component\EventDispatcher\EventDispatcher;
+
+class ApplicationTest extends \PHPUnit_Framework_TestCase
+{
+ protected static $fixturesPath;
+
+ public static function setUpBeforeClass()
+ {
+ self::$fixturesPath = realpath(__DIR__.'/Fixtures/');
+ require_once self::$fixturesPath.'/FooCommand.php';
+ require_once self::$fixturesPath.'/Foo1Command.php';
+ require_once self::$fixturesPath.'/Foo2Command.php';
+ require_once self::$fixturesPath.'/Foo3Command.php';
+ require_once self::$fixturesPath.'/Foo4Command.php';
+ require_once self::$fixturesPath.'/Foo5Command.php';
+ require_once self::$fixturesPath.'/FoobarCommand.php';
+ require_once self::$fixturesPath.'/BarBucCommand.php';
+ require_once self::$fixturesPath.'/FooSubnamespaced1Command.php';
+ require_once self::$fixturesPath.'/FooSubnamespaced2Command.php';
+ }
+
+ protected function normalizeLineBreaks($text)
+ {
+ return str_replace(PHP_EOL, "\n", $text);
+ }
+
+ /**
+ * Replaces the dynamic placeholders of the command help text with a static version.
+ * The placeholder %command.full_name% includes the script path that is not predictable
+ * and can not be tested against.
+ */
+ protected function ensureStaticCommandHelp(Application $application)
+ {
+ foreach ($application->all() as $command) {
+ $command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp()));
+ }
+ }
+
+ public function testConstructor()
+ {
+ $application = new Application('foo', 'bar');
+ $this->assertEquals('foo', $application->getName(), '__construct() takes the application name as its first argument');
+ $this->assertEquals('bar', $application->getVersion(), '__construct() takes the application version as its second argument');
+ $this->assertEquals(array('help', 'list'), array_keys($application->all()), '__construct() registered the help and list commands by default');
+ }
+
+ public function testSetGetName()
+ {
+ $application = new Application();
+ $application->setName('foo');
+ $this->assertEquals('foo', $application->getName(), '->setName() sets the name of the application');
+ }
+
+ public function testSetGetVersion()
+ {
+ $application = new Application();
+ $application->setVersion('bar');
+ $this->assertEquals('bar', $application->getVersion(), '->setVersion() sets the version of the application');
+ }
+
+ public function testGetLongVersion()
+ {
+ $application = new Application('foo', 'bar');
+ $this->assertEquals('<info>foo</info> version <comment>bar</comment>', $application->getLongVersion(), '->getLongVersion() returns the long version of the application');
+ }
+
+ public function testHelp()
+ {
+ $application = new Application();
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_gethelp.txt', $this->normalizeLineBreaks($application->getHelp()), '->getHelp() returns a help message');
+ }
+
+ public function testAll()
+ {
+ $application = new Application();
+ $commands = $application->all();
+ $this->assertInstanceOf('Symfony\\Component\\Console\\Command\\HelpCommand', $commands['help'], '->all() returns the registered commands');
+
+ $application->add(new \FooCommand());
+ $commands = $application->all('foo');
+ $this->assertCount(1, $commands, '->all() takes a namespace as its first argument');
+ }
+
+ public function testRegister()
+ {
+ $application = new Application();
+ $command = $application->register('foo');
+ $this->assertEquals('foo', $command->getName(), '->register() registers a new command');
+ }
+
+ public function testAdd()
+ {
+ $application = new Application();
+ $application->add($foo = new \FooCommand());
+ $commands = $application->all();
+ $this->assertEquals($foo, $commands['foo:bar'], '->add() registers a command');
+
+ $application = new Application();
+ $application->addCommands(array($foo = new \FooCommand(), $foo1 = new \Foo1Command()));
+ $commands = $application->all();
+ $this->assertEquals(array($foo, $foo1), array($commands['foo:bar'], $commands['foo:bar1']), '->addCommands() registers an array of commands');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage Command class "Foo5Command" is not correctly initialized. You probably forgot to call the parent constructor.
+ */
+ public function testAddCommandWithEmptyConstructor()
+ {
+ $application = new Application();
+ $application->add(new \Foo5Command());
+ }
+
+ public function testHasGet()
+ {
+ $application = new Application();
+ $this->assertTrue($application->has('list'), '->has() returns true if a named command is registered');
+ $this->assertFalse($application->has('afoobar'), '->has() returns false if a named command is not registered');
+
+ $application->add($foo = new \FooCommand());
+ $this->assertTrue($application->has('afoobar'), '->has() returns true if an alias is registered');
+ $this->assertEquals($foo, $application->get('foo:bar'), '->get() returns a command by name');
+ $this->assertEquals($foo, $application->get('afoobar'), '->get() returns a command by alias');
+
+ $application = new Application();
+ $application->add($foo = new \FooCommand());
+ // simulate --help
+ $r = new \ReflectionObject($application);
+ $p = $r->getProperty('wantHelps');
+ $p->setAccessible(true);
+ $p->setValue($application, true);
+ $command = $application->get('foo:bar');
+ $this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $command, '->get() returns the help command if --help is provided as the input');
+ }
+
+ public function testSilentHelp()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('-h' => true, '-q' => true), array('decorated' => false));
+
+ $this->assertEmpty($tester->getDisplay(true));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The command "foofoo" does not exist.
+ */
+ public function testGetInvalidCommand()
+ {
+ $application = new Application();
+ $application->get('foofoo');
+ }
+
+ public function testGetNamespaces()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $this->assertEquals(array('foo'), $application->getNamespaces(), '->getNamespaces() returns an array of unique used namespaces');
+ }
+
+ public function testFindNamespace()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists');
+ $this->assertEquals('foo', $application->findNamespace('f'), '->findNamespace() finds a namespace given an abbreviation');
+ $application->add(new \Foo2Command());
+ $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists');
+ }
+
+ public function testFindNamespaceWithSubnamespaces()
+ {
+ $application = new Application();
+ $application->add(new \FooSubnamespaced1Command());
+ $application->add(new \FooSubnamespaced2Command());
+ $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns commands even if the commands are only contained in subnamespaces');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The namespace "f" is ambiguous (foo, foo1).
+ */
+ public function testFindAmbiguousNamespace()
+ {
+ $application = new Application();
+ $application->add(new \BarBucCommand());
+ $application->add(new \FooCommand());
+ $application->add(new \Foo2Command());
+ $application->findNamespace('f');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage There are no commands defined in the "bar" namespace.
+ */
+ public function testFindInvalidNamespace()
+ {
+ $application = new Application();
+ $application->findNamespace('bar');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Command "foo1" is not defined
+ */
+ public function testFindUniqueNameButNamespaceName()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+
+ $application->find($commandName = 'foo1');
+ }
+
+ public function testFind()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+
+ $this->assertInstanceOf('FooCommand', $application->find('foo:bar'), '->find() returns a command if its name exists');
+ $this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $application->find('h'), '->find() returns a command if its name exists');
+ $this->assertInstanceOf('FooCommand', $application->find('f:bar'), '->find() returns a command if the abbreviation for the namespace exists');
+ $this->assertInstanceOf('FooCommand', $application->find('f:b'), '->find() returns a command if the abbreviation for the namespace and the command name exist');
+ $this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias');
+ }
+
+ /**
+ * @dataProvider provideAmbiguousAbbreviations
+ */
+ public function testFindWithAmbiguousAbbreviations($abbreviation, $expectedExceptionMessage)
+ {
+ $this->setExpectedException('InvalidArgumentException', $expectedExceptionMessage);
+
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+
+ $application->find($abbreviation);
+ }
+
+ public function provideAmbiguousAbbreviations()
+ {
+ return array(
+ array('f', 'Command "f" is not defined.'),
+ array('a', 'Command "a" is ambiguous (afoobar, afoobar1 and 1 more).'),
+ array('foo:b', 'Command "foo:b" is ambiguous (foo:bar, foo:bar1 and 1 more).'),
+ );
+ }
+
+ public function testFindCommandEqualNamespace()
+ {
+ $application = new Application();
+ $application->add(new \Foo3Command());
+ $application->add(new \Foo4Command());
+
+ $this->assertInstanceOf('Foo3Command', $application->find('foo3:bar'), '->find() returns the good command even if a namespace has same name');
+ $this->assertInstanceOf('Foo4Command', $application->find('foo3:bar:toh'), '->find() returns a command even if its namespace equals another command name');
+ }
+
+ public function testFindCommandWithAmbiguousNamespacesButUniqueName()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \FoobarCommand());
+
+ $this->assertInstanceOf('FoobarCommand', $application->find('f:f'));
+ }
+
+ public function testFindCommandWithMissingNamespace()
+ {
+ $application = new Application();
+ $application->add(new \Foo4Command());
+
+ $this->assertInstanceOf('Foo4Command', $application->find('f::t'));
+ }
+
+ /**
+ * @dataProvider provideInvalidCommandNamesSingle
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Did you mean this
+ */
+ public function testFindAlternativeExceptionMessageSingle($name)
+ {
+ $application = new Application();
+ $application->add(new \Foo3Command());
+ $application->find($name);
+ }
+
+ public function provideInvalidCommandNamesSingle()
+ {
+ return array(
+ array('foo3:baR'),
+ array('foO3:bar'),
+ );
+ }
+
+ public function testFindAlternativeExceptionMessageMultiple()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+
+ // Command + plural
+ try {
+ $application->find('foo:baR');
+ $this->fail('->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ $this->assertRegExp('/foo1:bar/', $e->getMessage());
+ $this->assertRegExp('/foo:bar/', $e->getMessage());
+ }
+
+ // Namespace + plural
+ try {
+ $application->find('foo2:bar');
+ $this->fail('->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ $this->assertRegExp('/foo1/', $e->getMessage());
+ }
+
+ $application->add(new \Foo3Command());
+ $application->add(new \Foo4Command());
+
+ // Subnamespace + plural
+ try {
+ $a = $application->find('foo3:');
+ $this->fail('->find() should throw an \InvalidArgumentException if a command is ambiguous because of a subnamespace, with alternatives');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e);
+ $this->assertRegExp('/foo3:bar/', $e->getMessage());
+ $this->assertRegExp('/foo3:bar:toh/', $e->getMessage());
+ }
+ }
+
+ public function testFindAlternativeCommands()
+ {
+ $application = new Application();
+
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+
+ try {
+ $application->find($commandName = 'Unknown command');
+ $this->fail('->find() throws an \InvalidArgumentException if command does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if command does not exist');
+ $this->assertEquals(sprintf('Command "%s" is not defined.', $commandName), $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, without alternatives');
+ }
+
+ // Test if "bar1" command throw an "\InvalidArgumentException" and does not contain
+ // "foo:bar" as alternative because "bar1" is too far from "foo:bar"
+ try {
+ $application->find($commandName = 'bar1');
+ $this->fail('->find() throws an \InvalidArgumentException if command does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if command does not exist');
+ $this->assertRegExp(sprintf('/Command "%s" is not defined./', $commandName), $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternatives');
+ $this->assertRegExp('/afoobar1/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternative : "afoobar1"');
+ $this->assertRegExp('/foo:bar1/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, with alternative : "foo:bar1"');
+ $this->assertNotRegExp('/foo:bar(?>!1)/', $e->getMessage(), '->find() throws an \InvalidArgumentException if command does not exist, without "foo:bar" alternative');
+ }
+ }
+
+ public function testFindAlternativeCommandsWithAnAlias()
+ {
+ $fooCommand = new \FooCommand();
+ $fooCommand->setAliases(array('foo2'));
+
+ $application = new Application();
+ $application->add($fooCommand);
+
+ $result = $application->find('foo');
+
+ $this->assertSame($fooCommand, $result);
+ }
+
+ public function testFindAlternativeNamespace()
+ {
+ $application = new Application();
+
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+ $application->add(new \foo3Command());
+
+ try {
+ $application->find('Unknown-namespace:Unknown-command');
+ $this->fail('->find() throws an \InvalidArgumentException if namespace does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if namespace does not exist');
+ $this->assertEquals('There are no commands defined in the "Unknown-namespace" namespace.', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, without alternatives');
+ }
+
+ try {
+ $application->find('foo2:command');
+ $this->fail('->find() throws an \InvalidArgumentException if namespace does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if namespace does not exist');
+ $this->assertRegExp('/There are no commands defined in the "foo2" namespace./', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, with alternative');
+ $this->assertRegExp('/foo/', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, with alternative : "foo"');
+ $this->assertRegExp('/foo1/', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, with alternative : "foo1"');
+ $this->assertRegExp('/foo3/', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, with alternative : "foo3"');
+ }
+ }
+
+ public function testFindNamespaceDoesNotFailOnDeepSimilarNamespaces()
+ {
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getNamespaces'));
+ $application->expects($this->once())
+ ->method('getNamespaces')
+ ->will($this->returnValue(array('foo:sublong', 'bar:sub')));
+
+ $this->assertEquals('foo:sublong', $application->findNamespace('f:sub'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Command "foo::bar" is not defined.
+ */
+ public function testFindWithDoubleColonInNameThrowsException()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo4Command());
+ $application->find('foo::bar');
+ }
+
+ public function testSetCatchExceptions()
+ {
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(120));
+ $tester = new ApplicationTester($application);
+
+ $application->setCatchExceptions(true);
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getDisplay(true), '->setCatchExceptions() sets the catch exception flag');
+
+ $application->setCatchExceptions(false);
+ try {
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->fail('->setCatchExceptions() sets the catch exception flag');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\Exception', $e, '->setCatchExceptions() sets the catch exception flag');
+ $this->assertEquals('Command "foo" is not defined.', $e->getMessage(), '->setCatchExceptions() sets the catch exception flag');
+ }
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testLegacyAsText()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $this->ensureStaticCommandHelp($application);
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_astext1.txt', $this->normalizeLineBreaks($application->asText()), '->asText() returns a text representation of the application');
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_astext2.txt', $this->normalizeLineBreaks($application->asText('foo')), '->asText() returns a text representation of the application');
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testLegacyAsXml()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $this->ensureStaticCommandHelp($application);
+ $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/application_asxml1.txt', $application->asXml(), '->asXml() returns an XML representation of the application');
+ $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/application_asxml2.txt', $application->asXml('foo'), '->asXml() returns an XML representation of the application');
+ }
+
+ public function testRenderException()
+ {
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(120));
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getDisplay(true), '->renderException() renders a pretty exception');
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
+ $this->assertContains('Exception trace', $tester->getDisplay(), '->renderException() renders a pretty exception with a stack trace when verbosity is verbose');
+
+ $tester->run(array('command' => 'list', '--foo' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception2.txt', $tester->getDisplay(true), '->renderException() renders the command synopsis when an exception occurs in the context of a command');
+
+ $application->add(new \Foo3Command());
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo3:bar'), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');
+
+ $tester->run(array('command' => 'foo3:bar'), array('decorated' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');
+
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(32));
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception4.txt', $tester->getDisplay(true), '->renderException() wraps messages when they are bigger than the terminal');
+ }
+
+ public function testRenderExceptionWithDoubleWidthCharacters()
+ {
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(120));
+ $application->register('foo')->setCode(function () {
+ throw new \Exception('エラーメッセージ');
+ });
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth1.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');
+
+ $tester->run(array('command' => 'foo'), array('decorated' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth1decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');
+
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(32));
+ $application->register('foo')->setCode(function () {
+ throw new \Exception('コマンドの実行中にエラーが発生しました。');
+ });
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth2.txt', $tester->getDisplay(true), '->renderException() wraps messages when they are bigger than the terminal');
+ }
+
+ public function testRun()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application->add($command = new \Foo1Command());
+ $_SERVER['argv'] = array('cli.php', 'foo:bar1');
+
+ ob_start();
+ $application->run();
+ ob_end_clean();
+
+ $this->assertInstanceOf('Symfony\Component\Console\Input\ArgvInput', $command->input, '->run() creates an ArgvInput by default if none is given');
+ $this->assertInstanceOf('Symfony\Component\Console\Output\ConsoleOutput', $command->output, '->run() creates a ConsoleOutput by default if none is given');
+
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $this->ensureStaticCommandHelp($application);
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array(), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run1.txt', $tester->getDisplay(true), '->run() runs the list command if no argument is passed');
+
+ $tester->run(array('--help' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if --help is passed');
+
+ $tester->run(array('-h' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if -h is passed');
+
+ $tester->run(array('command' => 'list', '--help' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if --help is passed');
+
+ $tester->run(array('command' => 'list', '-h' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if -h is passed');
+
+ $tester->run(array('--ansi' => true));
+ $this->assertTrue($tester->getOutput()->isDecorated(), '->run() forces color output if --ansi is passed');
+
+ $tester->run(array('--no-ansi' => true));
+ $this->assertFalse($tester->getOutput()->isDecorated(), '->run() forces color output to be disabled if --no-ansi is passed');
+
+ $tester->run(array('--version' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if --version is passed');
+
+ $tester->run(array('-V' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if -v is passed');
+
+ $tester->run(array('command' => 'list', '--quiet' => true));
+ $this->assertSame('', $tester->getDisplay(), '->run() removes all output if --quiet is passed');
+
+ $tester->run(array('command' => 'list', '-q' => true));
+ $this->assertSame('', $tester->getDisplay(), '->run() removes all output if -q is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => true));
+ $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => 1));
+ $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose=1 is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => 2));
+ $this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to very verbose if --verbose=2 is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => 3));
+ $this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to debug if --verbose=3 is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => 4));
+ $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if unknown --verbose level is passed');
+
+ $tester->run(array('command' => 'list', '-v' => true));
+ $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');
+
+ $tester->run(array('command' => 'list', '-vv' => true));
+ $this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');
+
+ $tester->run(array('command' => 'list', '-vvv' => true));
+ $this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');
+
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application->add(new \FooCommand());
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array('command' => 'foo:bar', '--no-interaction' => true), array('decorated' => false));
+ $this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if --no-interaction is passed');
+
+ $tester->run(array('command' => 'foo:bar', '-n' => true), array('decorated' => false));
+ $this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if -n is passed');
+ }
+
+ /**
+ * Issue #9285
+ *
+ * If the "verbose" option is just before an argument in ArgvInput,
+ * an argument value should not be treated as verbosity value.
+ * This test will fail with "Not enough arguments." if broken
+ */
+ public function testVerboseValueNotBreakArguments()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application->add(new \FooCommand());
+
+ $output = new StreamOutput(fopen('php://memory', 'w', false));
+
+ $input = new ArgvInput(array('cli.php', '-v', 'foo:bar'));
+ $application->run($input, $output);
+
+ $input = new ArgvInput(array('cli.php', '--verbose', 'foo:bar'));
+ $application->run($input, $output);
+ }
+
+ public function testRunReturnsIntegerExitCode()
+ {
+ $exception = new \Exception('', 4);
+
+ $application = $this->getMock('Symfony\Component\Console\Application', array('doRun'));
+ $application->setAutoExit(false);
+ $application->expects($this->once())
+ ->method('doRun')
+ ->will($this->throwException($exception));
+
+ $exitCode = $application->run(new ArrayInput(array()), new NullOutput());
+
+ $this->assertSame(4, $exitCode, '->run() returns integer exit code extracted from raised exception');
+ }
+
+ public function testRunReturnsExitCodeOneForExceptionCodeZero()
+ {
+ $exception = new \Exception('', 0);
+
+ $application = $this->getMock('Symfony\Component\Console\Application', array('doRun'));
+ $application->setAutoExit(false);
+ $application->expects($this->once())
+ ->method('doRun')
+ ->will($this->throwException($exception));
+
+ $exitCode = $application->run(new ArrayInput(array()), new NullOutput());
+
+ $this->assertSame(1, $exitCode, '->run() returns exit code 1 when exception code is 0');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @dataProvider getAddingAlreadySetDefinitionElementData
+ */
+ public function testAddingAlreadySetDefinitionElementData($def)
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application
+ ->register('foo')
+ ->setDefinition(array($def))
+ ->setCode(function (InputInterface $input, OutputInterface $output) {})
+ ;
+
+ $input = new ArrayInput(array('command' => 'foo'));
+ $output = new NullOutput();
+ $application->run($input, $output);
+ }
+
+ public function getAddingAlreadySetDefinitionElementData()
+ {
+ return array(
+ array(new InputArgument('command', InputArgument::REQUIRED)),
+ array(new InputOption('quiet', '', InputOption::VALUE_NONE)),
+ array(new InputOption('query', 'q', InputOption::VALUE_NONE)),
+ );
+ }
+
+ public function testGetDefaultHelperSetReturnsDefaultValues()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $helperSet = $application->getHelperSet();
+
+ $this->assertTrue($helperSet->has('formatter'));
+ $this->assertTrue($helperSet->has('dialog'));
+ $this->assertTrue($helperSet->has('progress'));
+ }
+
+ public function testAddingSingleHelperSetOverwritesDefaultValues()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $application->setHelperSet(new HelperSet(array(new FormatterHelper())));
+
+ $helperSet = $application->getHelperSet();
+
+ $this->assertTrue($helperSet->has('formatter'));
+
+ // no other default helper set should be returned
+ $this->assertFalse($helperSet->has('dialog'));
+ $this->assertFalse($helperSet->has('progress'));
+ }
+
+ public function testOverwritingDefaultHelperSetOverwritesDefaultValues()
+ {
+ $application = new CustomApplication();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $application->setHelperSet(new HelperSet(array(new FormatterHelper())));
+
+ $helperSet = $application->getHelperSet();
+
+ $this->assertTrue($helperSet->has('formatter'));
+
+ // no other default helper set should be returned
+ $this->assertFalse($helperSet->has('dialog'));
+ $this->assertFalse($helperSet->has('progress'));
+ }
+
+ public function testGetDefaultInputDefinitionReturnsDefaultValues()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $inputDefinition = $application->getDefinition();
+
+ $this->assertTrue($inputDefinition->hasArgument('command'));
+
+ $this->assertTrue($inputDefinition->hasOption('help'));
+ $this->assertTrue($inputDefinition->hasOption('quiet'));
+ $this->assertTrue($inputDefinition->hasOption('verbose'));
+ $this->assertTrue($inputDefinition->hasOption('version'));
+ $this->assertTrue($inputDefinition->hasOption('ansi'));
+ $this->assertTrue($inputDefinition->hasOption('no-ansi'));
+ $this->assertTrue($inputDefinition->hasOption('no-interaction'));
+ }
+
+ public function testOverwritingDefaultInputDefinitionOverwritesDefaultValues()
+ {
+ $application = new CustomApplication();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $inputDefinition = $application->getDefinition();
+
+ // check whether the default arguments and options are not returned any more
+ $this->assertFalse($inputDefinition->hasArgument('command'));
+
+ $this->assertFalse($inputDefinition->hasOption('help'));
+ $this->assertFalse($inputDefinition->hasOption('quiet'));
+ $this->assertFalse($inputDefinition->hasOption('verbose'));
+ $this->assertFalse($inputDefinition->hasOption('version'));
+ $this->assertFalse($inputDefinition->hasOption('ansi'));
+ $this->assertFalse($inputDefinition->hasOption('no-ansi'));
+ $this->assertFalse($inputDefinition->hasOption('no-interaction'));
+
+ $this->assertTrue($inputDefinition->hasOption('custom'));
+ }
+
+ public function testSettingCustomInputDefinitionOverwritesDefaultValues()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $application->setDefinition(new InputDefinition(array(new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.'))));
+
+ $inputDefinition = $application->getDefinition();
+
+ // check whether the default arguments and options are not returned any more
+ $this->assertFalse($inputDefinition->hasArgument('command'));
+
+ $this->assertFalse($inputDefinition->hasOption('help'));
+ $this->assertFalse($inputDefinition->hasOption('quiet'));
+ $this->assertFalse($inputDefinition->hasOption('verbose'));
+ $this->assertFalse($inputDefinition->hasOption('version'));
+ $this->assertFalse($inputDefinition->hasOption('ansi'));
+ $this->assertFalse($inputDefinition->hasOption('no-ansi'));
+ $this->assertFalse($inputDefinition->hasOption('no-interaction'));
+
+ $this->assertTrue($inputDefinition->hasOption('custom'));
+ }
+
+ public function testRunWithDispatcher()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setDispatcher($this->getDispatcher());
+
+ $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
+ $output->write('foo.');
+ });
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo'));
+ $this->assertEquals('before.foo.after.', $tester->getDisplay());
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage caught
+ */
+ public function testRunWithExceptionAndDispatcher()
+ {
+ $application = new Application();
+ $application->setDispatcher($this->getDispatcher());
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
+ throw new \RuntimeException('foo');
+ });
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo'));
+ }
+
+ public function testRunDispatchesAllEventsWithException()
+ {
+ $application = new Application();
+ $application->setDispatcher($this->getDispatcher());
+ $application->setAutoExit(false);
+
+ $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
+ $output->write('foo.');
+
+ throw new \RuntimeException('foo');
+ });
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo'));
+ $this->assertContains('before.foo.after.caught.', $tester->getDisplay());
+ }
+
+ public function testRunWithDispatcherSkippingCommand()
+ {
+ $application = new Application();
+ $application->setDispatcher($this->getDispatcher(true));
+ $application->setAutoExit(false);
+
+ $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
+ $output->write('foo.');
+ });
+
+ $tester = new ApplicationTester($application);
+ $exitCode = $tester->run(array('command' => 'foo'));
+ $this->assertContains('before.after.', $tester->getDisplay());
+ $this->assertEquals(ConsoleCommandEvent::RETURN_CODE_DISABLED, $exitCode);
+ }
+
+ public function testTerminalDimensions()
+ {
+ $application = new Application();
+ $originalDimensions = $application->getTerminalDimensions();
+ $this->assertCount(2, $originalDimensions);
+
+ $width = 80;
+ if ($originalDimensions[0] == $width) {
+ $width = 100;
+ }
+
+ $application->setTerminalDimensions($width, 80);
+ $this->assertSame(array($width, 80), $application->getTerminalDimensions());
+ }
+
+ protected function getDispatcher($skipCommand = false)
+ {
+ $dispatcher = new EventDispatcher();
+ $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use ($skipCommand) {
+ $event->getOutput()->write('before.');
+
+ if ($skipCommand) {
+ $event->disableCommand();
+ }
+ });
+ $dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use ($skipCommand) {
+ $event->getOutput()->write('after.');
+
+ if (!$skipCommand) {
+ $event->setExitCode(113);
+ }
+ });
+ $dispatcher->addListener('console.exception', function (ConsoleExceptionEvent $event) {
+ $event->getOutput()->writeln('caught.');
+
+ $event->setException(new \LogicException('caught.', $event->getExitCode(), $event->getException()));
+ });
+
+ return $dispatcher;
+ }
+
+ public function testSetRunCustomDefaultCommand()
+ {
+ $command = new \FooCommand();
+
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->add($command);
+ $application->setDefaultCommand($command->getName());
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array());
+ $this->assertEquals('interact called'.PHP_EOL.'called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');
+
+ $application = new CustomDefaultCommandApplication();
+ $application->setAutoExit(false);
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array());
+
+ $this->assertEquals('interact called'.PHP_EOL.'called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');
+ }
+
+ public function testCanCheckIfTerminalIsInteractive()
+ {
+ if (!function_exists('posix_isatty')) {
+ $this->markTestSkipped('posix_isatty function is required');
+ }
+
+ $application = new CustomDefaultCommandApplication();
+ $application->setAutoExit(false);
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'help'));
+
+ $this->assertFalse($tester->getInput()->hasParameterOption(array('--no-interaction', '-n')));
+
+ $inputStream = $application->getHelperSet()->get('question')->getInputStream();
+ $this->assertEquals($tester->getInput()->isInteractive(), @posix_isatty($inputStream));
+ }
+}
+
+class CustomApplication extends Application
+{
+ /**
+ * Overwrites the default input definition.
+ *
+ * @return InputDefinition An InputDefinition instance
+ */
+ protected function getDefaultInputDefinition()
+ {
+ return new InputDefinition(array(new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.')));
+ }
+
+ /**
+ * Gets the default helper set with the helpers that should always be available.
+ *
+ * @return HelperSet A HelperSet instance
+ */
+ protected function getDefaultHelperSet()
+ {
+ return new HelperSet(array(new FormatterHelper()));
+ }
+}
+
+class CustomDefaultCommandApplication extends Application
+{
+ /**
+ * Overwrites the constructor in order to set a different default command.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ $command = new \FooCommand();
+ $this->add($command);
+ $this->setDefaultCommand($command->getName());
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Command/CommandTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Command/CommandTest.php
new file mode 100644
index 0000000..c35617d
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Command/CommandTest.php
@@ -0,0 +1,348 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\FormatterHelper;
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\StringInput;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\NullOutput;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class CommandTest extends \PHPUnit_Framework_TestCase
+{
+ protected static $fixturesPath;
+
+ public static function setUpBeforeClass()
+ {
+ self::$fixturesPath = __DIR__.'/../Fixtures/';
+ require_once self::$fixturesPath.'/TestCommand.php';
+ }
+
+ public function testConstructor()
+ {
+ $command = new Command('foo:bar');
+ $this->assertEquals('foo:bar', $command->getName(), '__construct() takes the command name as its first argument');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage The command defined in "Symfony\Component\Console\Command\Command" cannot have an empty name.
+ */
+ public function testCommandNameCannotBeEmpty()
+ {
+ new Command();
+ }
+
+ public function testSetApplication()
+ {
+ $application = new Application();
+ $command = new \TestCommand();
+ $command->setApplication($application);
+ $this->assertEquals($application, $command->getApplication(), '->setApplication() sets the current application');
+ }
+
+ public function testSetGetDefinition()
+ {
+ $command = new \TestCommand();
+ $ret = $command->setDefinition($definition = new InputDefinition());
+ $this->assertEquals($command, $ret, '->setDefinition() implements a fluent interface');
+ $this->assertEquals($definition, $command->getDefinition(), '->setDefinition() sets the current InputDefinition instance');
+ $command->setDefinition(array(new InputArgument('foo'), new InputOption('bar')));
+ $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument');
+ $this->assertTrue($command->getDefinition()->hasOption('bar'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument');
+ $command->setDefinition(new InputDefinition());
+ }
+
+ public function testAddArgument()
+ {
+ $command = new \TestCommand();
+ $ret = $command->addArgument('foo');
+ $this->assertEquals($command, $ret, '->addArgument() implements a fluent interface');
+ $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->addArgument() adds an argument to the command');
+ }
+
+ public function testAddOption()
+ {
+ $command = new \TestCommand();
+ $ret = $command->addOption('foo');
+ $this->assertEquals($command, $ret, '->addOption() implements a fluent interface');
+ $this->assertTrue($command->getDefinition()->hasOption('foo'), '->addOption() adds an option to the command');
+ }
+
+ public function testGetNamespaceGetNameSetName()
+ {
+ $command = new \TestCommand();
+ $this->assertEquals('namespace:name', $command->getName(), '->getName() returns the command name');
+ $command->setName('foo');
+ $this->assertEquals('foo', $command->getName(), '->setName() sets the command name');
+
+ $ret = $command->setName('foobar:bar');
+ $this->assertEquals($command, $ret, '->setName() implements a fluent interface');
+ $this->assertEquals('foobar:bar', $command->getName(), '->setName() sets the command name');
+ }
+
+ /**
+ * @dataProvider provideInvalidCommandNames
+ */
+ public function testInvalidCommandNames($name)
+ {
+ $this->setExpectedException('InvalidArgumentException', sprintf('Command name "%s" is invalid.', $name));
+
+ $command = new \TestCommand();
+ $command->setName($name);
+ }
+
+ public function provideInvalidCommandNames()
+ {
+ return array(
+ array(''),
+ array('foo:'),
+ );
+ }
+
+ public function testGetSetDescription()
+ {
+ $command = new \TestCommand();
+ $this->assertEquals('description', $command->getDescription(), '->getDescription() returns the description');
+ $ret = $command->setDescription('description1');
+ $this->assertEquals($command, $ret, '->setDescription() implements a fluent interface');
+ $this->assertEquals('description1', $command->getDescription(), '->setDescription() sets the description');
+ }
+
+ public function testGetSetHelp()
+ {
+ $command = new \TestCommand();
+ $this->assertEquals('help', $command->getHelp(), '->getHelp() returns the help');
+ $ret = $command->setHelp('help1');
+ $this->assertEquals($command, $ret, '->setHelp() implements a fluent interface');
+ $this->assertEquals('help1', $command->getHelp(), '->setHelp() sets the help');
+ }
+
+ public function testGetProcessedHelp()
+ {
+ $command = new \TestCommand();
+ $command->setHelp('The %command.name% command does... Example: php %command.full_name%.');
+ $this->assertContains('The namespace:name command does...', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.name% correctly');
+ $this->assertNotContains('%command.full_name%', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.full_name%');
+ }
+
+ public function testGetSetAliases()
+ {
+ $command = new \TestCommand();
+ $this->assertEquals(array('name'), $command->getAliases(), '->getAliases() returns the aliases');
+ $ret = $command->setAliases(array('name1'));
+ $this->assertEquals($command, $ret, '->setAliases() implements a fluent interface');
+ $this->assertEquals(array('name1'), $command->getAliases(), '->setAliases() sets the aliases');
+ }
+
+ public function testGetSynopsis()
+ {
+ $command = new \TestCommand();
+ $command->addOption('foo');
+ $command->addArgument('foo');
+ $this->assertEquals('namespace:name [--foo] [foo]', $command->getSynopsis(), '->getSynopsis() returns the synopsis');
+ }
+
+ public function testGetHelper()
+ {
+ $application = new Application();
+ $command = new \TestCommand();
+ $command->setApplication($application);
+ $formatterHelper = new FormatterHelper();
+ $this->assertEquals($formatterHelper->getName(), $command->getHelper('formatter')->getName(), '->getHelper() returns the correct helper');
+ }
+
+ public function testGet()
+ {
+ $application = new Application();
+ $command = new \TestCommand();
+ $command->setApplication($application);
+ $formatterHelper = new FormatterHelper();
+ $this->assertEquals($formatterHelper->getName(), $command->getHelper('formatter')->getName(), '->__get() returns the correct helper');
+ }
+
+ public function testMergeApplicationDefinition()
+ {
+ $application1 = new Application();
+ $application1->getDefinition()->addArguments(array(new InputArgument('foo')));
+ $application1->getDefinition()->addOptions(array(new InputOption('bar')));
+ $command = new \TestCommand();
+ $command->setApplication($application1);
+ $command->setDefinition($definition = new InputDefinition(array(new InputArgument('bar'), new InputOption('foo'))));
+
+ $r = new \ReflectionObject($command);
+ $m = $r->getMethod('mergeApplicationDefinition');
+ $m->setAccessible(true);
+ $m->invoke($command);
+ $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition() merges the application arguments and the command arguments');
+ $this->assertTrue($command->getDefinition()->hasArgument('bar'), '->mergeApplicationDefinition() merges the application arguments and the command arguments');
+ $this->assertTrue($command->getDefinition()->hasOption('foo'), '->mergeApplicationDefinition() merges the application options and the command options');
+ $this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition() merges the application options and the command options');
+
+ $m->invoke($command);
+ $this->assertEquals(3, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments and options');
+ }
+
+ public function testMergeApplicationDefinitionWithoutArgsThenWithArgsAddsArgs()
+ {
+ $application1 = new Application();
+ $application1->getDefinition()->addArguments(array(new InputArgument('foo')));
+ $application1->getDefinition()->addOptions(array(new InputOption('bar')));
+ $command = new \TestCommand();
+ $command->setApplication($application1);
+ $command->setDefinition($definition = new InputDefinition(array()));
+
+ $r = new \ReflectionObject($command);
+ $m = $r->getMethod('mergeApplicationDefinition');
+ $m->setAccessible(true);
+ $m->invoke($command, false);
+ $this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition(false) merges the application and the command options');
+ $this->assertFalse($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(false) does not merge the application arguments');
+
+ $m->invoke($command, true);
+ $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(true) merges the application arguments and the command arguments');
+
+ $m->invoke($command);
+ $this->assertEquals(2, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments');
+ }
+
+ public function testRunInteractive()
+ {
+ $tester = new CommandTester(new \TestCommand());
+
+ $tester->execute(array(), array('interactive' => true));
+
+ $this->assertEquals('interact called'.PHP_EOL.'execute called'.PHP_EOL, $tester->getDisplay(), '->run() calls the interact() method if the input is interactive');
+ }
+
+ public function testRunNonInteractive()
+ {
+ $tester = new CommandTester(new \TestCommand());
+
+ $tester->execute(array(), array('interactive' => false));
+
+ $this->assertEquals('execute called'.PHP_EOL, $tester->getDisplay(), '->run() does not call the interact() method if the input is not interactive');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage You must override the execute() method in the concrete command class.
+ */
+ public function testExecuteMethodNeedsToBeOverridden()
+ {
+ $command = new Command('foo');
+ $command->run(new StringInput(''), new NullOutput());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "--bar" option does not exist.
+ */
+ public function testRunWithInvalidOption()
+ {
+ $command = new \TestCommand();
+ $tester = new CommandTester($command);
+ $tester->execute(array('--bar' => true));
+ }
+
+ public function testRunReturnsIntegerExitCode()
+ {
+ $command = new \TestCommand();
+ $exitCode = $command->run(new StringInput(''), new NullOutput());
+ $this->assertSame(0, $exitCode, '->run() returns integer exit code (treats null as 0)');
+
+ $command = $this->getMock('TestCommand', array('execute'));
+ $command->expects($this->once())
+ ->method('execute')
+ ->will($this->returnValue('2.3'));
+ $exitCode = $command->run(new StringInput(''), new NullOutput());
+ $this->assertSame(2, $exitCode, '->run() returns integer exit code (casts numeric to int)');
+ }
+
+ public function testRunReturnsAlwaysInteger()
+ {
+ $command = new \TestCommand();
+
+ $this->assertSame(0, $command->run(new StringInput(''), new NullOutput()));
+ }
+
+ public function testSetCode()
+ {
+ $command = new \TestCommand();
+ $ret = $command->setCode(function (InputInterface $input, OutputInterface $output) {
+ $output->writeln('from the code...');
+ });
+ $this->assertEquals($command, $ret, '->setCode() implements a fluent interface');
+ $tester = new CommandTester($command);
+ $tester->execute(array());
+ $this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay());
+ }
+
+ public function testSetCodeWithNonClosureCallable()
+ {
+ $command = new \TestCommand();
+ $ret = $command->setCode(array($this, 'callableMethodCommand'));
+ $this->assertEquals($command, $ret, '->setCode() implements a fluent interface');
+ $tester = new CommandTester($command);
+ $tester->execute(array());
+ $this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Invalid callable provided to Command::setCode.
+ */
+ public function testSetCodeWithNonCallable()
+ {
+ $command = new \TestCommand();
+ $command->setCode(array($this, 'nonExistentMethod'));
+ }
+
+ public function callableMethodCommand(InputInterface $input, OutputInterface $output)
+ {
+ $output->writeln('from the code...');
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testLegacyAsText()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ $command = new \TestCommand();
+ $command->setApplication(new Application());
+ $tester = new CommandTester($command);
+ $tester->execute(array('command' => $command->getName()));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/command_astext.txt', $command->asText(), '->asText() returns a text representation of the command');
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testLegacyAsXml()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ $command = new \TestCommand();
+ $command->setApplication(new Application());
+ $tester = new CommandTester($command);
+ $tester->execute(array('command' => $command->getName()));
+ $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/command_asxml.txt', $command->asXml(), '->asXml() returns an XML representation of the command');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Command/HelpCommandTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Command/HelpCommandTest.php
new file mode 100644
index 0000000..ea69c8b
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Command/HelpCommandTest.php
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Command;
+
+use Symfony\Component\Console\Tester\CommandTester;
+use Symfony\Component\Console\Command\HelpCommand;
+use Symfony\Component\Console\Command\ListCommand;
+use Symfony\Component\Console\Application;
+
+class HelpCommandTest extends \PHPUnit_Framework_TestCase
+{
+ public function testExecuteForCommandAlias()
+ {
+ $command = new HelpCommand();
+ $command->setApplication(new Application());
+ $commandTester = new CommandTester($command);
+ $commandTester->execute(array('command_name' => 'li'));
+ $this->assertRegExp('/list \[--xml\] \[--raw\] \[--format="\.\.\."\] \[namespace\]/', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
+ }
+
+ public function testExecuteForCommand()
+ {
+ $command = new HelpCommand();
+ $commandTester = new CommandTester($command);
+ $command->setCommand(new ListCommand());
+ $commandTester->execute(array());
+ $this->assertRegExp('/list \[--xml\] \[--raw\] \[--format="\.\.\."\] \[namespace\]/', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
+ }
+
+ public function testExecuteForCommandWithXmlOption()
+ {
+ $command = new HelpCommand();
+ $commandTester = new CommandTester($command);
+ $command->setCommand(new ListCommand());
+ $commandTester->execute(array('--format' => 'xml'));
+ $this->assertRegExp('/<command/', $commandTester->getDisplay(), '->execute() returns an XML help text if --xml is passed');
+ }
+
+ public function testExecuteForApplicationCommand()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($application->get('help'));
+ $commandTester->execute(array('command_name' => 'list'));
+ $this->assertRegExp('/list \[--xml\] \[--raw\] \[--format="\.\.\."\] \[namespace\]/', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
+ }
+
+ public function testExecuteForApplicationCommandWithXmlOption()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($application->get('help'));
+ $commandTester->execute(array('command_name' => 'list', '--format' => 'xml'));
+ $this->assertRegExp('/list \[--xml\] \[--raw\] \[--format="\.\.\."\] \[namespace\]/', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
+ $this->assertRegExp('/<command/', $commandTester->getDisplay(), '->execute() returns an XML help text if --format=xml is passed');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Command/ListCommandTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Command/ListCommandTest.php
new file mode 100644
index 0000000..fbb9fee
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Command/ListCommandTest.php
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Command;
+
+use Symfony\Component\Console\Tester\CommandTester;
+use Symfony\Component\Console\Application;
+
+class ListCommandTest extends \PHPUnit_Framework_TestCase
+{
+ public function testExecuteListsCommands()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName()), array('decorated' => false));
+
+ $this->assertRegExp('/help Displays help for a command/', $commandTester->getDisplay(), '->execute() returns a list of available commands');
+ }
+
+ public function testExecuteListsCommandsWithXmlOption()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName(), '--format' => 'xml'));
+ $this->assertRegExp('/<command id="list" name="list">/', $commandTester->getDisplay(), '->execute() returns a list of available commands in XML if --xml is passed');
+ }
+
+ public function testExecuteListsCommandsWithRawOption()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName(), '--raw' => true));
+ $output = <<<EOF
+help Displays help for a command
+list Lists commands
+
+EOF;
+
+ $this->assertEquals($output, $commandTester->getDisplay(true));
+ }
+
+ public function testExecuteListsCommandsWithNamespaceArgument()
+ {
+ require_once realpath(__DIR__.'/../Fixtures/FooCommand.php');
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName(), 'namespace' => 'foo', '--raw' => true));
+ $output = <<<EOF
+foo:bar The foo:bar command
+
+EOF;
+
+ $this->assertEquals($output, $commandTester->getDisplay(true));
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php
new file mode 100644
index 0000000..406c659
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\BufferedOutput;
+
+abstract class AbstractDescriptorTest extends \PHPUnit_Framework_TestCase
+{
+ /** @dataProvider getDescribeInputArgumentTestData */
+ public function testDescribeInputArgument(InputArgument $argument, $expectedDescription)
+ {
+ $this->assertDescription($expectedDescription, $argument);
+ }
+
+ /** @dataProvider getDescribeInputOptionTestData */
+ public function testDescribeInputOption(InputOption $option, $expectedDescription)
+ {
+ $this->assertDescription($expectedDescription, $option);
+ }
+
+ /** @dataProvider getDescribeInputDefinitionTestData */
+ public function testDescribeInputDefinition(InputDefinition $definition, $expectedDescription)
+ {
+ $this->assertDescription($expectedDescription, $definition);
+ }
+
+ /** @dataProvider getDescribeCommandTestData */
+ public function testDescribeCommand(Command $command, $expectedDescription)
+ {
+ $this->assertDescription($expectedDescription, $command);
+ }
+
+ /** @dataProvider getDescribeApplicationTestData */
+ public function testDescribeApplication(Application $application, $expectedDescription)
+ {
+ // Replaces the dynamic placeholders of the command help text with a static version.
+ // The placeholder %command.full_name% includes the script path that is not predictable
+ // and can not be tested against.
+ foreach ($application->all() as $command) {
+ $command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp()));
+ }
+
+ $this->assertDescription($expectedDescription, $application);
+ }
+
+ public function getDescribeInputArgumentTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getInputArguments());
+ }
+
+ public function getDescribeInputOptionTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getInputOptions());
+ }
+
+ public function getDescribeInputDefinitionTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getInputDefinitions());
+ }
+
+ public function getDescribeCommandTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getCommands());
+ }
+
+ public function getDescribeApplicationTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getApplications());
+ }
+
+ abstract protected function getDescriptor();
+ abstract protected function getFormat();
+
+ private function getDescriptionTestData(array $objects)
+ {
+ $data = array();
+ foreach ($objects as $name => $object) {
+ $description = file_get_contents(sprintf('%s/../Fixtures/%s.%s', __DIR__, $name, $this->getFormat()));
+ $data[] = array($object, $description);
+ }
+
+ return $data;
+ }
+
+ private function assertDescription($expectedDescription, $describedObject)
+ {
+ $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
+ $this->getDescriptor()->describe($output, $describedObject, array('raw_output' => true));
+ $this->assertEquals(trim($expectedDescription), trim(str_replace(PHP_EOL, "\n", $output->fetch())));
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/JsonDescriptorTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/JsonDescriptorTest.php
new file mode 100644
index 0000000..943ea29
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/JsonDescriptorTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\JsonDescriptor;
+
+class JsonDescriptorTest extends AbstractDescriptorTest
+{
+ protected function getDescriptor()
+ {
+ return new JsonDescriptor();
+ }
+
+ protected function getFormat()
+ {
+ return 'json';
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/MarkdownDescriptorTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/MarkdownDescriptorTest.php
new file mode 100644
index 0000000..c85e8a5
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/MarkdownDescriptorTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
+
+class MarkdownDescriptorTest extends AbstractDescriptorTest
+{
+ protected function getDescriptor()
+ {
+ return new MarkdownDescriptor();
+ }
+
+ protected function getFormat()
+ {
+ return 'md';
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php
new file mode 100644
index 0000000..a3c49d7
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication1;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication2;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand1;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand2;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class ObjectsProvider
+{
+ public static function getInputArguments()
+ {
+ return array(
+ 'input_argument_1' => new InputArgument('argument_name', InputArgument::REQUIRED),
+ 'input_argument_2' => new InputArgument('argument_name', InputArgument::IS_ARRAY, 'argument description'),
+ 'input_argument_3' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', 'default_value'),
+ );
+ }
+
+ public static function getInputOptions()
+ {
+ return array(
+ 'input_option_1' => new InputOption('option_name', 'o', InputOption::VALUE_NONE),
+ 'input_option_2' => new InputOption('option_name', 'o', InputOption::VALUE_OPTIONAL, 'option description', 'default_value'),
+ 'input_option_3' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, 'option description'),
+ 'input_option_4' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'option description', array()),
+ );
+ }
+
+ public static function getInputDefinitions()
+ {
+ return array(
+ 'input_definition_1' => new InputDefinition(),
+ 'input_definition_2' => new InputDefinition(array(new InputArgument('argument_name', InputArgument::REQUIRED))),
+ 'input_definition_3' => new InputDefinition(array(new InputOption('option_name', 'o', InputOption::VALUE_NONE))),
+ 'input_definition_4' => new InputDefinition(array(
+ new InputArgument('argument_name', InputArgument::REQUIRED),
+ new InputOption('option_name', 'o', InputOption::VALUE_NONE),
+ )),
+ );
+ }
+
+ public static function getCommands()
+ {
+ return array(
+ 'command_1' => new DescriptorCommand1(),
+ 'command_2' => new DescriptorCommand2(),
+ );
+ }
+
+ public static function getApplications()
+ {
+ return array(
+ 'application_1' => new DescriptorApplication1(),
+ 'application_2' => new DescriptorApplication2(),
+ );
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/TextDescriptorTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/TextDescriptorTest.php
new file mode 100644
index 0000000..350b679
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/TextDescriptorTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\TextDescriptor;
+
+class TextDescriptorTest extends AbstractDescriptorTest
+{
+ protected function getDescriptor()
+ {
+ return new TextDescriptor();
+ }
+
+ protected function getFormat()
+ {
+ return 'txt';
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/XmlDescriptorTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/XmlDescriptorTest.php
new file mode 100644
index 0000000..59a5d1e
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/XmlDescriptorTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\XmlDescriptor;
+
+class XmlDescriptorTest extends AbstractDescriptorTest
+{
+ protected function getDescriptor()
+ {
+ return new XmlDescriptor();
+ }
+
+ protected function getFormat()
+ {
+ return 'xml';
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/BarBucCommand.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/BarBucCommand.php
new file mode 100644
index 0000000..52b619e
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/BarBucCommand.php
@@ -0,0 +1,11 @@
+<?php
+
+use Symfony\Component\Console\Command\Command;
+
+class BarBucCommand extends Command
+{
+ protected function configure()
+ {
+ $this->setName('bar:buc');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication1.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication1.php
new file mode 100644
index 0000000..132b6d5
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication1.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Application;
+
+class DescriptorApplication1 extends Application
+{
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication2.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication2.php
new file mode 100644
index 0000000..ff55135
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication2.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Application;
+
+class DescriptorApplication2 extends Application
+{
+ public function __construct()
+ {
+ parent::__construct('My Symfony application', 'v1.0');
+ $this->add(new DescriptorCommand1());
+ $this->add(new DescriptorCommand2());
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand1.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand1.php
new file mode 100644
index 0000000..ede05d7
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand1.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Command\Command;
+
+class DescriptorCommand1 extends Command
+{
+ protected function configure()
+ {
+ $this
+ ->setName('descriptor:command1')
+ ->setAliases(array('alias1', 'alias2'))
+ ->setDescription('command 1 description')
+ ->setHelp('command 1 help')
+ ;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand2.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand2.php
new file mode 100644
index 0000000..bc04ca9
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand2.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+
+class DescriptorCommand2 extends Command
+{
+ protected function configure()
+ {
+ $this
+ ->setName('descriptor:command2')
+ ->setDescription('command 2 description')
+ ->setHelp('command 2 help')
+ ->addArgument('argument_name', InputArgument::REQUIRED)
+ ->addOption('option_name', 'o', InputOption::VALUE_NONE)
+ ;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DummyOutput.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DummyOutput.php
new file mode 100644
index 0000000..aef6d22
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DummyOutput.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Output\BufferedOutput;
+
+/**
+ * Dummy output
+ *
+ * @author Kévin Dunglas <dunglas@gmail.com>
+ */
+class DummyOutput extends BufferedOutput
+{
+ /**
+ * @return array
+ */
+ public function getLogs()
+ {
+ $logs = array();
+ foreach (explode("\n", trim($this->fetch())) as $message) {
+ preg_match('/^\[(.*)\] (.*)/', $message, $matches);
+ $logs[] = sprintf('%s %s', $matches[1], $matches[2]);
+ }
+
+ return $logs;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo1Command.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo1Command.php
new file mode 100644
index 0000000..254162f
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo1Command.php
@@ -0,0 +1,26 @@
+<?php
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Foo1Command extends Command
+{
+ public $input;
+ public $output;
+
+ protected function configure()
+ {
+ $this
+ ->setName('foo:bar1')
+ ->setDescription('The foo:bar1 command')
+ ->setAliases(array('afoobar1'))
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->output = $output;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo2Command.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo2Command.php
new file mode 100644
index 0000000..8071dc8
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo2Command.php
@@ -0,0 +1,21 @@
+<?php
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Foo2Command extends Command
+{
+ protected function configure()
+ {
+ $this
+ ->setName('foo1:bar')
+ ->setDescription('The foo1:bar command')
+ ->setAliases(array('afoobar2'))
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php
new file mode 100644
index 0000000..6c890fa
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php
@@ -0,0 +1,29 @@
+<?php
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Foo3Command extends Command
+{
+ protected function configure()
+ {
+ $this
+ ->setName('foo3:bar')
+ ->setDescription('The foo3:bar command')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ try {
+ try {
+ throw new \Exception('First exception <p>this is html</p>');
+ } catch (\Exception $e) {
+ throw new \Exception('Second exception <comment>comment</comment>', 0, $e);
+ }
+ } catch (\Exception $e) {
+ throw new \Exception('Third exception <fg=blue;bg=red>comment</>', 0, $e);
+ }
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo4Command.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo4Command.php
new file mode 100644
index 0000000..1c54639
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo4Command.php
@@ -0,0 +1,11 @@
+<?php
+
+use Symfony\Component\Console\Command\Command;
+
+class Foo4Command extends Command
+{
+ protected function configure()
+ {
+ $this->setName('foo3:bar:toh');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo5Command.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo5Command.php
new file mode 100644
index 0000000..a1c6082
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/Foo5Command.php
@@ -0,0 +1,10 @@
+<?php
+
+use Symfony\Component\Console\Command\Command;
+
+class Foo5Command extends Command
+{
+ public function __construct()
+ {
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooCommand.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooCommand.php
new file mode 100644
index 0000000..355e0ad
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooCommand.php
@@ -0,0 +1,33 @@
+<?php
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class FooCommand extends Command
+{
+ public $input;
+ public $output;
+
+ protected function configure()
+ {
+ $this
+ ->setName('foo:bar')
+ ->setDescription('The foo:bar command')
+ ->setAliases(array('afoobar'))
+ ;
+ }
+
+ protected function interact(InputInterface $input, OutputInterface $output)
+ {
+ $output->writeln('interact called');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->output = $output;
+
+ $output->writeln('called');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooSubnamespaced1Command.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooSubnamespaced1Command.php
new file mode 100644
index 0000000..fc50c72
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooSubnamespaced1Command.php
@@ -0,0 +1,26 @@
+<?php
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class FooSubnamespaced1Command extends Command
+{
+ public $input;
+ public $output;
+
+ protected function configure()
+ {
+ $this
+ ->setName('foo:bar:baz')
+ ->setDescription('The foo:bar:baz command')
+ ->setAliases(array('foobarbaz'))
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->output = $output;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooSubnamespaced2Command.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooSubnamespaced2Command.php
new file mode 100644
index 0000000..1cf31ff
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FooSubnamespaced2Command.php
@@ -0,0 +1,26 @@
+<?php
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class FooSubnamespaced2Command extends Command
+{
+ public $input;
+ public $output;
+
+ protected function configure()
+ {
+ $this
+ ->setName('foo:go:bret')
+ ->setDescription('The foo:bar:go command')
+ ->setAliases(array('foobargo'))
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->output = $output;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FoobarCommand.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FoobarCommand.php
new file mode 100644
index 0000000..9681628
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/FoobarCommand.php
@@ -0,0 +1,25 @@
+<?php
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class FoobarCommand extends Command
+{
+ public $input;
+ public $output;
+
+ protected function configure()
+ {
+ $this
+ ->setName('foobar:foo')
+ ->setDescription('The foobar:foo command')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->output = $output;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/TestCommand.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/TestCommand.php
new file mode 100644
index 0000000..dcd3273
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/TestCommand.php
@@ -0,0 +1,28 @@
+<?php
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class TestCommand extends Command
+{
+ protected function configure()
+ {
+ $this
+ ->setName('namespace:name')
+ ->setAliases(array('name'))
+ ->setDescription('description')
+ ->setHelp('help')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $output->writeln('execute called');
+ }
+
+ protected function interact(InputInterface $input, OutputInterface $output)
+ {
+ $output->writeln('interact called');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json
new file mode 100644
index 0000000..7f8d92e
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json
@@ -0,0 +1 @@
+{"commands":[{"name":"help","usage":"help [--xml] [--format=\"...\"] [--raw] [command_name]","description":"Displays help for a command","help":"The <info>help<\/info> command displays help for a given command:\n\n <info>php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the <comment>--format<\/comment> option:\n\n <info>php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the <info>list<\/info> command.","aliases":[],"definition":{"arguments":{"command_name":{"name":"command_name","is_required":false,"is_array":false,"description":"The command name","default":"help"}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output help as XML","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output help in other formats","default":"txt"},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command help","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question","default":false}}}},{"name":"list","usage":"list [--xml] [--raw] [--format=\"...\"] [namespace]","description":"Lists commands","help":"The <info>list<\/info> command lists all commands:\n\n <info>php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n <info>php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the <comment>--format<\/comment> option:\n\n <info>php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n <info>php app\/console list --raw<\/info>","aliases":[],"definition":{"arguments":{"namespace":{"name":"namespace","is_required":false,"is_array":false,"description":"The namespace name","default":null}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output list as XML","default":false},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command list","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output list in other formats","default":"txt"}}}}],"namespaces":[{"id":"_global","commands":["help","list"]}]}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md
new file mode 100644
index 0000000..e380416
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md
@@ -0,0 +1,199 @@
+UNKNOWN
+=======
+
+* help
+* list
+
+help
+----
+
+* Description: Displays help for a command
+* Usage: `help [--xml] [--format="..."] [--raw] [command_name]`
+* Aliases: <none>
+
+The <info>help</info> command displays help for a given command:
+
+ <info>php app/console help list</info>
+
+You can also output the help in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console help --format=xml list</info>
+
+To display the list of available commands, please use the <info>list</info> command.
+
+### Arguments:
+
+**command_name:**
+
+* Name: command_name
+* Is required: no
+* Is array: no
+* Description: The command name
+* Default: `'help'`
+
+### Options:
+
+**xml:**
+
+* Name: `--xml`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output help as XML
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut: <none>
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: To output help in other formats
+* Default: `'txt'`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command help
+* Default: `false`
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question
+* Default: `false`
+
+list
+----
+
+* Description: Lists commands
+* Usage: `list [--xml] [--raw] [--format="..."] [namespace]`
+* Aliases: <none>
+
+The <info>list</info> command lists all commands:
+
+ <info>php app/console list</info>
+
+You can also display the commands for a specific namespace:
+
+ <info>php app/console list test</info>
+
+You can also output the information in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console list --format=xml</info>
+
+It's also possible to get raw list of commands (useful for embedding command runner):
+
+ <info>php app/console list --raw</info>
+
+### Arguments:
+
+**namespace:**
+
+* Name: namespace
+* Is required: no
+* Is array: no
+* Description: The namespace name
+* Default: `NULL`
+
+### Options:
+
+**xml:**
+
+* Name: `--xml`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output list as XML
+* Default: `false`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command list
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut: <none>
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: To output list in other formats
+* Default: `'txt'`
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.txt
new file mode 100644
index 0000000..f3a1968
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.txt
@@ -0,0 +1,17 @@
+<info>Console Tool</info>
+
+<comment>Usage:</comment>
+ command [options] [arguments]
+
+<comment>Options:</comment>
+ <info>--help</info> (-h) Display this help message
+ <info>--quiet</info> (-q) Do not output any message
+ <info>--verbose</info> (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ <info>--version</info> (-V) Display this application version
+ <info>--ansi</info> Force ANSI output
+ <info>--no-ansi</info> Disable ANSI output
+ <info>--no-interaction</info> (-n) Do not ask any interactive question
+
+<comment>Available commands:</comment>
+ <info>help </info> Displays help for a command
+ <info>list </info> Lists commands
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml
new file mode 100644
index 0000000..1763108
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<symfony>
+ <commands>
+ <command id="help" name="help">
+ <usage>help [--xml] [--format="..."] [--raw] [command_name]</usage>
+ <description>Displays help for a command</description>
+ <help>The &lt;info&gt;help&lt;/info&gt; command displays help for a given command:
+
+ &lt;info&gt;php app/console help list&lt;/info&gt;
+
+ You can also output the help in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
+
+ &lt;info&gt;php app/console help --format=xml list&lt;/info&gt;
+
+ To display the list of available commands, please use the &lt;info&gt;list&lt;/info&gt; command.</help>
+ <aliases/>
+ <arguments>
+ <argument name="command_name" is_required="0" is_array="0">
+ <description>The command name</description>
+ <defaults>
+ <default>help</default>
+ </defaults>
+ </argument>
+ </arguments>
+ <options>
+ <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>To output help as XML</description>
+ </option>
+ <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
+ <description>To output help in other formats</description>
+ <defaults>
+ <default>txt</default>
+ </defaults>
+ </option>
+ <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>To output raw command help</description>
+ </option>
+ <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this help message</description>
+ </option>
+ <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not output any message</description>
+ </option>
+ <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
+ </option>
+ <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this application version</description>
+ </option>
+ <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Force ANSI output</description>
+ </option>
+ <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Disable ANSI output</description>
+ </option>
+ <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not ask any interactive question</description>
+ </option>
+ </options>
+ </command>
+ <command id="list" name="list">
+ <usage>list [--xml] [--raw] [--format="..."] [namespace]</usage>
+ <description>Lists commands</description>
+ <help>The &lt;info&gt;list&lt;/info&gt; command lists all commands:
+
+ &lt;info&gt;php app/console list&lt;/info&gt;
+
+ You can also display the commands for a specific namespace:
+
+ &lt;info&gt;php app/console list test&lt;/info&gt;
+
+ You can also output the information in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
+
+ &lt;info&gt;php app/console list --format=xml&lt;/info&gt;
+
+ It's also possible to get raw list of commands (useful for embedding command runner):
+
+ &lt;info&gt;php app/console list --raw&lt;/info&gt;</help>
+ <aliases/>
+ <arguments>
+ <argument name="namespace" is_required="0" is_array="0">
+ <description>The namespace name</description>
+ <defaults/>
+ </argument>
+ </arguments>
+ <options>
+ <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>To output list as XML</description>
+ </option>
+ <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>To output raw command list</description>
+ </option>
+ <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
+ <description>To output list in other formats</description>
+ <defaults>
+ <default>txt</default>
+ </defaults>
+ </option>
+ </options>
+ </command>
+ </commands>
+ <namespaces>
+ <namespace id="_global">
+ <command>help</command>
+ <command>list</command>
+ </namespace>
+ </namespaces>
+</symfony>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json
new file mode 100644
index 0000000..1655d47
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json
@@ -0,0 +1 @@
+{"commands":[{"name":"help","usage":"help [--xml] [--format=\"...\"] [--raw] [command_name]","description":"Displays help for a command","help":"The <info>help<\/info> command displays help for a given command:\n\n <info>php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the <comment>--format<\/comment> option:\n\n <info>php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the <info>list<\/info> command.","aliases":[],"definition":{"arguments":{"command_name":{"name":"command_name","is_required":false,"is_array":false,"description":"The command name","default":"help"}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output help as XML","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output help in other formats","default":"txt"},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command help","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question","default":false}}}},{"name":"list","usage":"list [--xml] [--raw] [--format=\"...\"] [namespace]","description":"Lists commands","help":"The <info>list<\/info> command lists all commands:\n\n <info>php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n <info>php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the <comment>--format<\/comment> option:\n\n <info>php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n <info>php app\/console list --raw<\/info>","aliases":[],"definition":{"arguments":{"namespace":{"name":"namespace","is_required":false,"is_array":false,"description":"The namespace name","default":null}},"options":{"xml":{"name":"--xml","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output list as XML","default":false},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command list","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"To output list in other formats","default":"txt"}}}},{"name":"descriptor:command1","usage":"descriptor:command1","description":"command 1 description","help":"command 1 help","aliases":["alias1","alias2"],"definition":{"arguments":[],"options":{"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question","default":false}}}},{"name":"descriptor:command2","usage":"descriptor:command2 [-o|--option_name] argument_name","description":"command 2 description","help":"command 2 help","aliases":[],"definition":{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question","default":false}}}}],"namespaces":[{"id":"_global","commands":["alias1","alias2","help","list"]},{"id":"descriptor","commands":["descriptor:command1","descriptor:command2"]}]}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md
new file mode 100644
index 0000000..7492886
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md
@@ -0,0 +1,388 @@
+My Symfony application
+======================
+
+* alias1
+* alias2
+* help
+* list
+
+**descriptor:**
+
+* descriptor:command1
+* descriptor:command2
+
+help
+----
+
+* Description: Displays help for a command
+* Usage: `help [--xml] [--format="..."] [--raw] [command_name]`
+* Aliases: <none>
+
+The <info>help</info> command displays help for a given command:
+
+ <info>php app/console help list</info>
+
+You can also output the help in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console help --format=xml list</info>
+
+To display the list of available commands, please use the <info>list</info> command.
+
+### Arguments:
+
+**command_name:**
+
+* Name: command_name
+* Is required: no
+* Is array: no
+* Description: The command name
+* Default: `'help'`
+
+### Options:
+
+**xml:**
+
+* Name: `--xml`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output help as XML
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut: <none>
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: To output help in other formats
+* Default: `'txt'`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command help
+* Default: `false`
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question
+* Default: `false`
+
+list
+----
+
+* Description: Lists commands
+* Usage: `list [--xml] [--raw] [--format="..."] [namespace]`
+* Aliases: <none>
+
+The <info>list</info> command lists all commands:
+
+ <info>php app/console list</info>
+
+You can also display the commands for a specific namespace:
+
+ <info>php app/console list test</info>
+
+You can also output the information in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console list --format=xml</info>
+
+It's also possible to get raw list of commands (useful for embedding command runner):
+
+ <info>php app/console list --raw</info>
+
+### Arguments:
+
+**namespace:**
+
+* Name: namespace
+* Is required: no
+* Is array: no
+* Description: The namespace name
+* Default: `NULL`
+
+### Options:
+
+**xml:**
+
+* Name: `--xml`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output list as XML
+* Default: `false`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command list
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut: <none>
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: To output list in other formats
+* Default: `'txt'`
+
+descriptor:command1
+-------------------
+
+* Description: command 1 description
+* Usage: `descriptor:command1`
+* Aliases: `alias1`, `alias2`
+
+command 1 help
+
+### Options:
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question
+* Default: `false`
+
+descriptor:command2
+-------------------
+
+* Description: command 2 description
+* Usage: `descriptor:command2 [-o|--option_name] argument_name`
+* Aliases: <none>
+
+command 2 help
+
+### Arguments:
+
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description: <none>
+* Default: `NULL`
+
+### Options:
+
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: <none>
+* Default: `false`
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question
+* Default: `false`
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.txt
new file mode 100644
index 0000000..a640a8d
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.txt
@@ -0,0 +1,22 @@
+<info>My Symfony application</info> version <comment>v1.0</comment>
+
+<comment>Usage:</comment>
+ command [options] [arguments]
+
+<comment>Options:</comment>
+ <info>--help</info> (-h) Display this help message
+ <info>--quiet</info> (-q) Do not output any message
+ <info>--verbose</info> (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ <info>--version</info> (-V) Display this application version
+ <info>--ansi</info> Force ANSI output
+ <info>--no-ansi</info> Disable ANSI output
+ <info>--no-interaction</info> (-n) Do not ask any interactive question
+
+<comment>Available commands:</comment>
+ <info>alias1 </info> command 1 description
+ <info>alias2 </info> command 1 description
+ <info>help </info> Displays help for a command
+ <info>list </info> Lists commands
+<comment>descriptor</comment>
+ <info>descriptor:command1 </info> command 1 description
+ <info>descriptor:command2 </info> command 2 description
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml
new file mode 100644
index 0000000..a7d65b4
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<symfony name="My Symfony application" version="v1.0">
+ <commands>
+ <command id="help" name="help">
+ <usage>help [--xml] [--format="..."] [--raw] [command_name]</usage>
+ <description>Displays help for a command</description>
+ <help>The &lt;info&gt;help&lt;/info&gt; command displays help for a given command:
+
+ &lt;info&gt;php app/console help list&lt;/info&gt;
+
+ You can also output the help in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
+
+ &lt;info&gt;php app/console help --format=xml list&lt;/info&gt;
+
+ To display the list of available commands, please use the &lt;info&gt;list&lt;/info&gt; command.</help>
+ <aliases/>
+ <arguments>
+ <argument name="command_name" is_required="0" is_array="0">
+ <description>The command name</description>
+ <defaults>
+ <default>help</default>
+ </defaults>
+ </argument>
+ </arguments>
+ <options>
+ <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>To output help as XML</description>
+ </option>
+ <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
+ <description>To output help in other formats</description>
+ <defaults>
+ <default>txt</default>
+ </defaults>
+ </option>
+ <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>To output raw command help</description>
+ </option>
+ <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this help message</description>
+ </option>
+ <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not output any message</description>
+ </option>
+ <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
+ </option>
+ <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this application version</description>
+ </option>
+ <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Force ANSI output</description>
+ </option>
+ <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Disable ANSI output</description>
+ </option>
+ <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not ask any interactive question</description>
+ </option>
+ </options>
+ </command>
+ <command id="list" name="list">
+ <usage>list [--xml] [--raw] [--format="..."] [namespace]</usage>
+ <description>Lists commands</description>
+ <help>The &lt;info&gt;list&lt;/info&gt; command lists all commands:
+
+ &lt;info&gt;php app/console list&lt;/info&gt;
+
+ You can also display the commands for a specific namespace:
+
+ &lt;info&gt;php app/console list test&lt;/info&gt;
+
+ You can also output the information in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
+
+ &lt;info&gt;php app/console list --format=xml&lt;/info&gt;
+
+ It's also possible to get raw list of commands (useful for embedding command runner):
+
+ &lt;info&gt;php app/console list --raw&lt;/info&gt;</help>
+ <aliases/>
+ <arguments>
+ <argument name="namespace" is_required="0" is_array="0">
+ <description>The namespace name</description>
+ <defaults/>
+ </argument>
+ </arguments>
+ <options>
+ <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>To output list as XML</description>
+ </option>
+ <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>To output raw command list</description>
+ </option>
+ <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
+ <description>To output list in other formats</description>
+ <defaults>
+ <default>txt</default>
+ </defaults>
+ </option>
+ </options>
+ </command>
+ <command id="descriptor:command1" name="descriptor:command1">
+ <usage>descriptor:command1</usage>
+ <description>command 1 description</description>
+ <help>command 1 help</help>
+ <aliases>
+ <alias>alias1</alias>
+ <alias>alias2</alias>
+ </aliases>
+ <arguments/>
+ <options>
+ <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this help message</description>
+ </option>
+ <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not output any message</description>
+ </option>
+ <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
+ </option>
+ <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this application version</description>
+ </option>
+ <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Force ANSI output</description>
+ </option>
+ <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Disable ANSI output</description>
+ </option>
+ <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not ask any interactive question</description>
+ </option>
+ </options>
+ </command>
+ <command id="descriptor:command2" name="descriptor:command2">
+ <usage>descriptor:command2 [-o|--option_name] argument_name</usage>
+ <description>command 2 description</description>
+ <help>command 2 help</help>
+ <aliases/>
+ <arguments>
+ <argument name="argument_name" is_required="1" is_array="0">
+ <description></description>
+ <defaults/>
+ </argument>
+ </arguments>
+ <options>
+ <option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
+ <description></description>
+ </option>
+ <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this help message</description>
+ </option>
+ <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not output any message</description>
+ </option>
+ <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
+ </option>
+ <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this application version</description>
+ </option>
+ <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Force ANSI output</description>
+ </option>
+ <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Disable ANSI output</description>
+ </option>
+ <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not ask any interactive question</description>
+ </option>
+ </options>
+ </command>
+ </commands>
+ <namespaces>
+ <namespace id="_global">
+ <command>alias1</command>
+ <command>alias2</command>
+ <command>help</command>
+ <command>list</command>
+ </namespace>
+ <namespace id="descriptor">
+ <command>descriptor:command1</command>
+ <command>descriptor:command2</command>
+ </namespace>
+ </namespaces>
+</symfony>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt
new file mode 100644
index 0000000..d9734fe
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext1.txt
@@ -0,0 +1,20 @@
+<info>Console Tool</info>
+
+<comment>Usage:</comment>
+ command [options] [arguments]
+
+<comment>Options:</comment>
+ <info>--help</info> (-h) Display this help message
+ <info>--quiet</info> (-q) Do not output any message
+ <info>--verbose</info> (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ <info>--version</info> (-V) Display this application version
+ <info>--ansi</info> Force ANSI output
+ <info>--no-ansi</info> Disable ANSI output
+ <info>--no-interaction</info> (-n) Do not ask any interactive question
+
+<comment>Available commands:</comment>
+ <info>afoobar </info> The foo:bar command
+ <info>help </info> Displays help for a command
+ <info>list </info> Lists commands
+<comment>foo</comment>
+ <info>foo:bar </info> The foo:bar command
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt
new file mode 100644
index 0000000..49992cf
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_astext2.txt
@@ -0,0 +1,16 @@
+<info>Console Tool</info>
+
+<comment>Usage:</comment>
+ command [options] [arguments]
+
+<comment>Options:</comment>
+ <info>--help</info> (-h) Display this help message
+ <info>--quiet</info> (-q) Do not output any message
+ <info>--verbose</info> (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ <info>--version</info> (-V) Display this application version
+ <info>--ansi</info> Force ANSI output
+ <info>--no-ansi</info> Disable ANSI output
+ <info>--no-interaction</info> (-n) Do not ask any interactive question
+
+<comment>Available commands for the "foo" namespace:</comment>
+ <info>foo:bar </info> The foo:bar command
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt
new file mode 100644
index 0000000..d956781
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml1.txt
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<symfony>
+ <commands>
+ <command id="help" name="help">
+ <usage>help [--xml] [--format="..."] [--raw] [command_name]</usage>
+ <description>Displays help for a command</description>
+ <help>The &lt;info&gt;help&lt;/info&gt; command displays help for a given command:
+
+ &lt;info&gt;php app/console help list&lt;/info&gt;
+
+ You can also output the help in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
+
+ &lt;info&gt;php app/console help --format=xml list&lt;/info&gt;
+
+ To display the list of available commands, please use the &lt;info&gt;list&lt;/info&gt; command.</help>
+ <aliases />
+ <arguments>
+ <argument name="command_name" is_required="0" is_array="0">
+ <description>The command name</description>
+ <defaults>
+ <default>help</default>
+ </defaults>
+ </argument>
+ </arguments>
+ <options>
+ <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>To output help as XML</description>
+ </option>
+ <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
+ <description>To output help in other formats</description>
+ <defaults>
+ <default>txt</default>
+ </defaults>
+ </option>
+ <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>To output raw command help</description>
+ </option>
+ <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this help message</description>
+ </option>
+ <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not output any message</description>
+ </option>
+ <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
+ </option>
+ <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this application version</description>
+ </option>
+ <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Force ANSI output</description>
+ </option>
+ <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Disable ANSI output</description>
+ </option>
+ <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not ask any interactive question</description>
+ </option>
+ </options>
+</command>
+ <command id="list" name="list">
+ <usage>list [--xml] [--raw] [--format="..."] [namespace]</usage>
+ <description>Lists commands</description>
+ <help>The &lt;info&gt;list&lt;/info&gt; command lists all commands:
+
+ &lt;info&gt;php app/console list&lt;/info&gt;
+
+ You can also display the commands for a specific namespace:
+
+ &lt;info&gt;php app/console list test&lt;/info&gt;
+
+ You can also output the information in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
+
+ &lt;info&gt;php app/console list --format=xml&lt;/info&gt;
+
+ It's also possible to get raw list of commands (useful for embedding command runner):
+
+ &lt;info&gt;php app/console list --raw&lt;/info&gt;</help>
+ <aliases/>
+ <arguments>
+ <argument name="namespace" is_required="0" is_array="0">
+ <description>The namespace name</description>
+ <defaults/>
+ </argument>
+ </arguments>
+ <options>
+ <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>To output list as XML</description>
+ </option>
+ <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>To output raw command list</description>
+ </option>
+ <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
+ <description>To output list in other formats</description>
+ <defaults>
+ <default>txt</default>
+ </defaults>
+ </option>
+ </options>
+</command>
+ <command id="foo:bar" name="foo:bar">
+ <usage>foo:bar</usage>
+ <description>The foo:bar command</description>
+ <help/>
+ <aliases>
+ <alias>afoobar</alias>
+ </aliases>
+ <arguments/>
+ <options>
+ <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this help message</description>
+ </option>
+ <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not output any message</description>
+ </option>
+ <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
+ </option>
+ <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this application version</description>
+ </option>
+ <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Force ANSI output</description>
+ </option>
+ <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Disable ANSI output</description>
+ </option>
+ <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not ask any interactive question</description>
+ </option>
+ </options>
+</command>
+ </commands>
+ <namespaces>
+ <namespace id="_global">
+ <command>afoobar</command>
+ <command>help</command>
+ <command>list</command>
+ </namespace>
+ <namespace id="foo">
+ <command>foo:bar</command>
+ </namespace>
+ </namespaces>
+</symfony>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml2.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml2.txt
new file mode 100644
index 0000000..0b30b20
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_asxml2.txt
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<symfony>
+ <commands namespace="foo">
+ <command id="foo:bar" name="foo:bar">
+ <usage>foo:bar</usage>
+ <description>The foo:bar command</description>
+ <help/>
+ <aliases>
+ <alias>afoobar</alias>
+ </aliases>
+ <arguments/>
+ <options>
+ <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this help message</description>
+ </option>
+ <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not output any message</description>
+ </option>
+ <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
+ </option>
+ <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this application version</description>
+ </option>
+ <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Force ANSI output</description>
+ </option>
+ <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Disable ANSI output</description>
+ </option>
+ <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not ask any interactive question</description>
+ </option>
+ </options>
+</command>
+ </commands>
+</symfony>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_gethelp.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_gethelp.txt
new file mode 100644
index 0000000..0c16e3c
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_gethelp.txt
@@ -0,0 +1 @@
+<info>Console Tool</info> \ No newline at end of file
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception1.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception1.txt
new file mode 100644
index 0000000..4629345
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception1.txt
@@ -0,0 +1,8 @@
+
+
+
+ [InvalidArgumentException]
+ Command "foo" is not defined.
+
+
+
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception2.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception2.txt
new file mode 100644
index 0000000..c758129
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception2.txt
@@ -0,0 +1,11 @@
+
+
+
+ [InvalidArgumentException]
+ The "--foo" option does not exist.
+
+
+
+list [--xml] [--raw] [--format="..."] [namespace]
+
+
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt
new file mode 100644
index 0000000..72a7286
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt
@@ -0,0 +1,27 @@
+
+
+
+ [Exception]
+ Third exception comment
+
+
+
+
+
+
+ [Exception]
+ Second exception comment
+
+
+
+
+
+
+ [Exception]
+ First exception <p>this is html</p>
+
+
+
+foo3:bar
+
+
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt
new file mode 100644
index 0000000..b44d50b
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt
@@ -0,0 +1,27 @@
+
+
+ 
+ [Exception] 
+ Third exception comment 
+ 
+
+
+
+
+ 
+ [Exception] 
+ Second exception comment 
+ 
+
+
+
+
+ 
+ [Exception] 
+ First exception <p>this is html</p> 
+ 
+
+
+foo3:bar
+
+
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception4.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception4.txt
new file mode 100644
index 0000000..19f893b
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception4.txt
@@ -0,0 +1,9 @@
+
+
+
+ [InvalidArgumentException]
+ Command "foo" is not define
+ d.
+
+
+
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1.txt
new file mode 100644
index 0000000..6a98660
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1.txt
@@ -0,0 +1,11 @@
+
+
+
+ [Exception]
+ エラーメッセージ
+
+
+
+foo
+
+
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txt
new file mode 100644
index 0000000..8c8801b
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txt
@@ -0,0 +1,11 @@
+
+
+ 
+ [Exception] 
+ エラーメッセージ 
+ 
+
+
+foo
+
+
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth2.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth2.txt
new file mode 100644
index 0000000..545cd7b
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_renderexception_doublewidth2.txt
@@ -0,0 +1,12 @@
+
+
+
+ [Exception]
+ コマンドの実行中にエラーが
+ 発生しました。
+
+
+
+foo
+
+
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run1.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run1.txt
new file mode 100644
index 0000000..9bd08b5
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run1.txt
@@ -0,0 +1,17 @@
+Console Tool
+
+Usage:
+ command [options] [arguments]
+
+Options:
+ --help (-h) Display this help message
+ --quiet (-q) Do not output any message
+ --verbose (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ --version (-V) Display this application version
+ --ansi Force ANSI output
+ --no-ansi Disable ANSI output
+ --no-interaction (-n) Do not ask any interactive question
+
+Available commands:
+ help Displays help for a command
+ list Lists commands
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run2.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run2.txt
new file mode 100644
index 0000000..6963c0f
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run2.txt
@@ -0,0 +1,29 @@
+Usage:
+ help [--xml] [--format="..."] [--raw] [command_name]
+
+Arguments:
+ command The command to execute
+ command_name The command name (default: "help")
+
+Options:
+ --xml To output help as XML
+ --format To output help in other formats (default: "txt")
+ --raw To output raw command help
+ --help (-h) Display this help message
+ --quiet (-q) Do not output any message
+ --verbose (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ --version (-V) Display this application version
+ --ansi Force ANSI output
+ --no-ansi Disable ANSI output
+ --no-interaction (-n) Do not ask any interactive question
+
+Help:
+ The help command displays help for a given command:
+
+ php app/console help list
+
+ You can also output the help in other formats by using the --format option:
+
+ php app/console help --format=xml list
+
+ To display the list of available commands, please use the list command.
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run3.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run3.txt
new file mode 100644
index 0000000..0139775
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run3.txt
@@ -0,0 +1,27 @@
+Usage:
+ list [--xml] [--raw] [--format="..."] [namespace]
+
+Arguments:
+ namespace The namespace name
+
+Options:
+ --xml To output list as XML
+ --raw To output raw command list
+ --format To output list in other formats (default: "txt")
+
+Help:
+ The list command lists all commands:
+
+ php app/console list
+
+ You can also display the commands for a specific namespace:
+
+ php app/console list test
+
+ You can also output the information in other formats by using the --format option:
+
+ php app/console list --format=xml
+
+ It's also possible to get raw list of commands (useful for embedding command runner):
+
+ php app/console list --raw
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run4.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run4.txt
new file mode 100644
index 0000000..47187fc
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_run4.txt
@@ -0,0 +1 @@
+Console Tool
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.json
new file mode 100644
index 0000000..0c1675d
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.json
@@ -0,0 +1 @@
+{"name":"descriptor:command1","usage":"descriptor:command1","description":"command 1 description","help":"command 1 help","aliases":["alias1","alias2"],"definition":{"arguments":[],"options":[]}}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.md
new file mode 100644
index 0000000..2cef9a2
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.md
@@ -0,0 +1,8 @@
+descriptor:command1
+-------------------
+
+* Description: command 1 description
+* Usage: `descriptor:command1`
+* Aliases: `alias1`, `alias2`
+
+command 1 help
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.txt
new file mode 100644
index 0000000..2375ac0
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.txt
@@ -0,0 +1,7 @@
+<comment>Usage:</comment>
+ descriptor:command1
+
+<comment>Aliases:</comment> <info>alias1, alias2</info>
+
+<comment>Help:</comment>
+ command 1 help
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.xml
new file mode 100644
index 0000000..dcfa6fa
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<command id="descriptor:command1" name="descriptor:command1">
+ <usage>descriptor:command1</usage>
+ <description>command 1 description</description>
+ <help>command 1 help</help>
+ <aliases>
+ <alias>alias1</alias>
+ <alias>alias2</alias>
+ </aliases>
+ <arguments/>
+ <options/>
+</command>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.json
new file mode 100644
index 0000000..493b584
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.json
@@ -0,0 +1 @@
+{"name":"descriptor:command2","usage":"descriptor:command2 [-o|--option_name] argument_name","description":"command 2 description","help":"command 2 help","aliases":[],"definition":{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}}}}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.md
new file mode 100644
index 0000000..5257c0d
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.md
@@ -0,0 +1,30 @@
+descriptor:command2
+-------------------
+
+* Description: command 2 description
+* Usage: `descriptor:command2 [-o|--option_name] argument_name`
+* Aliases: <none>
+
+command 2 help
+
+### Arguments:
+
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description: <none>
+* Default: `NULL`
+
+### Options:
+
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: <none>
+* Default: `false`
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.txt
new file mode 100644
index 0000000..1da9f3d
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.txt
@@ -0,0 +1,11 @@
+<comment>Usage:</comment>
+ descriptor:command2 [-o|--option_name] argument_name
+
+<comment>Arguments:</comment>
+ <info>argument_name </info>
+
+<comment>Options:</comment>
+ <info>--option_name</info> (-o)
+
+<comment>Help:</comment>
+ command 2 help
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.xml
new file mode 100644
index 0000000..c411c36
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<command id="descriptor:command2" name="descriptor:command2">
+ <usage>descriptor:command2 [-o|--option_name] argument_name</usage>
+ <description>command 2 description</description>
+ <help>command 2 help</help>
+ <aliases/>
+ <arguments>
+ <argument name="argument_name" is_required="1" is_array="0">
+ <description></description>
+ <defaults/>
+ </argument>
+ </arguments>
+ <options>
+ <option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
+ <description></description>
+ </option>
+ </options>
+</command>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_astext.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_astext.txt
new file mode 100644
index 0000000..5d70351
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_astext.txt
@@ -0,0 +1,18 @@
+<comment>Usage:</comment>
+ namespace:name
+
+<comment>Aliases:</comment> <info>name</info>
+<comment>Arguments:</comment>
+ <info>command </info> The command to execute
+
+<comment>Options:</comment>
+ <info>--help</info> (-h) Display this help message
+ <info>--quiet</info> (-q) Do not output any message
+ <info>--verbose</info> (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+ <info>--version</info> (-V) Display this application version
+ <info>--ansi</info> Force ANSI output
+ <info>--no-ansi</info> Disable ANSI output
+ <info>--no-interaction</info> (-n) Do not ask any interactive question
+
+<comment>Help:</comment>
+ help
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_asxml.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_asxml.txt
new file mode 100644
index 0000000..57542fa
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_asxml.txt
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<command id="namespace:name" name="namespace:name">
+ <usage>namespace:name</usage>
+ <description>description</description>
+ <help>help</help>
+ <aliases>
+ <alias>name</alias>
+ </aliases>
+ <arguments>
+ <argument name="command" is_required="1" is_array="0">
+ <description>The command to execute</description>
+ <defaults/>
+ </argument>
+ </arguments>
+ <options>
+ <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this help message</description>
+ </option>
+ <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not output any message</description>
+ </option>
+ <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
+ </option>
+ <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Display this application version</description>
+ </option>
+ <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Force ANSI output</description>
+ </option>
+ <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Disable ANSI output</description>
+ </option>
+ <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
+ <description>Do not ask any interactive question</description>
+ </option>
+ </options>
+</command>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_astext.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_astext.txt
new file mode 100644
index 0000000..a7d7e0d
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_astext.txt
@@ -0,0 +1,11 @@
+<comment>Arguments:</comment>
+ <info>foo </info> The foo argument
+ <info>baz </info> The baz argument<comment> (default: true)</comment>
+ <info>bar </info> The bar argument<comment> (default: ["http://foo.com/"])</comment>
+
+<comment>Options:</comment>
+ <info>--foo</info> (-f) The foo option
+ <info>--baz</info> The baz option<comment> (default: false)</comment>
+ <info>--bar</info> (-b) The bar option<comment> (default: "bar")</comment>
+ <info>--qux</info> The qux option<comment> (default: ["http://foo.com/","bar"])</comment><comment> (multiple values allowed)</comment>
+ <info>--qux2</info> The qux2 option<comment> (default: {"foo":"bar"})</comment><comment> (multiple values allowed)</comment>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_asxml.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_asxml.txt
new file mode 100644
index 0000000..eec8c07
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/definition_asxml.txt
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definition>
+ <arguments>
+ <argument name="foo" is_required="0" is_array="0">
+ <description>The foo argument</description>
+ <defaults/>
+ </argument>
+ <argument name="baz" is_required="0" is_array="0">
+ <description>The baz argument</description>
+ <defaults>
+ <default>true</default>
+ </defaults>
+ </argument>
+ <argument name="bar" is_required="0" is_array="1">
+ <description>The bar argument</description>
+ <defaults>
+ <default>bar</default>
+ </defaults>
+ </argument>
+ </arguments>
+ <options>
+ <option name="--foo" shortcut="-f" accept_value="1" is_value_required="1" is_multiple="0">
+ <description>The foo option</description>
+ <defaults/>
+ </option>
+ <option name="--baz" shortcut="" accept_value="1" is_value_required="0" is_multiple="0">
+ <description>The baz option</description>
+ <defaults>
+ <default>false</default>
+ </defaults>
+ </option>
+ <option name="--bar" shortcut="-b" accept_value="1" is_value_required="0" is_multiple="0">
+ <description>The bar option</description>
+ <defaults>
+ <default>bar</default>
+ </defaults>
+ </option>
+ </options>
+</definition>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.json
new file mode 100644
index 0000000..b8173b6
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.json
@@ -0,0 +1 @@
+{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.md
new file mode 100644
index 0000000..88f311a
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.md
@@ -0,0 +1,7 @@
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description: <none>
+* Default: `NULL`
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.txt
new file mode 100644
index 0000000..111e515
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.txt
@@ -0,0 +1 @@
+ <info>argument_name</info>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.xml
new file mode 100644
index 0000000..cb37f81
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<argument name="argument_name" is_required="1" is_array="0">
+ <description></description>
+ <defaults/>
+</argument>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.json
new file mode 100644
index 0000000..ef06b09
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.json
@@ -0,0 +1 @@
+{"name":"argument_name","is_required":false,"is_array":true,"description":"argument description","default":[]}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.md
new file mode 100644
index 0000000..3cdb00c
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.md
@@ -0,0 +1,7 @@
+**argument_name:**
+
+* Name: argument_name
+* Is required: no
+* Is array: yes
+* Description: argument description
+* Default: `array ()`
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.txt
new file mode 100644
index 0000000..9497b1c
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.txt
@@ -0,0 +1 @@
+ <info>argument_name</info> argument description
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.xml
new file mode 100644
index 0000000..629da5a
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<argument name="argument_name" is_required="0" is_array="1">
+ <description>argument description</description>
+ <defaults/>
+</argument>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.json
new file mode 100644
index 0000000..de8484e
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.json
@@ -0,0 +1 @@
+{"name":"argument_name","is_required":false,"is_array":false,"description":"argument description","default":"default_value"}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.md
new file mode 100644
index 0000000..be1c443
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.md
@@ -0,0 +1,7 @@
+**argument_name:**
+
+* Name: argument_name
+* Is required: no
+* Is array: no
+* Description: argument description
+* Default: `'default_value'`
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.txt
new file mode 100644
index 0000000..c421fc9
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.txt
@@ -0,0 +1 @@
+ <info>argument_name</info> argument description<comment> (default: "default_value")</comment>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.xml
new file mode 100644
index 0000000..399a5c8
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<argument name="argument_name" is_required="0" is_array="0">
+ <description>argument description</description>
+ <defaults>
+ <default>default_value</default>
+ </defaults>
+</argument>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.json
new file mode 100644
index 0000000..c7a7d83
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.json
@@ -0,0 +1 @@
+{"arguments":[],"options":[]}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.md
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.txt
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.xml
new file mode 100644
index 0000000..b5481ce
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definition>
+ <arguments/>
+ <options/>
+</definition>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.json
new file mode 100644
index 0000000..9964a55
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.json
@@ -0,0 +1 @@
+{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":[]}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.md
new file mode 100644
index 0000000..923191c
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.md
@@ -0,0 +1,9 @@
+### Arguments:
+
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description: <none>
+* Default: `NULL`
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.txt
new file mode 100644
index 0000000..0db9f66
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.txt
@@ -0,0 +1,2 @@
+<comment>Arguments:</comment>
+ <info>argument_name </info>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.xml
new file mode 100644
index 0000000..102efc1
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definition>
+ <arguments>
+ <argument name="argument_name" is_required="1" is_array="0">
+ <description></description>
+ <defaults/>
+ </argument>
+ </arguments>
+ <options/>
+</definition>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.json
new file mode 100644
index 0000000..6a86056
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.json
@@ -0,0 +1 @@
+{"arguments":[],"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}}}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.md
new file mode 100644
index 0000000..40fd7b0
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.md
@@ -0,0 +1,11 @@
+### Options:
+
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: <none>
+* Default: `false`
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.txt
new file mode 100644
index 0000000..c6fb2cc
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.txt
@@ -0,0 +1,2 @@
+<comment>Options:</comment>
+ <info>--option_name</info> (-o)
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.xml
new file mode 100644
index 0000000..bc95151
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definition>
+ <arguments/>
+ <options>
+ <option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
+ <description></description>
+ </option>
+ </options>
+</definition>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.json
new file mode 100644
index 0000000..c5a0019
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.json
@@ -0,0 +1 @@
+{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}}}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.md
new file mode 100644
index 0000000..a31feea
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.md
@@ -0,0 +1,21 @@
+### Arguments:
+
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description: <none>
+* Default: `NULL`
+
+### Options:
+
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: <none>
+* Default: `false`
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.txt
new file mode 100644
index 0000000..e17c61c
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.txt
@@ -0,0 +1,5 @@
+<comment>Arguments:</comment>
+ <info>argument_name </info>
+
+<comment>Options:</comment>
+ <info>--option_name</info> (-o)
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.xml
new file mode 100644
index 0000000..cffceec
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definition>
+ <arguments>
+ <argument name="argument_name" is_required="1" is_array="0">
+ <description></description>
+ <defaults/>
+ </argument>
+ </arguments>
+ <options>
+ <option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
+ <description></description>
+ </option>
+ </options>
+</definition>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.json
new file mode 100644
index 0000000..60c5b56
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.json
@@ -0,0 +1 @@
+{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.md
new file mode 100644
index 0000000..6f9e9a7
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.md
@@ -0,0 +1,9 @@
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: <none>
+* Default: `false`
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.txt
new file mode 100644
index 0000000..daf83d0
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.txt
@@ -0,0 +1 @@
+ <info>--option_name</info> (-o)
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.xml
new file mode 100644
index 0000000..8a64ea6
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
+ <description></description>
+</option>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.json
new file mode 100644
index 0000000..04e4228
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.json
@@ -0,0 +1 @@
+{"name":"--option_name","shortcut":"-o","accept_value":true,"is_value_required":false,"is_multiple":false,"description":"option description","default":"default_value"}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.md
new file mode 100644
index 0000000..634ac0b
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.md
@@ -0,0 +1,9 @@
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: yes
+* Is value required: no
+* Is multiple: no
+* Description: option description
+* Default: `'default_value'`
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.txt
new file mode 100644
index 0000000..627e3c1
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.txt
@@ -0,0 +1 @@
+ <info>--option_name</info> (-o) option description<comment> (default: "default_value")</comment>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.xml
new file mode 100644
index 0000000..4afac5b
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<option name="--option_name" shortcut="-o" accept_value="1" is_value_required="0" is_multiple="0">
+ <description>option description</description>
+ <defaults>
+ <default>default_value</default>
+ </defaults>
+</option>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.json
new file mode 100644
index 0000000..c1ea120
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.json
@@ -0,0 +1 @@
+{"name":"--option_name","shortcut":"-o","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"option description","default":null}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.md
new file mode 100644
index 0000000..3428289
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.md
@@ -0,0 +1,9 @@
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: option description
+* Default: `NULL`
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.txt
new file mode 100644
index 0000000..b88b12d
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.txt
@@ -0,0 +1 @@
+ <info>--option_name</info> (-o) option description
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.xml
new file mode 100644
index 0000000..dcc0631
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<option name="--option_name" shortcut="-o" accept_value="1" is_value_required="1" is_multiple="0">
+ <description>option description</description>
+ <defaults/>
+</option>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.json b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.json
new file mode 100644
index 0000000..1b671d8
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.json
@@ -0,0 +1 @@
+{"name":"--option_name","shortcut":"-o","accept_value":true,"is_value_required":false,"is_multiple":true,"description":"option description","default":[]}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.md b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.md
new file mode 100644
index 0000000..8ffba56
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.md
@@ -0,0 +1,9 @@
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: yes
+* Is value required: no
+* Is multiple: yes
+* Description: option description
+* Default: `array ()`
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.txt b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.txt
new file mode 100644
index 0000000..5dba5e6
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.txt
@@ -0,0 +1 @@
+ <info>--option_name</info> (-o) option description<comment> (multiple values allowed)</comment>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.xml b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.xml
new file mode 100644
index 0000000..5e2418b
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<option name="--option_name" shortcut="-o" accept_value="1" is_value_required="0" is_multiple="1">
+ <description>option description</description>
+ <defaults/>
+</option>
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php
new file mode 100644
index 0000000..774df26
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleStackTest.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Formatter;
+
+use Symfony\Component\Console\Formatter\OutputFormatterStyleStack;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+
+class OutputFormatterStyleStackTest extends \PHPUnit_Framework_TestCase
+{
+ public function testPush()
+ {
+ $stack = new OutputFormatterStyleStack();
+ $stack->push($s1 = new OutputFormatterStyle('white', 'black'));
+ $stack->push($s2 = new OutputFormatterStyle('yellow', 'blue'));
+
+ $this->assertEquals($s2, $stack->getCurrent());
+
+ $stack->push($s3 = new OutputFormatterStyle('green', 'red'));
+
+ $this->assertEquals($s3, $stack->getCurrent());
+ }
+
+ public function testPop()
+ {
+ $stack = new OutputFormatterStyleStack();
+ $stack->push($s1 = new OutputFormatterStyle('white', 'black'));
+ $stack->push($s2 = new OutputFormatterStyle('yellow', 'blue'));
+
+ $this->assertEquals($s2, $stack->pop());
+ $this->assertEquals($s1, $stack->pop());
+ }
+
+ public function testPopEmpty()
+ {
+ $stack = new OutputFormatterStyleStack();
+ $style = new OutputFormatterStyle();
+
+ $this->assertEquals($style, $stack->pop());
+ }
+
+ public function testPopNotLast()
+ {
+ $stack = new OutputFormatterStyleStack();
+ $stack->push($s1 = new OutputFormatterStyle('white', 'black'));
+ $stack->push($s2 = new OutputFormatterStyle('yellow', 'blue'));
+ $stack->push($s3 = new OutputFormatterStyle('green', 'red'));
+
+ $this->assertEquals($s2, $stack->pop($s2));
+ $this->assertEquals($s1, $stack->pop());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testInvalidPop()
+ {
+ $stack = new OutputFormatterStyleStack();
+ $stack->push(new OutputFormatterStyle('white', 'black'));
+ $stack->pop(new OutputFormatterStyle('yellow', 'blue'));
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleTest.php
new file mode 100644
index 0000000..52ada9e
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterStyleTest.php
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Formatter;
+
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+
+class OutputFormatterStyleTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $style = new OutputFormatterStyle('green', 'black', array('bold', 'underscore'));
+ $this->assertEquals("\033[32;40;1;4mfoo\033[39;49;22;24m", $style->apply('foo'));
+
+ $style = new OutputFormatterStyle('red', null, array('blink'));
+ $this->assertEquals("\033[31;5mfoo\033[39;25m", $style->apply('foo'));
+
+ $style = new OutputFormatterStyle(null, 'white');
+ $this->assertEquals("\033[47mfoo\033[49m", $style->apply('foo'));
+ }
+
+ public function testForeground()
+ {
+ $style = new OutputFormatterStyle();
+
+ $style->setForeground('black');
+ $this->assertEquals("\033[30mfoo\033[39m", $style->apply('foo'));
+
+ $style->setForeground('blue');
+ $this->assertEquals("\033[34mfoo\033[39m", $style->apply('foo'));
+
+ $this->setExpectedException('InvalidArgumentException');
+ $style->setForeground('undefined-color');
+ }
+
+ public function testBackground()
+ {
+ $style = new OutputFormatterStyle();
+
+ $style->setBackground('black');
+ $this->assertEquals("\033[40mfoo\033[49m", $style->apply('foo'));
+
+ $style->setBackground('yellow');
+ $this->assertEquals("\033[43mfoo\033[49m", $style->apply('foo'));
+
+ $this->setExpectedException('InvalidArgumentException');
+ $style->setBackground('undefined-color');
+ }
+
+ public function testOptions()
+ {
+ $style = new OutputFormatterStyle();
+
+ $style->setOptions(array('reverse', 'conceal'));
+ $this->assertEquals("\033[7;8mfoo\033[27;28m", $style->apply('foo'));
+
+ $style->setOption('bold');
+ $this->assertEquals("\033[7;8;1mfoo\033[27;28;22m", $style->apply('foo'));
+
+ $style->unsetOption('reverse');
+ $this->assertEquals("\033[8;1mfoo\033[28;22m", $style->apply('foo'));
+
+ $style->setOption('bold');
+ $this->assertEquals("\033[8;1mfoo\033[28;22m", $style->apply('foo'));
+
+ $style->setOptions(array('bold'));
+ $this->assertEquals("\033[1mfoo\033[22m", $style->apply('foo'));
+
+ try {
+ $style->setOption('foo');
+ $this->fail('->setOption() throws an \InvalidArgumentException when the option does not exist in the available options');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->setOption() throws an \InvalidArgumentException when the option does not exist in the available options');
+ $this->assertContains('Invalid option specified: "foo"', $e->getMessage(), '->setOption() throws an \InvalidArgumentException when the option does not exist in the available options');
+ }
+
+ try {
+ $style->unsetOption('foo');
+ $this->fail('->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options');
+ $this->assertContains('Invalid option specified: "foo"', $e->getMessage(), '->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options');
+ }
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php
new file mode 100644
index 0000000..4f4fbbe
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php
@@ -0,0 +1,257 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Formatter;
+
+use Symfony\Component\Console\Formatter\OutputFormatter;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+
+class OutputFormatterTest extends \PHPUnit_Framework_TestCase
+{
+ public function testEmptyTag()
+ {
+ $formatter = new OutputFormatter(true);
+ $this->assertEquals('foo<>bar', $formatter->format('foo<>bar'));
+ }
+
+ public function testLGCharEscaping()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals('foo<bar', $formatter->format('foo\\<bar'));
+ $this->assertEquals('<info>some info</info>', $formatter->format('\\<info>some info\\</info>'));
+ $this->assertEquals("\\<info>some info\\</info>", OutputFormatter::escape('<info>some info</info>'));
+
+ $this->assertEquals(
+ "\033[33mSymfony\\Component\\Console does work very well!\033[39m",
+ $formatter->format('<comment>Symfony\Component\Console does work very well!</comment>')
+ );
+ }
+
+ public function testBundledStyles()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertTrue($formatter->hasStyle('error'));
+ $this->assertTrue($formatter->hasStyle('info'));
+ $this->assertTrue($formatter->hasStyle('comment'));
+ $this->assertTrue($formatter->hasStyle('question'));
+
+ $this->assertEquals(
+ "\033[37;41msome error\033[39;49m",
+ $formatter->format('<error>some error</error>')
+ );
+ $this->assertEquals(
+ "\033[32msome info\033[39m",
+ $formatter->format('<info>some info</info>')
+ );
+ $this->assertEquals(
+ "\033[33msome comment\033[39m",
+ $formatter->format('<comment>some comment</comment>')
+ );
+ $this->assertEquals(
+ "\033[30;46msome question\033[39;49m",
+ $formatter->format('<question>some question</question>')
+ );
+ }
+
+ public function testNestedStyles()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(
+ "\033[37;41msome \033[39;49m\033[32msome info\033[39m\033[37;41m error\033[39;49m",
+ $formatter->format('<error>some <info>some info</info> error</error>')
+ );
+ }
+
+ public function testAdjacentStyles()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(
+ "\033[37;41msome error\033[39;49m\033[32msome info\033[39m",
+ $formatter->format('<error>some error</error><info>some info</info>')
+ );
+ }
+
+ public function testStyleMatchingNotGreedy()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(
+ "(\033[32m>=2.0,<2.3\033[39m)",
+ $formatter->format('(<info>>=2.0,<2.3</info>)')
+ );
+ }
+
+ public function testStyleEscaping()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(
+ "(\033[32mz>=2.0,<a2.3\033[39m)",
+ $formatter->format('(<info>'.$formatter->escape('z>=2.0,<a2.3').'</info>)')
+ );
+
+ $this->assertEquals(
+ "\033[32m<error>some error</error>\033[39m",
+ $formatter->format('<info>'.$formatter->escape('<error>some error</error>').'</info>')
+ );
+ }
+
+ public function testDeepNestedStyles()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(
+ "\033[37;41merror\033[39;49m\033[32minfo\033[39m\033[33mcomment\033[39m\033[37;41merror\033[39;49m",
+ $formatter->format('<error>error<info>info<comment>comment</info>error</error>')
+ );
+ }
+
+ public function testNewStyle()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $style = new OutputFormatterStyle('blue', 'white');
+ $formatter->setStyle('test', $style);
+
+ $this->assertEquals($style, $formatter->getStyle('test'));
+ $this->assertNotEquals($style, $formatter->getStyle('info'));
+
+ $style = new OutputFormatterStyle('blue', 'white');
+ $formatter->setStyle('b', $style);
+
+ $this->assertEquals("\033[34;47msome \033[39;49m\033[34;47mcustom\033[39;49m\033[34;47m msg\033[39;49m", $formatter->format('<test>some <b>custom</b> msg</test>'));
+ }
+
+ public function testRedefineStyle()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $style = new OutputFormatterStyle('blue', 'white');
+ $formatter->setStyle('info', $style);
+
+ $this->assertEquals("\033[34;47msome custom msg\033[39;49m", $formatter->format('<info>some custom msg</info>'));
+ }
+
+ public function testInlineStyle()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals("\033[34;41msome text\033[39;49m", $formatter->format('<fg=blue;bg=red>some text</>'));
+ $this->assertEquals("\033[34;41msome text\033[39;49m", $formatter->format('<fg=blue;bg=red>some text</fg=blue;bg=red>'));
+ }
+
+ public function testNonStyleTag()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals("\033[32msome \033[39m\033[32m<tag>\033[39m\033[32m \033[39m\033[32m<setting=value>\033[39m\033[32m styled \033[39m\033[32m<p>\033[39m\033[32msingle-char tag\033[39m\033[32m</p>\033[39m", $formatter->format('<info>some <tag> <setting=value> styled <p>single-char tag</p></info>'));
+ }
+
+ public function testFormatLongString()
+ {
+ $formatter = new OutputFormatter(true);
+ $long = str_repeat("\\", 14000);
+ $this->assertEquals("\033[37;41msome error\033[39;49m".$long, $formatter->format('<error>some error</error>'.$long));
+ }
+
+ public function testNotDecoratedFormatter()
+ {
+ $formatter = new OutputFormatter(false);
+
+ $this->assertTrue($formatter->hasStyle('error'));
+ $this->assertTrue($formatter->hasStyle('info'));
+ $this->assertTrue($formatter->hasStyle('comment'));
+ $this->assertTrue($formatter->hasStyle('question'));
+
+ $this->assertEquals(
+ 'some error', $formatter->format('<error>some error</error>')
+ );
+ $this->assertEquals(
+ 'some info', $formatter->format('<info>some info</info>')
+ );
+ $this->assertEquals(
+ 'some comment', $formatter->format('<comment>some comment</comment>')
+ );
+ $this->assertEquals(
+ 'some question', $formatter->format('<question>some question</question>')
+ );
+
+ $formatter->setDecorated(true);
+
+ $this->assertEquals(
+ "\033[37;41msome error\033[39;49m", $formatter->format('<error>some error</error>')
+ );
+ $this->assertEquals(
+ "\033[32msome info\033[39m", $formatter->format('<info>some info</info>')
+ );
+ $this->assertEquals(
+ "\033[33msome comment\033[39m", $formatter->format('<comment>some comment</comment>')
+ );
+ $this->assertEquals(
+ "\033[30;46msome question\033[39;49m", $formatter->format('<question>some question</question>')
+ );
+ }
+
+ public function testContentWithLineBreaks()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(<<<EOF
+\033[32m
+some text\033[39m
+EOF
+ , $formatter->format(<<<EOF
+<info>
+some text</info>
+EOF
+ ));
+
+ $this->assertEquals(<<<EOF
+\033[32msome text
+\033[39m
+EOF
+ , $formatter->format(<<<EOF
+<info>some text
+</info>
+EOF
+ ));
+
+ $this->assertEquals(<<<EOF
+\033[32m
+some text
+\033[39m
+EOF
+ , $formatter->format(<<<EOF
+<info>
+some text
+</info>
+EOF
+ ));
+
+ $this->assertEquals(<<<EOF
+\033[32m
+some text
+more text
+\033[39m
+EOF
+ , $formatter->format(<<<EOF
+<info>
+some text
+more text
+</info>
+EOF
+ ));
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/FormatterHelperTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/FormatterHelperTest.php
new file mode 100644
index 0000000..e332774
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/FormatterHelperTest.php
@@ -0,0 +1,99 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Helper\FormatterHelper;
+
+class FormatterHelperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testFormatSection()
+ {
+ $formatter = new FormatterHelper();
+
+ $this->assertEquals(
+ '<info>[cli]</info> Some text to display',
+ $formatter->formatSection('cli', 'Some text to display'),
+ '::formatSection() formats a message in a section'
+ );
+ }
+
+ public function testFormatBlock()
+ {
+ $formatter = new FormatterHelper();
+
+ $this->assertEquals(
+ '<error> Some text to display </error>',
+ $formatter->formatBlock('Some text to display', 'error'),
+ '::formatBlock() formats a message in a block'
+ );
+
+ $this->assertEquals(
+ '<error> Some text to display </error>'."\n".
+ '<error> foo bar </error>',
+ $formatter->formatBlock(array('Some text to display', 'foo bar'), 'error'),
+ '::formatBlock() formats a message in a block'
+ );
+
+ $this->assertEquals(
+ '<error> </error>'."\n".
+ '<error> Some text to display </error>'."\n".
+ '<error> </error>',
+ $formatter->formatBlock('Some text to display', 'error', true),
+ '::formatBlock() formats a message in a block'
+ );
+ }
+
+ public function testFormatBlockWithDiacriticLetters()
+ {
+ if (!function_exists('mb_detect_encoding')) {
+ $this->markTestSkipped('This test requires mbstring to work.');
+ }
+
+ $formatter = new FormatterHelper();
+
+ $this->assertEquals(
+ '<error> </error>'."\n".
+ '<error> Du texte à afficher </error>'."\n".
+ '<error> </error>',
+ $formatter->formatBlock('Du texte à afficher', 'error', true),
+ '::formatBlock() formats a message in a block'
+ );
+ }
+
+ public function testFormatBlockWithDoubleWidthDiacriticLetters()
+ {
+ if (!extension_loaded('mbstring')) {
+ $this->markTestSkipped('This test requires mbstring to work.');
+ }
+ $formatter = new FormatterHelper();
+ $this->assertEquals(
+ '<error> </error>'."\n".
+ '<error> 表示するテキスト </error>'."\n".
+ '<error> </error>',
+ $formatter->formatBlock('表示するテキスト', 'error', true),
+ '::formatBlock() formats a message in a block'
+ );
+ }
+
+ public function testFormatBlockLGEscaping()
+ {
+ $formatter = new FormatterHelper();
+
+ $this->assertEquals(
+ '<error> </error>'."\n".
+ '<error> \<info>some info\</info> </error>'."\n".
+ '<error> </error>',
+ $formatter->formatBlock('<info>some info</info>', 'error', true),
+ '::formatBlock() escapes \'<\' chars'
+ );
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php
new file mode 100644
index 0000000..bf58a45
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php
@@ -0,0 +1,153 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Command\Command;
+
+class HelperSetTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::__construct
+ */
+ public function testConstructor()
+ {
+ $mock_helper = $this->getGenericMockHelper('fake_helper');
+ $helperset = new HelperSet(array('fake_helper_alias' => $mock_helper));
+
+ $this->assertEquals($mock_helper, $helperset->get('fake_helper_alias'), '__construct sets given helper to helpers');
+ $this->assertTrue($helperset->has('fake_helper_alias'), '__construct sets helper alias for given helper');
+ }
+
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::set
+ */
+ public function testSet()
+ {
+ $helperset = new HelperSet();
+ $helperset->set($this->getGenericMockHelper('fake_helper', $helperset));
+ $this->assertTrue($helperset->has('fake_helper'), '->set() adds helper to helpers');
+
+ $helperset = new HelperSet();
+ $helperset->set($this->getGenericMockHelper('fake_helper_01', $helperset));
+ $helperset->set($this->getGenericMockHelper('fake_helper_02', $helperset));
+ $this->assertTrue($helperset->has('fake_helper_01'), '->set() will set multiple helpers on consecutive calls');
+ $this->assertTrue($helperset->has('fake_helper_02'), '->set() will set multiple helpers on consecutive calls');
+
+ $helperset = new HelperSet();
+ $helperset->set($this->getGenericMockHelper('fake_helper', $helperset), 'fake_helper_alias');
+ $this->assertTrue($helperset->has('fake_helper'), '->set() adds helper alias when set');
+ $this->assertTrue($helperset->has('fake_helper_alias'), '->set() adds helper alias when set');
+ }
+
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::has
+ */
+ public function testHas()
+ {
+ $helperset = new HelperSet(array('fake_helper_alias' => $this->getGenericMockHelper('fake_helper')));
+ $this->assertTrue($helperset->has('fake_helper'), '->has() finds set helper');
+ $this->assertTrue($helperset->has('fake_helper_alias'), '->has() finds set helper by alias');
+ }
+
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::get
+ */
+ public function testGet()
+ {
+ $helper_01 = $this->getGenericMockHelper('fake_helper_01');
+ $helper_02 = $this->getGenericMockHelper('fake_helper_02');
+ $helperset = new HelperSet(array('fake_helper_01_alias' => $helper_01, 'fake_helper_02_alias' => $helper_02));
+ $this->assertEquals($helper_01, $helperset->get('fake_helper_01'), '->get() returns correct helper by name');
+ $this->assertEquals($helper_01, $helperset->get('fake_helper_01_alias'), '->get() returns correct helper by alias');
+ $this->assertEquals($helper_02, $helperset->get('fake_helper_02'), '->get() returns correct helper by name');
+ $this->assertEquals($helper_02, $helperset->get('fake_helper_02_alias'), '->get() returns correct helper by alias');
+
+ $helperset = new HelperSet();
+ try {
+ $helperset->get('foo');
+ $this->fail('->get() throws \InvalidArgumentException when helper not found');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->get() throws \InvalidArgumentException when helper not found');
+ $this->assertContains('The helper "foo" is not defined.', $e->getMessage(), '->get() throws \InvalidArgumentException when helper not found');
+ }
+ }
+
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::setCommand
+ */
+ public function testSetCommand()
+ {
+ $cmd_01 = new Command('foo');
+ $cmd_02 = new Command('bar');
+
+ $helperset = new HelperSet();
+ $helperset->setCommand($cmd_01);
+ $this->assertEquals($cmd_01, $helperset->getCommand(), '->setCommand() stores given command');
+
+ $helperset = new HelperSet();
+ $helperset->setCommand($cmd_01);
+ $helperset->setCommand($cmd_02);
+ $this->assertEquals($cmd_02, $helperset->getCommand(), '->setCommand() overwrites stored command with consecutive calls');
+ }
+
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::getCommand
+ */
+ public function testGetCommand()
+ {
+ $cmd = new Command('foo');
+ $helperset = new HelperSet();
+ $helperset->setCommand($cmd);
+ $this->assertEquals($cmd, $helperset->getCommand(), '->getCommand() retrieves stored command');
+ }
+
+ /**
+ * @covers \Symfony\Component\Console\Helper\HelperSet::getIterator
+ */
+ public function testIteration()
+ {
+ $helperset = new HelperSet();
+ $helperset->set($this->getGenericMockHelper('fake_helper_01', $helperset));
+ $helperset->set($this->getGenericMockHelper('fake_helper_02', $helperset));
+
+ $helpers = array('fake_helper_01', 'fake_helper_02');
+ $i = 0;
+
+ foreach ($helperset as $helper) {
+ $this->assertEquals($helpers[$i++], $helper->getName());
+ }
+ }
+
+ /**
+ * Create a generic mock for the helper interface. Optionally check for a call to setHelperSet with a specific
+ * helperset instance.
+ *
+ * @param string $name
+ * @param HelperSet $helperset allows a mock to verify a particular helperset set is being added to the Helper
+ */
+ private function getGenericMockHelper($name, HelperSet $helperset = null)
+ {
+ $mock_helper = $this->getMock('\Symfony\Component\Console\Helper\HelperInterface');
+ $mock_helper->expects($this->any())
+ ->method('getName')
+ ->will($this->returnValue($name));
+
+ if ($helperset) {
+ $mock_helper->expects($this->any())
+ ->method('setHelperSet')
+ ->with($this->equalTo($helperset));
+ }
+
+ return $mock_helper;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyDialogHelperTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyDialogHelperTest.php
new file mode 100644
index 0000000..cf07793
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyDialogHelperTest.php
@@ -0,0 +1,200 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Helper\DialogHelper;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Helper\FormatterHelper;
+use Symfony\Component\Console\Output\StreamOutput;
+
+/**
+ * @group legacy
+ */
+class LegacyDialogHelperTest extends \PHPUnit_Framework_TestCase
+{
+ protected function setUp()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+ }
+
+ public function testSelect()
+ {
+ $dialog = new DialogHelper();
+
+ $helperSet = new HelperSet(array(new FormatterHelper()));
+ $dialog->setHelperSet($helperSet);
+
+ $heroes = array('Superman', 'Batman', 'Spiderman');
+
+ $dialog->setInputStream($this->getInputStream("\n1\n 1 \nFabien\n1\nFabien\n1\n0,2\n 0 , 2 \n\n\n"));
+ $this->assertEquals('2', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, '2'));
+ $this->assertEquals('1', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes));
+ $this->assertEquals('1', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes));
+ $this->assertEquals('1', $dialog->select($output = $this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', false));
+
+ rewind($output->getStream());
+ $this->assertContains('Input "Fabien" is not a superhero!', stream_get_contents($output->getStream()));
+
+ try {
+ $this->assertEquals('1', $dialog->select($output = $this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, 1));
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertEquals('Value "Fabien" is invalid', $e->getMessage());
+ }
+
+ $this->assertEquals(array('1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true));
+ $this->assertEquals(array('0', '2'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true));
+ $this->assertEquals(array('0', '2'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true));
+ $this->assertEquals(array('0', '1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, '0,1', false, 'Input "%s" is not a superhero!', true));
+ $this->assertEquals(array('0', '1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, ' 0 , 1 ', false, 'Input "%s" is not a superhero!', true));
+ }
+
+ public function testAsk()
+ {
+ $dialog = new DialogHelper();
+
+ $dialog->setInputStream($this->getInputStream("\n8AM\n"));
+
+ $this->assertEquals('2PM', $dialog->ask($this->getOutputStream(), 'What time is it?', '2PM'));
+ $this->assertEquals('8AM', $dialog->ask($output = $this->getOutputStream(), 'What time is it?', '2PM'));
+
+ rewind($output->getStream());
+ $this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
+ }
+
+ public function testAskWithAutocomplete()
+ {
+ if (!$this->hasSttyAvailable()) {
+ $this->markTestSkipped('`stty` is required to test autocomplete functionality');
+ }
+
+ // Acm<NEWLINE>
+ // Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
+ // <NEWLINE>
+ // <UP ARROW><UP ARROW><NEWLINE>
+ // <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
+ // <DOWN ARROW><NEWLINE>
+ // S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
+ // F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
+ $inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");
+
+ $dialog = new DialogHelper();
+ $dialog->setInputStream($inputStream);
+
+ $bundles = array('AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle');
+
+ $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('AsseticBundleTest', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('FrameworkBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('SecurityBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('FooBundleTest', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('AsseticBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ $this->assertEquals('FooBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
+ }
+
+ /**
+ * @group tty
+ */
+ public function testAskHiddenResponse()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('This test is not supported on Windows');
+ }
+
+ $dialog = new DialogHelper();
+
+ $dialog->setInputStream($this->getInputStream("8AM\n"));
+
+ $this->assertEquals('8AM', $dialog->askHiddenResponse($this->getOutputStream(), 'What time is it?'));
+ }
+
+ public function testAskConfirmation()
+ {
+ $dialog = new DialogHelper();
+
+ $dialog->setInputStream($this->getInputStream("\n\n"));
+ $this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?'));
+ $this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false));
+
+ $dialog->setInputStream($this->getInputStream("y\nyes\n"));
+ $this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false));
+ $this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false));
+
+ $dialog->setInputStream($this->getInputStream("n\nno\n"));
+ $this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', true));
+ $this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', true));
+ }
+
+ public function testAskAndValidate()
+ {
+ $dialog = new DialogHelper();
+ $helperSet = new HelperSet(array(new FormatterHelper()));
+ $dialog->setHelperSet($helperSet);
+
+ $question = 'What color was the white horse of Henry IV?';
+ $error = 'This is not a color!';
+ $validator = function ($color) use ($error) {
+ if (!in_array($color, array('white', 'black'))) {
+ throw new \InvalidArgumentException($error);
+ }
+
+ return $color;
+ };
+
+ $dialog->setInputStream($this->getInputStream("\nblack\n"));
+ $this->assertEquals('white', $dialog->askAndValidate($this->getOutputStream(), $question, $validator, 2, 'white'));
+ $this->assertEquals('black', $dialog->askAndValidate($this->getOutputStream(), $question, $validator, 2, 'white'));
+
+ $dialog->setInputStream($this->getInputStream("green\nyellow\norange\n"));
+ try {
+ $this->assertEquals('white', $dialog->askAndValidate($this->getOutputStream(), $question, $validator, 2, 'white'));
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertEquals($error, $e->getMessage());
+ }
+ }
+
+ public function testNoInteraction()
+ {
+ $dialog = new DialogHelper();
+
+ $input = new ArrayInput(array());
+ $input->setInteractive(false);
+
+ $dialog->setInput($input);
+
+ $this->assertEquals('not yet', $dialog->ask($this->getOutputStream(), 'Do you have a job?', 'not yet'));
+ }
+
+ protected function getInputStream($input)
+ {
+ $stream = fopen('php://memory', 'r+', false);
+ fwrite($stream, $input);
+ rewind($stream);
+
+ return $stream;
+ }
+
+ protected function getOutputStream()
+ {
+ return new StreamOutput(fopen('php://memory', 'r+', false));
+ }
+
+ private function hasSttyAvailable()
+ {
+ exec('stty 2>&1', $output, $exitcode);
+
+ return $exitcode === 0;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyProgressHelperTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyProgressHelperTest.php
new file mode 100644
index 0000000..e93057a
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyProgressHelperTest.php
@@ -0,0 +1,232 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Helper\ProgressHelper;
+use Symfony\Component\Console\Output\StreamOutput;
+
+/**
+ * @group legacy
+ */
+class LegacyProgressHelperTest extends \PHPUnit_Framework_TestCase
+{
+ protected function setUp()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+ }
+
+ public function testAdvance()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream());
+ $progress->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 1 [->--------------------------]'), stream_get_contents($output->getStream()));
+ }
+
+ public function testAdvanceWithStep()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream());
+ $progress->advance(5);
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 5 [----->----------------------]'), stream_get_contents($output->getStream()));
+ }
+
+ public function testAdvanceMultipleTimes()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream());
+ $progress->advance(3);
+ $progress->advance(2);
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 3 [--->------------------------]').$this->generateOutput(' 5 [----->----------------------]'), stream_get_contents($output->getStream()));
+ }
+
+ public function testCustomizations()
+ {
+ $progress = new ProgressHelper();
+ $progress->setBarWidth(10);
+ $progress->setBarCharacter('_');
+ $progress->setEmptyBarCharacter(' ');
+ $progress->setProgressCharacter('/');
+ $progress->setFormat(' %current%/%max% [%bar%] %percent%%');
+ $progress->start($output = $this->getOutputStream(), 10);
+ $progress->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 1/10 [_/ ] 10%'), stream_get_contents($output->getStream()));
+ }
+
+ public function testPercent()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream(), 50);
+ $progress->display();
+ $progress->advance();
+ $progress->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 0/50 [>---------------------------] 0%').$this->generateOutput(' 1/50 [>---------------------------] 2%').$this->generateOutput(' 2/50 [=>--------------------------] 4%'), stream_get_contents($output->getStream()));
+ }
+
+ public function testOverwriteWithShorterLine()
+ {
+ $progress = new ProgressHelper();
+ $progress->setFormat(' %current%/%max% [%bar%] %percent%%');
+ $progress->start($output = $this->getOutputStream(), 50);
+ $progress->display();
+ $progress->advance();
+
+ // set shorter format
+ $progress->setFormat(' %current%/%max% [%bar%]');
+ $progress->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/50 [>---------------------------] 0%').
+ $this->generateOutput(' 1/50 [>---------------------------] 2%').
+ $this->generateOutput(' 2/50 [=>--------------------------] '),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testSetCurrentProgress()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream(), 50);
+ $progress->display();
+ $progress->advance();
+ $progress->setCurrent(15);
+ $progress->setCurrent(25);
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/50 [>---------------------------] 0%').
+ $this->generateOutput(' 1/50 [>---------------------------] 2%').
+ $this->generateOutput(' 15/50 [========>-------------------] 30%').
+ $this->generateOutput(' 25/50 [==============>-------------] 50%'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage You must start the progress bar
+ */
+ public function testSetCurrentBeforeStarting()
+ {
+ $progress = new ProgressHelper();
+ $progress->setCurrent(15);
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage You can't regress the progress bar
+ */
+ public function testRegressProgress()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream(), 50);
+ $progress->setCurrent(15);
+ $progress->setCurrent(10);
+ }
+
+ public function testRedrawFrequency()
+ {
+ $progress = $this->getMock('Symfony\Component\Console\Helper\ProgressHelper', array('display'));
+ $progress->expects($this->exactly(4))
+ ->method('display');
+
+ $progress->setRedrawFrequency(2);
+
+ $progress->start($output = $this->getOutputStream(), 6);
+ $progress->setCurrent(1);
+ $progress->advance(2);
+ $progress->advance(2);
+ $progress->advance(1);
+ }
+
+ public function testMultiByteSupport()
+ {
+ if (!function_exists('mb_strlen') || (false === $encoding = mb_detect_encoding('■'))) {
+ $this->markTestSkipped('The mbstring extension is needed for multi-byte support');
+ }
+
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream());
+ $progress->setBarCharacter('■');
+ $progress->advance(3);
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 3 [■■■>------------------------]'), stream_get_contents($output->getStream()));
+ }
+
+ public function testClear()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream(), 50);
+ $progress->setCurrent(25);
+ $progress->clear();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 25/50 [==============>-------------] 50%').$this->generateOutput(''),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testPercentNotHundredBeforeComplete()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream(), 200);
+ $progress->display();
+ $progress->advance(199);
+ $progress->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals($this->generateOutput(' 0/200 [>---------------------------] 0%').$this->generateOutput(' 199/200 [===========================>] 99%').$this->generateOutput(' 200/200 [============================] 100%'), stream_get_contents($output->getStream()));
+ }
+
+ public function testNonDecoratedOutput()
+ {
+ $progress = new ProgressHelper();
+ $progress->start($output = $this->getOutputStream(false));
+ $progress->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals('', stream_get_contents($output->getStream()));
+ }
+
+ protected function getOutputStream($decorated = true)
+ {
+ return new StreamOutput(fopen('php://memory', 'r+', false), StreamOutput::VERBOSITY_NORMAL, $decorated);
+ }
+
+ protected $lastMessagesLength;
+
+ protected function generateOutput($expected)
+ {
+ $expectedout = $expected;
+
+ if ($this->lastMessagesLength !== null) {
+ $expectedout = str_pad($expected, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
+ }
+
+ $this->lastMessagesLength = strlen($expectedout);
+
+ return "\x0D".$expectedout;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyTableHelperTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyTableHelperTest.php
new file mode 100644
index 0000000..b7e3159
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/LegacyTableHelperTest.php
@@ -0,0 +1,325 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Helper\TableHelper;
+use Symfony\Component\Console\Output\StreamOutput;
+
+/**
+ * @group legacy
+ */
+class LegacyTableHelperTest extends \PHPUnit_Framework_TestCase
+{
+ protected $stream;
+
+ protected function setUp()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+ $this->stream = fopen('php://memory', 'r+');
+ }
+
+ protected function tearDown()
+ {
+ fclose($this->stream);
+ $this->stream = null;
+ }
+
+ /**
+ * @dataProvider testRenderProvider
+ */
+ public function testRender($headers, $rows, $layout, $expected)
+ {
+ $table = new TableHelper();
+ $table
+ ->setHeaders($headers)
+ ->setRows($rows)
+ ->setLayout($layout)
+ ;
+ $table->render($output = $this->getOutputStream());
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ /**
+ * @dataProvider testRenderProvider
+ */
+ public function testRenderAddRows($headers, $rows, $layout, $expected)
+ {
+ $table = new TableHelper();
+ $table
+ ->setHeaders($headers)
+ ->addRows($rows)
+ ->setLayout($layout)
+ ;
+ $table->render($output = $this->getOutputStream());
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ /**
+ * @dataProvider testRenderProvider
+ */
+ public function testRenderAddRowsOneByOne($headers, $rows, $layout, $expected)
+ {
+ $table = new TableHelper();
+ $table
+ ->setHeaders($headers)
+ ->setLayout($layout)
+ ;
+ foreach ($rows as $row) {
+ $table->addRow($row);
+ }
+ $table->render($output = $this->getOutputStream());
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ public function testRenderProvider()
+ {
+ $books = array(
+ array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
+ array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
+ array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
+ array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
+ );
+
+ return array(
+ array(
+ array('ISBN', 'Title', 'Author'),
+ $books,
+ TableHelper::LAYOUT_DEFAULT,
+<<<TABLE
++---------------+--------------------------+------------------+
+| ISBN | Title | Author |
++---------------+--------------------------+------------------+
+| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+| 80-902734-1-6 | And Then There Were None | Agatha Christie |
++---------------+--------------------------+------------------+
+
+TABLE
+ ),
+ array(
+ array('ISBN', 'Title', 'Author'),
+ $books,
+ TableHelper::LAYOUT_COMPACT,
+<<<TABLE
+ ISBN Title Author
+ 99921-58-10-7 Divine Comedy Dante Alighieri
+ 9971-5-0210-0 A Tale of Two Cities Charles Dickens
+ 960-425-059-0 The Lord of the Rings J. R. R. Tolkien
+ 80-902734-1-6 And Then There Were None Agatha Christie
+
+TABLE
+ ),
+ array(
+ array('ISBN', 'Title', 'Author'),
+ $books,
+ TableHelper::LAYOUT_BORDERLESS,
+<<<TABLE
+ =============== ========================== ==================
+ ISBN Title Author
+ =============== ========================== ==================
+ 99921-58-10-7 Divine Comedy Dante Alighieri
+ 9971-5-0210-0 A Tale of Two Cities Charles Dickens
+ 960-425-059-0 The Lord of the Rings J. R. R. Tolkien
+ 80-902734-1-6 And Then There Were None Agatha Christie
+ =============== ========================== ==================
+
+TABLE
+ ),
+ array(
+ array('ISBN', 'Title'),
+ array(
+ array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
+ array('9971-5-0210-0'),
+ array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
+ array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
+ ),
+ TableHelper::LAYOUT_DEFAULT,
+<<<TABLE
++---------------+--------------------------+------------------+
+| ISBN | Title | |
++---------------+--------------------------+------------------+
+| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+| 9971-5-0210-0 | | |
+| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+| 80-902734-1-6 | And Then There Were None | Agatha Christie |
++---------------+--------------------------+------------------+
+
+TABLE
+ ),
+ array(
+ array(),
+ array(
+ array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
+ array('9971-5-0210-0'),
+ array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
+ array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
+ ),
+ TableHelper::LAYOUT_DEFAULT,
+<<<TABLE
++---------------+--------------------------+------------------+
+| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+| 9971-5-0210-0 | | |
+| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+| 80-902734-1-6 | And Then There Were None | Agatha Christie |
++---------------+--------------------------+------------------+
+
+TABLE
+ ),
+ array(
+ array('ISBN', 'Title', 'Author'),
+ array(
+ array('99921-58-10-7', "Divine\nComedy", 'Dante Alighieri'),
+ array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
+ array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
+ array('960-425-059-0', 'The Lord of the Rings', "J. R. R.\nTolkien"),
+ ),
+ TableHelper::LAYOUT_DEFAULT,
+<<<TABLE
++---------------+----------------------------+-----------------+
+| ISBN | Title | Author |
++---------------+----------------------------+-----------------+
+| 99921-58-10-7 | Divine | Dante Alighieri |
+| | Comedy | |
+| 9971-5-0210-2 | Harry Potter | Rowling |
+| | and the Chamber of Secrets | Joanne K. |
+| 9971-5-0210-2 | Harry Potter | Rowling |
+| | and the Chamber of Secrets | Joanne K. |
+| 960-425-059-0 | The Lord of the Rings | J. R. R. |
+| | | Tolkien |
++---------------+----------------------------+-----------------+
+
+TABLE
+ ),
+ array(
+ array('ISBN', 'Title'),
+ array(),
+ TableHelper::LAYOUT_DEFAULT,
+<<<TABLE
++------+-------+
+| ISBN | Title |
++------+-------+
+
+TABLE
+ ),
+ array(
+ array(),
+ array(),
+ TableHelper::LAYOUT_DEFAULT,
+ '',
+ ),
+ 'Cell text with tags used for Output styling' => array(
+ array('ISBN', 'Title', 'Author'),
+ array(
+ array('<info>99921-58-10-7</info>', '<error>Divine Comedy</error>', '<fg=blue;bg=white>Dante Alighieri</fg=blue;bg=white>'),
+ array('9971-5-0210-0', 'A Tale of Two Cities', '<info>Charles Dickens</>'),
+ ),
+ TableHelper::LAYOUT_DEFAULT,
+<<<TABLE
++---------------+----------------------+-----------------+
+| ISBN | Title | Author |
++---------------+----------------------+-----------------+
+| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
++---------------+----------------------+-----------------+
+
+TABLE
+ ),
+ 'Cell text with tags not used for Output styling' => array(
+ array('ISBN', 'Title', 'Author'),
+ array(
+ array('<strong>99921-58-10-700</strong>', '<f>Divine Com</f>', 'Dante Alighieri'),
+ array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
+ ),
+ TableHelper::LAYOUT_DEFAULT,
+<<<TABLE
++----------------------------------+----------------------+-----------------+
+| ISBN | Title | Author |
++----------------------------------+----------------------+-----------------+
+| <strong>99921-58-10-700</strong> | <f>Divine Com</f> | Dante Alighieri |
+| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
++----------------------------------+----------------------+-----------------+
+
+TABLE
+ ),
+ );
+ }
+
+ public function testRenderMultiByte()
+ {
+ if (!function_exists('mb_strwidth')) {
+ $this->markTestSkipped('The "mbstring" extension is not available');
+ }
+
+ $table = new TableHelper();
+ $table
+ ->setHeaders(array('■■'))
+ ->setRows(array(array(1234)))
+ ->setLayout(TableHelper::LAYOUT_DEFAULT)
+ ;
+ $table->render($output = $this->getOutputStream());
+
+ $expected =
+<<<TABLE
++------+
+| ■■ |
++------+
+| 1234 |
++------+
+
+TABLE;
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ public function testRenderFullWidthCharacters()
+ {
+ if (!function_exists('mb_strwidth')) {
+ $this->markTestSkipped('The "mbstring" extension is not available');
+ }
+
+ $table = new TableHelper();
+ $table
+ ->setHeaders(array('あいうえお'))
+ ->setRows(array(array(1234567890)))
+ ->setLayout(TableHelper::LAYOUT_DEFAULT)
+ ;
+ $table->render($output = $this->getOutputStream());
+
+ $expected =
+ <<<TABLE
++------------+
+| あいうえお |
++------------+
+| 1234567890 |
++------------+
+
+TABLE;
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ protected function getOutputStream()
+ {
+ return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false);
+ }
+
+ protected function getOutputContent(StreamOutput $output)
+ {
+ rewind($output->getStream());
+
+ return str_replace(PHP_EOL, "\n", stream_get_contents($output->getStream()));
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php
new file mode 100644
index 0000000..2e333dc
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php
@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Helper\DebugFormatterHelper;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Helper\Helper;
+use Symfony\Component\Console\Output\StreamOutput;
+use Symfony\Component\Console\Helper\ProcessHelper;
+use Symfony\Component\Process\Process;
+
+class ProcessHelperTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider provideCommandsAndOutput
+ */
+ public function testVariousProcessRuns($expected, $cmd, $verbosity, $error)
+ {
+ $helper = new ProcessHelper();
+ $helper->setHelperSet(new HelperSet(array(new DebugFormatterHelper())));
+ $output = $this->getOutputStream($verbosity);
+ $helper->run($output, $cmd, $error);
+ $this->assertEquals($expected, $this->getOutput($output));
+ }
+
+ public function testPassedCallbackIsExecuted()
+ {
+ $helper = new ProcessHelper();
+ $helper->setHelperSet(new HelperSet(array(new DebugFormatterHelper())));
+ $output = $this->getOutputStream(StreamOutput::VERBOSITY_NORMAL);
+
+ $executed = false;
+ $callback = function () use (&$executed) { $executed = true; };
+
+ $helper->run($output, 'php -r "echo 42;"', null, $callback);
+ $this->assertTrue($executed);
+ }
+
+ public function provideCommandsAndOutput()
+ {
+ $successOutputVerbose = <<<EOT
+ RUN php -r "echo 42;"
+ RES Command ran successfully
+
+EOT;
+ $successOutputDebug = <<<EOT
+ RUN php -r "echo 42;"
+ OUT 42
+ RES Command ran successfully
+
+EOT;
+ $successOutputDebugWithTags = <<<EOT
+ RUN php -r "echo \"<info>42</info>\";"
+ OUT <info>42</info>
+ RES Command ran successfully
+
+EOT;
+ $successOutputProcessDebug = <<<EOT
+ RUN 'php' '-r' 'echo 42;'
+ OUT 42
+ RES Command ran successfully
+
+EOT;
+ $syntaxErrorOutputVerbose = <<<EOT
+ RUN php -r "fwrite(STDERR, 'error message');usleep(50000);fwrite(STDOUT, 'out message');exit(252);"
+ RES 252 Command did not run successfully
+
+EOT;
+ $syntaxErrorOutputDebug = <<<EOT
+ RUN php -r "fwrite(STDERR, 'error message');usleep(50000);fwrite(STDOUT, 'out message');exit(252);"
+ ERR error message
+ OUT out message
+ RES 252 Command did not run successfully
+
+EOT;
+
+ $errorMessage = 'An error occurred';
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $successOutputProcessDebug = str_replace("'", '"', $successOutputProcessDebug);
+ }
+
+ return array(
+ array('', 'php -r "echo 42;"', StreamOutput::VERBOSITY_VERBOSE, null),
+ array($successOutputVerbose, 'php -r "echo 42;"', StreamOutput::VERBOSITY_VERY_VERBOSE, null),
+ array($successOutputDebug, 'php -r "echo 42;"', StreamOutput::VERBOSITY_DEBUG, null),
+ array($successOutputDebugWithTags, 'php -r "echo \"<info>42</info>\";"', StreamOutput::VERBOSITY_DEBUG, null),
+ array('', 'php -r "syntax error"', StreamOutput::VERBOSITY_VERBOSE, null),
+ array($syntaxErrorOutputVerbose, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERY_VERBOSE, null),
+ array($syntaxErrorOutputDebug, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, null),
+ array($errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERBOSE, $errorMessage),
+ array($syntaxErrorOutputVerbose.$errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERY_VERBOSE, $errorMessage),
+ array($syntaxErrorOutputDebug.$errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, $errorMessage),
+ array($successOutputProcessDebug, array('php', '-r', 'echo 42;'), StreamOutput::VERBOSITY_DEBUG, null),
+ array($successOutputDebug, new Process('php -r "echo 42;"'), StreamOutput::VERBOSITY_DEBUG, null),
+ );
+ }
+
+ private function getOutputStream($verbosity)
+ {
+ return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, false);
+ }
+
+ private function getOutput(StreamOutput $output)
+ {
+ rewind($output->getStream());
+
+ return stream_get_contents($output->getStream());
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php
new file mode 100644
index 0000000..59c06bb
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php
@@ -0,0 +1,598 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Helper\ProgressBar;
+use Symfony\Component\Console\Helper\Helper;
+use Symfony\Component\Console\Output\StreamOutput;
+
+class ProgressBarTest extends \PHPUnit_Framework_TestCase
+{
+ public function testMultipleStart()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream());
+ $bar->start();
+ $bar->advance();
+ $bar->start();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0 [>---------------------------]').
+ $this->generateOutput(' 1 [->--------------------------]').
+ $this->generateOutput(' 0 [>---------------------------]'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testAdvance()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream());
+ $bar->start();
+ $bar->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0 [>---------------------------]').
+ $this->generateOutput(' 1 [->--------------------------]'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testAdvanceWithStep()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream());
+ $bar->start();
+ $bar->advance(5);
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0 [>---------------------------]').
+ $this->generateOutput(' 5 [----->----------------------]'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testAdvanceMultipleTimes()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream());
+ $bar->start();
+ $bar->advance(3);
+ $bar->advance(2);
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0 [>---------------------------]').
+ $this->generateOutput(' 3 [--->------------------------]').
+ $this->generateOutput(' 5 [----->----------------------]'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testAdvanceOverMax()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(), 10);
+ $bar->setProgress(9);
+ $bar->advance();
+ $bar->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 9/10 [=========================>--] 90%').
+ $this->generateOutput(' 10/10 [============================] 100%').
+ $this->generateOutput(' 11/11 [============================] 100%'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testCustomizations()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(), 10);
+ $bar->setBarWidth(10);
+ $bar->setBarCharacter('_');
+ $bar->setEmptyBarCharacter(' ');
+ $bar->setProgressCharacter('/');
+ $bar->setFormat(' %current%/%max% [%bar%] %percent:3s%%');
+ $bar->start();
+ $bar->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/10 [/ ] 0%').
+ $this->generateOutput(' 1/10 [_/ ] 10%'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testDisplayWithoutStart()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(), 50);
+ $bar->display();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/50 [>---------------------------] 0%'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testDisplayWithQuietVerbosity()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(true, StreamOutput::VERBOSITY_QUIET), 50);
+ $bar->display();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ '',
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testFinishWithoutStart()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(), 50);
+ $bar->finish();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 50/50 [============================] 100%'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testPercent()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(), 50);
+ $bar->start();
+ $bar->display();
+ $bar->advance();
+ $bar->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/50 [>---------------------------] 0%').
+ $this->generateOutput(' 0/50 [>---------------------------] 0%').
+ $this->generateOutput(' 1/50 [>---------------------------] 2%').
+ $this->generateOutput(' 2/50 [=>--------------------------] 4%'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testOverwriteWithShorterLine()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(), 50);
+ $bar->setFormat(' %current%/%max% [%bar%] %percent:3s%%');
+ $bar->start();
+ $bar->display();
+ $bar->advance();
+
+ // set shorter format
+ $bar->setFormat(' %current%/%max% [%bar%]');
+ $bar->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/50 [>---------------------------] 0%').
+ $this->generateOutput(' 0/50 [>---------------------------] 0%').
+ $this->generateOutput(' 1/50 [>---------------------------] 2%').
+ $this->generateOutput(' 2/50 [=>--------------------------] '),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testStartWithMax()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream());
+ $bar->setFormat('%current%/%max% [%bar%]');
+ $bar->start(50);
+ $bar->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/50 [>---------------------------]').
+ $this->generateOutput(' 1/50 [>---------------------------]'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testSetCurrentProgress()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(), 50);
+ $bar->start();
+ $bar->display();
+ $bar->advance();
+ $bar->setProgress(15);
+ $bar->setProgress(25);
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/50 [>---------------------------] 0%').
+ $this->generateOutput(' 0/50 [>---------------------------] 0%').
+ $this->generateOutput(' 1/50 [>---------------------------] 2%').
+ $this->generateOutput(' 15/50 [========>-------------------] 30%').
+ $this->generateOutput(' 25/50 [==============>-------------] 50%'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ /**
+ */
+ public function testSetCurrentBeforeStarting()
+ {
+ $bar = new ProgressBar($this->getOutputStream());
+ $bar->setProgress(15);
+ $this->assertNotNull($bar->getStartTime());
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage You can't regress the progress bar
+ */
+ public function testRegressProgress()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(), 50);
+ $bar->start();
+ $bar->setProgress(15);
+ $bar->setProgress(10);
+ }
+
+ public function testRedrawFrequency()
+ {
+ $bar = $this->getMock('Symfony\Component\Console\Helper\ProgressBar', array('display'), array($output = $this->getOutputStream(), 6));
+ $bar->expects($this->exactly(4))->method('display');
+
+ $bar->setRedrawFrequency(2);
+ $bar->start();
+ $bar->setProgress(1);
+ $bar->advance(2);
+ $bar->advance(2);
+ $bar->advance(1);
+ }
+
+ public function testMultiByteSupport()
+ {
+ if (!function_exists('mb_strlen') || (false === $encoding = mb_detect_encoding('■'))) {
+ $this->markTestSkipped('The mbstring extension is needed for multi-byte support');
+ }
+
+ $bar = new ProgressBar($output = $this->getOutputStream());
+ $bar->start();
+ $bar->setBarCharacter('■');
+ $bar->advance(3);
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0 [>---------------------------]').
+ $this->generateOutput(' 3 [■■■>------------------------]'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testClear()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(), 50);
+ $bar->start();
+ $bar->setProgress(25);
+ $bar->clear();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/50 [>---------------------------] 0%').
+ $this->generateOutput(' 25/50 [==============>-------------] 50%').
+ $this->generateOutput(' '),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testPercentNotHundredBeforeComplete()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(), 200);
+ $bar->start();
+ $bar->display();
+ $bar->advance(199);
+ $bar->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/200 [>---------------------------] 0%').
+ $this->generateOutput(' 0/200 [>---------------------------] 0%').
+ $this->generateOutput(' 199/200 [===========================>] 99%').
+ $this->generateOutput(' 200/200 [============================] 100%'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testNonDecoratedOutput()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(false), 200);
+ $bar->start();
+
+ for ($i = 0; $i < 200; $i++) {
+ $bar->advance();
+ }
+
+ $bar->finish();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ " 0/200 [>---------------------------] 0%\n".
+ " 20/200 [==>-------------------------] 10%\n".
+ " 40/200 [=====>----------------------] 20%\n".
+ " 60/200 [========>-------------------] 30%\n".
+ " 80/200 [===========>----------------] 40%\n".
+ " 100/200 [==============>-------------] 50%\n".
+ " 120/200 [================>-----------] 60%\n".
+ " 140/200 [===================>--------] 70%\n".
+ " 160/200 [======================>-----] 80%\n".
+ " 180/200 [=========================>--] 90%\n".
+ " 200/200 [============================] 100%",
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testNonDecoratedOutputWithClear()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(false), 50);
+ $bar->start();
+ $bar->setProgress(25);
+ $bar->clear();
+ $bar->setProgress(50);
+ $bar->finish();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ " 0/50 [>---------------------------] 0%\n".
+ " 25/50 [==============>-------------] 50%\n".
+ " 50/50 [============================] 100%",
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testNonDecoratedOutputWithoutMax()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(false));
+ $bar->start();
+ $bar->advance();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ " 0 [>---------------------------]\n".
+ " 1 [->--------------------------]",
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testParallelBars()
+ {
+ $output = $this->getOutputStream();
+ $bar1 = new ProgressBar($output, 2);
+ $bar2 = new ProgressBar($output, 3);
+ $bar2->setProgressCharacter('#');
+ $bar3 = new ProgressBar($output);
+
+ $bar1->start();
+ $output->write("\n");
+ $bar2->start();
+ $output->write("\n");
+ $bar3->start();
+
+ for ($i = 1; $i <= 3; $i++) {
+ // up two lines
+ $output->write("\033[2A");
+ if ($i <= 2) {
+ $bar1->advance();
+ }
+ $output->write("\n");
+ $bar2->advance();
+ $output->write("\n");
+ $bar3->advance();
+ }
+ $output->write("\033[2A");
+ $output->write("\n");
+ $output->write("\n");
+ $bar3->finish();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/2 [>---------------------------] 0%')."\n".
+ $this->generateOutput(' 0/3 [#---------------------------] 0%')."\n".
+ rtrim($this->generateOutput(' 0 [>---------------------------]')).
+
+ "\033[2A".
+ $this->generateOutput(' 1/2 [==============>-------------] 50%')."\n".
+ $this->generateOutput(' 1/3 [=========#------------------] 33%')."\n".
+ rtrim($this->generateOutput(' 1 [->--------------------------]')).
+
+ "\033[2A".
+ $this->generateOutput(' 2/2 [============================] 100%')."\n".
+ $this->generateOutput(' 2/3 [==================#---------] 66%')."\n".
+ rtrim($this->generateOutput(' 2 [-->-------------------------]')).
+
+ "\033[2A".
+ "\n".
+ $this->generateOutput(' 3/3 [============================] 100%')."\n".
+ rtrim($this->generateOutput(' 3 [--->------------------------]')).
+
+ "\033[2A".
+ "\n".
+ "\n".
+ rtrim($this->generateOutput(' 3 [============================]')),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testWithoutMax()
+ {
+ $output = $this->getOutputStream();
+
+ $bar = new ProgressBar($output);
+ $bar->start();
+ $bar->advance();
+ $bar->advance();
+ $bar->advance();
+ $bar->finish();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ rtrim($this->generateOutput(' 0 [>---------------------------]')).
+ rtrim($this->generateOutput(' 1 [->--------------------------]')).
+ rtrim($this->generateOutput(' 2 [-->-------------------------]')).
+ rtrim($this->generateOutput(' 3 [--->------------------------]')).
+ rtrim($this->generateOutput(' 3 [============================]')),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testAddingPlaceholderFormatter()
+ {
+ ProgressBar::setPlaceholderFormatterDefinition('remaining_steps', function (ProgressBar $bar) {
+ return $bar->getMaxSteps() - $bar->getProgress();
+ });
+ $bar = new ProgressBar($output = $this->getOutputStream(), 3);
+ $bar->setFormat(' %remaining_steps% [%bar%]');
+
+ $bar->start();
+ $bar->advance();
+ $bar->finish();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 3 [>---------------------------]').
+ $this->generateOutput(' 2 [=========>------------------]').
+ $this->generateOutput(' 0 [============================]'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testMultilineFormat()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(), 3);
+ $bar->setFormat("%bar%\nfoobar");
+
+ $bar->start();
+ $bar->advance();
+ $bar->clear();
+ $bar->finish();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(">---------------------------\nfoobar").
+ $this->generateOutput("=========>------------------\nfoobar ").
+ $this->generateOutput(" \n ").
+ $this->generateOutput("============================\nfoobar "),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testAnsiColorsAndEmojis()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream(), 15);
+ ProgressBar::setPlaceholderFormatterDefinition('memory', function (ProgressBar $bar) {
+ static $i = 0;
+ $mem = 100000 * $i;
+ $colors = $i++ ? '41;37' : '44;37';
+
+ return "\033[".$colors."m ".Helper::formatMemory($mem)." \033[0m";
+ });
+ $bar->setFormat(" \033[44;37m %title:-37s% \033[0m\n %current%/%max% %bar% %percent:3s%%\n 🏁 %remaining:-10s% %memory:37s%");
+ $bar->setBarCharacter($done = "\033[32m●\033[0m");
+ $bar->setEmptyBarCharacter($empty = "\033[31m●\033[0m");
+ $bar->setProgressCharacter($progress = "\033[32m➤ \033[0m");
+
+ $bar->setMessage('Starting the demo... fingers crossed', 'title');
+ $bar->start();
+ $bar->setMessage('Looks good to me...', 'title');
+ $bar->advance(4);
+ $bar->setMessage('Thanks, bye', 'title');
+ $bar->finish();
+
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(
+ " \033[44;37m Starting the demo... fingers crossed \033[0m\n".
+ " 0/15 ".$progress.str_repeat($empty, 26)." 0%\n".
+ " \xf0\x9f\x8f\x81 1 sec \033[44;37m 0 B \033[0m"
+ ).
+ $this->generateOutput(
+ " \033[44;37m Looks good to me... \033[0m\n".
+ " 4/15 ".str_repeat($done, 7).$progress.str_repeat($empty, 19)." 26%\n".
+ " \xf0\x9f\x8f\x81 1 sec \033[41;37m 97 KiB \033[0m"
+ ).
+ $this->generateOutput(
+ " \033[44;37m Thanks, bye \033[0m\n".
+ " 15/15 ".str_repeat($done, 28)." 100%\n".
+ " \xf0\x9f\x8f\x81 1 sec \033[41;37m 195 KiB \033[0m"
+ ),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ public function testSetFormat()
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream());
+ $bar->setFormat('normal');
+ $bar->start();
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0 [>---------------------------]'),
+ stream_get_contents($output->getStream())
+ );
+
+ $bar = new ProgressBar($output = $this->getOutputStream(), 10);
+ $bar->setFormat('normal');
+ $bar->start();
+ rewind($output->getStream());
+ $this->assertEquals(
+ $this->generateOutput(' 0/10 [>---------------------------] 0%'),
+ stream_get_contents($output->getStream())
+ );
+ }
+
+ /**
+ * @dataProvider provideFormat
+ */
+ public function testFormatsWithoutMax($format)
+ {
+ $bar = new ProgressBar($output = $this->getOutputStream());
+ $bar->setFormat($format);
+ $bar->start();
+
+ rewind($output->getStream());
+ $this->assertNotEmpty(stream_get_contents($output->getStream()));
+ }
+
+ /**
+ * Provides each defined format
+ *
+ * @return array
+ */
+ public function provideFormat()
+ {
+ return array(
+ array('normal'),
+ array('verbose'),
+ array('very_verbose'),
+ array('debug'),
+ );
+ }
+
+ protected function getOutputStream($decorated = true, $verbosity = StreamOutput::VERBOSITY_NORMAL)
+ {
+ return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, $decorated);
+ }
+
+ protected function generateOutput($expected)
+ {
+ $count = substr_count($expected, "\n");
+
+ return "\x0D".($count ? sprintf("\033[%dA", $count) : '').$expected;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php
new file mode 100644
index 0000000..0ab0849
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php
@@ -0,0 +1,238 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Helper\QuestionHelper;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Helper\FormatterHelper;
+use Symfony\Component\Console\Output\StreamOutput;
+use Symfony\Component\Console\Question\ChoiceQuestion;
+use Symfony\Component\Console\Question\ConfirmationQuestion;
+use Symfony\Component\Console\Question\Question;
+
+/**
+ * @group tty
+ */
+class QuestionHelperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testAskChoice()
+ {
+ $questionHelper = new QuestionHelper();
+
+ $helperSet = new HelperSet(array(new FormatterHelper()));
+ $questionHelper->setHelperSet($helperSet);
+
+ $heroes = array('Superman', 'Batman', 'Spiderman');
+
+ $questionHelper->setInputStream($this->getInputStream("\n1\n 1 \nFabien\n1\nFabien\n1\n0,2\n 0 , 2 \n\n\n"));
+
+ $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '2');
+ // first answer is an empty answer, we're supposed to receive the default value
+ $this->assertEquals('Spiderman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+
+ $question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
+ $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+
+ $question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
+ $question->setErrorMessage('Input "%s" is not a superhero!');
+ $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));
+
+ rewind($output->getStream());
+ $stream = stream_get_contents($output->getStream());
+ $this->assertContains('Input "Fabien" is not a superhero!', $stream);
+
+ try {
+ $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '1');
+ $question->setMaxAttempts(1);
+ $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question);
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertEquals('Value "Fabien" is invalid', $e->getMessage());
+ }
+
+ $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null);
+ $question->setMultiselect(true);
+
+ $this->assertEquals(array('Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+
+ $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0,1');
+ $question->setMultiselect(true);
+
+ $this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+
+ $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, ' 0 , 1 ');
+ $question->setMultiselect(true);
+
+ $this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ }
+
+ public function testAsk()
+ {
+ $dialog = new QuestionHelper();
+
+ $dialog->setInputStream($this->getInputStream("\n8AM\n"));
+
+ $question = new Question('What time is it?', '2PM');
+ $this->assertEquals('2PM', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+
+ $question = new Question('What time is it?', '2PM');
+ $this->assertEquals('8AM', $dialog->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));
+
+ rewind($output->getStream());
+ $this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
+ }
+
+ public function testAskWithAutocomplete()
+ {
+ if (!$this->hasSttyAvailable()) {
+ $this->markTestSkipped('`stty` is required to test autocomplete functionality');
+ }
+
+ // Acm<NEWLINE>
+ // Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
+ // <NEWLINE>
+ // <UP ARROW><UP ARROW><NEWLINE>
+ // <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
+ // <DOWN ARROW><NEWLINE>
+ // S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
+ // F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
+ $inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");
+
+ $dialog = new QuestionHelper();
+ $dialog->setInputStream($inputStream);
+ $helperSet = new HelperSet(array(new FormatterHelper()));
+ $dialog->setHelperSet($helperSet);
+
+ $question = new Question('Please select a bundle', 'FrameworkBundle');
+ $question->setAutocompleterValues(array('AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle'));
+
+ $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $this->assertEquals('AsseticBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $this->assertEquals('FrameworkBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $this->assertEquals('SecurityBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $this->assertEquals('FooBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $this->assertEquals('FooBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ }
+
+ public function testAskHiddenResponse()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('This test is not supported on Windows');
+ }
+
+ $dialog = new QuestionHelper();
+ $dialog->setInputStream($this->getInputStream("8AM\n"));
+
+ $question = new Question('What time is it?');
+ $question->setHidden(true);
+
+ $this->assertEquals('8AM', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ }
+
+ public function testAskConfirmation()
+ {
+ $dialog = new QuestionHelper();
+
+ $dialog->setInputStream($this->getInputStream("\n\n"));
+ $question = new ConfirmationQuestion('Do you like French fries?');
+ $this->assertTrue($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $question = new ConfirmationQuestion('Do you like French fries?', false);
+ $this->assertFalse($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+
+ $dialog->setInputStream($this->getInputStream("y\nyes\n"));
+ $question = new ConfirmationQuestion('Do you like French fries?', false);
+ $this->assertTrue($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $question = new ConfirmationQuestion('Do you like French fries?', false);
+ $this->assertTrue($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+
+ $dialog->setInputStream($this->getInputStream("n\nno\n"));
+ $question = new ConfirmationQuestion('Do you like French fries?', true);
+ $this->assertFalse($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $question = new ConfirmationQuestion('Do you like French fries?', true);
+ $this->assertFalse($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ }
+
+ public function testAskAndValidate()
+ {
+ $dialog = new QuestionHelper();
+ $helperSet = new HelperSet(array(new FormatterHelper()));
+ $dialog->setHelperSet($helperSet);
+
+ $error = 'This is not a color!';
+ $validator = function ($color) use ($error) {
+ if (!in_array($color, array('white', 'black'))) {
+ throw new \InvalidArgumentException($error);
+ }
+
+ return $color;
+ };
+
+ $question = new Question('What color was the white horse of Henry IV?', 'white');
+ $question->setValidator($validator);
+ $question->setMaxAttempts(2);
+
+ $dialog->setInputStream($this->getInputStream("\nblack\n"));
+ $this->assertEquals('white', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $this->assertEquals('black', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+
+ $dialog->setInputStream($this->getInputStream("green\nyellow\norange\n"));
+ try {
+ $this->assertEquals('white', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertEquals($error, $e->getMessage());
+ }
+ }
+
+ public function testNoInteraction()
+ {
+ $dialog = new QuestionHelper();
+ $question = new Question('Do you have a job?', 'not yet');
+ $this->assertEquals('not yet', $dialog->ask($this->createInputInterfaceMock(false), $this->createOutputInterface(), $question));
+ }
+
+ protected function getInputStream($input)
+ {
+ $stream = fopen('php://memory', 'r+', false);
+ fwrite($stream, $input);
+ rewind($stream);
+
+ return $stream;
+ }
+
+ protected function createOutputInterface()
+ {
+ return new StreamOutput(fopen('php://memory', 'r+', false));
+ }
+
+ protected function createInputInterfaceMock($interactive = true)
+ {
+ $mock = $this->getMock('Symfony\Component\Console\Input\InputInterface');
+ $mock->expects($this->any())
+ ->method('isInteractive')
+ ->will($this->returnValue($interactive));
+
+ return $mock;
+ }
+
+ private function hasSttyAvailable()
+ {
+ exec('stty 2>&1', $output, $exitcode);
+
+ return $exitcode === 0;
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/TableTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/TableTest.php
new file mode 100644
index 0000000..18a2ab6
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/TableTest.php
@@ -0,0 +1,357 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Helper\Table;
+use Symfony\Component\Console\Helper\TableStyle;
+use Symfony\Component\Console\Helper\TableSeparator;
+use Symfony\Component\Console\Output\StreamOutput;
+
+class TableTest extends \PHPUnit_Framework_TestCase
+{
+ protected $stream;
+
+ protected function setUp()
+ {
+ $this->stream = fopen('php://memory', 'r+');
+ }
+
+ protected function tearDown()
+ {
+ fclose($this->stream);
+ $this->stream = null;
+ }
+
+ /**
+ * @dataProvider testRenderProvider
+ */
+ public function testRender($headers, $rows, $style, $expected)
+ {
+ $table = new Table($output = $this->getOutputStream());
+ $table
+ ->setHeaders($headers)
+ ->setRows($rows)
+ ->setStyle($style)
+ ;
+ $table->render();
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ /**
+ * @dataProvider testRenderProvider
+ */
+ public function testRenderAddRows($headers, $rows, $style, $expected)
+ {
+ $table = new Table($output = $this->getOutputStream());
+ $table
+ ->setHeaders($headers)
+ ->addRows($rows)
+ ->setStyle($style)
+ ;
+ $table->render();
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ /**
+ * @dataProvider testRenderProvider
+ */
+ public function testRenderAddRowsOneByOne($headers, $rows, $style, $expected)
+ {
+ $table = new Table($output = $this->getOutputStream());
+ $table
+ ->setHeaders($headers)
+ ->setStyle($style)
+ ;
+ foreach ($rows as $row) {
+ $table->addRow($row);
+ }
+ $table->render();
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ public function testRenderProvider()
+ {
+ $books = array(
+ array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
+ array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
+ array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
+ array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
+ );
+
+ return array(
+ array(
+ array('ISBN', 'Title', 'Author'),
+ $books,
+ 'default',
+<<<TABLE
++---------------+--------------------------+------------------+
+| ISBN | Title | Author |
++---------------+--------------------------+------------------+
+| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+| 80-902734-1-6 | And Then There Were None | Agatha Christie |
++---------------+--------------------------+------------------+
+
+TABLE
+ ),
+ array(
+ array('ISBN', 'Title', 'Author'),
+ $books,
+ 'compact',
+<<<TABLE
+ ISBN Title Author
+ 99921-58-10-7 Divine Comedy Dante Alighieri
+ 9971-5-0210-0 A Tale of Two Cities Charles Dickens
+ 960-425-059-0 The Lord of the Rings J. R. R. Tolkien
+ 80-902734-1-6 And Then There Were None Agatha Christie
+
+TABLE
+ ),
+ array(
+ array('ISBN', 'Title', 'Author'),
+ $books,
+ 'borderless',
+<<<TABLE
+ =============== ========================== ==================
+ ISBN Title Author
+ =============== ========================== ==================
+ 99921-58-10-7 Divine Comedy Dante Alighieri
+ 9971-5-0210-0 A Tale of Two Cities Charles Dickens
+ 960-425-059-0 The Lord of the Rings J. R. R. Tolkien
+ 80-902734-1-6 And Then There Were None Agatha Christie
+ =============== ========================== ==================
+
+TABLE
+ ),
+ array(
+ array('ISBN', 'Title'),
+ array(
+ array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
+ array('9971-5-0210-0'),
+ array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
+ array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
+ ),
+ 'default',
+<<<TABLE
++---------------+--------------------------+------------------+
+| ISBN | Title | |
++---------------+--------------------------+------------------+
+| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+| 9971-5-0210-0 | | |
+| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+| 80-902734-1-6 | And Then There Were None | Agatha Christie |
++---------------+--------------------------+------------------+
+
+TABLE
+ ),
+ array(
+ array(),
+ array(
+ array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
+ array('9971-5-0210-0'),
+ array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
+ array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
+ ),
+ 'default',
+<<<TABLE
++---------------+--------------------------+------------------+
+| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+| 9971-5-0210-0 | | |
+| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+| 80-902734-1-6 | And Then There Were None | Agatha Christie |
++---------------+--------------------------+------------------+
+
+TABLE
+ ),
+ array(
+ array('ISBN', 'Title', 'Author'),
+ array(
+ array("99921-58-10-7", "Divine\nComedy", "Dante Alighieri"),
+ array("9971-5-0210-2", "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
+ array("9971-5-0210-2", "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
+ array("960-425-059-0", "The Lord of the Rings", "J. R. R.\nTolkien"),
+ ),
+ 'default',
+<<<TABLE
++---------------+----------------------------+-----------------+
+| ISBN | Title | Author |
++---------------+----------------------------+-----------------+
+| 99921-58-10-7 | Divine | Dante Alighieri |
+| | Comedy | |
+| 9971-5-0210-2 | Harry Potter | Rowling |
+| | and the Chamber of Secrets | Joanne K. |
+| 9971-5-0210-2 | Harry Potter | Rowling |
+| | and the Chamber of Secrets | Joanne K. |
+| 960-425-059-0 | The Lord of the Rings | J. R. R. |
+| | | Tolkien |
++---------------+----------------------------+-----------------+
+
+TABLE
+ ),
+ array(
+ array('ISBN', 'Title'),
+ array(),
+ 'default',
+<<<TABLE
++------+-------+
+| ISBN | Title |
++------+-------+
+
+TABLE
+ ),
+ array(
+ array(),
+ array(),
+ 'default',
+ '',
+ ),
+ 'Cell text with tags used for Output styling' => array(
+ array('ISBN', 'Title', 'Author'),
+ array(
+ array('<info>99921-58-10-7</info>', '<error>Divine Comedy</error>', '<fg=blue;bg=white>Dante Alighieri</fg=blue;bg=white>'),
+ array('9971-5-0210-0', 'A Tale of Two Cities', '<info>Charles Dickens</>'),
+ ),
+ 'default',
+<<<TABLE
++---------------+----------------------+-----------------+
+| ISBN | Title | Author |
++---------------+----------------------+-----------------+
+| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
++---------------+----------------------+-----------------+
+
+TABLE
+ ),
+ 'Cell text with tags not used for Output styling' => array(
+ array('ISBN', 'Title', 'Author'),
+ array(
+ array('<strong>99921-58-10-700</strong>', '<f>Divine Com</f>', 'Dante Alighieri'),
+ array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
+ ),
+ 'default',
+<<<TABLE
++----------------------------------+----------------------+-----------------+
+| ISBN | Title | Author |
++----------------------------------+----------------------+-----------------+
+| <strong>99921-58-10-700</strong> | <f>Divine Com</f> | Dante Alighieri |
+| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
++----------------------------------+----------------------+-----------------+
+
+TABLE
+ ),
+ );
+ }
+
+ public function testRenderMultiByte()
+ {
+ if (!function_exists('mb_strlen')) {
+ $this->markTestSkipped('The "mbstring" extension is not available');
+ }
+
+ $table = new Table($output = $this->getOutputStream());
+ $table
+ ->setHeaders(array('■■'))
+ ->setRows(array(array(1234)))
+ ->setStyle('default')
+ ;
+ $table->render();
+
+ $expected =
+<<<TABLE
++------+
+| ■■ |
++------+
+| 1234 |
++------+
+
+TABLE;
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ public function testStyle()
+ {
+ $style = new TableStyle();
+ $style
+ ->setHorizontalBorderChar('.')
+ ->setVerticalBorderChar('.')
+ ->setCrossingChar('.')
+ ;
+
+ Table::setStyleDefinition('dotfull', $style);
+ $table = new Table($output = $this->getOutputStream());
+ $table
+ ->setHeaders(array('Foo'))
+ ->setRows(array(array('Bar')))
+ ->setStyle('dotfull');
+ $table->render();
+
+ $expected =
+<<<TABLE
+.......
+. Foo .
+.......
+. Bar .
+.......
+
+TABLE;
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ public function testRowSeparator()
+ {
+ $table = new Table($output = $this->getOutputStream());
+ $table
+ ->setHeaders(array('Foo'))
+ ->setRows(array(
+ array('Bar1'),
+ new TableSeparator(),
+ array('Bar2'),
+ new TableSeparator(),
+ array('Bar3'),
+ ));
+ $table->render();
+
+ $expected =
+<<<TABLE
++------+
+| Foo |
++------+
+| Bar1 |
++------+
+| Bar2 |
++------+
+| Bar3 |
++------+
+
+TABLE;
+
+ $this->assertEquals($expected, $this->getOutputContent($output));
+ }
+
+ protected function getOutputStream()
+ {
+ return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false);
+ }
+
+ protected function getOutputContent(StreamOutput $output)
+ {
+ rewind($output->getStream());
+
+ return str_replace(PHP_EOL, "\n", stream_get_contents($output->getStream()));
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArgvInputTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArgvInputTest.php
new file mode 100644
index 0000000..d2c540e
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArgvInputTest.php
@@ -0,0 +1,317 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\ArgvInput;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+
+class ArgvInputTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $_SERVER['argv'] = array('cli.php', 'foo');
+ $input = new ArgvInput();
+ $r = new \ReflectionObject($input);
+ $p = $r->getProperty('tokens');
+ $p->setAccessible(true);
+
+ $this->assertEquals(array('foo'), $p->getValue($input), '__construct() automatically get its input from the argv server variable');
+ }
+
+ public function testParseArguments()
+ {
+ $input = new ArgvInput(array('cli.php', 'foo'));
+ $input->bind(new InputDefinition(array(new InputArgument('name'))));
+ $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() parses required arguments');
+
+ $input->bind(new InputDefinition(array(new InputArgument('name'))));
+ $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() is stateless');
+ }
+
+ /**
+ * @dataProvider provideOptions
+ */
+ public function testParseOptions($input, $options, $expectedOptions, $message)
+ {
+ $input = new ArgvInput($input);
+ $input->bind(new InputDefinition($options));
+
+ $this->assertEquals($expectedOptions, $input->getOptions(), $message);
+ }
+
+ public function provideOptions()
+ {
+ return array(
+ array(
+ array('cli.php', '--foo'),
+ array(new InputOption('foo')),
+ array('foo' => true),
+ '->parse() parses long options without a value',
+ ),
+ array(
+ array('cli.php', '--foo=bar'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
+ array('foo' => 'bar'),
+ '->parse() parses long options with a required value (with a = separator)',
+ ),
+ array(
+ array('cli.php', '--foo', 'bar'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
+ array('foo' => 'bar'),
+ '->parse() parses long options with a required value (with a space separator)',
+ ),
+ array(
+ array('cli.php', '-f'),
+ array(new InputOption('foo', 'f')),
+ array('foo' => true),
+ '->parse() parses short options without a value',
+ ),
+ array(
+ array('cli.php', '-fbar'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
+ array('foo' => 'bar'),
+ '->parse() parses short options with a required value (with no separator)',
+ ),
+ array(
+ array('cli.php', '-f', 'bar'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
+ array('foo' => 'bar'),
+ '->parse() parses short options with a required value (with a space separator)',
+ ),
+ array(
+ array('cli.php', '-f', ''),
+ array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
+ array('foo' => ''),
+ '->parse() parses short options with an optional empty value',
+ ),
+ array(
+ array('cli.php', '-f', '', 'foo'),
+ array(new InputArgument('name'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
+ array('foo' => ''),
+ '->parse() parses short options with an optional empty value followed by an argument',
+ ),
+ array(
+ array('cli.php', '-f', '', '-b'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b')),
+ array('foo' => '', 'bar' => true),
+ '->parse() parses short options with an optional empty value followed by an option',
+ ),
+ array(
+ array('cli.php', '-f', '-b', 'foo'),
+ array(new InputArgument('name'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b')),
+ array('foo' => null, 'bar' => true),
+ '->parse() parses short options with an optional value which is not present',
+ ),
+ array(
+ array('cli.php', '-fb'),
+ array(new InputOption('foo', 'f'), new InputOption('bar', 'b')),
+ array('foo' => true, 'bar' => true),
+ '->parse() parses short options when they are aggregated as a single one',
+ ),
+ array(
+ array('cli.php', '-fb', 'bar'),
+ array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_REQUIRED)),
+ array('foo' => true, 'bar' => 'bar'),
+ '->parse() parses short options when they are aggregated as a single one and the last one has a required value',
+ ),
+ array(
+ array('cli.php', '-fb', 'bar'),
+ array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
+ array('foo' => true, 'bar' => 'bar'),
+ '->parse() parses short options when they are aggregated as a single one and the last one has an optional value',
+ ),
+ array(
+ array('cli.php', '-fbbar'),
+ array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
+ array('foo' => true, 'bar' => 'bar'),
+ '->parse() parses short options when they are aggregated as a single one and the last one has an optional value with no separator',
+ ),
+ array(
+ array('cli.php', '-fbbar'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
+ array('foo' => 'bbar', 'bar' => null),
+ '->parse() parses short options when they are aggregated as a single one and one of them takes a value',
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider provideInvalidInput
+ */
+ public function testInvalidInput($argv, $definition, $expectedExceptionMessage)
+ {
+ $this->setExpectedException('RuntimeException', $expectedExceptionMessage);
+
+ $input = new ArgvInput($argv);
+ $input->bind($definition);
+ }
+
+ public function provideInvalidInput()
+ {
+ return array(
+ array(
+ array('cli.php', '--foo'),
+ new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
+ 'The "--foo" option requires a value.',
+ ),
+ array(
+ array('cli.php', '-f'),
+ new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
+ 'The "--foo" option requires a value.',
+ ),
+ array(
+ array('cli.php', '-ffoo'),
+ new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_NONE))),
+ 'The "-o" option does not exist.',
+ ),
+ array(
+ array('cli.php', '--foo=bar'),
+ new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_NONE))),
+ 'The "--foo" option does not accept a value.',
+ ),
+ array(
+ array('cli.php', 'foo', 'bar'),
+ new InputDefinition(),
+ 'Too many arguments.',
+ ),
+ array(
+ array('cli.php', '--foo'),
+ new InputDefinition(),
+ 'The "--foo" option does not exist.',
+ ),
+ array(
+ array('cli.php', '-f'),
+ new InputDefinition(),
+ 'The "-f" option does not exist.',
+ ),
+ array(
+ array('cli.php', '-1'),
+ new InputDefinition(array(new InputArgument('number'))),
+ 'The "-1" option does not exist.',
+ ),
+ );
+ }
+
+ public function testParseArrayArgument()
+ {
+ $input = new ArgvInput(array('cli.php', 'foo', 'bar', 'baz', 'bat'));
+ $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::IS_ARRAY))));
+
+ $this->assertEquals(array('name' => array('foo', 'bar', 'baz', 'bat')), $input->getArguments(), '->parse() parses array arguments');
+ }
+
+ public function testParseArrayOption()
+ {
+ $input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name=baz'));
+ $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
+
+ $this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option=value" syntax)');
+
+ $input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', 'baz'));
+ $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
+ $this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option value" syntax)');
+
+ $input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name='));
+ $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
+ $this->assertSame(array('name' => array('foo', 'bar', null)), $input->getOptions(), '->parse() parses empty array options as null ("--option=value" syntax)');
+
+ $input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', '--anotherOption'));
+ $input->bind(new InputDefinition(array(
+ new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY),
+ new InputOption('anotherOption', null, InputOption::VALUE_NONE),
+ )));
+ $this->assertSame(array('name' => array('foo', 'bar', null), 'anotherOption' => true), $input->getOptions(), '->parse() parses empty array options as null ("--option value" syntax)');
+ }
+
+ public function testParseNegativeNumberAfterDoubleDash()
+ {
+ $input = new ArgvInput(array('cli.php', '--', '-1'));
+ $input->bind(new InputDefinition(array(new InputArgument('number'))));
+ $this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence');
+
+ $input = new ArgvInput(array('cli.php', '-f', 'bar', '--', '-1'));
+ $input->bind(new InputDefinition(array(new InputArgument('number'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))));
+ $this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses arguments with leading dashes as options before having encountered a double-dash sequence');
+ $this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence');
+ }
+
+ public function testParseEmptyStringArgument()
+ {
+ $input = new ArgvInput(array('cli.php', '-f', 'bar', ''));
+ $input->bind(new InputDefinition(array(new InputArgument('empty'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))));
+
+ $this->assertEquals(array('empty' => ''), $input->getArguments(), '->parse() parses empty string arguments');
+ }
+
+ public function testGetFirstArgument()
+ {
+ $input = new ArgvInput(array('cli.php', '-fbbar'));
+ $this->assertNull($input->getFirstArgument(), '->getFirstArgument() returns null when there is no arguments');
+
+ $input = new ArgvInput(array('cli.php', '-fbbar', 'foo'));
+ $this->assertEquals('foo', $input->getFirstArgument(), '->getFirstArgument() returns the first argument from the raw input');
+ }
+
+ public function testHasParameterOption()
+ {
+ $input = new ArgvInput(array('cli.php', '-f', 'foo'));
+ $this->assertTrue($input->hasParameterOption('-f'), '->hasParameterOption() returns true if the given short option is in the raw input');
+
+ $input = new ArgvInput(array('cli.php', '--foo', 'foo'));
+ $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given short option is in the raw input');
+
+ $input = new ArgvInput(array('cli.php', 'foo'));
+ $this->assertFalse($input->hasParameterOption('--foo'), '->hasParameterOption() returns false if the given short option is not in the raw input');
+
+ $input = new ArgvInput(array('cli.php', '--foo=bar'));
+ $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given option with provided value is in the raw input');
+ }
+
+ public function testToString()
+ {
+ $input = new ArgvInput(array('cli.php', '-f', 'foo'));
+ $this->assertEquals('-f foo', (string) $input);
+
+ $input = new ArgvInput(array('cli.php', '-f', '--bar=foo', 'a b c d', "A\nB'C"));
+ $this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d').' '.escapeshellarg("A\nB'C"), (string) $input);
+ }
+
+ /**
+ * @dataProvider provideGetParameterOptionValues
+ */
+ public function testGetParameterOptionEqualSign($argv, $key, $expected)
+ {
+ $input = new ArgvInput($argv);
+ $this->assertEquals($expected, $input->getParameterOption($key), '->getParameterOption() returns the expected value');
+ }
+
+ public function provideGetParameterOptionValues()
+ {
+ return array(
+ array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', 'dev'),
+ array(array('app/console', 'foo:bar', '--env=dev'), '--env', 'dev'),
+ array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'dev'),
+ array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), 'dev'),
+ array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), '1'),
+ array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), '1'),
+ );
+ }
+
+ public function testParseSingleDashAsArgument()
+ {
+ $input = new ArgvInput(array('cli.php', '-'));
+ $input->bind(new InputDefinition(array(new InputArgument('file'))));
+ $this->assertEquals(array('file' => '-'), $input->getArguments(), '->parse() parses single dash as an argument');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArrayInputTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
new file mode 100644
index 0000000..cc89083
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
@@ -0,0 +1,138 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+
+class ArrayInputTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetFirstArgument()
+ {
+ $input = new ArrayInput(array());
+ $this->assertNull($input->getFirstArgument(), '->getFirstArgument() returns null if no argument were passed');
+ $input = new ArrayInput(array('name' => 'Fabien'));
+ $this->assertEquals('Fabien', $input->getFirstArgument(), '->getFirstArgument() returns the first passed argument');
+ $input = new ArrayInput(array('--foo' => 'bar', 'name' => 'Fabien'));
+ $this->assertEquals('Fabien', $input->getFirstArgument(), '->getFirstArgument() returns the first passed argument');
+ }
+
+ public function testHasParameterOption()
+ {
+ $input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar'));
+ $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if an option is present in the passed parameters');
+ $this->assertFalse($input->hasParameterOption('--bar'), '->hasParameterOption() returns false if an option is not present in the passed parameters');
+
+ $input = new ArrayInput(array('--foo'));
+ $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if an option is present in the passed parameters');
+ }
+
+ public function testGetParameterOption()
+ {
+ $input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar'));
+ $this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name');
+
+ $input = new ArrayInput(array('Fabien', '--foo' => 'bar'));
+ $this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name');
+ }
+
+ public function testParseArguments()
+ {
+ $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'))));
+
+ $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() parses required arguments');
+ }
+
+ /**
+ * @dataProvider provideOptions
+ */
+ public function testParseOptions($input, $options, $expectedOptions, $message)
+ {
+ $input = new ArrayInput($input, new InputDefinition($options));
+
+ $this->assertEquals($expectedOptions, $input->getOptions(), $message);
+ }
+
+ public function provideOptions()
+ {
+ return array(
+ array(
+ array('--foo' => 'bar'),
+ array(new InputOption('foo')),
+ array('foo' => 'bar'),
+ '->parse() parses long options',
+ ),
+ array(
+ array('--foo' => 'bar'),
+ array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')),
+ array('foo' => 'bar'),
+ '->parse() parses long options with a default value',
+ ),
+ array(
+ array('--foo' => null),
+ array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')),
+ array('foo' => 'default'),
+ '->parse() parses long options with a default value',
+ ),
+ array(
+ array('-f' => 'bar'),
+ array(new InputOption('foo', 'f')),
+ array('foo' => 'bar'),
+ '->parse() parses short options',
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider provideInvalidInput
+ */
+ public function testParseInvalidInput($parameters, $definition, $expectedExceptionMessage)
+ {
+ $this->setExpectedException('InvalidArgumentException', $expectedExceptionMessage);
+
+ new ArrayInput($parameters, $definition);
+ }
+
+ public function provideInvalidInput()
+ {
+ return array(
+ array(
+ array('foo' => 'foo'),
+ new InputDefinition(array(new InputArgument('name'))),
+ 'The "foo" argument does not exist.',
+ ),
+ array(
+ array('--foo' => null),
+ new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
+ 'The "--foo" option requires a value.',
+ ),
+ array(
+ array('--foo' => 'foo'),
+ new InputDefinition(),
+ 'The "--foo" option does not exist.',
+ ),
+ array(
+ array('-o' => 'foo'),
+ new InputDefinition(),
+ 'The "-o" option does not exist.',
+ ),
+ );
+ }
+
+ public function testToString()
+ {
+ $input = new ArrayInput(array('-f' => null, '-b' => 'bar', '--foo' => 'b a z', '--lala' => null, 'test' => 'Foo', 'test2' => "A\nB'C"));
+ $this->assertEquals('-f -b=bar --foo='.escapeshellarg('b a z').' --lala Foo '.escapeshellarg("A\nB'C"), (string) $input);
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputArgumentTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputArgumentTest.php
new file mode 100644
index 0000000..cfb37cd
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputArgumentTest.php
@@ -0,0 +1,111 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\InputArgument;
+
+class InputArgumentTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $argument = new InputArgument('foo');
+ $this->assertEquals('foo', $argument->getName(), '__construct() takes a name as its first argument');
+ }
+
+ public function testModes()
+ {
+ $argument = new InputArgument('foo');
+ $this->assertFalse($argument->isRequired(), '__construct() gives a "InputArgument::OPTIONAL" mode by default');
+
+ $argument = new InputArgument('foo', null);
+ $this->assertFalse($argument->isRequired(), '__construct() can take "InputArgument::OPTIONAL" as its mode');
+
+ $argument = new InputArgument('foo', InputArgument::OPTIONAL);
+ $this->assertFalse($argument->isRequired(), '__construct() can take "InputArgument::OPTIONAL" as its mode');
+
+ $argument = new InputArgument('foo', InputArgument::REQUIRED);
+ $this->assertTrue($argument->isRequired(), '__construct() can take "InputArgument::REQUIRED" as its mode');
+ }
+
+ /**
+ * @dataProvider provideInvalidModes
+ */
+ public function testInvalidModes($mode)
+ {
+ $this->setExpectedException('InvalidArgumentException', sprintf('Argument mode "%s" is not valid.', $mode));
+
+ new InputArgument('foo', $mode);
+ }
+
+ public function provideInvalidModes()
+ {
+ return array(
+ array('ANOTHER_ONE'),
+ array(-1),
+ );
+ }
+
+ public function testIsArray()
+ {
+ $argument = new InputArgument('foo', InputArgument::IS_ARRAY);
+ $this->assertTrue($argument->isArray(), '->isArray() returns true if the argument can be an array');
+ $argument = new InputArgument('foo', InputArgument::OPTIONAL | InputArgument::IS_ARRAY);
+ $this->assertTrue($argument->isArray(), '->isArray() returns true if the argument can be an array');
+ $argument = new InputArgument('foo', InputArgument::OPTIONAL);
+ $this->assertFalse($argument->isArray(), '->isArray() returns false if the argument can not be an array');
+ }
+
+ public function testGetDescription()
+ {
+ $argument = new InputArgument('foo', null, 'Some description');
+ $this->assertEquals('Some description', $argument->getDescription(), '->getDescription() return the message description');
+ }
+
+ public function testGetDefault()
+ {
+ $argument = new InputArgument('foo', InputArgument::OPTIONAL, '', 'default');
+ $this->assertEquals('default', $argument->getDefault(), '->getDefault() return the default value');
+ }
+
+ public function testSetDefault()
+ {
+ $argument = new InputArgument('foo', InputArgument::OPTIONAL, '', 'default');
+ $argument->setDefault(null);
+ $this->assertNull($argument->getDefault(), '->setDefault() can reset the default value by passing null');
+ $argument->setDefault('another');
+ $this->assertEquals('another', $argument->getDefault(), '->setDefault() changes the default value');
+
+ $argument = new InputArgument('foo', InputArgument::OPTIONAL | InputArgument::IS_ARRAY);
+ $argument->setDefault(array(1, 2));
+ $this->assertEquals(array(1, 2), $argument->getDefault(), '->setDefault() changes the default value');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage Cannot set a default value except for InputArgument::OPTIONAL mode.
+ */
+ public function testSetDefaultWithRequiredArgument()
+ {
+ $argument = new InputArgument('foo', InputArgument::REQUIRED);
+ $argument->setDefault('default');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage A default value for an array argument must be an array.
+ */
+ public function testSetDefaultWithArrayArgument()
+ {
+ $argument = new InputArgument('foo', InputArgument::IS_ARRAY);
+ $argument->setDefault('default');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php
new file mode 100644
index 0000000..ce0654d
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php
@@ -0,0 +1,430 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+
+class InputDefinitionTest extends \PHPUnit_Framework_TestCase
+{
+ protected static $fixtures;
+
+ protected $foo, $bar, $foo1, $foo2;
+
+ public static function setUpBeforeClass()
+ {
+ self::$fixtures = __DIR__.'/../Fixtures/';
+ }
+
+ public function testConstructorArguments()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $this->assertEquals(array(), $definition->getArguments(), '__construct() creates a new InputDefinition object');
+
+ $definition = new InputDefinition(array($this->foo, $this->bar));
+ $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '__construct() takes an array of InputArgument objects as its first argument');
+ }
+
+ public function testConstructorOptions()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition();
+ $this->assertEquals(array(), $definition->getOptions(), '__construct() creates a new InputDefinition object');
+
+ $definition = new InputDefinition(array($this->foo, $this->bar));
+ $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '__construct() takes an array of InputOption objects as its first argument');
+ }
+
+ public function testSetArguments()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->setArguments(array($this->foo));
+ $this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->setArguments() sets the array of InputArgument objects');
+ $definition->setArguments(array($this->bar));
+
+ $this->assertEquals(array('bar' => $this->bar), $definition->getArguments(), '->setArguments() clears all InputArgument objects');
+ }
+
+ public function testAddArguments()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArguments(array($this->foo));
+ $this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->addArguments() adds an array of InputArgument objects');
+ $definition->addArguments(array($this->bar));
+ $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '->addArguments() does not clear existing InputArgument objects');
+ }
+
+ public function testAddArgument()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArgument($this->foo);
+ $this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->addArgument() adds a InputArgument object');
+ $definition->addArgument($this->bar);
+ $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '->addArgument() adds a InputArgument object');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage An argument with name "foo" already exists.
+ */
+ public function testArgumentsMustHaveDifferentNames()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArgument($this->foo);
+ $definition->addArgument($this->foo1);
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage Cannot add an argument after an array argument.
+ */
+ public function testArrayArgumentHasToBeLast()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArgument(new InputArgument('fooarray', InputArgument::IS_ARRAY));
+ $definition->addArgument(new InputArgument('anotherbar'));
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage Cannot add a required argument after an optional one.
+ */
+ public function testRequiredArgumentCannotFollowAnOptionalOne()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArgument($this->foo);
+ $definition->addArgument($this->foo2);
+ }
+
+ public function testGetArgument()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArguments(array($this->foo));
+ $this->assertEquals($this->foo, $definition->getArgument('foo'), '->getArgument() returns a InputArgument by its name');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "bar" argument does not exist.
+ */
+ public function testGetInvalidArgument()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArguments(array($this->foo));
+ $definition->getArgument('bar');
+ }
+
+ public function testHasArgument()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArguments(array($this->foo));
+
+ $this->assertTrue($definition->hasArgument('foo'), '->hasArgument() returns true if a InputArgument exists for the given name');
+ $this->assertFalse($definition->hasArgument('bar'), '->hasArgument() returns false if a InputArgument exists for the given name');
+ }
+
+ public function testGetArgumentRequiredCount()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArgument($this->foo2);
+ $this->assertEquals(1, $definition->getArgumentRequiredCount(), '->getArgumentRequiredCount() returns the number of required arguments');
+ $definition->addArgument($this->foo);
+ $this->assertEquals(1, $definition->getArgumentRequiredCount(), '->getArgumentRequiredCount() returns the number of required arguments');
+ }
+
+ public function testGetArgumentCount()
+ {
+ $this->initializeArguments();
+
+ $definition = new InputDefinition();
+ $definition->addArgument($this->foo2);
+ $this->assertEquals(1, $definition->getArgumentCount(), '->getArgumentCount() returns the number of arguments');
+ $definition->addArgument($this->foo);
+ $this->assertEquals(2, $definition->getArgumentCount(), '->getArgumentCount() returns the number of arguments');
+ }
+
+ public function testGetArgumentDefaults()
+ {
+ $definition = new InputDefinition(array(
+ new InputArgument('foo1', InputArgument::OPTIONAL),
+ new InputArgument('foo2', InputArgument::OPTIONAL, '', 'default'),
+ new InputArgument('foo3', InputArgument::OPTIONAL | InputArgument::IS_ARRAY),
+ // new InputArgument('foo4', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, '', array(1, 2)),
+ ));
+ $this->assertEquals(array('foo1' => null, 'foo2' => 'default', 'foo3' => array()), $definition->getArgumentDefaults(), '->getArgumentDefaults() return the default values for each argument');
+
+ $definition = new InputDefinition(array(
+ new InputArgument('foo4', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, '', array(1, 2)),
+ ));
+ $this->assertEquals(array('foo4' => array(1, 2)), $definition->getArgumentDefaults(), '->getArgumentDefaults() return the default values for each argument');
+ }
+
+ public function testSetOptions()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->setOptions() sets the array of InputOption objects');
+ $definition->setOptions(array($this->bar));
+ $this->assertEquals(array('bar' => $this->bar), $definition->getOptions(), '->setOptions() clears all InputOption objects');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "-f" option does not exist.
+ */
+ public function testSetOptionsClearsOptions()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $definition->setOptions(array($this->bar));
+ $definition->getOptionForShortcut('f');
+ }
+
+ public function testAddOptions()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->addOptions() adds an array of InputOption objects');
+ $definition->addOptions(array($this->bar));
+ $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '->addOptions() does not clear existing InputOption objects');
+ }
+
+ public function testAddOption()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition();
+ $definition->addOption($this->foo);
+ $this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->addOption() adds a InputOption object');
+ $definition->addOption($this->bar);
+ $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '->addOption() adds a InputOption object');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage An option named "foo" already exists.
+ */
+ public function testAddDuplicateOption()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition();
+ $definition->addOption($this->foo);
+ $definition->addOption($this->foo2);
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage An option with shortcut "f" already exists.
+ */
+ public function testAddDuplicateShortcutOption()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition();
+ $definition->addOption($this->foo);
+ $definition->addOption($this->foo1);
+ }
+
+ public function testGetOption()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $this->assertEquals($this->foo, $definition->getOption('foo'), '->getOption() returns a InputOption by its name');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "--bar" option does not exist.
+ */
+ public function testGetInvalidOption()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $definition->getOption('bar');
+ }
+
+ public function testHasOption()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $this->assertTrue($definition->hasOption('foo'), '->hasOption() returns true if a InputOption exists for the given name');
+ $this->assertFalse($definition->hasOption('bar'), '->hasOption() returns false if a InputOption exists for the given name');
+ }
+
+ public function testHasShortcut()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $this->assertTrue($definition->hasShortcut('f'), '->hasShortcut() returns true if a InputOption exists for the given shortcut');
+ $this->assertFalse($definition->hasShortcut('b'), '->hasShortcut() returns false if a InputOption exists for the given shortcut');
+ }
+
+ public function testGetOptionForShortcut()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $this->assertEquals($this->foo, $definition->getOptionForShortcut('f'), '->getOptionForShortcut() returns a InputOption by its shortcut');
+ }
+
+ public function testGetOptionForMultiShortcut()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->multi));
+ $this->assertEquals($this->multi, $definition->getOptionForShortcut('m'), '->getOptionForShortcut() returns a InputOption by its shortcut');
+ $this->assertEquals($this->multi, $definition->getOptionForShortcut('mmm'), '->getOptionForShortcut() returns a InputOption by its shortcut');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "-l" option does not exist.
+ */
+ public function testGetOptionForInvalidShortcut()
+ {
+ $this->initializeOptions();
+
+ $definition = new InputDefinition(array($this->foo));
+ $definition->getOptionForShortcut('l');
+ }
+
+ public function testGetOptionDefaults()
+ {
+ $definition = new InputDefinition(array(
+ new InputOption('foo1', null, InputOption::VALUE_NONE),
+ new InputOption('foo2', null, InputOption::VALUE_REQUIRED),
+ new InputOption('foo3', null, InputOption::VALUE_REQUIRED, '', 'default'),
+ new InputOption('foo4', null, InputOption::VALUE_OPTIONAL),
+ new InputOption('foo5', null, InputOption::VALUE_OPTIONAL, '', 'default'),
+ new InputOption('foo6', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY),
+ new InputOption('foo7', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, '', array(1, 2)),
+ ));
+ $defaults = array(
+ 'foo1' => false,
+ 'foo2' => null,
+ 'foo3' => 'default',
+ 'foo4' => null,
+ 'foo5' => 'default',
+ 'foo6' => array(),
+ 'foo7' => array(1, 2),
+ );
+ $this->assertSame($defaults, $definition->getOptionDefaults(), '->getOptionDefaults() returns the default values for all options');
+ }
+
+ public function testGetSynopsis()
+ {
+ $definition = new InputDefinition(array(new InputOption('foo')));
+ $this->assertEquals('[--foo]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ $definition = new InputDefinition(array(new InputOption('foo', 'f')));
+ $this->assertEquals('[-f|--foo]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ $definition = new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)));
+ $this->assertEquals('[-f|--foo="..."]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ $definition = new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)));
+ $this->assertEquals('[-f|--foo[="..."]]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+
+ $definition = new InputDefinition(array(new InputArgument('foo')));
+ $this->assertEquals('[foo]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ $definition = new InputDefinition(array(new InputArgument('foo', InputArgument::REQUIRED)));
+ $this->assertEquals('foo', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ $definition = new InputDefinition(array(new InputArgument('foo', InputArgument::IS_ARRAY)));
+ $this->assertEquals('[foo1] ... [fooN]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ $definition = new InputDefinition(array(new InputArgument('foo', InputArgument::REQUIRED | InputArgument::IS_ARRAY)));
+ $this->assertEquals('foo1 ... [fooN]', $definition->getSynopsis(), '->getSynopsis() returns a synopsis of arguments and options');
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testLegacyAsText()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ $definition = new InputDefinition(array(
+ new InputArgument('foo', InputArgument::OPTIONAL, 'The foo argument'),
+ new InputArgument('baz', InputArgument::OPTIONAL, 'The baz argument', true),
+ new InputArgument('bar', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'The bar argument', array('http://foo.com/')),
+ new InputOption('foo', 'f', InputOption::VALUE_REQUIRED, 'The foo option'),
+ new InputOption('baz', null, InputOption::VALUE_OPTIONAL, 'The baz option', false),
+ new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL, 'The bar option', 'bar'),
+ new InputOption('qux', '', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The qux option', array('http://foo.com/', 'bar')),
+ new InputOption('qux2', '', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The qux2 option', array('foo' => 'bar')),
+ ));
+ $this->assertStringEqualsFile(self::$fixtures.'/definition_astext.txt', $definition->asText(), '->asText() returns a textual representation of the InputDefinition');
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testLegacyAsXml()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ $definition = new InputDefinition(array(
+ new InputArgument('foo', InputArgument::OPTIONAL, 'The foo argument'),
+ new InputArgument('baz', InputArgument::OPTIONAL, 'The baz argument', true),
+ new InputArgument('bar', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'The bar argument', array('bar')),
+ new InputOption('foo', 'f', InputOption::VALUE_REQUIRED, 'The foo option'),
+ new InputOption('baz', null, InputOption::VALUE_OPTIONAL, 'The baz option', false),
+ new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL, 'The bar option', 'bar'),
+ ));
+ $this->assertXmlStringEqualsXmlFile(self::$fixtures.'/definition_asxml.txt', $definition->asXml(), '->asXml() returns an XML representation of the InputDefinition');
+ }
+
+ protected function initializeArguments()
+ {
+ $this->foo = new InputArgument('foo');
+ $this->bar = new InputArgument('bar');
+ $this->foo1 = new InputArgument('foo');
+ $this->foo2 = new InputArgument('foo2', InputArgument::REQUIRED);
+ }
+
+ protected function initializeOptions()
+ {
+ $this->foo = new InputOption('foo', 'f');
+ $this->bar = new InputOption('bar', 'b');
+ $this->foo1 = new InputOption('fooBis', 'f');
+ $this->foo2 = new InputOption('foo', 'p');
+ $this->multi = new InputOption('multi', 'm|mm|mmm');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputOptionTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputOptionTest.php
new file mode 100644
index 0000000..53ce1df
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputOptionTest.php
@@ -0,0 +1,204 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\InputOption;
+
+class InputOptionTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $option = new InputOption('foo');
+ $this->assertEquals('foo', $option->getName(), '__construct() takes a name as its first argument');
+ $option = new InputOption('--foo');
+ $this->assertEquals('foo', $option->getName(), '__construct() removes the leading -- of the option name');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.
+ */
+ public function testArrayModeWithoutValue()
+ {
+ new InputOption('foo', 'f', InputOption::VALUE_IS_ARRAY);
+ }
+
+ public function testShortcut()
+ {
+ $option = new InputOption('foo', 'f');
+ $this->assertEquals('f', $option->getShortcut(), '__construct() can take a shortcut as its second argument');
+ $option = new InputOption('foo', '-f|-ff|fff');
+ $this->assertEquals('f|ff|fff', $option->getShortcut(), '__construct() removes the leading - of the shortcuts');
+ $option = new InputOption('foo', array('f', 'ff', '-fff'));
+ $this->assertEquals('f|ff|fff', $option->getShortcut(), '__construct() removes the leading - of the shortcuts');
+ $option = new InputOption('foo');
+ $this->assertNull($option->getShortcut(), '__construct() makes the shortcut null by default');
+ }
+
+ public function testModes()
+ {
+ $option = new InputOption('foo', 'f');
+ $this->assertFalse($option->acceptValue(), '__construct() gives a "InputOption::VALUE_NONE" mode by default');
+ $this->assertFalse($option->isValueRequired(), '__construct() gives a "InputOption::VALUE_NONE" mode by default');
+ $this->assertFalse($option->isValueOptional(), '__construct() gives a "InputOption::VALUE_NONE" mode by default');
+
+ $option = new InputOption('foo', 'f', null);
+ $this->assertFalse($option->acceptValue(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
+ $this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
+ $this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
+
+ $option = new InputOption('foo', 'f', InputOption::VALUE_NONE);
+ $this->assertFalse($option->acceptValue(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
+ $this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
+ $this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
+
+ $option = new InputOption('foo', 'f', InputOption::VALUE_REQUIRED);
+ $this->assertTrue($option->acceptValue(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode');
+ $this->assertTrue($option->isValueRequired(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode');
+ $this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode');
+
+ $option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL);
+ $this->assertTrue($option->acceptValue(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode');
+ $this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode');
+ $this->assertTrue($option->isValueOptional(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode');
+ }
+
+ /**
+ * @dataProvider provideInvalidModes
+ */
+ public function testInvalidModes($mode)
+ {
+ $this->setExpectedException('InvalidArgumentException', sprintf('Option mode "%s" is not valid.', $mode));
+
+ new InputOption('foo', 'f', $mode);
+ }
+
+ public function provideInvalidModes()
+ {
+ return array(
+ array('ANOTHER_ONE'),
+ array(-1),
+ );
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testEmptyNameIsInvalid()
+ {
+ new InputOption('');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testDoubleDashNameIsInvalid()
+ {
+ new InputOption('--');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSingleDashOptionIsInvalid()
+ {
+ new InputOption('foo', '-');
+ }
+
+ public function testIsArray()
+ {
+ $option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY);
+ $this->assertTrue($option->isArray(), '->isArray() returns true if the option can be an array');
+ $option = new InputOption('foo', null, InputOption::VALUE_NONE);
+ $this->assertFalse($option->isArray(), '->isArray() returns false if the option can not be an array');
+ }
+
+ public function testGetDescription()
+ {
+ $option = new InputOption('foo', 'f', null, 'Some description');
+ $this->assertEquals('Some description', $option->getDescription(), '->getDescription() returns the description message');
+ }
+
+ public function testGetDefault()
+ {
+ $option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL, '', 'default');
+ $this->assertEquals('default', $option->getDefault(), '->getDefault() returns the default value');
+
+ $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED, '', 'default');
+ $this->assertEquals('default', $option->getDefault(), '->getDefault() returns the default value');
+
+ $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED);
+ $this->assertNull($option->getDefault(), '->getDefault() returns null if no default value is configured');
+
+ $option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY);
+ $this->assertEquals(array(), $option->getDefault(), '->getDefault() returns an empty array if option is an array');
+
+ $option = new InputOption('foo', null, InputOption::VALUE_NONE);
+ $this->assertFalse($option->getDefault(), '->getDefault() returns false if the option does not take a value');
+ }
+
+ public function testSetDefault()
+ {
+ $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED, '', 'default');
+ $option->setDefault(null);
+ $this->assertNull($option->getDefault(), '->setDefault() can reset the default value by passing null');
+ $option->setDefault('another');
+ $this->assertEquals('another', $option->getDefault(), '->setDefault() changes the default value');
+
+ $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY);
+ $option->setDefault(array(1, 2));
+ $this->assertEquals(array(1, 2), $option->getDefault(), '->setDefault() changes the default value');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage Cannot set a default value when using InputOption::VALUE_NONE mode.
+ */
+ public function testDefaultValueWithValueNoneMode()
+ {
+ $option = new InputOption('foo', 'f', InputOption::VALUE_NONE);
+ $option->setDefault('default');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage A default value for an array option must be an array.
+ */
+ public function testDefaultValueWithIsArrayMode()
+ {
+ $option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY);
+ $option->setDefault('default');
+ }
+
+ public function testEquals()
+ {
+ $option = new InputOption('foo', 'f', null, 'Some description');
+ $option2 = new InputOption('foo', 'f', null, 'Alternative description');
+ $this->assertTrue($option->equals($option2));
+
+ $option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description');
+ $option2 = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description', true);
+ $this->assertFalse($option->equals($option2));
+
+ $option = new InputOption('foo', 'f', null, 'Some description');
+ $option2 = new InputOption('bar', 'f', null, 'Some description');
+ $this->assertFalse($option->equals($option2));
+
+ $option = new InputOption('foo', 'f', null, 'Some description');
+ $option2 = new InputOption('foo', '', null, 'Some description');
+ $this->assertFalse($option->equals($option2));
+
+ $option = new InputOption('foo', 'f', null, 'Some description');
+ $option2 = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description');
+ $this->assertFalse($option->equals($option2));
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputTest.php
new file mode 100644
index 0000000..0b3e38f
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/InputTest.php
@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+
+class InputTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'))));
+ $this->assertEquals('foo', $input->getArgument('name'), '->__construct() takes a InputDefinition as an argument');
+ }
+
+ public function testOptions()
+ {
+ $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'))));
+ $this->assertEquals('foo', $input->getOption('name'), '->getOption() returns the value for the given option');
+
+ $input->setOption('name', 'bar');
+ $this->assertEquals('bar', $input->getOption('name'), '->setOption() sets the value for a given option');
+ $this->assertEquals(array('name' => 'bar'), $input->getOptions(), '->getOptions() returns all option values');
+
+ $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
+ $this->assertEquals('default', $input->getOption('bar'), '->getOption() returns the default value for optional options');
+ $this->assertEquals(array('name' => 'foo', 'bar' => 'default'), $input->getOptions(), '->getOptions() returns all option values, even optional ones');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "foo" option does not exist.
+ */
+ public function testSetInvalidOption()
+ {
+ $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
+ $input->setOption('foo', 'bar');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "foo" option does not exist.
+ */
+ public function testGetInvalidOption()
+ {
+ $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
+ $input->getOption('foo');
+ }
+
+ public function testArguments()
+ {
+ $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'))));
+ $this->assertEquals('foo', $input->getArgument('name'), '->getArgument() returns the value for the given argument');
+
+ $input->setArgument('name', 'bar');
+ $this->assertEquals('bar', $input->getArgument('name'), '->setArgument() sets the value for a given argument');
+ $this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->getArguments() returns all argument values');
+
+ $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default'))));
+ $this->assertEquals('default', $input->getArgument('bar'), '->getArgument() returns the default value for optional arguments');
+ $this->assertEquals(array('name' => 'foo', 'bar' => 'default'), $input->getArguments(), '->getArguments() returns all argument values, even optional ones');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "foo" argument does not exist.
+ */
+ public function testSetInvalidArgument()
+ {
+ $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default'))));
+ $input->setArgument('foo', 'bar');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The "foo" argument does not exist.
+ */
+ public function testGetInvalidArgument()
+ {
+ $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default'))));
+ $input->getArgument('foo');
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ * @expectedExceptionMessage Not enough arguments.
+ */
+ public function testValidateWithMissingArguments()
+ {
+ $input = new ArrayInput(array());
+ $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED))));
+ $input->validate();
+ }
+
+ public function testValidate()
+ {
+ $input = new ArrayInput(array('name' => 'foo'));
+ $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED))));
+
+ $this->assertNull($input->validate());
+ }
+
+ public function testSetGetInteractive()
+ {
+ $input = new ArrayInput(array());
+ $this->assertTrue($input->isInteractive(), '->isInteractive() returns whether the input should be interactive or not');
+ $input->setInteractive(false);
+ $this->assertFalse($input->isInteractive(), '->setInteractive() changes the interactive flag');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Input/StringInputTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/StringInputTest.php
new file mode 100644
index 0000000..575d527
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Input/StringInputTest.php
@@ -0,0 +1,101 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Input;
+
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\StringInput;
+
+class StringInputTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getTokenizeData
+ */
+ public function testTokenize($input, $tokens, $message)
+ {
+ $input = new StringInput($input);
+ $r = new \ReflectionClass('Symfony\Component\Console\Input\ArgvInput');
+ $p = $r->getProperty('tokens');
+ $p->setAccessible(true);
+ $this->assertEquals($tokens, $p->getValue($input), $message);
+ }
+
+ public function testInputOptionWithGivenString()
+ {
+ $definition = new InputDefinition(
+ array(new InputOption('foo', null, InputOption::VALUE_REQUIRED))
+ );
+
+ // call to bind
+ $input = new StringInput('--foo=bar');
+ $input->bind($definition);
+ $this->assertEquals('bar', $input->getOption('foo'));
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testLegacyInputOptionDefinitionInConstructor()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ $definition = new InputDefinition(
+ array(new InputOption('foo', null, InputOption::VALUE_REQUIRED))
+ );
+
+ $input = new StringInput('--foo=bar', $definition);
+ $this->assertEquals('bar', $input->getOption('foo'));
+ }
+
+ public function getTokenizeData()
+ {
+ return array(
+ array('', array(), '->tokenize() parses an empty string'),
+ array('foo', array('foo'), '->tokenize() parses arguments'),
+ array(' foo bar ', array('foo', 'bar'), '->tokenize() ignores whitespaces between arguments'),
+ array('"quoted"', array('quoted'), '->tokenize() parses quoted arguments'),
+ array("'quoted'", array('quoted'), '->tokenize() parses quoted arguments'),
+ array("'a\rb\nc\td'", array("a\rb\nc\td"), '->tokenize() parses whitespace chars in strings'),
+ array("'a'\r'b'\n'c'\t'd'", array('a','b','c','d'), '->tokenize() parses whitespace chars between args as spaces'),
+ array('\"quoted\"', array('"quoted"'), '->tokenize() parses escaped-quoted arguments'),
+ array("\'quoted\'", array('\'quoted\''), '->tokenize() parses escaped-quoted arguments'),
+ array('-a', array('-a'), '->tokenize() parses short options'),
+ array('-azc', array('-azc'), '->tokenize() parses aggregated short options'),
+ array('-awithavalue', array('-awithavalue'), '->tokenize() parses short options with a value'),
+ array('-a"foo bar"', array('-afoo bar'), '->tokenize() parses short options with a value'),
+ array('-a"foo bar""foo bar"', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'),
+ array('-a\'foo bar\'', array('-afoo bar'), '->tokenize() parses short options with a value'),
+ array('-a\'foo bar\'\'foo bar\'', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'),
+ array('-a\'foo bar\'"foo bar"', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'),
+ array('--long-option', array('--long-option'), '->tokenize() parses long options'),
+ array('--long-option=foo', array('--long-option=foo'), '->tokenize() parses long options with a value'),
+ array('--long-option="foo bar"', array('--long-option=foo bar'), '->tokenize() parses long options with a value'),
+ array('--long-option="foo bar""another"', array('--long-option=foo baranother'), '->tokenize() parses long options with a value'),
+ array('--long-option=\'foo bar\'', array('--long-option=foo bar'), '->tokenize() parses long options with a value'),
+ array("--long-option='foo bar''another'", array('--long-option=foo baranother'), '->tokenize() parses long options with a value'),
+ array("--long-option='foo bar'\"another\"", array('--long-option=foo baranother'), '->tokenize() parses long options with a value'),
+ array('foo -a -ffoo --long bar', array('foo', '-a', '-ffoo', '--long', 'bar'), '->tokenize() parses when several arguments and options'),
+ );
+ }
+
+ public function testToString()
+ {
+ $input = new StringInput('-f foo');
+ $this->assertEquals('-f foo', (string) $input);
+
+ $input = new StringInput('-f --bar=foo "a b c d"');
+ $this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d'), (string) $input);
+
+ $input = new StringInput('-f --bar=foo \'a b c d\' '."'A\nB\\'C'");
+ $this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d').' '.escapeshellarg("A\nB'C"), (string) $input);
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Logger/ConsoleLoggerTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Logger/ConsoleLoggerTest.php
new file mode 100644
index 0000000..1abc363
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Logger/ConsoleLoggerTest.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Logger;
+
+use Psr\Log\Test\LoggerInterfaceTest;
+use Psr\Log\LogLevel;
+use Symfony\Component\Console\Logger\ConsoleLogger;
+use Symfony\Component\Console\Tests\Fixtures\DummyOutput;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Console logger test
+ *
+ * @author Kévin Dunglas <dunglas@gmail.com>
+ */
+class ConsoleLoggerTest extends LoggerInterfaceTest
+{
+ /**
+ * @var DummyOutput
+ */
+ protected $output;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLogger()
+ {
+ $this->output = new DummyOutput(OutputInterface::VERBOSITY_VERBOSE);
+
+ return new ConsoleLogger($this->output, array(
+ LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::NOTICE => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::INFO => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::DEBUG => OutputInterface::VERBOSITY_NORMAL,
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLogs()
+ {
+ return $this->output->getLogs();
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php
new file mode 100644
index 0000000..1afbbb6
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Output/ConsoleOutputTest.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Output;
+
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Console\Output\Output;
+
+class ConsoleOutputTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $output = new ConsoleOutput(Output::VERBOSITY_QUIET, true);
+ $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
+ $this->assertSame($output->getFormatter(), $output->getErrorOutput()->getFormatter(), '__construct() takes a formatter or null as the third argument');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Output/NullOutputTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Output/NullOutputTest.php
new file mode 100644
index 0000000..b20ae4e
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Output/NullOutputTest.php
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Output;
+
+use Symfony\Component\Console\Output\NullOutput;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class NullOutputTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $output = new NullOutput();
+
+ ob_start();
+ $output->write('foo');
+ $buffer = ob_get_clean();
+
+ $this->assertSame('', $buffer, '->write() does nothing (at least nothing is printed)');
+ $this->assertFalse($output->isDecorated(), '->isDecorated() returns false');
+ }
+
+ public function testVerbosity()
+ {
+ $output = new NullOutput();
+ $this->assertSame(OutputInterface::VERBOSITY_QUIET, $output->getVerbosity(), '->getVerbosity() returns VERBOSITY_QUIET for NullOutput by default');
+
+ $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
+ $this->assertSame(OutputInterface::VERBOSITY_QUIET, $output->getVerbosity(), '->getVerbosity() always returns VERBOSITY_QUIET for NullOutput');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Output/OutputTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Output/OutputTest.php
new file mode 100644
index 0000000..cfb4afe
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Output/OutputTest.php
@@ -0,0 +1,156 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Output;
+
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+
+class OutputTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ $output = new TestOutput(Output::VERBOSITY_QUIET, true);
+ $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
+ $this->assertTrue($output->isDecorated(), '__construct() takes the decorated flag as its second argument');
+ }
+
+ public function testSetIsDecorated()
+ {
+ $output = new TestOutput();
+ $output->setDecorated(true);
+ $this->assertTrue($output->isDecorated(), 'setDecorated() sets the decorated flag');
+ }
+
+ public function testSetGetVerbosity()
+ {
+ $output = new TestOutput();
+ $output->setVerbosity(Output::VERBOSITY_QUIET);
+ $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '->setVerbosity() sets the verbosity');
+
+ $this->assertTrue($output->isQuiet());
+ $this->assertFalse($output->isVerbose());
+ $this->assertFalse($output->isVeryVerbose());
+ $this->assertFalse($output->isDebug());
+
+ $output->setVerbosity(Output::VERBOSITY_NORMAL);
+ $this->assertFalse($output->isQuiet());
+ $this->assertFalse($output->isVerbose());
+ $this->assertFalse($output->isVeryVerbose());
+ $this->assertFalse($output->isDebug());
+
+ $output->setVerbosity(Output::VERBOSITY_VERBOSE);
+ $this->assertFalse($output->isQuiet());
+ $this->assertTrue($output->isVerbose());
+ $this->assertFalse($output->isVeryVerbose());
+ $this->assertFalse($output->isDebug());
+
+ $output->setVerbosity(Output::VERBOSITY_VERY_VERBOSE);
+ $this->assertFalse($output->isQuiet());
+ $this->assertTrue($output->isVerbose());
+ $this->assertTrue($output->isVeryVerbose());
+ $this->assertFalse($output->isDebug());
+
+ $output->setVerbosity(Output::VERBOSITY_DEBUG);
+ $this->assertFalse($output->isQuiet());
+ $this->assertTrue($output->isVerbose());
+ $this->assertTrue($output->isVeryVerbose());
+ $this->assertTrue($output->isDebug());
+ }
+
+ public function testWriteWithVerbosityQuiet()
+ {
+ $output = new TestOutput(Output::VERBOSITY_QUIET);
+ $output->writeln('foo');
+ $this->assertEquals('', $output->output, '->writeln() outputs nothing if verbosity is set to VERBOSITY_QUIET');
+ }
+
+ public function testWriteAnArrayOfMessages()
+ {
+ $output = new TestOutput();
+ $output->writeln(array('foo', 'bar'));
+ $this->assertEquals("foo\nbar\n", $output->output, '->writeln() can take an array of messages to output');
+ }
+
+ /**
+ * @dataProvider provideWriteArguments
+ */
+ public function testWriteRawMessage($message, $type, $expectedOutput)
+ {
+ $output = new TestOutput();
+ $output->writeln($message, $type);
+ $this->assertEquals($expectedOutput, $output->output);
+ }
+
+ public function provideWriteArguments()
+ {
+ return array(
+ array('<info>foo</info>', Output::OUTPUT_RAW, "<info>foo</info>\n"),
+ array('<info>foo</info>', Output::OUTPUT_PLAIN, "foo\n"),
+ );
+ }
+
+ public function testWriteWithDecorationTurnedOff()
+ {
+ $output = new TestOutput();
+ $output->setDecorated(false);
+ $output->writeln('<info>foo</info>');
+ $this->assertEquals("foo\n", $output->output, '->writeln() strips decoration tags if decoration is set to false');
+ }
+
+ public function testWriteDecoratedMessage()
+ {
+ $fooStyle = new OutputFormatterStyle('yellow', 'red', array('blink'));
+ $output = new TestOutput();
+ $output->getFormatter()->setStyle('FOO', $fooStyle);
+ $output->setDecorated(true);
+ $output->writeln('<foo>foo</foo>');
+ $this->assertEquals("\033[33;41;5mfoo\033[39;49;25m\n", $output->output, '->writeln() decorates the output');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage Unknown output type given (24)
+ */
+ public function testWriteWithInvalidOutputType()
+ {
+ $output = new TestOutput();
+ $output->writeln('<foo>foo</foo>', 24);
+ }
+
+ public function testWriteWithInvalidStyle()
+ {
+ $output = new TestOutput();
+
+ $output->clear();
+ $output->write('<bar>foo</bar>');
+ $this->assertEquals('<bar>foo</bar>', $output->output, '->write() do nothing when a style does not exist');
+
+ $output->clear();
+ $output->writeln('<bar>foo</bar>');
+ $this->assertEquals("<bar>foo</bar>\n", $output->output, '->writeln() do nothing when a style does not exist');
+ }
+}
+
+class TestOutput extends Output
+{
+ public $output = '';
+
+ public function clear()
+ {
+ $this->output = '';
+ }
+
+ protected function doWrite($message, $newline)
+ {
+ $this->output .= $message.($newline ? "\n" : '');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Output/StreamOutputTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Output/StreamOutputTest.php
new file mode 100644
index 0000000..2fd4f61
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Output/StreamOutputTest.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Output;
+
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Output\StreamOutput;
+
+class StreamOutputTest extends \PHPUnit_Framework_TestCase
+{
+ protected $stream;
+
+ protected function setUp()
+ {
+ $this->stream = fopen('php://memory', 'a', false);
+ }
+
+ protected function tearDown()
+ {
+ $this->stream = null;
+ }
+
+ public function testConstructor()
+ {
+ $output = new StreamOutput($this->stream, Output::VERBOSITY_QUIET, true);
+ $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
+ $this->assertTrue($output->isDecorated(), '__construct() takes the decorated flag as its second argument');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The StreamOutput class needs a stream as its first argument.
+ */
+ public function testStreamIsRequired()
+ {
+ new StreamOutput('foo');
+ }
+
+ public function testGetStream()
+ {
+ $output = new StreamOutput($this->stream);
+ $this->assertEquals($this->stream, $output->getStream(), '->getStream() returns the current stream');
+ }
+
+ public function testDoWrite()
+ {
+ $output = new StreamOutput($this->stream);
+ $output->writeln('foo');
+ rewind($output->getStream());
+ $this->assertEquals('foo'.PHP_EOL, stream_get_contents($output->getStream()), '->doWrite() writes to the stream');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php
new file mode 100644
index 0000000..a8389dd
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Tester;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Tester\ApplicationTester;
+
+class ApplicationTesterTest extends \PHPUnit_Framework_TestCase
+{
+ protected $application;
+ protected $tester;
+
+ protected function setUp()
+ {
+ $this->application = new Application();
+ $this->application->setAutoExit(false);
+ $this->application->register('foo')
+ ->addArgument('foo')
+ ->setCode(function ($input, $output) { $output->writeln('foo'); })
+ ;
+
+ $this->tester = new ApplicationTester($this->application);
+ $this->tester->run(array('command' => 'foo', 'foo' => 'bar'), array('interactive' => false, 'decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
+ }
+
+ protected function tearDown()
+ {
+ $this->application = null;
+ $this->tester = null;
+ }
+
+ public function testRun()
+ {
+ $this->assertFalse($this->tester->getInput()->isInteractive(), '->execute() takes an interactive option');
+ $this->assertFalse($this->tester->getOutput()->isDecorated(), '->execute() takes a decorated option');
+ $this->assertEquals(Output::VERBOSITY_VERBOSE, $this->tester->getOutput()->getVerbosity(), '->execute() takes a verbosity option');
+ }
+
+ public function testGetInput()
+ {
+ $this->assertEquals('bar', $this->tester->getInput()->getArgument('foo'), '->getInput() returns the current input instance');
+ }
+
+ public function testGetOutput()
+ {
+ rewind($this->tester->getOutput()->getStream());
+ $this->assertEquals('foo'.PHP_EOL, stream_get_contents($this->tester->getOutput()->getStream()), '->getOutput() returns the current output instance');
+ }
+
+ public function testGetDisplay()
+ {
+ $this->assertEquals('foo'.PHP_EOL, $this->tester->getDisplay(), '->getDisplay() returns the display of the last execution');
+ }
+
+ public function testGetStatusCode()
+ {
+ $this->assertSame(0, $this->tester->getStatusCode(), '->getStatusCode() returns the status code');
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php b/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php
new file mode 100644
index 0000000..b54c00e
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Tester;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class CommandTesterTest extends \PHPUnit_Framework_TestCase
+{
+ protected $command;
+ protected $tester;
+
+ protected function setUp()
+ {
+ $this->command = new Command('foo');
+ $this->command->addArgument('command');
+ $this->command->addArgument('foo');
+ $this->command->setCode(function ($input, $output) { $output->writeln('foo'); });
+
+ $this->tester = new CommandTester($this->command);
+ $this->tester->execute(array('foo' => 'bar'), array('interactive' => false, 'decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
+ }
+
+ protected function tearDown()
+ {
+ $this->command = null;
+ $this->tester = null;
+ }
+
+ public function testExecute()
+ {
+ $this->assertFalse($this->tester->getInput()->isInteractive(), '->execute() takes an interactive option');
+ $this->assertFalse($this->tester->getOutput()->isDecorated(), '->execute() takes a decorated option');
+ $this->assertEquals(Output::VERBOSITY_VERBOSE, $this->tester->getOutput()->getVerbosity(), '->execute() takes a verbosity option');
+ }
+
+ public function testGetInput()
+ {
+ $this->assertEquals('bar', $this->tester->getInput()->getArgument('foo'), '->getInput() returns the current input instance');
+ }
+
+ public function testGetOutput()
+ {
+ rewind($this->tester->getOutput()->getStream());
+ $this->assertEquals('foo'.PHP_EOL, stream_get_contents($this->tester->getOutput()->getStream()), '->getOutput() returns the current output instance');
+ }
+
+ public function testGetDisplay()
+ {
+ $this->assertEquals('foo'.PHP_EOL, $this->tester->getDisplay(), '->getDisplay() returns the display of the last execution');
+ }
+
+ public function testGetStatusCode()
+ {
+ $this->assertSame(0, $this->tester->getStatusCode(), '->getStatusCode() returns the status code');
+ }
+
+ public function testCommandFromApplication()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+
+ $command = new Command('foo');
+ $command->setCode(function ($input, $output) { $output->writeln('foo'); });
+
+ $application->add($command);
+
+ $tester = new CommandTester($application->find('foo'));
+
+ // check that there is no need to pass the command name here
+ $this->assertEquals(0, $tester->execute(array()));
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/composer.json b/vendor/symfony/console/Symfony/Component/Console/composer.json
new file mode 100644
index 0000000..2e3fbd8
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/composer.json
@@ -0,0 +1,42 @@
+{
+ "name": "symfony/console",
+ "type": "library",
+ "description": "Symfony Console Component",
+ "keywords": [],
+ "homepage": "http://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7",
+ "symfony/event-dispatcher": "~2.1",
+ "symfony/process": "~2.1",
+ "psr/log": "~1.0"
+ },
+ "suggest": {
+ "symfony/event-dispatcher": "",
+ "symfony/process": "",
+ "psr/log": "For using the console logger"
+ },
+ "autoload": {
+ "psr-0": { "Symfony\\Component\\Console\\": "" }
+ },
+ "target-dir": "Symfony/Component/Console",
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ }
+}
diff --git a/vendor/symfony/console/Symfony/Component/Console/phpunit.xml.dist b/vendor/symfony/console/Symfony/Component/Console/phpunit.xml.dist
new file mode 100644
index 0000000..729c433
--- /dev/null
+++ b/vendor/symfony/console/Symfony/Component/Console/phpunit.xml.dist
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+ <testsuites>
+ <testsuite name="Symfony Console Component Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Resources</directory>
+ <directory>./Tests</directory>
+ <directory>./vendor</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/.gitignore b/vendor/symfony/filesystem/Symfony/Component/Filesystem/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/CHANGELOG.md b/vendor/symfony/filesystem/Symfony/Component/Filesystem/CHANGELOG.md
new file mode 100644
index 0000000..a4c0479
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/CHANGELOG.md
@@ -0,0 +1,28 @@
+CHANGELOG
+=========
+
+2.6.0
+-----
+
+ * added LockHandler
+
+2.3.12
+------
+
+ * deprecated dumpFile() file mode argument.
+
+2.3.0
+-----
+
+ * added the dumpFile() method to atomically write files
+
+2.2.0
+-----
+
+ * added a delete option for the mirror() method
+
+2.1.0
+-----
+
+ * 24eb396 : BC Break : mkdir() function now throws exception in case of failure instead of returning Boolean value
+ * created the component
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/ExceptionInterface.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..c212e66
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/ExceptionInterface.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Filesystem\Exception;
+
+/**
+ * Exception interface for all exceptions thrown by the component.
+ *
+ * @author Romain Neutron <imprec@gmail.com>
+ *
+ * @api
+ */
+interface ExceptionInterface
+{
+}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/FileNotFoundException.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/FileNotFoundException.php
new file mode 100644
index 0000000..15533db
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/FileNotFoundException.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Filesystem\Exception;
+
+/**
+ * Exception class thrown when a file couldn't be found
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Christian Gärtner <christiangaertner.film@googlemail.com>
+ */
+class FileNotFoundException extends IOException
+{
+ public function __construct($message = null, $code = 0, \Exception $previous = null, $path = null)
+ {
+ if (null === $message) {
+ if (null === $path) {
+ $message = 'File could not be found.';
+ } else {
+ $message = sprintf('File "%s" could not be found.', $path);
+ }
+ }
+
+ parent::__construct($message, $code, $previous, $path);
+ }
+}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOException.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOException.php
new file mode 100644
index 0000000..f68a820
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOException.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Filesystem\Exception;
+
+/**
+ * Exception class thrown when a filesystem operation failure happens.
+ *
+ * @author Romain Neutron <imprec@gmail.com>
+ * @author Christian Gärtner <christiangaertner.film@googlemail.com>
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class IOException extends \RuntimeException implements IOExceptionInterface
+{
+ private $path;
+
+ public function __construct($message, $code = 0, \Exception $previous = null, $path = null)
+ {
+ $this->path = $path;
+
+ parent::__construct($message, $code, $previous);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOExceptionInterface.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOExceptionInterface.php
new file mode 100644
index 0000000..c88c763
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOExceptionInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Filesystem\Exception;
+
+/**
+ * IOException interface for file and input/output stream related exceptions thrown by the component.
+ *
+ * @author Christian Gärtner <christiangaertner.film@googlemail.com>
+ */
+interface IOExceptionInterface extends ExceptionInterface
+{
+ /**
+ * Returns the associated path for the exception
+ *
+ * @return string The path.
+ */
+ public function getPath();
+}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/Filesystem.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Filesystem.php
new file mode 100644
index 0000000..a9ea652
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Filesystem.php
@@ -0,0 +1,497 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Filesystem;
+
+use Symfony\Component\Filesystem\Exception\IOException;
+use Symfony\Component\Filesystem\Exception\FileNotFoundException;
+
+/**
+ * Provides basic utility to manipulate the file system.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Filesystem
+{
+ /**
+ * Copies a file.
+ *
+ * This method only copies the file if the origin file is newer than the target file.
+ *
+ * By default, if the target already exists, it is not overridden.
+ *
+ * @param string $originFile The original filename
+ * @param string $targetFile The target filename
+ * @param bool $override Whether to override an existing file or not
+ *
+ * @throws FileNotFoundException When originFile doesn't exist
+ * @throws IOException When copy fails
+ */
+ public function copy($originFile, $targetFile, $override = false)
+ {
+ if (stream_is_local($originFile) && !is_file($originFile)) {
+ throw new FileNotFoundException(sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile);
+ }
+
+ $this->mkdir(dirname($targetFile));
+
+ $doCopy = true;
+ if (!$override && null === parse_url($originFile, PHP_URL_HOST) && is_file($targetFile)) {
+ $doCopy = filemtime($originFile) > filemtime($targetFile);
+ }
+
+ if ($doCopy) {
+ // https://bugs.php.net/bug.php?id=64634
+ if (false === $source = @fopen($originFile, 'r')) {
+ throw new IOException(sprintf('Failed to copy "%s" to "%s" because source file could not be opened for reading.', $originFile, $targetFile), 0, null, $originFile);
+ }
+
+ // Stream context created to allow files overwrite when using FTP stream wrapper - disabled by default
+ if (false === $target = @fopen($targetFile, 'w', null, stream_context_create(array('ftp' => array('overwrite' => true))))) {
+ throw new IOException(sprintf('Failed to copy "%s" to "%s" because target file could not be opened for writing.', $originFile, $targetFile), 0, null, $originFile);
+ }
+
+ $bytesCopied = stream_copy_to_stream($source, $target);
+ fclose($source);
+ fclose($target);
+ unset($source, $target);
+
+ if (!is_file($targetFile)) {
+ throw new IOException(sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile);
+ }
+
+ if (stream_is_local($originFile) && $bytesCopied !== filesize($originFile)) {
+ throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s %g bytes copied".', $originFile, $targetFile, $bytesCopied), 0, null, $originFile);
+ }
+ }
+ }
+
+ /**
+ * Creates a directory recursively.
+ *
+ * @param string|array|\Traversable $dirs The directory path
+ * @param int $mode The directory mode
+ *
+ * @throws IOException On any directory creation failure
+ */
+ public function mkdir($dirs, $mode = 0777)
+ {
+ foreach ($this->toIterator($dirs) as $dir) {
+ if (is_dir($dir)) {
+ continue;
+ }
+
+ if (true !== @mkdir($dir, $mode, true)) {
+ $error = error_get_last();
+ if (!is_dir($dir)) {
+ // The directory was not created by a concurrent process. Let's throw an exception with a developer friendly error message if we have one
+ if ($error) {
+ throw new IOException(sprintf('Failed to create "%s": %s.', $dir, $error['message']), 0, null, $dir);
+ }
+ throw new IOException(sprintf('Failed to create "%s"', $dir), 0, null, $dir);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks the existence of files or directories.
+ *
+ * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to check
+ *
+ * @return bool true if the file exists, false otherwise
+ */
+ public function exists($files)
+ {
+ foreach ($this->toIterator($files) as $file) {
+ if (!file_exists($file)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Sets access and modification time of file.
+ *
+ * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to create
+ * @param int $time The touch time as a Unix timestamp
+ * @param int $atime The access time as a Unix timestamp
+ *
+ * @throws IOException When touch fails
+ */
+ public function touch($files, $time = null, $atime = null)
+ {
+ foreach ($this->toIterator($files) as $file) {
+ $touch = $time ? @touch($file, $time, $atime) : @touch($file);
+ if (true !== $touch) {
+ throw new IOException(sprintf('Failed to touch "%s".', $file), 0, null, $file);
+ }
+ }
+ }
+
+ /**
+ * Removes files or directories.
+ *
+ * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to remove
+ *
+ * @throws IOException When removal fails
+ */
+ public function remove($files)
+ {
+ $files = iterator_to_array($this->toIterator($files));
+ $files = array_reverse($files);
+ foreach ($files as $file) {
+ if (!file_exists($file) && !is_link($file)) {
+ continue;
+ }
+
+ if (is_dir($file) && !is_link($file)) {
+ $this->remove(new \FilesystemIterator($file));
+
+ if (true !== @rmdir($file)) {
+ throw new IOException(sprintf('Failed to remove directory "%s".', $file), 0, null, $file);
+ }
+ } else {
+ // https://bugs.php.net/bug.php?id=52176
+ if ('\\' === DIRECTORY_SEPARATOR && is_dir($file)) {
+ if (true !== @rmdir($file)) {
+ throw new IOException(sprintf('Failed to remove file "%s".', $file), 0, null, $file);
+ }
+ } else {
+ if (true !== @unlink($file)) {
+ throw new IOException(sprintf('Failed to remove file "%s".', $file), 0, null, $file);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Change mode for an array of files or directories.
+ *
+ * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to change mode
+ * @param int $mode The new mode (octal)
+ * @param int $umask The mode mask (octal)
+ * @param bool $recursive Whether change the mod recursively or not
+ *
+ * @throws IOException When the change fail
+ */
+ public function chmod($files, $mode, $umask = 0000, $recursive = false)
+ {
+ foreach ($this->toIterator($files) as $file) {
+ if ($recursive && is_dir($file) && !is_link($file)) {
+ $this->chmod(new \FilesystemIterator($file), $mode, $umask, true);
+ }
+ if (true !== @chmod($file, $mode & ~$umask)) {
+ throw new IOException(sprintf('Failed to chmod file "%s".', $file), 0, null, $file);
+ }
+ }
+ }
+
+ /**
+ * Change the owner of an array of files or directories.
+ *
+ * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to change owner
+ * @param string $user The new owner user name
+ * @param bool $recursive Whether change the owner recursively or not
+ *
+ * @throws IOException When the change fail
+ */
+ public function chown($files, $user, $recursive = false)
+ {
+ foreach ($this->toIterator($files) as $file) {
+ if ($recursive && is_dir($file) && !is_link($file)) {
+ $this->chown(new \FilesystemIterator($file), $user, true);
+ }
+ if (is_link($file) && function_exists('lchown')) {
+ if (true !== @lchown($file, $user)) {
+ throw new IOException(sprintf('Failed to chown file "%s".', $file), 0, null, $file);
+ }
+ } else {
+ if (true !== @chown($file, $user)) {
+ throw new IOException(sprintf('Failed to chown file "%s".', $file), 0, null, $file);
+ }
+ }
+ }
+ }
+
+ /**
+ * Change the group of an array of files or directories.
+ *
+ * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to change group
+ * @param string $group The group name
+ * @param bool $recursive Whether change the group recursively or not
+ *
+ * @throws IOException When the change fail
+ */
+ public function chgrp($files, $group, $recursive = false)
+ {
+ foreach ($this->toIterator($files) as $file) {
+ if ($recursive && is_dir($file) && !is_link($file)) {
+ $this->chgrp(new \FilesystemIterator($file), $group, true);
+ }
+ if (is_link($file) && function_exists('lchgrp')) {
+ if (true !== @lchgrp($file, $group)) {
+ throw new IOException(sprintf('Failed to chgrp file "%s".', $file), 0, null, $file);
+ }
+ } else {
+ if (true !== @chgrp($file, $group)) {
+ throw new IOException(sprintf('Failed to chgrp file "%s".', $file), 0, null, $file);
+ }
+ }
+ }
+ }
+
+ /**
+ * Renames a file or a directory.
+ *
+ * @param string $origin The origin filename or directory
+ * @param string $target The new filename or directory
+ * @param bool $overwrite Whether to overwrite the target if it already exists
+ *
+ * @throws IOException When target file or directory already exists
+ * @throws IOException When origin cannot be renamed
+ */
+ public function rename($origin, $target, $overwrite = false)
+ {
+ // we check that target does not exist
+ if (!$overwrite && is_readable($target)) {
+ throw new IOException(sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target);
+ }
+
+ if (true !== @rename($origin, $target)) {
+ throw new IOException(sprintf('Cannot rename "%s" to "%s".', $origin, $target), 0, null, $target);
+ }
+ }
+
+ /**
+ * Creates a symbolic link or copy a directory.
+ *
+ * @param string $originDir The origin directory path
+ * @param string $targetDir The symbolic link name
+ * @param bool $copyOnWindows Whether to copy files if on Windows
+ *
+ * @throws IOException When symlink fails
+ */
+ public function symlink($originDir, $targetDir, $copyOnWindows = false)
+ {
+ if ('\\' === DIRECTORY_SEPARATOR && $copyOnWindows) {
+ $this->mirror($originDir, $targetDir);
+
+ return;
+ }
+
+ $this->mkdir(dirname($targetDir));
+
+ $ok = false;
+ if (is_link($targetDir)) {
+ if (readlink($targetDir) != $originDir) {
+ $this->remove($targetDir);
+ } else {
+ $ok = true;
+ }
+ }
+
+ if (!$ok && true !== @symlink($originDir, $targetDir)) {
+ $report = error_get_last();
+ if (is_array($report)) {
+ if ('\\' === DIRECTORY_SEPARATOR && false !== strpos($report['message'], 'error code(1314)')) {
+ throw new IOException('Unable to create symlink due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?');
+ }
+ throw new IOException(sprintf('Failed to create symbolic link from "%s" to "%s".', $originDir, $targetDir), 0, null, $targetDir);
+ }
+ throw new IOException(sprintf('Failed to create symbolic link from %s to %s', $originDir, $targetDir));
+ }
+ }
+
+ /**
+ * Given an existing path, convert it to a path relative to a given starting path.
+ *
+ * @param string $endPath Absolute path of target
+ * @param string $startPath Absolute path where traversal begins
+ *
+ * @return string Path of target relative to starting path
+ */
+ public function makePathRelative($endPath, $startPath)
+ {
+ // Normalize separators on Windows
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $endPath = strtr($endPath, '\\', '/');
+ $startPath = strtr($startPath, '\\', '/');
+ }
+
+ // Split the paths into arrays
+ $startPathArr = explode('/', trim($startPath, '/'));
+ $endPathArr = explode('/', trim($endPath, '/'));
+
+ // Find for which directory the common path stops
+ $index = 0;
+ while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) {
+ $index++;
+ }
+
+ // Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels)
+ $depth = count($startPathArr) - $index;
+
+ // Repeated "../" for each level need to reach the common path
+ $traverser = str_repeat('../', $depth);
+
+ $endPathRemainder = implode('/', array_slice($endPathArr, $index));
+
+ // Construct $endPath from traversing to the common path, then to the remaining $endPath
+ $relativePath = $traverser.('' !== $endPathRemainder ? $endPathRemainder.'/' : '');
+
+ return '' === $relativePath ? './' : $relativePath;
+ }
+
+ /**
+ * Mirrors a directory to another.
+ *
+ * @param string $originDir The origin directory
+ * @param string $targetDir The target directory
+ * @param \Traversable $iterator A Traversable instance
+ * @param array $options An array of boolean options
+ * Valid options are:
+ * - $options['override'] Whether to override an existing file on copy or not (see copy())
+ * - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink())
+ * - $options['delete'] Whether to delete files that are not in the source directory (defaults to false)
+ *
+ * @throws IOException When file type is unknown
+ */
+ public function mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array())
+ {
+ $targetDir = rtrim($targetDir, '/\\');
+ $originDir = rtrim($originDir, '/\\');
+
+ // Iterate in destination folder to remove obsolete entries
+ if ($this->exists($targetDir) && isset($options['delete']) && $options['delete']) {
+ $deleteIterator = $iterator;
+ if (null === $deleteIterator) {
+ $flags = \FilesystemIterator::SKIP_DOTS;
+ $deleteIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($targetDir, $flags), \RecursiveIteratorIterator::CHILD_FIRST);
+ }
+ foreach ($deleteIterator as $file) {
+ $origin = str_replace($targetDir, $originDir, $file->getPathname());
+ if (!$this->exists($origin)) {
+ $this->remove($file);
+ }
+ }
+ }
+
+ $copyOnWindows = false;
+ if (isset($options['copy_on_windows'])) {
+ $copyOnWindows = $options['copy_on_windows'];
+ }
+
+ if (null === $iterator) {
+ $flags = $copyOnWindows ? \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS : \FilesystemIterator::SKIP_DOTS;
+ $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($originDir, $flags), \RecursiveIteratorIterator::SELF_FIRST);
+ }
+
+ if ($this->exists($originDir)) {
+ $this->mkdir($targetDir);
+ }
+
+ foreach ($iterator as $file) {
+ $target = str_replace($originDir, $targetDir, $file->getPathname());
+
+ if ($copyOnWindows) {
+ if (is_link($file) || is_file($file)) {
+ $this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
+ } elseif (is_dir($file)) {
+ $this->mkdir($target);
+ } else {
+ throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
+ }
+ } else {
+ if (is_link($file)) {
+ $this->symlink($file->getRealPath(), $target);
+ } elseif (is_dir($file)) {
+ $this->mkdir($target);
+ } elseif (is_file($file)) {
+ $this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
+ } else {
+ throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns whether the file path is an absolute path.
+ *
+ * @param string $file A file path
+ *
+ * @return bool
+ */
+ public function isAbsolutePath($file)
+ {
+ if (strspn($file, '/\\', 0, 1)
+ || (strlen($file) > 3 && ctype_alpha($file[0])
+ && substr($file, 1, 1) === ':'
+ && (strspn($file, '/\\', 2, 1))
+ )
+ || null !== parse_url($file, PHP_URL_SCHEME)
+ ) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Atomically dumps content into a file.
+ *
+ * @param string $filename The file to be written to.
+ * @param string $content The data to write into the file.
+ * @param null|int $mode The file mode (octal). If null, file permissions are not modified
+ * Deprecated since version 2.3.12, to be removed in 3.0.
+ *
+ * @throws IOException If the file cannot be written to.
+ */
+ public function dumpFile($filename, $content, $mode = 0666)
+ {
+ $dir = dirname($filename);
+
+ if (!is_dir($dir)) {
+ $this->mkdir($dir);
+ } elseif (!is_writable($dir)) {
+ throw new IOException(sprintf('Unable to write to the "%s" directory.', $dir), 0, null, $dir);
+ }
+
+ $tmpFile = tempnam($dir, basename($filename));
+
+ if (false === @file_put_contents($tmpFile, $content)) {
+ throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename);
+ }
+
+ $this->rename($tmpFile, $filename, true);
+ if (null !== $mode) {
+ $this->chmod($filename, $mode);
+ }
+ }
+
+ /**
+ * @param mixed $files
+ *
+ * @return \Traversable
+ */
+ private function toIterator($files)
+ {
+ if (!$files instanceof \Traversable) {
+ $files = new \ArrayObject(is_array($files) ? $files : array($files));
+ }
+
+ return $files;
+ }
+}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/LICENSE b/vendor/symfony/filesystem/Symfony/Component/Filesystem/LICENSE
new file mode 100644
index 0000000..43028bc
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2015 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/vendor/symfony/filesystem/Symfony/Component/Filesystem/LockHandler.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/LockHandler.php
new file mode 100644
index 0000000..59d35ec
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/LockHandler.php
@@ -0,0 +1,111 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Filesystem;
+
+use Symfony\Component\Filesystem\Exception\IOException;
+
+/**
+ * LockHandler class provides a simple abstraction to lock anything by means of
+ * a file lock.
+ *
+ * A locked file is created based on the lock name when calling lock(). Other
+ * lock handlers will not be able to lock the same name until it is released
+ * (explicitly by calling release() or implicitly when the instance holding the
+ * lock is destroyed).
+ *
+ * @author Grégoire Pineau <lyrixx@lyrixx.info>
+ * @author Romain Neutron <imprec@gmail.com>
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class LockHandler
+{
+ private $file;
+ private $handle;
+
+ /**
+ * @param string $name The lock name
+ * @param string|null $lockPath The directory to store the lock. Default values will use temporary directory
+ * @throws IOException If the lock directory could not be created or is not writable
+ */
+ public function __construct($name, $lockPath = null)
+ {
+ $lockPath = $lockPath ?: sys_get_temp_dir();
+
+ if (!is_dir($lockPath)) {
+ $fs = new Filesystem();
+ $fs->mkdir($lockPath);
+ }
+
+ if (!is_writable($lockPath)) {
+ throw new IOException(sprintf('The directory "%s" is not writable.', $lockPath), 0, null, $lockPath);
+ }
+
+ $this->file = sprintf('%s/sf.%s.%s.lock', $lockPath, preg_replace('/[^a-z0-9\._-]+/i', '-', $name), hash('sha256', $name));
+ }
+
+ /**
+ * Lock the resource
+ *
+ * @param bool $blocking wait until the lock is released
+ * @return bool Returns true if the lock was acquired, false otherwise
+ * @throws IOException If the lock file could not be created or opened
+ */
+ public function lock($blocking = false)
+ {
+ if ($this->handle) {
+ return true;
+ }
+
+ // Silence both userland and native PHP error handlers
+ $errorLevel = error_reporting(0);
+ set_error_handler('var_dump', 0);
+
+ if (!$this->handle = fopen($this->file, 'r')) {
+ if ($this->handle = fopen($this->file, 'x')) {
+ chmod($this->file, 0444);
+ } elseif (!$this->handle = fopen($this->file, 'r')) {
+ usleep(100); // Give some time for chmod() to complete
+ $this->handle = fopen($this->file, 'r');
+ }
+ }
+ restore_error_handler();
+ error_reporting($errorLevel);
+
+ if (!$this->handle) {
+ $error = error_get_last();
+ throw new IOException($error['message'], 0, null, $this->file);
+ }
+
+ // On Windows, even if PHP doc says the contrary, LOCK_NB works, see
+ // https://bugs.php.net/54129
+ if (!flock($this->handle, LOCK_EX | ($blocking ? 0 : LOCK_NB))) {
+ fclose($this->handle);
+ $this->handle = null;
+
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Release the resource
+ */
+ public function release()
+ {
+ if ($this->handle) {
+ flock($this->handle, LOCK_UN | LOCK_NB);
+ fclose($this->handle);
+ $this->handle = null;
+ }
+ }
+}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/README.md b/vendor/symfony/filesystem/Symfony/Component/Filesystem/README.md
new file mode 100644
index 0000000..df09f93
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/README.md
@@ -0,0 +1,47 @@
+Filesystem Component
+====================
+
+Filesystem provides basic utility to manipulate the file system:
+
+```php
+<?php
+
+use Symfony\Component\Filesystem\Filesystem;
+
+$filesystem = new Filesystem();
+
+$filesystem->copy($originFile, $targetFile, $override = false);
+
+$filesystem->mkdir($dirs, $mode = 0777);
+
+$filesystem->touch($files, $time = null, $atime = null);
+
+$filesystem->remove($files);
+
+$filesystem->exists($files);
+
+$filesystem->chmod($files, $mode, $umask = 0000, $recursive = false);
+
+$filesystem->chown($files, $user, $recursive = false);
+
+$filesystem->chgrp($files, $group, $recursive = false);
+
+$filesystem->rename($origin, $target);
+
+$filesystem->symlink($originDir, $targetDir, $copyOnWindows = false);
+
+$filesystem->makePathRelative($endPath, $startPath);
+
+$filesystem->mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array());
+
+$filesystem->isAbsolutePath($file);
+```
+
+Resources
+---------
+
+You can run the unit tests with the following command:
+
+ $ cd path/to/Symfony/Component/Filesystem/
+ $ composer install
+ $ phpunit
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/ExceptionTest.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/ExceptionTest.php
new file mode 100644
index 0000000..53bd8db
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/ExceptionTest.php
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Filesystem\Tests;
+
+use Symfony\Component\Filesystem\Exception\IOException;
+use Symfony\Component\Filesystem\Exception\FileNotFoundException;
+
+/**
+ * Test class for Filesystem.
+ */
+class ExceptionTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetPath()
+ {
+ $e = new IOException('', 0, null, '/foo');
+ $this->assertEquals('/foo', $e->getPath(), 'The pass should be returned.');
+ }
+
+ public function testGeneratedMessage()
+ {
+ $e = new FileNotFoundException(null, 0, null, '/foo');
+ $this->assertEquals('/foo', $e->getPath());
+ $this->assertEquals('File "/foo" could not be found.', $e->getMessage(), 'A message should be generated.');
+ }
+
+ public function testGeneratedMessageWithoutPath()
+ {
+ $e = new FileNotFoundException();
+ $this->assertEquals('File could not be found.', $e->getMessage(), 'A message should be generated.');
+ }
+
+ public function testCustomMessage()
+ {
+ $e = new FileNotFoundException('bar', 0, null, '/foo');
+ $this->assertEquals('bar', $e->getMessage(), 'A custom message should be possible still.');
+ }
+}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTest.php
new file mode 100644
index 0000000..16b8be7
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTest.php
@@ -0,0 +1,998 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Filesystem\Tests;
+
+use Symfony\Component\Filesystem\Filesystem;
+
+/**
+ * Test class for Filesystem.
+ */
+class FilesystemTest extends FilesystemTestCase
+{
+ /**
+ * @var \Symfony\Component\Filesystem\Filesystem $filesystem
+ */
+ private $filesystem = null;
+
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->filesystem = new Filesystem();
+ }
+
+ public function testCopyCreatesNewFile()
+ {
+ $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
+ $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
+
+ file_put_contents($sourceFilePath, 'SOURCE FILE');
+
+ $this->filesystem->copy($sourceFilePath, $targetFilePath);
+
+ $this->assertFileExists($targetFilePath);
+ $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Filesystem\Exception\IOException
+ */
+ public function testCopyFails()
+ {
+ $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
+ $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
+
+ $this->filesystem->copy($sourceFilePath, $targetFilePath);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Filesystem\Exception\IOException
+ */
+ public function testCopyUnreadableFileFails()
+ {
+ // skip test on Windows; PHP can't easily set file as unreadable on Windows
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('This test cannot run on Windows.');
+ }
+
+ $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
+ $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
+
+ file_put_contents($sourceFilePath, 'SOURCE FILE');
+
+ // make sure target cannot be read
+ $this->filesystem->chmod($sourceFilePath, 0222);
+
+ $this->filesystem->copy($sourceFilePath, $targetFilePath);
+ }
+
+ public function testCopyOverridesExistingFileIfModified()
+ {
+ $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
+ $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
+
+ file_put_contents($sourceFilePath, 'SOURCE FILE');
+ file_put_contents($targetFilePath, 'TARGET FILE');
+ touch($targetFilePath, time() - 1000);
+
+ $this->filesystem->copy($sourceFilePath, $targetFilePath);
+
+ $this->assertFileExists($targetFilePath);
+ $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
+ }
+
+ public function testCopyDoesNotOverrideExistingFileByDefault()
+ {
+ $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
+ $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
+
+ file_put_contents($sourceFilePath, 'SOURCE FILE');
+ file_put_contents($targetFilePath, 'TARGET FILE');
+
+ // make sure both files have the same modification time
+ $modificationTime = time() - 1000;
+ touch($sourceFilePath, $modificationTime);
+ touch($targetFilePath, $modificationTime);
+
+ $this->filesystem->copy($sourceFilePath, $targetFilePath);
+
+ $this->assertFileExists($targetFilePath);
+ $this->assertEquals('TARGET FILE', file_get_contents($targetFilePath));
+ }
+
+ public function testCopyOverridesExistingFileIfForced()
+ {
+ $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
+ $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
+
+ file_put_contents($sourceFilePath, 'SOURCE FILE');
+ file_put_contents($targetFilePath, 'TARGET FILE');
+
+ // make sure both files have the same modification time
+ $modificationTime = time() - 1000;
+ touch($sourceFilePath, $modificationTime);
+ touch($targetFilePath, $modificationTime);
+
+ $this->filesystem->copy($sourceFilePath, $targetFilePath, true);
+
+ $this->assertFileExists($targetFilePath);
+ $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Filesystem\Exception\IOException
+ */
+ public function testCopyWithOverrideWithReadOnlyTargetFails()
+ {
+ // skip test on Windows; PHP can't easily set file as unwritable on Windows
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('This test cannot run on Windows.');
+ }
+
+ $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
+ $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
+
+ file_put_contents($sourceFilePath, 'SOURCE FILE');
+ file_put_contents($targetFilePath, 'TARGET FILE');
+
+ // make sure both files have the same modification time
+ $modificationTime = time() - 1000;
+ touch($sourceFilePath, $modificationTime);
+ touch($targetFilePath, $modificationTime);
+
+ // make sure target is read-only
+ $this->filesystem->chmod($targetFilePath, 0444);
+
+ $this->filesystem->copy($sourceFilePath, $targetFilePath, true);
+ }
+
+ public function testCopyCreatesTargetDirectoryIfItDoesNotExist()
+ {
+ $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
+ $targetFileDirectory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
+ $targetFilePath = $targetFileDirectory.DIRECTORY_SEPARATOR.'copy_target_file';
+
+ file_put_contents($sourceFilePath, 'SOURCE FILE');
+
+ $this->filesystem->copy($sourceFilePath, $targetFilePath);
+
+ $this->assertTrue(is_dir($targetFileDirectory));
+ $this->assertFileExists($targetFilePath);
+ $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
+ }
+
+ public function testCopyForOriginUrlsAndExistingLocalFileDefaultsToNotCopy()
+ {
+ $sourceFilePath = 'http://symfony.com/images/common/logo/logo_symfony_header.png';
+ $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
+
+ file_put_contents($targetFilePath, 'TARGET FILE');
+
+ $this->filesystem->copy($sourceFilePath, $targetFilePath, false);
+
+ $this->assertFileExists($targetFilePath);
+ $this->assertEquals(file_get_contents($sourceFilePath), file_get_contents($targetFilePath));
+ }
+
+ public function testMkdirCreatesDirectoriesRecursively()
+ {
+ $directory = $this->workspace
+ .DIRECTORY_SEPARATOR.'directory'
+ .DIRECTORY_SEPARATOR.'sub_directory';
+
+ $this->filesystem->mkdir($directory);
+
+ $this->assertTrue(is_dir($directory));
+ }
+
+ public function testMkdirCreatesDirectoriesFromArray()
+ {
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR;
+ $directories = array(
+ $basePath.'1', $basePath.'2', $basePath.'3',
+ );
+
+ $this->filesystem->mkdir($directories);
+
+ $this->assertTrue(is_dir($basePath.'1'));
+ $this->assertTrue(is_dir($basePath.'2'));
+ $this->assertTrue(is_dir($basePath.'3'));
+ }
+
+ public function testMkdirCreatesDirectoriesFromTraversableObject()
+ {
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR;
+ $directories = new \ArrayObject(array(
+ $basePath.'1', $basePath.'2', $basePath.'3',
+ ));
+
+ $this->filesystem->mkdir($directories);
+
+ $this->assertTrue(is_dir($basePath.'1'));
+ $this->assertTrue(is_dir($basePath.'2'));
+ $this->assertTrue(is_dir($basePath.'3'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Filesystem\Exception\IOException
+ */
+ public function testMkdirCreatesDirectoriesFails()
+ {
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR;
+ $dir = $basePath.'2';
+
+ file_put_contents($dir, '');
+
+ $this->filesystem->mkdir($dir);
+ }
+
+ public function testTouchCreatesEmptyFile()
+ {
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'1';
+
+ $this->filesystem->touch($file);
+
+ $this->assertFileExists($file);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Filesystem\Exception\IOException
+ */
+ public function testTouchFails()
+ {
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'1'.DIRECTORY_SEPARATOR.'2';
+
+ $this->filesystem->touch($file);
+ }
+
+ public function testTouchCreatesEmptyFilesFromArray()
+ {
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR;
+ $files = array(
+ $basePath.'1', $basePath.'2', $basePath.'3',
+ );
+
+ $this->filesystem->touch($files);
+
+ $this->assertFileExists($basePath.'1');
+ $this->assertFileExists($basePath.'2');
+ $this->assertFileExists($basePath.'3');
+ }
+
+ public function testTouchCreatesEmptyFilesFromTraversableObject()
+ {
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR;
+ $files = new \ArrayObject(array(
+ $basePath.'1', $basePath.'2', $basePath.'3',
+ ));
+
+ $this->filesystem->touch($files);
+
+ $this->assertFileExists($basePath.'1');
+ $this->assertFileExists($basePath.'2');
+ $this->assertFileExists($basePath.'3');
+ }
+
+ public function testRemoveCleansFilesAndDirectoriesIteratively()
+ {
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;
+
+ mkdir($basePath);
+ mkdir($basePath.'dir');
+ touch($basePath.'file');
+
+ $this->filesystem->remove($basePath);
+
+ $this->assertTrue(!is_dir($basePath));
+ }
+
+ public function testRemoveCleansArrayOfFilesAndDirectories()
+ {
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR;
+
+ mkdir($basePath.'dir');
+ touch($basePath.'file');
+
+ $files = array(
+ $basePath.'dir', $basePath.'file',
+ );
+
+ $this->filesystem->remove($files);
+
+ $this->assertTrue(!is_dir($basePath.'dir'));
+ $this->assertTrue(!is_file($basePath.'file'));
+ }
+
+ public function testRemoveCleansTraversableObjectOfFilesAndDirectories()
+ {
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR;
+
+ mkdir($basePath.'dir');
+ touch($basePath.'file');
+
+ $files = new \ArrayObject(array(
+ $basePath.'dir', $basePath.'file',
+ ));
+
+ $this->filesystem->remove($files);
+
+ $this->assertTrue(!is_dir($basePath.'dir'));
+ $this->assertTrue(!is_file($basePath.'file'));
+ }
+
+ public function testRemoveIgnoresNonExistingFiles()
+ {
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR;
+
+ mkdir($basePath.'dir');
+
+ $files = array(
+ $basePath.'dir', $basePath.'file',
+ );
+
+ $this->filesystem->remove($files);
+
+ $this->assertTrue(!is_dir($basePath.'dir'));
+ }
+
+ public function testRemoveCleansInvalidLinks()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;
+
+ mkdir($basePath);
+ mkdir($basePath.'dir');
+ // create symlink to nonexistent file
+ @symlink($basePath.'file', $basePath.'link');
+
+ $this->filesystem->remove($basePath);
+
+ $this->assertTrue(!is_dir($basePath));
+ }
+
+ public function testFilesExists()
+ {
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;
+
+ mkdir($basePath);
+ touch($basePath.'file1');
+ mkdir($basePath.'folder');
+
+ $this->assertTrue($this->filesystem->exists($basePath.'file1'));
+ $this->assertTrue($this->filesystem->exists($basePath.'folder'));
+ }
+
+ public function testFilesExistsTraversableObjectOfFilesAndDirectories()
+ {
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR;
+
+ mkdir($basePath.'dir');
+ touch($basePath.'file');
+
+ $files = new \ArrayObject(array(
+ $basePath.'dir', $basePath.'file',
+ ));
+
+ $this->assertTrue($this->filesystem->exists($files));
+ }
+
+ public function testFilesNotExistsTraversableObjectOfFilesAndDirectories()
+ {
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR;
+
+ mkdir($basePath.'dir');
+ touch($basePath.'file');
+ touch($basePath.'file2');
+
+ $files = new \ArrayObject(array(
+ $basePath.'dir', $basePath.'file', $basePath.'file2',
+ ));
+
+ unlink($basePath.'file');
+
+ $this->assertFalse($this->filesystem->exists($files));
+ }
+
+ public function testInvalidFileNotExists()
+ {
+ $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;
+
+ $this->assertFalse($this->filesystem->exists($basePath.time()));
+ }
+
+ public function testChmodChangesFileMode()
+ {
+ $this->markAsSkippedIfChmodIsMissing();
+
+ $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
+ mkdir($dir);
+ $file = $dir.DIRECTORY_SEPARATOR.'file';
+ touch($file);
+
+ $this->filesystem->chmod($file, 0400);
+ $this->filesystem->chmod($dir, 0753);
+
+ $this->assertFilePermissions(753, $dir);
+ $this->assertFilePermissions(400, $file);
+ }
+
+ public function testChmodWrongMod()
+ {
+ $this->markAsSkippedIfChmodIsMissing();
+
+ $dir = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ touch($dir);
+
+ $this->filesystem->chmod($dir, 'Wrongmode');
+ }
+
+ public function testChmodRecursive()
+ {
+ $this->markAsSkippedIfChmodIsMissing();
+
+ $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
+ mkdir($dir);
+ $file = $dir.DIRECTORY_SEPARATOR.'file';
+ touch($file);
+
+ $this->filesystem->chmod($file, 0400, 0000, true);
+ $this->filesystem->chmod($dir, 0753, 0000, true);
+
+ $this->assertFilePermissions(753, $dir);
+ $this->assertFilePermissions(753, $file);
+ }
+
+ public function testChmodAppliesUmask()
+ {
+ $this->markAsSkippedIfChmodIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ touch($file);
+
+ $this->filesystem->chmod($file, 0770, 0022);
+ $this->assertFilePermissions(750, $file);
+ }
+
+ public function testChmodChangesModeOfArrayOfFiles()
+ {
+ $this->markAsSkippedIfChmodIsMissing();
+
+ $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $files = array($directory, $file);
+
+ mkdir($directory);
+ touch($file);
+
+ $this->filesystem->chmod($files, 0753);
+
+ $this->assertFilePermissions(753, $file);
+ $this->assertFilePermissions(753, $directory);
+ }
+
+ public function testChmodChangesModeOfTraversableFileObject()
+ {
+ $this->markAsSkippedIfChmodIsMissing();
+
+ $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $files = new \ArrayObject(array($directory, $file));
+
+ mkdir($directory);
+ touch($file);
+
+ $this->filesystem->chmod($files, 0753);
+
+ $this->assertFilePermissions(753, $file);
+ $this->assertFilePermissions(753, $directory);
+ }
+
+ public function testChown()
+ {
+ $this->markAsSkippedIfPosixIsMissing();
+
+ $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
+ mkdir($dir);
+
+ $this->filesystem->chown($dir, $this->getFileOwner($dir));
+ }
+
+ public function testChownRecursive()
+ {
+ $this->markAsSkippedIfPosixIsMissing();
+
+ $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
+ mkdir($dir);
+ $file = $dir.DIRECTORY_SEPARATOR.'file';
+ touch($file);
+
+ $this->filesystem->chown($dir, $this->getFileOwner($dir), true);
+ }
+
+ public function testChownSymlink()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+
+ $this->filesystem->symlink($file, $link);
+
+ $this->filesystem->chown($link, $this->getFileOwner($link));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Filesystem\Exception\IOException
+ */
+ public function testChownSymlinkFails()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+
+ $this->filesystem->symlink($file, $link);
+
+ $this->filesystem->chown($link, 'user'.time().mt_rand(1000, 9999));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Filesystem\Exception\IOException
+ */
+ public function testChownFail()
+ {
+ $this->markAsSkippedIfPosixIsMissing();
+
+ $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
+ mkdir($dir);
+
+ $this->filesystem->chown($dir, 'user'.time().mt_rand(1000, 9999));
+ }
+
+ public function testChgrp()
+ {
+ $this->markAsSkippedIfPosixIsMissing();
+
+ $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
+ mkdir($dir);
+
+ $this->filesystem->chgrp($dir, $this->getFileGroup($dir));
+ }
+
+ public function testChgrpRecursive()
+ {
+ $this->markAsSkippedIfPosixIsMissing();
+
+ $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
+ mkdir($dir);
+ $file = $dir.DIRECTORY_SEPARATOR.'file';
+ touch($file);
+
+ $this->filesystem->chgrp($dir, $this->getFileGroup($dir), true);
+ }
+
+ public function testChgrpSymlink()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+
+ $this->filesystem->symlink($file, $link);
+
+ $this->filesystem->chgrp($link, $this->getFileGroup($link));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Filesystem\Exception\IOException
+ */
+ public function testChgrpSymlinkFails()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+
+ $this->filesystem->symlink($file, $link);
+
+ $this->filesystem->chgrp($link, 'user'.time().mt_rand(1000, 9999));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Filesystem\Exception\IOException
+ */
+ public function testChgrpFail()
+ {
+ $this->markAsSkippedIfPosixIsMissing();
+
+ $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
+ mkdir($dir);
+
+ $this->filesystem->chgrp($dir, 'user'.time().mt_rand(1000, 9999));
+ }
+
+ public function testRename()
+ {
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';
+ touch($file);
+
+ $this->filesystem->rename($file, $newPath);
+
+ $this->assertFileNotExists($file);
+ $this->assertFileExists($newPath);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Filesystem\Exception\IOException
+ */
+ public function testRenameThrowsExceptionIfTargetAlreadyExists()
+ {
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';
+
+ touch($file);
+ touch($newPath);
+
+ $this->filesystem->rename($file, $newPath);
+ }
+
+ public function testRenameOverwritesTheTargetIfItAlreadyExists()
+ {
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';
+
+ touch($file);
+ touch($newPath);
+
+ $this->filesystem->rename($file, $newPath, true);
+
+ $this->assertFileNotExists($file);
+ $this->assertFileExists($newPath);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Filesystem\Exception\IOException
+ */
+ public function testRenameThrowsExceptionOnError()
+ {
+ $file = $this->workspace.DIRECTORY_SEPARATOR.uniqid();
+ $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';
+
+ $this->filesystem->rename($file, $newPath);
+ }
+
+ public function testSymlink()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ // $file does not exists right now: creating "broken" links is a wanted feature
+ $this->filesystem->symlink($file, $link);
+
+ $this->assertTrue(is_link($link));
+
+ // Create the linked file AFTER creating the link
+ touch($file);
+
+ $this->assertEquals($file, readlink($link));
+ }
+
+ /**
+ * @depends testSymlink
+ */
+ public function testRemoveSymlink()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ $this->filesystem->remove($link);
+
+ $this->assertTrue(!is_link($link));
+ }
+
+ public function testSymlinkIsOverwrittenIfPointsToDifferentTarget()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+ symlink($this->workspace, $link);
+
+ $this->filesystem->symlink($file, $link);
+
+ $this->assertTrue(is_link($link));
+ $this->assertEquals($file, readlink($link));
+ }
+
+ public function testSymlinkIsNotOverwrittenIfAlreadyCreated()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+ symlink($file, $link);
+
+ $this->filesystem->symlink($file, $link);
+
+ $this->assertTrue(is_link($link));
+ $this->assertEquals($file, readlink($link));
+ }
+
+ public function testSymlinkCreatesTargetDirectoryIfItDoesNotExist()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link1 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'link';
+ $link2 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'subdir'.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+
+ $this->filesystem->symlink($file, $link1);
+ $this->filesystem->symlink($file, $link2);
+
+ $this->assertTrue(is_link($link1));
+ $this->assertEquals($file, readlink($link1));
+ $this->assertTrue(is_link($link2));
+ $this->assertEquals($file, readlink($link2));
+ }
+
+ /**
+ * @dataProvider providePathsForMakePathRelative
+ */
+ public function testMakePathRelative($endPath, $startPath, $expectedPath)
+ {
+ $path = $this->filesystem->makePathRelative($endPath, $startPath);
+
+ $this->assertEquals($expectedPath, $path);
+ }
+
+ /**
+ * @return array
+ */
+ public function providePathsForMakePathRelative()
+ {
+ $paths = array(
+ array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component', '../'),
+ array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component/', '../'),
+ array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component', '../'),
+ array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component/', '../'),
+ array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'),
+ array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'),
+ array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'),
+ array('/aa/bb', '/aa/bb', './'),
+ array('/aa/bb', '/aa/bb/', './'),
+ array('/aa/bb/', '/aa/bb', './'),
+ array('/aa/bb/', '/aa/bb/', './'),
+ array('/aa/bb/cc', '/aa/bb/cc/dd', '../'),
+ array('/aa/bb/cc', '/aa/bb/cc/dd/', '../'),
+ array('/aa/bb/cc/', '/aa/bb/cc/dd', '../'),
+ array('/aa/bb/cc/', '/aa/bb/cc/dd/', '../'),
+ array('/aa/bb/cc', '/aa', 'bb/cc/'),
+ array('/aa/bb/cc', '/aa/', 'bb/cc/'),
+ array('/aa/bb/cc/', '/aa', 'bb/cc/'),
+ array('/aa/bb/cc/', '/aa/', 'bb/cc/'),
+ array('/a/aab/bb', '/a/aa', '../aab/bb/'),
+ array('/a/aab/bb', '/a/aa/', '../aab/bb/'),
+ array('/a/aab/bb/', '/a/aa', '../aab/bb/'),
+ array('/a/aab/bb/', '/a/aa/', '../aab/bb/'),
+ );
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $paths[] = array('c:\var\lib/symfony/src/Symfony/', 'c:/var/lib/symfony/', 'src/Symfony/');
+ }
+
+ return $paths;
+ }
+
+ public function testMirrorCopiesFilesAndDirectoriesRecursively()
+ {
+ $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
+ $directory = $sourcePath.'directory'.DIRECTORY_SEPARATOR;
+ $file1 = $directory.'file1';
+ $file2 = $sourcePath.'file2';
+
+ mkdir($sourcePath);
+ mkdir($directory);
+ file_put_contents($file1, 'FILE1');
+ file_put_contents($file2, 'FILE2');
+
+ $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;
+
+ $this->filesystem->mirror($sourcePath, $targetPath);
+
+ $this->assertTrue(is_dir($targetPath));
+ $this->assertTrue(is_dir($targetPath.'directory'));
+ $this->assertFileEquals($file1, $targetPath.'directory'.DIRECTORY_SEPARATOR.'file1');
+ $this->assertFileEquals($file2, $targetPath.'file2');
+
+ $this->filesystem->remove($file1);
+
+ $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => false));
+ $this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));
+
+ $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true));
+ $this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));
+
+ file_put_contents($file1, 'FILE1');
+
+ $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true));
+ $this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));
+
+ $this->filesystem->remove($directory);
+ $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true));
+ $this->assertFalse($this->filesystem->exists($targetPath.'directory'));
+ $this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));
+ }
+
+ public function testMirrorCreatesEmptyDirectory()
+ {
+ $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
+
+ mkdir($sourcePath);
+
+ $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;
+
+ $this->filesystem->mirror($sourcePath, $targetPath);
+
+ $this->assertTrue(is_dir($targetPath));
+
+ $this->filesystem->remove($sourcePath);
+ }
+
+ public function testMirrorCopiesLinks()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
+
+ mkdir($sourcePath);
+ file_put_contents($sourcePath.'file1', 'FILE1');
+ symlink($sourcePath.'file1', $sourcePath.'link1');
+
+ $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;
+
+ $this->filesystem->mirror($sourcePath, $targetPath);
+
+ $this->assertTrue(is_dir($targetPath));
+ $this->assertFileEquals($sourcePath.'file1', $targetPath.DIRECTORY_SEPARATOR.'link1');
+ $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1'));
+ }
+
+ public function testMirrorCopiesLinkedDirectoryContents()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
+
+ mkdir($sourcePath.'nested/', 0777, true);
+ file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1');
+ // Note: We symlink directory, not file
+ symlink($sourcePath.'nested', $sourcePath.'link1');
+
+ $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;
+
+ $this->filesystem->mirror($sourcePath, $targetPath);
+
+ $this->assertTrue(is_dir($targetPath));
+ $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.DIRECTORY_SEPARATOR.'link1/file1.txt');
+ $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1'));
+ }
+
+ public function testMirrorCopiesRelativeLinkedContents()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
+ $oldPath = getcwd();
+
+ mkdir($sourcePath.'nested/', 0777, true);
+ file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1');
+ // Note: Create relative symlink
+ chdir($sourcePath);
+ symlink('nested', 'link1');
+
+ chdir($oldPath);
+
+ $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;
+
+ $this->filesystem->mirror($sourcePath, $targetPath);
+
+ $this->assertTrue(is_dir($targetPath));
+ $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.DIRECTORY_SEPARATOR.'link1/file1.txt');
+ $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1'));
+ $this->assertEquals($sourcePath.'nested', readlink($targetPath.DIRECTORY_SEPARATOR.'link1'));
+ }
+
+ /**
+ * @dataProvider providePathsForIsAbsolutePath
+ */
+ public function testIsAbsolutePath($path, $expectedResult)
+ {
+ $result = $this->filesystem->isAbsolutePath($path);
+
+ $this->assertEquals($expectedResult, $result);
+ }
+
+ /**
+ * @return array
+ */
+ public function providePathsForIsAbsolutePath()
+ {
+ return array(
+ array('/var/lib', true),
+ array('c:\\\\var\\lib', true),
+ array('\\var\\lib', true),
+ array('var/lib', false),
+ array('../var/lib', false),
+ array('', false),
+ array(null, false),
+ );
+ }
+
+ public function testDumpFile()
+ {
+ $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';
+
+ $this->filesystem->dumpFile($filename, 'bar', 0753);
+
+ $this->assertFileExists($filename);
+ $this->assertSame('bar', file_get_contents($filename));
+
+ // skip mode check on Windows
+ if ('\\' !== DIRECTORY_SEPARATOR) {
+ $this->assertFilePermissions(753, $filename);
+ }
+ }
+
+ public function testDumpFileWithNullMode()
+ {
+ $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';
+
+ $this->filesystem->dumpFile($filename, 'bar', null);
+
+ $this->assertFileExists($filename);
+ $this->assertSame('bar', file_get_contents($filename));
+
+ // skip mode check on Windows
+ if ('\\' !== DIRECTORY_SEPARATOR) {
+ $this->assertFilePermissions(600, $filename);
+ }
+ }
+
+ public function testDumpFileOverwritesAnExistingFile()
+ {
+ $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo.txt';
+ file_put_contents($filename, 'FOO BAR');
+
+ $this->filesystem->dumpFile($filename, 'bar');
+
+ $this->assertFileExists($filename);
+ $this->assertSame('bar', file_get_contents($filename));
+ }
+}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php
new file mode 100644
index 0000000..80cd57e
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php
@@ -0,0 +1,131 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Filesystem\Tests;
+
+class FilesystemTestCase extends \PHPUnit_Framework_TestCase
+{
+ private $umask;
+
+ /**
+ * @var string $workspace
+ */
+ protected $workspace = null;
+
+ protected static $symlinkOnWindows = null;
+
+ public static function setUpBeforeClass()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ static::$symlinkOnWindows = true;
+ $originDir = tempnam(sys_get_temp_dir(), 'sl');
+ $targetDir = tempnam(sys_get_temp_dir(), 'sl');
+ if (true !== @symlink($originDir, $targetDir)) {
+ $report = error_get_last();
+ if (is_array($report) && false !== strpos($report['message'], 'error code(1314)')) {
+ static::$symlinkOnWindows = false;
+ }
+ }
+ }
+ }
+
+ protected function setUp()
+ {
+ $this->umask = umask(0);
+ $this->workspace = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.time().rand(0, 1000);
+ mkdir($this->workspace, 0777, true);
+ $this->workspace = realpath($this->workspace);
+ }
+
+ protected function tearDown()
+ {
+ $this->clean($this->workspace);
+ umask($this->umask);
+ }
+
+ /**
+ * @param string $file
+ */
+ protected function clean($file)
+ {
+ if (is_dir($file) && !is_link($file)) {
+ $dir = new \FilesystemIterator($file);
+ foreach ($dir as $childFile) {
+ $this->clean($childFile);
+ }
+
+ rmdir($file);
+ } else {
+ unlink($file);
+ }
+ }
+
+ /**
+ * @param int $expectedFilePerms expected file permissions as three digits (i.e. 755)
+ * @param string $filePath
+ */
+ protected function assertFilePermissions($expectedFilePerms, $filePath)
+ {
+ $actualFilePerms = (int) substr(sprintf('%o', fileperms($filePath)), -3);
+ $this->assertEquals(
+ $expectedFilePerms,
+ $actualFilePerms,
+ sprintf('File permissions for %s must be %s. Actual %s', $filePath, $expectedFilePerms, $actualFilePerms)
+ );
+ }
+
+ protected function getFileOwner($filepath)
+ {
+ $this->markAsSkippedIfPosixIsMissing();
+
+ $infos = stat($filepath);
+ if ($datas = posix_getpwuid($infos['uid'])) {
+ return $datas['name'];
+ }
+ }
+
+ protected function getFileGroup($filepath)
+ {
+ $this->markAsSkippedIfPosixIsMissing();
+
+ $infos = stat($filepath);
+ if ($datas = posix_getgrgid($infos['gid'])) {
+ return $datas['name'];
+ }
+
+ $this->markTestSkipped('Unable to retrieve file group name');
+ }
+
+ protected function markAsSkippedIfSymlinkIsMissing()
+ {
+ if (!function_exists('symlink')) {
+ $this->markTestSkipped('symlink is not supported');
+ }
+
+ if ('\\' === DIRECTORY_SEPARATOR && false === static::$symlinkOnWindows) {
+ $this->markTestSkipped('symlink requires "Create symbolic links" privilege on windows');
+ }
+ }
+
+ protected function markAsSkippedIfChmodIsMissing()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('chmod is not supported on windows');
+ }
+ }
+
+ protected function markAsSkippedIfPosixIsMissing()
+ {
+ if ('\\' === DIRECTORY_SEPARATOR || !function_exists('posix_isatty')) {
+ $this->markTestSkipped('Posix is not supported');
+ }
+ }
+}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/LockHandlerTest.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/LockHandlerTest.php
new file mode 100644
index 0000000..c2058ff
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/LockHandlerTest.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace Symfony\Component\Filesystem\Tests;
+
+use Symfony\Component\Filesystem\LockHandler;
+
+class LockHandlerTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException Symfony\Component\Filesystem\Exception\IOException
+ * @expectedExceptionMessage Failed to create "/a/b/c/d/e": mkdir(): Permission denied.
+ */
+ public function testConstructWhenRepositoryDoesNotExist()
+ {
+ new LockHandler('lock', '/a/b/c/d/e');
+ }
+
+ /**
+ * @expectedException Symfony\Component\Filesystem\Exception\IOException
+ * @expectedExceptionMessage The directory "/" is not writable.
+ */
+ public function testConstructWhenRepositoryIsNotWriteable()
+ {
+ new LockHandler('lock', '/');
+ }
+
+ public function testConstructSanitizeName()
+ {
+ $lock = new LockHandler('<?php echo "% hello word ! %" ?>');
+
+ $file = sprintf('%s/sf.-php-echo-hello-word-.4b3d9d0d27ddef3a78a64685dda3a963e478659a9e5240feaf7b4173a8f28d5f.lock', sys_get_temp_dir());
+ // ensure the file does not exist before the lock
+ @unlink($file);
+
+ $lock->lock();
+
+ $this->assertFileExists($file);
+
+ $lock->release();
+ }
+
+ public function testLockRelease()
+ {
+ $name = 'symfony-test-filesystem.lock';
+
+ $l1 = new LockHandler($name);
+ $l2 = new LockHandler($name);
+
+ $this->assertTrue($l1->lock());
+ $this->assertFalse($l2->lock());
+
+ $l1->release();
+
+ $this->assertTrue($l2->lock());
+ $l2->release();
+ }
+
+ public function testLockTwice()
+ {
+ $name = 'symfony-test-filesystem.lock';
+
+ $lockHandler = new LockHandler($name);
+
+ $this->assertTrue($lockHandler->lock());
+ $this->assertTrue($lockHandler->lock());
+
+ $lockHandler->release();
+ }
+
+ public function testLockIsReleased()
+ {
+ $name = 'symfony-test-filesystem.lock';
+
+ $l1 = new LockHandler($name);
+ $l2 = new LockHandler($name);
+
+ $this->assertTrue($l1->lock());
+ $this->assertFalse($l2->lock());
+
+ $l1 = null;
+
+ $this->assertTrue($l2->lock());
+ $l2->release();
+ }
+}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/composer.json b/vendor/symfony/filesystem/Symfony/Component/Filesystem/composer.json
new file mode 100644
index 0000000..0c81259
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/composer.json
@@ -0,0 +1,34 @@
+{
+ "name": "symfony/filesystem",
+ "type": "library",
+ "description": "Symfony Filesystem Component",
+ "keywords": [],
+ "homepage": "http://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7"
+ },
+ "autoload": {
+ "psr-0": { "Symfony\\Component\\Filesystem\\": "" }
+ },
+ "target-dir": "Symfony/Component/Filesystem",
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ }
+}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/phpunit.xml.dist b/vendor/symfony/filesystem/Symfony/Component/Filesystem/phpunit.xml.dist
new file mode 100644
index 0000000..3244418
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/phpunit.xml.dist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+ <testsuites>
+ <testsuite name="Symfony Filesystem Component Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Tests</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/.gitignore b/vendor/symfony/finder/Symfony/Component/Finder/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php
new file mode 100644
index 0000000..4ddd913
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php
@@ -0,0 +1,236 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Adapter;
+
+/**
+ * Interface for finder engine implementations.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+abstract class AbstractAdapter implements AdapterInterface
+{
+ protected $followLinks = false;
+ protected $mode = 0;
+ protected $minDepth = 0;
+ protected $maxDepth = PHP_INT_MAX;
+ protected $exclude = array();
+ protected $names = array();
+ protected $notNames = array();
+ protected $contains = array();
+ protected $notContains = array();
+ protected $sizes = array();
+ protected $dates = array();
+ protected $filters = array();
+ protected $sort = false;
+ protected $paths = array();
+ protected $notPaths = array();
+ protected $ignoreUnreadableDirs = false;
+
+ private static $areSupported = array();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isSupported()
+ {
+ $name = $this->getName();
+
+ if (!array_key_exists($name, self::$areSupported)) {
+ self::$areSupported[$name] = $this->canBeUsed();
+ }
+
+ return self::$areSupported[$name];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setFollowLinks($followLinks)
+ {
+ $this->followLinks = $followLinks;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMode($mode)
+ {
+ $this->mode = $mode;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDepths(array $depths)
+ {
+ $this->minDepth = 0;
+ $this->maxDepth = PHP_INT_MAX;
+
+ foreach ($depths as $comparator) {
+ switch ($comparator->getOperator()) {
+ case '>':
+ $this->minDepth = $comparator->getTarget() + 1;
+ break;
+ case '>=':
+ $this->minDepth = $comparator->getTarget();
+ break;
+ case '<':
+ $this->maxDepth = $comparator->getTarget() - 1;
+ break;
+ case '<=':
+ $this->maxDepth = $comparator->getTarget();
+ break;
+ default:
+ $this->minDepth = $this->maxDepth = $comparator->getTarget();
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setExclude(array $exclude)
+ {
+ $this->exclude = $exclude;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setNames(array $names)
+ {
+ $this->names = $names;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setNotNames(array $notNames)
+ {
+ $this->notNames = $notNames;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setContains(array $contains)
+ {
+ $this->contains = $contains;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setNotContains(array $notContains)
+ {
+ $this->notContains = $notContains;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setSizes(array $sizes)
+ {
+ $this->sizes = $sizes;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDates(array $dates)
+ {
+ $this->dates = $dates;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setFilters(array $filters)
+ {
+ $this->filters = $filters;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setSort($sort)
+ {
+ $this->sort = $sort;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setPath(array $paths)
+ {
+ $this->paths = $paths;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setNotPath(array $notPaths)
+ {
+ $this->notPaths = $notPaths;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function ignoreUnreadableDirs($ignore = true)
+ {
+ $this->ignoreUnreadableDirs = (bool) $ignore;
+
+ return $this;
+ }
+
+ /**
+ * Returns whether the adapter is supported in the current environment.
+ *
+ * This method should be implemented in all adapters. Do not implement
+ * isSupported in the adapters as the generic implementation provides a cache
+ * layer.
+ *
+ * @see isSupported()
+ *
+ * @return bool Whether the adapter is supported
+ */
+ abstract protected function canBeUsed();
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php
new file mode 100644
index 0000000..244301a
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php
@@ -0,0 +1,327 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Adapter;
+
+use Symfony\Component\Finder\Exception\AccessDeniedException;
+use Symfony\Component\Finder\Iterator;
+use Symfony\Component\Finder\Shell\Shell;
+use Symfony\Component\Finder\Expression\Expression;
+use Symfony\Component\Finder\Shell\Command;
+use Symfony\Component\Finder\Comparator\NumberComparator;
+use Symfony\Component\Finder\Comparator\DateComparator;
+
+/**
+ * Shell engine implementation using GNU find command.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+abstract class AbstractFindAdapter extends AbstractAdapter
+{
+ /**
+ * @var Shell
+ */
+ protected $shell;
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ $this->shell = new Shell();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ // having "/../" in path make find fail
+ $dir = realpath($dir);
+
+ // searching directories containing or not containing strings leads to no result
+ if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode && ($this->contains || $this->notContains)) {
+ return new Iterator\FilePathsIterator(array(), $dir);
+ }
+
+ $command = Command::create();
+ $find = $this->buildFindCommand($command, $dir);
+
+ if ($this->followLinks) {
+ $find->add('-follow');
+ }
+
+ $find->add('-mindepth')->add($this->minDepth + 1);
+
+ if (PHP_INT_MAX !== $this->maxDepth) {
+ $find->add('-maxdepth')->add($this->maxDepth + 1);
+ }
+
+ if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode) {
+ $find->add('-type d');
+ } elseif (Iterator\FileTypeFilterIterator::ONLY_FILES === $this->mode) {
+ $find->add('-type f');
+ }
+
+ $this->buildNamesFiltering($find, $this->names);
+ $this->buildNamesFiltering($find, $this->notNames, true);
+ $this->buildPathsFiltering($find, $dir, $this->paths);
+ $this->buildPathsFiltering($find, $dir, $this->notPaths, true);
+ $this->buildSizesFiltering($find, $this->sizes);
+ $this->buildDatesFiltering($find, $this->dates);
+
+ $useGrep = $this->shell->testCommand('grep') && $this->shell->testCommand('xargs');
+ $useSort = is_int($this->sort) && $this->shell->testCommand('sort') && $this->shell->testCommand('cut');
+
+ if ($useGrep && ($this->contains || $this->notContains)) {
+ $grep = $command->ins('grep');
+ $this->buildContentFiltering($grep, $this->contains);
+ $this->buildContentFiltering($grep, $this->notContains, true);
+ }
+
+ if ($useSort) {
+ $this->buildSorting($command, $this->sort);
+ }
+
+ $command->setErrorHandler(
+ $this->ignoreUnreadableDirs
+ // If directory is unreadable and finder is set to ignore it, `stderr` is ignored.
+ ? function ($stderr) { return; }
+ : function ($stderr) { throw new AccessDeniedException($stderr); }
+ );
+
+ $paths = $this->shell->testCommand('uniq') ? $command->add('| uniq')->execute() : array_unique($command->execute());
+ $iterator = new Iterator\FilePathsIterator($paths, $dir);
+
+ if ($this->exclude) {
+ $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
+ }
+
+ if (!$useGrep && ($this->contains || $this->notContains)) {
+ $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
+ }
+
+ if ($this->filters) {
+ $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
+ }
+
+ if (!$useSort && $this->sort) {
+ $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
+ $iterator = $iteratorAggregate->getIterator();
+ }
+
+ return $iterator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return $this->shell->testCommand('find');
+ }
+
+ /**
+ * @param Command $command
+ * @param string $dir
+ *
+ * @return Command
+ */
+ protected function buildFindCommand(Command $command, $dir)
+ {
+ return $command
+ ->ins('find')
+ ->add('find ')
+ ->arg($dir)
+ ->add('-noleaf'); // the -noleaf option is required for filesystems that don't follow the '.' and '..' conventions
+ }
+
+ /**
+ * @param Command $command
+ * @param string[] $names
+ * @param bool $not
+ */
+ private function buildNamesFiltering(Command $command, array $names, $not = false)
+ {
+ if (0 === count($names)) {
+ return;
+ }
+
+ $command->add($not ? '-not' : null)->cmd('(');
+
+ foreach ($names as $i => $name) {
+ $expr = Expression::create($name);
+
+ // Find does not support expandable globs ("*.{a,b}" syntax).
+ if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
+ $expr = Expression::create($expr->getGlob()->toRegex(false));
+ }
+
+ // Fixes 'not search' and 'full path matching' regex problems.
+ // - Jokers '.' are replaced by [^/].
+ // - We add '[^/]*' before and after regex (if no ^|$ flags are present).
+ if ($expr->isRegex()) {
+ $regex = $expr->getRegex();
+ $regex->prepend($regex->hasStartFlag() ? '/' : '/[^/]*')
+ ->setStartFlag(false)
+ ->setStartJoker(true)
+ ->replaceJokers('[^/]');
+ if (!$regex->hasEndFlag() || $regex->hasEndJoker()) {
+ $regex->setEndJoker(false)->append('[^/]*');
+ }
+ }
+
+ $command
+ ->add($i > 0 ? '-or' : null)
+ ->add($expr->isRegex()
+ ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
+ : ($expr->isCaseSensitive() ? '-name' : '-iname')
+ )
+ ->arg($expr->renderPattern());
+ }
+
+ $command->cmd(')');
+ }
+
+ /**
+ * @param Command $command
+ * @param string $dir
+ * @param string[] $paths
+ * @param bool $not
+ */
+ private function buildPathsFiltering(Command $command, $dir, array $paths, $not = false)
+ {
+ if (0 === count($paths)) {
+ return;
+ }
+
+ $command->add($not ? '-not' : null)->cmd('(');
+
+ foreach ($paths as $i => $path) {
+ $expr = Expression::create($path);
+
+ // Find does not support expandable globs ("*.{a,b}" syntax).
+ if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
+ $expr = Expression::create($expr->getGlob()->toRegex(false));
+ }
+
+ // Fixes 'not search' regex problems.
+ if ($expr->isRegex()) {
+ $regex = $expr->getRegex();
+ $regex->prepend($regex->hasStartFlag() ? preg_quote($dir).DIRECTORY_SEPARATOR : '.*')->setEndJoker(!$regex->hasEndFlag());
+ } else {
+ $expr->prepend('*')->append('*');
+ }
+
+ $command
+ ->add($i > 0 ? '-or' : null)
+ ->add($expr->isRegex()
+ ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
+ : ($expr->isCaseSensitive() ? '-path' : '-ipath')
+ )
+ ->arg($expr->renderPattern());
+ }
+
+ $command->cmd(')');
+ }
+
+ /**
+ * @param Command $command
+ * @param NumberComparator[] $sizes
+ */
+ private function buildSizesFiltering(Command $command, array $sizes)
+ {
+ foreach ($sizes as $i => $size) {
+ $command->add($i > 0 ? '-and' : null);
+
+ switch ($size->getOperator()) {
+ case '<=':
+ $command->add('-size -'.($size->getTarget() + 1).'c');
+ break;
+ case '>=':
+ $command->add('-size +'.($size->getTarget() - 1).'c');
+ break;
+ case '>':
+ $command->add('-size +'.$size->getTarget().'c');
+ break;
+ case '!=':
+ $command->add('-size -'.$size->getTarget().'c');
+ $command->add('-size +'.$size->getTarget().'c');
+ break;
+ case '<':
+ default:
+ $command->add('-size -'.$size->getTarget().'c');
+ }
+ }
+ }
+
+ /**
+ * @param Command $command
+ * @param DateComparator[] $dates
+ */
+ private function buildDatesFiltering(Command $command, array $dates)
+ {
+ foreach ($dates as $i => $date) {
+ $command->add($i > 0 ? '-and' : null);
+
+ $mins = (int) round((time() - $date->getTarget()) / 60);
+
+ if (0 > $mins) {
+ // mtime is in the future
+ $command->add(' -mmin -0');
+ // we will have no result so we don't need to continue
+ return;
+ }
+
+ switch ($date->getOperator()) {
+ case '<=':
+ $command->add('-mmin +'.($mins - 1));
+ break;
+ case '>=':
+ $command->add('-mmin -'.($mins + 1));
+ break;
+ case '>':
+ $command->add('-mmin -'.$mins);
+ break;
+ case '!=':
+ $command->add('-mmin +'.$mins.' -or -mmin -'.$mins);
+ break;
+ case '<':
+ default:
+ $command->add('-mmin +'.$mins);
+ }
+ }
+ }
+
+ /**
+ * @param Command $command
+ * @param string $sort
+ *
+ * @throws \InvalidArgumentException
+ */
+ private function buildSorting(Command $command, $sort)
+ {
+ $this->buildFormatSorting($command, $sort);
+ }
+
+ /**
+ * @param Command $command
+ * @param string $sort
+ */
+ abstract protected function buildFormatSorting(Command $command, $sort);
+
+ /**
+ * @param Command $command
+ * @param array $contains
+ * @param bool $not
+ */
+ abstract protected function buildContentFiltering(Command $command, array $contains, $not = false);
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php
new file mode 100644
index 0000000..bdc3a93
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php
@@ -0,0 +1,144 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Adapter;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+interface AdapterInterface
+{
+ /**
+ * @param bool $followLinks
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setFollowLinks($followLinks);
+
+ /**
+ * @param int $mode
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setMode($mode);
+
+ /**
+ * @param array $exclude
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setExclude(array $exclude);
+
+ /**
+ * @param array $depths
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setDepths(array $depths);
+
+ /**
+ * @param array $names
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setNames(array $names);
+
+ /**
+ * @param array $notNames
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setNotNames(array $notNames);
+
+ /**
+ * @param array $contains
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setContains(array $contains);
+
+ /**
+ * @param array $notContains
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setNotContains(array $notContains);
+
+ /**
+ * @param array $sizes
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setSizes(array $sizes);
+
+ /**
+ * @param array $dates
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setDates(array $dates);
+
+ /**
+ * @param array $filters
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setFilters(array $filters);
+
+ /**
+ * @param \Closure|int $sort
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setSort($sort);
+
+ /**
+ * @param array $paths
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setPath(array $paths);
+
+ /**
+ * @param array $notPaths
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function setNotPath(array $notPaths);
+
+ /**
+ * @param bool $ignore
+ *
+ * @return AdapterInterface Current instance
+ */
+ public function ignoreUnreadableDirs($ignore = true);
+
+ /**
+ * @param string $dir
+ *
+ * @return \Iterator Result iterator
+ */
+ public function searchInDirectory($dir);
+
+ /**
+ * Tests adapter support for current platform.
+ *
+ * @return bool
+ */
+ public function isSupported();
+
+ /**
+ * Returns adapter name.
+ *
+ * @return string
+ */
+ public function getName();
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php
new file mode 100644
index 0000000..4a25bae
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Adapter;
+
+use Symfony\Component\Finder\Shell\Shell;
+use Symfony\Component\Finder\Shell\Command;
+use Symfony\Component\Finder\Iterator\SortableIterator;
+use Symfony\Component\Finder\Expression\Expression;
+
+/**
+ * Shell engine implementation using BSD find command.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class BsdFindAdapter extends AbstractFindAdapter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'bsd_find';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return in_array($this->shell->getType(), array(Shell::TYPE_BSD, Shell::TYPE_DARWIN)) && parent::canBeUsed();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildFormatSorting(Command $command, $sort)
+ {
+ switch ($sort) {
+ case SortableIterator::SORT_BY_NAME:
+ $command->ins('sort')->add('| sort');
+
+ return;
+ case SortableIterator::SORT_BY_TYPE:
+ $format = '%HT';
+ break;
+ case SortableIterator::SORT_BY_ACCESSED_TIME:
+ $format = '%a';
+ break;
+ case SortableIterator::SORT_BY_CHANGED_TIME:
+ $format = '%c';
+ break;
+ case SortableIterator::SORT_BY_MODIFIED_TIME:
+ $format = '%m';
+ break;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
+ }
+
+ $command
+ ->add('-print0 | xargs -0 stat -f')
+ ->arg($format.'%t%N')
+ ->add('| sort | cut -f 2');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildFindCommand(Command $command, $dir)
+ {
+ parent::buildFindCommand($command, $dir)->addAtIndex('-E', 1);
+
+ return $command;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildContentFiltering(Command $command, array $contains, $not = false)
+ {
+ foreach ($contains as $contain) {
+ $expr = Expression::create($contain);
+
+ // todo: avoid forking process for each $pattern by using multiple -e options
+ $command
+ ->add('| grep -v \'^$\'')
+ ->add('| xargs -I{} grep -I')
+ ->add($expr->isCaseSensitive() ? null : '-i')
+ ->add($not ? '-L' : '-l')
+ ->add('-Ee')->arg($expr->renderPattern())
+ ->add('{}')
+ ;
+ }
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php
new file mode 100644
index 0000000..0fbf48f
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php
@@ -0,0 +1,104 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Adapter;
+
+use Symfony\Component\Finder\Shell\Shell;
+use Symfony\Component\Finder\Shell\Command;
+use Symfony\Component\Finder\Iterator\SortableIterator;
+use Symfony\Component\Finder\Expression\Expression;
+
+/**
+ * Shell engine implementation using GNU find command.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class GnuFindAdapter extends AbstractFindAdapter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'gnu_find';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildFormatSorting(Command $command, $sort)
+ {
+ switch ($sort) {
+ case SortableIterator::SORT_BY_NAME:
+ $command->ins('sort')->add('| sort');
+
+ return;
+ case SortableIterator::SORT_BY_TYPE:
+ $format = '%y';
+ break;
+ case SortableIterator::SORT_BY_ACCESSED_TIME:
+ $format = '%A@';
+ break;
+ case SortableIterator::SORT_BY_CHANGED_TIME:
+ $format = '%C@';
+ break;
+ case SortableIterator::SORT_BY_MODIFIED_TIME:
+ $format = '%T@';
+ break;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
+ }
+
+ $command
+ ->get('find')
+ ->add('-printf')
+ ->arg($format.' %h/%f\\n')
+ ->add('| sort | cut')
+ ->arg('-d ')
+ ->arg('-f2-')
+ ;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return $this->shell->getType() === Shell::TYPE_UNIX && parent::canBeUsed();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildFindCommand(Command $command, $dir)
+ {
+ return parent::buildFindCommand($command, $dir)->add('-regextype posix-extended');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function buildContentFiltering(Command $command, array $contains, $not = false)
+ {
+ foreach ($contains as $contain) {
+ $expr = Expression::create($contain);
+
+ // todo: avoid forking process for each $pattern by using multiple -e options
+ $command
+ ->add('| xargs -I{} -r grep -I')
+ ->add($expr->isCaseSensitive() ? null : '-i')
+ ->add($not ? '-L' : '-l')
+ ->add('-Ee')->arg($expr->renderPattern())
+ ->add('{}')
+ ;
+ }
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php
new file mode 100644
index 0000000..378a26a
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Adapter;
+
+use Symfony\Component\Finder\Iterator;
+
+/**
+ * PHP finder engine implementation.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class PhpAdapter extends AbstractAdapter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ $flags = \RecursiveDirectoryIterator::SKIP_DOTS;
+
+ if ($this->followLinks) {
+ $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
+ }
+
+ $iterator = new \RecursiveIteratorIterator(
+ new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs),
+ \RecursiveIteratorIterator::SELF_FIRST
+ );
+
+ if ($this->minDepth > 0 || $this->maxDepth < PHP_INT_MAX) {
+ $iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->minDepth, $this->maxDepth);
+ }
+
+ if ($this->mode) {
+ $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
+ }
+
+ if ($this->exclude) {
+ $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
+ }
+
+ if ($this->names || $this->notNames) {
+ $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
+ }
+
+ if ($this->contains || $this->notContains) {
+ $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
+ }
+
+ if ($this->sizes) {
+ $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
+ }
+
+ if ($this->dates) {
+ $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
+ }
+
+ if ($this->filters) {
+ $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
+ }
+
+ if ($this->sort) {
+ $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
+ $iterator = $iteratorAggregate->getIterator();
+ }
+
+ if ($this->paths || $this->notPaths) {
+ $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
+ }
+
+ return $iterator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'php';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return true;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/CHANGELOG.md b/vendor/symfony/finder/Symfony/Component/Finder/CHANGELOG.md
new file mode 100644
index 0000000..f1dd7d5
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/CHANGELOG.md
@@ -0,0 +1,34 @@
+CHANGELOG
+=========
+
+2.5.0
+-----
+ * added support for GLOB_BRACE in the paths passed to Finder::in()
+
+2.3.0
+-----
+
+ * added a way to ignore unreadable directories (via Finder::ignoreUnreadableDirs())
+ * unified the way subfolders that are not executable are handled by always throwing an AccessDeniedException exception
+
+2.2.0
+-----
+
+ * added Finder::path() and Finder::notPath() methods
+ * added finder adapters to improve performance on specific platforms
+ * added support for wildcard characters (glob patterns) in the paths passed
+ to Finder::in()
+
+2.1.0
+-----
+
+ * added Finder::sortByAccessedTime(), Finder::sortByChangedTime(), and
+ Finder::sortByModifiedTime()
+ * added Countable to Finder
+ * added support for an array of directories as an argument to
+ Finder::exclude()
+ * added searching based on the file content via Finder::contains() and
+ Finder::notContains()
+ * added support for the != operator in the Comparator
+ * [BC BREAK] filter expressions (used for file name and content) are no more
+ considered as regexps but glob patterns when they are enclosed in '*' or '?'
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Comparator/Comparator.php b/vendor/symfony/finder/Symfony/Component/Finder/Comparator/Comparator.php
new file mode 100644
index 0000000..4f5e1ff
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Comparator/Comparator.php
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Comparator;
+
+/**
+ * Comparator.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Comparator
+{
+ private $target;
+ private $operator = '==';
+
+ /**
+ * Gets the target value.
+ *
+ * @return string The target value
+ */
+ public function getTarget()
+ {
+ return $this->target;
+ }
+
+ /**
+ * Sets the target value.
+ *
+ * @param string $target The target value
+ */
+ public function setTarget($target)
+ {
+ $this->target = $target;
+ }
+
+ /**
+ * Gets the comparison operator.
+ *
+ * @return string The operator
+ */
+ public function getOperator()
+ {
+ return $this->operator;
+ }
+
+ /**
+ * Sets the comparison operator.
+ *
+ * @param string $operator A valid operator
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setOperator($operator)
+ {
+ if (!$operator) {
+ $operator = '==';
+ }
+
+ if (!in_array($operator, array('>', '<', '>=', '<=', '==', '!='))) {
+ throw new \InvalidArgumentException(sprintf('Invalid operator "%s".', $operator));
+ }
+
+ $this->operator = $operator;
+ }
+
+ /**
+ * Tests against the target.
+ *
+ * @param mixed $test A test value
+ *
+ * @return bool
+ */
+ public function test($test)
+ {
+ switch ($this->operator) {
+ case '>':
+ return $test > $this->target;
+ case '>=':
+ return $test >= $this->target;
+ case '<':
+ return $test < $this->target;
+ case '<=':
+ return $test <= $this->target;
+ case '!=':
+ return $test != $this->target;
+ }
+
+ return $test == $this->target;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Comparator/DateComparator.php b/vendor/symfony/finder/Symfony/Component/Finder/Comparator/DateComparator.php
new file mode 100644
index 0000000..8b7746b
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Comparator/DateComparator.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Comparator;
+
+/**
+ * DateCompare compiles date comparisons.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class DateComparator extends Comparator
+{
+ /**
+ * Constructor.
+ *
+ * @param string $test A comparison string
+ *
+ * @throws \InvalidArgumentException If the test is not understood
+ */
+ public function __construct($test)
+ {
+ if (!preg_match('#^\s*(==|!=|[<>]=?|after|since|before|until)?\s*(.+?)\s*$#i', $test, $matches)) {
+ throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a date test.', $test));
+ }
+
+ try {
+ $date = new \DateTime($matches[2]);
+ $target = $date->format('U');
+ } catch (\Exception $e) {
+ throw new \InvalidArgumentException(sprintf('"%s" is not a valid date.', $matches[2]));
+ }
+
+ $operator = isset($matches[1]) ? $matches[1] : '==';
+ if ('since' === $operator || 'after' === $operator) {
+ $operator = '>';
+ }
+
+ if ('until' === $operator || 'before' === $operator) {
+ $operator = '<';
+ }
+
+ $this->setOperator($operator);
+ $this->setTarget($target);
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.php b/vendor/symfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.php
new file mode 100644
index 0000000..4b5b5ba
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.php
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Comparator;
+
+/**
+ * NumberComparator compiles a simple comparison to an anonymous
+ * subroutine, which you can call with a value to be tested again.
+ *
+ * Now this would be very pointless, if NumberCompare didn't understand
+ * magnitudes.
+ *
+ * The target value may use magnitudes of kilobytes (k, ki),
+ * megabytes (m, mi), or gigabytes (g, gi). Those suffixed
+ * with an i use the appropriate 2**n version in accordance with the
+ * IEC standard: http://physics.nist.gov/cuu/Units/binary.html
+ *
+ * Based on the Perl Number::Compare module.
+ *
+ * @author Fabien Potencier <fabien@symfony.com> PHP port
+ * @author Richard Clamp <richardc@unixbeard.net> Perl version
+ * @copyright 2004-2005 Fabien Potencier <fabien@symfony.com>
+ * @copyright 2002 Richard Clamp <richardc@unixbeard.net>
+ *
+ * @see http://physics.nist.gov/cuu/Units/binary.html
+ */
+class NumberComparator extends Comparator
+{
+ /**
+ * Constructor.
+ *
+ * @param string $test A comparison string
+ *
+ * @throws \InvalidArgumentException If the test is not understood
+ */
+ public function __construct($test)
+ {
+ if (!preg_match('#^\s*(==|!=|[<>]=?)?\s*([0-9\.]+)\s*([kmg]i?)?\s*$#i', $test, $matches)) {
+ throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a number test.', $test));
+ }
+
+ $target = $matches[2];
+ if (!is_numeric($target)) {
+ throw new \InvalidArgumentException(sprintf('Invalid number "%s".', $target));
+ }
+ if (isset($matches[3])) {
+ // magnitude
+ switch (strtolower($matches[3])) {
+ case 'k':
+ $target *= 1000;
+ break;
+ case 'ki':
+ $target *= 1024;
+ break;
+ case 'm':
+ $target *= 1000000;
+ break;
+ case 'mi':
+ $target *= 1024 * 1024;
+ break;
+ case 'g':
+ $target *= 1000000000;
+ break;
+ case 'gi':
+ $target *= 1024 * 1024 * 1024;
+ break;
+ }
+ }
+
+ $this->setTarget($target);
+ $this->setOperator(isset($matches[1]) ? $matches[1] : '==');
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php b/vendor/symfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php
new file mode 100644
index 0000000..ee195ea
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Exception;
+
+/**
+ * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
+ */
+class AccessDeniedException extends \UnexpectedValueException
+{
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php b/vendor/symfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php
new file mode 100644
index 0000000..15fa221
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Exception;
+
+use Symfony\Component\Finder\Adapter\AdapterInterface;
+
+/**
+ * Base exception for all adapter failures.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class AdapterFailureException extends \RuntimeException implements ExceptionInterface
+{
+ /**
+ * @var \Symfony\Component\Finder\Adapter\AdapterInterface
+ */
+ private $adapter;
+
+ /**
+ * @param AdapterInterface $adapter
+ * @param string|null $message
+ * @param \Exception|null $previous
+ */
+ public function __construct(AdapterInterface $adapter, $message = null, \Exception $previous = null)
+ {
+ $this->adapter = $adapter;
+ parent::__construct($message ?: 'Search failed with "'.$adapter->getName().'" adapter.', $previous);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getAdapter()
+ {
+ return $this->adapter;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.php b/vendor/symfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..bff0214
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Exception;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+interface ExceptionInterface
+{
+ /**
+ * @return \Symfony\Component\Finder\Adapter\AdapterInterface
+ */
+ public function getAdapter();
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php b/vendor/symfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php
new file mode 100644
index 0000000..3663112
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Exception;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class OperationNotPermitedException extends AdapterFailureException
+{
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php b/vendor/symfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php
new file mode 100644
index 0000000..2658f6a
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Exception;
+
+use Symfony\Component\Finder\Adapter\AdapterInterface;
+use Symfony\Component\Finder\Shell\Command;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class ShellCommandFailureException extends AdapterFailureException
+{
+ /**
+ * @var Command
+ */
+ private $command;
+
+ /**
+ * @param AdapterInterface $adapter
+ * @param Command $command
+ * @param \Exception|null $previous
+ */
+ public function __construct(AdapterInterface $adapter, Command $command, \Exception $previous = null)
+ {
+ $this->command = $command;
+ parent::__construct($adapter, 'Shell command failed: "'.$command->join().'".', $previous);
+ }
+
+ /**
+ * @return Command
+ */
+ public function getCommand()
+ {
+ return $this->command;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Expression/Expression.php b/vendor/symfony/finder/Symfony/Component/Finder/Expression/Expression.php
new file mode 100644
index 0000000..9002607
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Expression/Expression.php
@@ -0,0 +1,146 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Expression;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class Expression implements ValueInterface
+{
+ const TYPE_REGEX = 1;
+ const TYPE_GLOB = 2;
+
+ /**
+ * @var ValueInterface
+ */
+ private $value;
+
+ /**
+ * @param string $expr
+ *
+ * @return Expression
+ */
+ public static function create($expr)
+ {
+ return new self($expr);
+ }
+
+ /**
+ * @param string $expr
+ */
+ public function __construct($expr)
+ {
+ try {
+ $this->value = Regex::create($expr);
+ } catch (\InvalidArgumentException $e) {
+ $this->value = new Glob($expr);
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render()
+ {
+ return $this->value->render();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function renderPattern()
+ {
+ return $this->value->renderPattern();
+ }
+
+ /**
+ * @return bool
+ */
+ public function isCaseSensitive()
+ {
+ return $this->value->isCaseSensitive();
+ }
+
+ /**
+ * @return int
+ */
+ public function getType()
+ {
+ return $this->value->getType();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prepend($expr)
+ {
+ $this->value->prepend($expr);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function append($expr)
+ {
+ $this->value->append($expr);
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isRegex()
+ {
+ return self::TYPE_REGEX === $this->value->getType();
+ }
+
+ /**
+ * @return bool
+ */
+ public function isGlob()
+ {
+ return self::TYPE_GLOB === $this->value->getType();
+ }
+
+ /**
+ * @throws \LogicException
+ *
+ * @return Glob
+ */
+ public function getGlob()
+ {
+ if (self::TYPE_GLOB !== $this->value->getType()) {
+ throw new \LogicException('Regex can\'t be transformed to glob.');
+ }
+
+ return $this->value;
+ }
+
+ /**
+ * @return Regex
+ */
+ public function getRegex()
+ {
+ return self::TYPE_REGEX === $this->value->getType() ? $this->value : $this->value->toRegex();
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Expression/Glob.php b/vendor/symfony/finder/Symfony/Component/Finder/Expression/Glob.php
new file mode 100644
index 0000000..3023cee
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Expression/Glob.php
@@ -0,0 +1,157 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Expression;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class Glob implements ValueInterface
+{
+ /**
+ * @var string
+ */
+ private $pattern;
+
+ /**
+ * @param string $pattern
+ */
+ public function __construct($pattern)
+ {
+ $this->pattern = $pattern;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render()
+ {
+ return $this->pattern;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function renderPattern()
+ {
+ return $this->pattern;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getType()
+ {
+ return Expression::TYPE_GLOB;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isCaseSensitive()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prepend($expr)
+ {
+ $this->pattern = $expr.$this->pattern;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function append($expr)
+ {
+ $this->pattern .= $expr;
+
+ return $this;
+ }
+
+ /**
+ * Tests if glob is expandable ("*.{a,b}" syntax).
+ *
+ * @return bool
+ */
+ public function isExpandable()
+ {
+ return false !== strpos($this->pattern, '{')
+ && false !== strpos($this->pattern, '}');
+ }
+
+ /**
+ * @param bool $strictLeadingDot
+ * @param bool $strictWildcardSlash
+ *
+ * @return Regex
+ */
+ public function toRegex($strictLeadingDot = true, $strictWildcardSlash = true)
+ {
+ $firstByte = true;
+ $escaping = false;
+ $inCurlies = 0;
+ $regex = '';
+ $sizeGlob = strlen($this->pattern);
+ for ($i = 0; $i < $sizeGlob; $i++) {
+ $car = $this->pattern[$i];
+ if ($firstByte) {
+ if ($strictLeadingDot && '.' !== $car) {
+ $regex .= '(?=[^\.])';
+ }
+
+ $firstByte = false;
+ }
+
+ if ('/' === $car) {
+ $firstByte = true;
+ }
+
+ if ('.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) {
+ $regex .= "\\$car";
+ } elseif ('*' === $car) {
+ $regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*');
+ } elseif ('?' === $car) {
+ $regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.');
+ } elseif ('{' === $car) {
+ $regex .= $escaping ? '\\{' : '(';
+ if (!$escaping) {
+ ++$inCurlies;
+ }
+ } elseif ('}' === $car && $inCurlies) {
+ $regex .= $escaping ? '}' : ')';
+ if (!$escaping) {
+ --$inCurlies;
+ }
+ } elseif (',' === $car && $inCurlies) {
+ $regex .= $escaping ? ',' : '|';
+ } elseif ('\\' === $car) {
+ if ($escaping) {
+ $regex .= '\\\\';
+ $escaping = false;
+ } else {
+ $escaping = true;
+ }
+
+ continue;
+ } else {
+ $regex .= $car;
+ }
+ $escaping = false;
+ }
+
+ return new Regex('^'.$regex.'$');
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Expression/Regex.php b/vendor/symfony/finder/Symfony/Component/Finder/Expression/Regex.php
new file mode 100644
index 0000000..a249fc2
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Expression/Regex.php
@@ -0,0 +1,321 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Expression;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class Regex implements ValueInterface
+{
+ const START_FLAG = '^';
+ const END_FLAG = '$';
+ const BOUNDARY = '~';
+ const JOKER = '.*';
+ const ESCAPING = '\\';
+
+ /**
+ * @var string
+ */
+ private $pattern;
+
+ /**
+ * @var array
+ */
+ private $options;
+
+ /**
+ * @var bool
+ */
+ private $startFlag;
+
+ /**
+ * @var bool
+ */
+ private $endFlag;
+
+ /**
+ * @var bool
+ */
+ private $startJoker;
+
+ /**
+ * @var bool
+ */
+ private $endJoker;
+
+ /**
+ * @param string $expr
+ *
+ * @return Regex
+ *
+ * @throws \InvalidArgumentException
+ */
+ public static function create($expr)
+ {
+ if (preg_match('/^(.{3,}?)([imsxuADU]*)$/', $expr, $m)) {
+ $start = substr($m[1], 0, 1);
+ $end = substr($m[1], -1);
+
+ if (
+ ($start === $end && !preg_match('/[*?[:alnum:] \\\\]/', $start))
+ || ($start === '{' && $end === '}')
+ || ($start === '(' && $end === ')')
+ ) {
+ return new self(substr($m[1], 1, -1), $m[2], $end);
+ }
+ }
+
+ throw new \InvalidArgumentException('Given expression is not a regex.');
+ }
+
+ /**
+ * @param string $pattern
+ * @param string $options
+ * @param string $delimiter
+ */
+ public function __construct($pattern, $options = '', $delimiter = null)
+ {
+ if (null !== $delimiter) {
+ // removes delimiter escaping
+ $pattern = str_replace('\\'.$delimiter, $delimiter, $pattern);
+ }
+
+ $this->parsePattern($pattern);
+ $this->options = $options;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render()
+ {
+ return self::BOUNDARY
+ .$this->renderPattern()
+ .self::BOUNDARY
+ .$this->options;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function renderPattern()
+ {
+ return ($this->startFlag ? self::START_FLAG : '')
+ .($this->startJoker ? self::JOKER : '')
+ .str_replace(self::BOUNDARY, '\\'.self::BOUNDARY, $this->pattern)
+ .($this->endJoker ? self::JOKER : '')
+ .($this->endFlag ? self::END_FLAG : '');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isCaseSensitive()
+ {
+ return !$this->hasOption('i');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getType()
+ {
+ return Expression::TYPE_REGEX;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prepend($expr)
+ {
+ $this->pattern = $expr.$this->pattern;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function append($expr)
+ {
+ $this->pattern .= $expr;
+
+ return $this;
+ }
+
+ /**
+ * @param string $option
+ *
+ * @return bool
+ */
+ public function hasOption($option)
+ {
+ return false !== strpos($this->options, $option);
+ }
+
+ /**
+ * @param string $option
+ *
+ * @return Regex
+ */
+ public function addOption($option)
+ {
+ if (!$this->hasOption($option)) {
+ $this->options .= $option;
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param string $option
+ *
+ * @return Regex
+ */
+ public function removeOption($option)
+ {
+ $this->options = str_replace($option, '', $this->options);
+
+ return $this;
+ }
+
+ /**
+ * @param bool $startFlag
+ *
+ * @return Regex
+ */
+ public function setStartFlag($startFlag)
+ {
+ $this->startFlag = $startFlag;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasStartFlag()
+ {
+ return $this->startFlag;
+ }
+
+ /**
+ * @param bool $endFlag
+ *
+ * @return Regex
+ */
+ public function setEndFlag($endFlag)
+ {
+ $this->endFlag = (bool) $endFlag;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasEndFlag()
+ {
+ return $this->endFlag;
+ }
+
+ /**
+ * @param bool $startJoker
+ *
+ * @return Regex
+ */
+ public function setStartJoker($startJoker)
+ {
+ $this->startJoker = $startJoker;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasStartJoker()
+ {
+ return $this->startJoker;
+ }
+
+ /**
+ * @param bool $endJoker
+ *
+ * @return Regex
+ */
+ public function setEndJoker($endJoker)
+ {
+ $this->endJoker = (bool) $endJoker;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasEndJoker()
+ {
+ return $this->endJoker;
+ }
+
+ /**
+ * @param array $replacement
+ *
+ * @return Regex
+ */
+ public function replaceJokers($replacement)
+ {
+ $replace = function ($subject) use ($replacement) {
+ $subject = $subject[0];
+ $replace = 0 === substr_count($subject, '\\') % 2;
+
+ return $replace ? str_replace('.', $replacement, $subject) : $subject;
+ };
+
+ $this->pattern = preg_replace_callback('~[\\\\]*\\.~', $replace, $this->pattern);
+
+ return $this;
+ }
+
+ /**
+ * @param string $pattern
+ */
+ private function parsePattern($pattern)
+ {
+ if ($this->startFlag = self::START_FLAG === substr($pattern, 0, 1)) {
+ $pattern = substr($pattern, 1);
+ }
+
+ if ($this->startJoker = self::JOKER === substr($pattern, 0, 2)) {
+ $pattern = substr($pattern, 2);
+ }
+
+ if ($this->endFlag = (self::END_FLAG === substr($pattern, -1) && self::ESCAPING !== substr($pattern, -2, -1))) {
+ $pattern = substr($pattern, 0, -1);
+ }
+
+ if ($this->endJoker = (self::JOKER === substr($pattern, -2) && self::ESCAPING !== substr($pattern, -3, -2))) {
+ $pattern = substr($pattern, 0, -2);
+ }
+
+ $this->pattern = $pattern;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Expression/ValueInterface.php b/vendor/symfony/finder/Symfony/Component/Finder/Expression/ValueInterface.php
new file mode 100644
index 0000000..34ce0e7
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Expression/ValueInterface.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Expression;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+interface ValueInterface
+{
+ /**
+ * Renders string representation of expression.
+ *
+ * @return string
+ */
+ public function render();
+
+ /**
+ * Renders string representation of pattern.
+ *
+ * @return string
+ */
+ public function renderPattern();
+
+ /**
+ * Returns value case sensitivity.
+ *
+ * @return bool
+ */
+ public function isCaseSensitive();
+
+ /**
+ * Returns expression type.
+ *
+ * @return int
+ */
+ public function getType();
+
+ /**
+ * @param string $expr
+ *
+ * @return ValueInterface
+ */
+ public function prepend($expr);
+
+ /**
+ * @param string $expr
+ *
+ * @return ValueInterface
+ */
+ public function append($expr);
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Finder.php b/vendor/symfony/finder/Symfony/Component/Finder/Finder.php
new file mode 100644
index 0000000..d3829a2
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Finder.php
@@ -0,0 +1,840 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder;
+
+use Symfony\Component\Finder\Adapter\AdapterInterface;
+use Symfony\Component\Finder\Adapter\GnuFindAdapter;
+use Symfony\Component\Finder\Adapter\BsdFindAdapter;
+use Symfony\Component\Finder\Adapter\PhpAdapter;
+use Symfony\Component\Finder\Comparator\DateComparator;
+use Symfony\Component\Finder\Comparator\NumberComparator;
+use Symfony\Component\Finder\Exception\ExceptionInterface;
+use Symfony\Component\Finder\Iterator\CustomFilterIterator;
+use Symfony\Component\Finder\Iterator\DateRangeFilterIterator;
+use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator;
+use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
+use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
+use Symfony\Component\Finder\Iterator\FilenameFilterIterator;
+use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator;
+use Symfony\Component\Finder\Iterator\SortableIterator;
+
+/**
+ * Finder allows to build rules to find files and directories.
+ *
+ * It is a thin wrapper around several specialized iterator classes.
+ *
+ * All rules may be invoked several times.
+ *
+ * All methods return the current Finder object to allow easy chaining:
+ *
+ * $finder = Finder::create()->files()->name('*.php')->in(__DIR__);
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class Finder implements \IteratorAggregate, \Countable
+{
+ const IGNORE_VCS_FILES = 1;
+ const IGNORE_DOT_FILES = 2;
+
+ private $mode = 0;
+ private $names = array();
+ private $notNames = array();
+ private $exclude = array();
+ private $filters = array();
+ private $depths = array();
+ private $sizes = array();
+ private $followLinks = false;
+ private $sort = false;
+ private $ignore = 0;
+ private $dirs = array();
+ private $dates = array();
+ private $iterators = array();
+ private $contains = array();
+ private $notContains = array();
+ private $adapters = array();
+ private $paths = array();
+ private $notPaths = array();
+ private $ignoreUnreadableDirs = false;
+
+ private static $vcsPatterns = array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg');
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ $this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES;
+
+ $this
+ ->addAdapter(new GnuFindAdapter())
+ ->addAdapter(new BsdFindAdapter())
+ ->addAdapter(new PhpAdapter(), -50)
+ ->setAdapter('php')
+ ;
+ }
+
+ /**
+ * Creates a new Finder.
+ *
+ * @return Finder A new Finder instance
+ *
+ * @api
+ */
+ public static function create()
+ {
+ return new static();
+ }
+
+ /**
+ * Registers a finder engine implementation.
+ *
+ * @param AdapterInterface $adapter An adapter instance
+ * @param int $priority Highest is selected first
+ *
+ * @return Finder The current Finder instance
+ */
+ public function addAdapter(AdapterInterface $adapter, $priority = 0)
+ {
+ $this->adapters[$adapter->getName()] = array(
+ 'adapter' => $adapter,
+ 'priority' => $priority,
+ 'selected' => false,
+ );
+
+ return $this->sortAdapters();
+ }
+
+ /**
+ * Sets the selected adapter to the best one according to the current platform the code is run on.
+ *
+ * @return Finder The current Finder instance
+ */
+ public function useBestAdapter()
+ {
+ $this->resetAdapterSelection();
+
+ return $this->sortAdapters();
+ }
+
+ /**
+ * Selects the adapter to use.
+ *
+ * @param string $name
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return Finder The current Finder instance
+ */
+ public function setAdapter($name)
+ {
+ if (!isset($this->adapters[$name])) {
+ throw new \InvalidArgumentException(sprintf('Adapter "%s" does not exist.', $name));
+ }
+
+ $this->resetAdapterSelection();
+ $this->adapters[$name]['selected'] = true;
+
+ return $this->sortAdapters();
+ }
+
+ /**
+ * Removes all adapters registered in the finder.
+ *
+ * @return Finder The current Finder instance
+ */
+ public function removeAdapters()
+ {
+ $this->adapters = array();
+
+ return $this;
+ }
+
+ /**
+ * Returns registered adapters ordered by priority without extra information.
+ *
+ * @return AdapterInterface[]
+ */
+ public function getAdapters()
+ {
+ return array_values(array_map(function (array $adapter) {
+ return $adapter['adapter'];
+ }, $this->adapters));
+ }
+
+ /**
+ * Restricts the matching to directories only.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @api
+ */
+ public function directories()
+ {
+ $this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES;
+
+ return $this;
+ }
+
+ /**
+ * Restricts the matching to files only.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @api
+ */
+ public function files()
+ {
+ $this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES;
+
+ return $this;
+ }
+
+ /**
+ * Adds tests for the directory depth.
+ *
+ * Usage:
+ *
+ * $finder->depth('> 1') // the Finder will start matching at level 1.
+ * $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point.
+ *
+ * @param int $level The depth level expression
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see DepthRangeFilterIterator
+ * @see NumberComparator
+ *
+ * @api
+ */
+ public function depth($level)
+ {
+ $this->depths[] = new Comparator\NumberComparator($level);
+
+ return $this;
+ }
+
+ /**
+ * Adds tests for file dates (last modified).
+ *
+ * The date must be something that strtotime() is able to parse:
+ *
+ * $finder->date('since yesterday');
+ * $finder->date('until 2 days ago');
+ * $finder->date('> now - 2 hours');
+ * $finder->date('>= 2005-10-15');
+ *
+ * @param string $date A date range string
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see strtotime
+ * @see DateRangeFilterIterator
+ * @see DateComparator
+ *
+ * @api
+ */
+ public function date($date)
+ {
+ $this->dates[] = new Comparator\DateComparator($date);
+
+ return $this;
+ }
+
+ /**
+ * Adds rules that files must match.
+ *
+ * You can use patterns (delimited with / sign), globs or simple strings.
+ *
+ * $finder->name('*.php')
+ * $finder->name('/\.php$/') // same as above
+ * $finder->name('test.php')
+ *
+ * @param string $pattern A pattern (a regexp, a glob, or a string)
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see FilenameFilterIterator
+ *
+ * @api
+ */
+ public function name($pattern)
+ {
+ $this->names[] = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Adds rules that files must not match.
+ *
+ * @param string $pattern A pattern (a regexp, a glob, or a string)
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see FilenameFilterIterator
+ *
+ * @api
+ */
+ public function notName($pattern)
+ {
+ $this->notNames[] = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Adds tests that file contents must match.
+ *
+ * Strings or PCRE patterns can be used:
+ *
+ * $finder->contains('Lorem ipsum')
+ * $finder->contains('/Lorem ipsum/i')
+ *
+ * @param string $pattern A pattern (string or regexp)
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see FilecontentFilterIterator
+ */
+ public function contains($pattern)
+ {
+ $this->contains[] = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Adds tests that file contents must not match.
+ *
+ * Strings or PCRE patterns can be used:
+ *
+ * $finder->notContains('Lorem ipsum')
+ * $finder->notContains('/Lorem ipsum/i')
+ *
+ * @param string $pattern A pattern (string or regexp)
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see FilecontentFilterIterator
+ */
+ public function notContains($pattern)
+ {
+ $this->notContains[] = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Adds rules that filenames must match.
+ *
+ * You can use patterns (delimited with / sign) or simple strings.
+ *
+ * $finder->path('some/special/dir')
+ * $finder->path('/some\/special\/dir/') // same as above
+ *
+ * Use only / as dirname separator.
+ *
+ * @param string $pattern A pattern (a regexp or a string)
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see FilenameFilterIterator
+ */
+ public function path($pattern)
+ {
+ $this->paths[] = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Adds rules that filenames must not match.
+ *
+ * You can use patterns (delimited with / sign) or simple strings.
+ *
+ * $finder->notPath('some/special/dir')
+ * $finder->notPath('/some\/special\/dir/') // same as above
+ *
+ * Use only / as dirname separator.
+ *
+ * @param string $pattern A pattern (a regexp or a string)
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see FilenameFilterIterator
+ */
+ public function notPath($pattern)
+ {
+ $this->notPaths[] = $pattern;
+
+ return $this;
+ }
+
+ /**
+ * Adds tests for file sizes.
+ *
+ * $finder->size('> 10K');
+ * $finder->size('<= 1Ki');
+ * $finder->size(4);
+ *
+ * @param string $size A size range string
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see SizeRangeFilterIterator
+ * @see NumberComparator
+ *
+ * @api
+ */
+ public function size($size)
+ {
+ $this->sizes[] = new Comparator\NumberComparator($size);
+
+ return $this;
+ }
+
+ /**
+ * Excludes directories.
+ *
+ * @param string|array $dirs A directory path or an array of directories
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see ExcludeDirectoryFilterIterator
+ *
+ * @api
+ */
+ public function exclude($dirs)
+ {
+ $this->exclude = array_merge($this->exclude, (array) $dirs);
+
+ return $this;
+ }
+
+ /**
+ * Excludes "hidden" directories and files (starting with a dot).
+ *
+ * @param bool $ignoreDotFiles Whether to exclude "hidden" files or not
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see ExcludeDirectoryFilterIterator
+ *
+ * @api
+ */
+ public function ignoreDotFiles($ignoreDotFiles)
+ {
+ if ($ignoreDotFiles) {
+ $this->ignore |= static::IGNORE_DOT_FILES;
+ } else {
+ $this->ignore &= ~static::IGNORE_DOT_FILES;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Forces the finder to ignore version control directories.
+ *
+ * @param bool $ignoreVCS Whether to exclude VCS files or not
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see ExcludeDirectoryFilterIterator
+ *
+ * @api
+ */
+ public function ignoreVCS($ignoreVCS)
+ {
+ if ($ignoreVCS) {
+ $this->ignore |= static::IGNORE_VCS_FILES;
+ } else {
+ $this->ignore &= ~static::IGNORE_VCS_FILES;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds VCS patterns.
+ *
+ * @see ignoreVCS()
+ *
+ * @param string|string[] $pattern VCS patterns to ignore
+ */
+ public static function addVCSPattern($pattern)
+ {
+ foreach ((array) $pattern as $p) {
+ self::$vcsPatterns[] = $p;
+ }
+
+ self::$vcsPatterns = array_unique(self::$vcsPatterns);
+ }
+
+ /**
+ * Sorts files and directories by an anonymous function.
+ *
+ * The anonymous function receives two \SplFileInfo instances to compare.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @param \Closure $closure An anonymous function
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see SortableIterator
+ *
+ * @api
+ */
+ public function sort(\Closure $closure)
+ {
+ $this->sort = $closure;
+
+ return $this;
+ }
+
+ /**
+ * Sorts files and directories by name.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see SortableIterator
+ *
+ * @api
+ */
+ public function sortByName()
+ {
+ $this->sort = Iterator\SortableIterator::SORT_BY_NAME;
+
+ return $this;
+ }
+
+ /**
+ * Sorts files and directories by type (directories before files), then by name.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see SortableIterator
+ *
+ * @api
+ */
+ public function sortByType()
+ {
+ $this->sort = Iterator\SortableIterator::SORT_BY_TYPE;
+
+ return $this;
+ }
+
+ /**
+ * Sorts files and directories by the last accessed time.
+ *
+ * This is the time that the file was last accessed, read or written to.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see SortableIterator
+ *
+ * @api
+ */
+ public function sortByAccessedTime()
+ {
+ $this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME;
+
+ return $this;
+ }
+
+ /**
+ * Sorts files and directories by the last inode changed time.
+ *
+ * This is the time that the inode information was last modified (permissions, owner, group or other metadata).
+ *
+ * On Windows, since inode is not available, changed time is actually the file creation time.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see SortableIterator
+ *
+ * @api
+ */
+ public function sortByChangedTime()
+ {
+ $this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME;
+
+ return $this;
+ }
+
+ /**
+ * Sorts files and directories by the last modified time.
+ *
+ * This is the last time the actual contents of the file were last modified.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see SortableIterator
+ *
+ * @api
+ */
+ public function sortByModifiedTime()
+ {
+ $this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME;
+
+ return $this;
+ }
+
+ /**
+ * Filters the iterator with an anonymous function.
+ *
+ * The anonymous function receives a \SplFileInfo and must return false
+ * to remove files.
+ *
+ * @param \Closure $closure An anonymous function
+ *
+ * @return Finder The current Finder instance
+ *
+ * @see CustomFilterIterator
+ *
+ * @api
+ */
+ public function filter(\Closure $closure)
+ {
+ $this->filters[] = $closure;
+
+ return $this;
+ }
+
+ /**
+ * Forces the following of symlinks.
+ *
+ * @return Finder The current Finder instance
+ *
+ * @api
+ */
+ public function followLinks()
+ {
+ $this->followLinks = true;
+
+ return $this;
+ }
+
+ /**
+ * Tells finder to ignore unreadable directories.
+ *
+ * By default, scanning unreadable directories content throws an AccessDeniedException.
+ *
+ * @param bool $ignore
+ *
+ * @return Finder The current Finder instance
+ */
+ public function ignoreUnreadableDirs($ignore = true)
+ {
+ $this->ignoreUnreadableDirs = (bool) $ignore;
+
+ return $this;
+ }
+
+ /**
+ * Searches files and directories which match defined rules.
+ *
+ * @param string|array $dirs A directory path or an array of directories
+ *
+ * @return Finder The current Finder instance
+ *
+ * @throws \InvalidArgumentException if one of the directories does not exist
+ *
+ * @api
+ */
+ public function in($dirs)
+ {
+ $resolvedDirs = array();
+
+ foreach ((array) $dirs as $dir) {
+ if (is_dir($dir)) {
+ $resolvedDirs[] = $dir;
+ } elseif ($glob = glob($dir, GLOB_BRACE | GLOB_ONLYDIR)) {
+ $resolvedDirs = array_merge($resolvedDirs, $glob);
+ } else {
+ throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $dir));
+ }
+ }
+
+ $this->dirs = array_merge($this->dirs, $resolvedDirs);
+
+ return $this;
+ }
+
+ /**
+ * Returns an Iterator for the current Finder configuration.
+ *
+ * This method implements the IteratorAggregate interface.
+ *
+ * @return \Iterator An iterator
+ *
+ * @throws \LogicException if the in() method has not been called
+ */
+ public function getIterator()
+ {
+ if (0 === count($this->dirs) && 0 === count($this->iterators)) {
+ throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.');
+ }
+
+ if (1 === count($this->dirs) && 0 === count($this->iterators)) {
+ return $this->searchInDirectory($this->dirs[0]);
+ }
+
+ $iterator = new \AppendIterator();
+ foreach ($this->dirs as $dir) {
+ $iterator->append($this->searchInDirectory($dir));
+ }
+
+ foreach ($this->iterators as $it) {
+ $iterator->append($it);
+ }
+
+ return $iterator;
+ }
+
+ /**
+ * Appends an existing set of files/directories to the finder.
+ *
+ * The set can be another Finder, an Iterator, an IteratorAggregate, or even a plain array.
+ *
+ * @param mixed $iterator
+ *
+ * @return Finder The finder
+ *
+ * @throws \InvalidArgumentException When the given argument is not iterable.
+ */
+ public function append($iterator)
+ {
+ if ($iterator instanceof \IteratorAggregate) {
+ $this->iterators[] = $iterator->getIterator();
+ } elseif ($iterator instanceof \Iterator) {
+ $this->iterators[] = $iterator;
+ } elseif ($iterator instanceof \Traversable || is_array($iterator)) {
+ $it = new \ArrayIterator();
+ foreach ($iterator as $file) {
+ $it->append($file instanceof \SplFileInfo ? $file : new \SplFileInfo($file));
+ }
+ $this->iterators[] = $it;
+ } else {
+ throw new \InvalidArgumentException('Finder::append() method wrong argument type.');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Counts all the results collected by the iterators.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return iterator_count($this->getIterator());
+ }
+
+ /**
+ * @return Finder The current Finder instance
+ */
+ private function sortAdapters()
+ {
+ uasort($this->adapters, function (array $a, array $b) {
+ if ($a['selected'] || $b['selected']) {
+ return $a['selected'] ? -1 : 1;
+ }
+
+ return $a['priority'] > $b['priority'] ? -1 : 1;
+ });
+
+ return $this;
+ }
+
+ /**
+ * @param $dir
+ *
+ * @return \Iterator
+ *
+ * @throws \RuntimeException When none of the adapters are supported
+ */
+ private function searchInDirectory($dir)
+ {
+ if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) {
+ $this->exclude = array_merge($this->exclude, self::$vcsPatterns);
+ }
+
+ if (static::IGNORE_DOT_FILES === (static::IGNORE_DOT_FILES & $this->ignore)) {
+ $this->notPaths[] = '#(^|/)\..+(/|$)#';
+ }
+
+ foreach ($this->adapters as $adapter) {
+ if ($adapter['adapter']->isSupported()) {
+ try {
+ return $this
+ ->buildAdapter($adapter['adapter'])
+ ->searchInDirectory($dir);
+ } catch (ExceptionInterface $e) {
+ }
+ }
+ }
+
+ throw new \RuntimeException('No supported adapter found.');
+ }
+
+ /**
+ * @param AdapterInterface $adapter
+ *
+ * @return AdapterInterface
+ */
+ private function buildAdapter(AdapterInterface $adapter)
+ {
+ return $adapter
+ ->setFollowLinks($this->followLinks)
+ ->setDepths($this->depths)
+ ->setMode($this->mode)
+ ->setExclude($this->exclude)
+ ->setNames($this->names)
+ ->setNotNames($this->notNames)
+ ->setContains($this->contains)
+ ->setNotContains($this->notContains)
+ ->setSizes($this->sizes)
+ ->setDates($this->dates)
+ ->setFilters($this->filters)
+ ->setSort($this->sort)
+ ->setPath($this->paths)
+ ->setNotPath($this->notPaths)
+ ->ignoreUnreadableDirs($this->ignoreUnreadableDirs);
+ }
+
+ /**
+ * Unselects all adapters.
+ */
+ private function resetAdapterSelection()
+ {
+ $this->adapters = array_map(function (array $properties) {
+ $properties['selected'] = false;
+
+ return $properties;
+ }, $this->adapters);
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Glob.php b/vendor/symfony/finder/Symfony/Component/Finder/Glob.php
new file mode 100644
index 0000000..c2030c9
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Glob.php
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder;
+
+/**
+ * Glob matches globbing patterns against text.
+ *
+ * if match_glob("foo.*", "foo.bar") echo "matched\n";
+ *
+ * // prints foo.bar and foo.baz
+ * $regex = glob_to_regex("foo.*");
+ * for (array('foo.bar', 'foo.baz', 'foo', 'bar') as $t)
+ * {
+ * if (/$regex/) echo "matched: $car\n";
+ * }
+ *
+ * Glob implements glob(3) style matching that can be used to match
+ * against text, rather than fetching names from a filesystem.
+ *
+ * Based on the Perl Text::Glob module.
+ *
+ * @author Fabien Potencier <fabien@symfony.com> PHP port
+ * @author Richard Clamp <richardc@unixbeard.net> Perl version
+ * @copyright 2004-2005 Fabien Potencier <fabien@symfony.com>
+ * @copyright 2002 Richard Clamp <richardc@unixbeard.net>
+ */
+class Glob
+{
+ /**
+ * Returns a regexp which is the equivalent of the glob pattern.
+ *
+ * @param string $glob The glob pattern
+ * @param bool $strictLeadingDot
+ * @param bool $strictWildcardSlash
+ *
+ * @return string regex The regexp
+ */
+ public static function toRegex($glob, $strictLeadingDot = true, $strictWildcardSlash = true)
+ {
+ $firstByte = true;
+ $escaping = false;
+ $inCurlies = 0;
+ $regex = '';
+ $sizeGlob = strlen($glob);
+ for ($i = 0; $i < $sizeGlob; $i++) {
+ $car = $glob[$i];
+ if ($firstByte) {
+ if ($strictLeadingDot && '.' !== $car) {
+ $regex .= '(?=[^\.])';
+ }
+
+ $firstByte = false;
+ }
+
+ if ('/' === $car) {
+ $firstByte = true;
+ }
+
+ if ('.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) {
+ $regex .= "\\$car";
+ } elseif ('*' === $car) {
+ $regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*');
+ } elseif ('?' === $car) {
+ $regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.');
+ } elseif ('{' === $car) {
+ $regex .= $escaping ? '\\{' : '(';
+ if (!$escaping) {
+ ++$inCurlies;
+ }
+ } elseif ('}' === $car && $inCurlies) {
+ $regex .= $escaping ? '}' : ')';
+ if (!$escaping) {
+ --$inCurlies;
+ }
+ } elseif (',' === $car && $inCurlies) {
+ $regex .= $escaping ? ',' : '|';
+ } elseif ('\\' === $car) {
+ if ($escaping) {
+ $regex .= '\\\\';
+ $escaping = false;
+ } else {
+ $escaping = true;
+ }
+
+ continue;
+ } else {
+ $regex .= $car;
+ }
+ $escaping = false;
+ }
+
+ return '#^'.$regex.'$#';
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php
new file mode 100644
index 0000000..24b15d9
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * CustomFilterIterator filters files by applying anonymous functions.
+ *
+ * The anonymous function receives a \SplFileInfo and must return false
+ * to remove files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class CustomFilterIterator extends FilterIterator
+{
+ private $filters = array();
+
+ /**
+ * Constructor.
+ *
+ * @param \Iterator $iterator The Iterator to filter
+ * @param array $filters An array of PHP callbacks
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function __construct(\Iterator $iterator, array $filters)
+ {
+ foreach ($filters as $filter) {
+ if (!is_callable($filter)) {
+ throw new \InvalidArgumentException('Invalid PHP callback.');
+ }
+ }
+ $this->filters = $filters;
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $fileinfo = $this->current();
+
+ foreach ($this->filters as $filter) {
+ if (false === call_user_func($filter, $fileinfo)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php
new file mode 100644
index 0000000..4d5ef9a
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+use Symfony\Component\Finder\Comparator\DateComparator;
+
+/**
+ * DateRangeFilterIterator filters out files that are not in the given date range (last modified dates).
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class DateRangeFilterIterator extends FilterIterator
+{
+ private $comparators = array();
+
+ /**
+ * Constructor.
+ *
+ * @param \Iterator $iterator The Iterator to filter
+ * @param DateComparator[] $comparators An array of DateComparator instances
+ */
+ public function __construct(\Iterator $iterator, array $comparators)
+ {
+ $this->comparators = $comparators;
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $fileinfo = $this->current();
+
+ if (!file_exists($fileinfo->getRealPath())) {
+ return false;
+ }
+
+ $filedate = $fileinfo->getMTime();
+ foreach ($this->comparators as $compare) {
+ if (!$compare->test($filedate)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php
new file mode 100644
index 0000000..f78c71e
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * DepthRangeFilterIterator limits the directory depth.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class DepthRangeFilterIterator extends FilterIterator
+{
+ private $minDepth = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param \RecursiveIteratorIterator $iterator The Iterator to filter
+ * @param int $minDepth The min depth
+ * @param int $maxDepth The max depth
+ */
+ public function __construct(\RecursiveIteratorIterator $iterator, $minDepth = 0, $maxDepth = PHP_INT_MAX)
+ {
+ $this->minDepth = $minDepth;
+ $iterator->setMaxDepth(PHP_INT_MAX === $maxDepth ? -1 : $maxDepth);
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ return $this->getInnerIterator()->getDepth() >= $this->minDepth;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php
new file mode 100644
index 0000000..1ddde85
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * ExcludeDirectoryFilterIterator filters out directories.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ExcludeDirectoryFilterIterator extends FilterIterator
+{
+ private $patterns = array();
+
+ /**
+ * Constructor.
+ *
+ * @param \Iterator $iterator The Iterator to filter
+ * @param array $directories An array of directories to exclude
+ */
+ public function __construct(\Iterator $iterator, array $directories)
+ {
+ foreach ($directories as $directory) {
+ $this->patterns[] = '#(^|/)'.preg_quote($directory, '#').'(/|$)#';
+ }
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath();
+ $path = strtr($path, '\\', '/');
+ foreach ($this->patterns as $pattern) {
+ if (preg_match($pattern, $path)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php
new file mode 100644
index 0000000..4da2f5b
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php
@@ -0,0 +1,131 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+use Symfony\Component\Finder\SplFileInfo;
+
+/**
+ * Iterate over shell command result.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class FilePathsIterator extends \ArrayIterator
+{
+ /**
+ * @var string
+ */
+ private $baseDir;
+
+ /**
+ * @var int
+ */
+ private $baseDirLength;
+
+ /**
+ * @var string
+ */
+ private $subPath;
+
+ /**
+ * @var string
+ */
+ private $subPathname;
+
+ /**
+ * @var SplFileInfo
+ */
+ private $current;
+
+ /**
+ * @param array $paths List of paths returned by shell command
+ * @param string $baseDir Base dir for relative path building
+ */
+ public function __construct(array $paths, $baseDir)
+ {
+ $this->baseDir = $baseDir;
+ $this->baseDirLength = strlen($baseDir);
+
+ parent::__construct($paths);
+ }
+
+ /**
+ * @param string $name
+ * @param array $arguments
+ *
+ * @return mixed
+ */
+ public function __call($name, array $arguments)
+ {
+ return call_user_func_array(array($this->current(), $name), $arguments);
+ }
+
+ /**
+ * Return an instance of SplFileInfo with support for relative paths.
+ *
+ * @return SplFileInfo File information
+ */
+ public function current()
+ {
+ return $this->current;
+ }
+
+ /**
+ * @return string
+ */
+ public function key()
+ {
+ return $this->current->getPathname();
+ }
+
+ public function next()
+ {
+ parent::next();
+ $this->buildProperties();
+ }
+
+ public function rewind()
+ {
+ parent::rewind();
+ $this->buildProperties();
+ }
+
+ /**
+ * @return string
+ */
+ public function getSubPath()
+ {
+ return $this->subPath;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSubPathname()
+ {
+ return $this->subPathname;
+ }
+
+ private function buildProperties()
+ {
+ $absolutePath = parent::current();
+
+ if ($this->baseDir === substr($absolutePath, 0, $this->baseDirLength)) {
+ $this->subPathname = ltrim(substr($absolutePath, $this->baseDirLength), '/\\');
+ $dir = dirname($this->subPathname);
+ $this->subPath = '.' === $dir ? '' : $dir;
+ } else {
+ $this->subPath = $this->subPathname = '';
+ }
+
+ $this->current = new SplFileInfo(parent::current(), $this->subPath, $this->subPathname);
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php
new file mode 100644
index 0000000..f50fd82
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * FileTypeFilterIterator only keeps files, directories, or both.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class FileTypeFilterIterator extends FilterIterator
+{
+ const ONLY_FILES = 1;
+ const ONLY_DIRECTORIES = 2;
+
+ private $mode;
+
+ /**
+ * Constructor.
+ *
+ * @param \Iterator $iterator The Iterator to filter
+ * @param int $mode The mode (self::ONLY_FILES or self::ONLY_DIRECTORIES)
+ */
+ public function __construct(\Iterator $iterator, $mode)
+ {
+ $this->mode = $mode;
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $fileinfo = $this->current();
+ if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) {
+ return false;
+ } elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php
new file mode 100644
index 0000000..28cf770
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * FilecontentFilterIterator filters files by their contents using patterns (regexps or strings).
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Włodzimierz Gajda <gajdaw@gajdaw.pl>
+ */
+class FilecontentFilterIterator extends MultiplePcreFilterIterator
+{
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ if (!$this->matchRegexps && !$this->noMatchRegexps) {
+ return true;
+ }
+
+ $fileinfo = $this->current();
+
+ if ($fileinfo->isDir() || !$fileinfo->isReadable()) {
+ return false;
+ }
+
+ $content = $fileinfo->getContents();
+ if (!$content) {
+ return false;
+ }
+
+ // should at least not match one rule to exclude
+ foreach ($this->noMatchRegexps as $regex) {
+ if (preg_match($regex, $content)) {
+ return false;
+ }
+ }
+
+ // should at least match one rule
+ $match = true;
+ if ($this->matchRegexps) {
+ $match = false;
+ foreach ($this->matchRegexps as $regex) {
+ if (preg_match($regex, $content)) {
+ return true;
+ }
+ }
+ }
+
+ return $match;
+ }
+
+ /**
+ * Converts string to regexp if necessary.
+ *
+ * @param string $str Pattern: string or regexp
+ *
+ * @return string regexp corresponding to a given string or regexp
+ */
+ protected function toRegex($str)
+ {
+ return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php
new file mode 100644
index 0000000..f1cd391
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+use Symfony\Component\Finder\Expression\Expression;
+
+/**
+ * FilenameFilterIterator filters files by patterns (a regexp, a glob, or a string).
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class FilenameFilterIterator extends MultiplePcreFilterIterator
+{
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $filename = $this->current()->getFilename();
+
+ // should at least not match one rule to exclude
+ foreach ($this->noMatchRegexps as $regex) {
+ if (preg_match($regex, $filename)) {
+ return false;
+ }
+ }
+
+ // should at least match one rule
+ $match = true;
+ if ($this->matchRegexps) {
+ $match = false;
+ foreach ($this->matchRegexps as $regex) {
+ if (preg_match($regex, $filename)) {
+ return true;
+ }
+ }
+ }
+
+ return $match;
+ }
+
+ /**
+ * Converts glob to regexp.
+ *
+ * PCRE patterns are left unchanged.
+ * Glob strings are transformed with Glob::toRegex().
+ *
+ * @param string $str Pattern: glob or regexp
+ *
+ * @return string regexp corresponding to a given glob or regexp
+ */
+ protected function toRegex($str)
+ {
+ return Expression::create($str)->getRegex()->render();
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.php
new file mode 100644
index 0000000..f4da44c
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * This iterator just overrides the rewind method in order to correct a PHP bug.
+ *
+ * @see https://bugs.php.net/bug.php?id=49104
+ *
+ * @author Alex Bogomazov
+ */
+abstract class FilterIterator extends \FilterIterator
+{
+ /**
+ * This is a workaround for the problem with \FilterIterator leaving inner \FilesystemIterator in wrong state after
+ * rewind in some cases.
+ *
+ * @see FilterIterator::rewind()
+ */
+ public function rewind()
+ {
+ $iterator = $this;
+ while ($iterator instanceof \OuterIterator) {
+ $innerIterator = $iterator->getInnerIterator();
+
+ if ($innerIterator instanceof RecursiveDirectoryIterator) {
+ if ($innerIterator->isRewindable()) {
+ $innerIterator->next();
+ $innerIterator->rewind();
+ }
+ } elseif ($iterator->getInnerIterator() instanceof \FilesystemIterator) {
+ $iterator->getInnerIterator()->next();
+ $iterator->getInnerIterator()->rewind();
+ }
+ $iterator = $iterator->getInnerIterator();
+ }
+
+ parent::rewind();
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php
new file mode 100644
index 0000000..068a7ef
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+use Symfony\Component\Finder\Expression\Expression;
+
+/**
+ * MultiplePcreFilterIterator filters files using patterns (regexps, globs or strings).
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class MultiplePcreFilterIterator extends FilterIterator
+{
+ protected $matchRegexps = array();
+ protected $noMatchRegexps = array();
+
+ /**
+ * Constructor.
+ *
+ * @param \Iterator $iterator The Iterator to filter
+ * @param array $matchPatterns An array of patterns that need to match
+ * @param array $noMatchPatterns An array of patterns that need to not match
+ */
+ public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns)
+ {
+ foreach ($matchPatterns as $pattern) {
+ $this->matchRegexps[] = $this->toRegex($pattern);
+ }
+
+ foreach ($noMatchPatterns as $pattern) {
+ $this->noMatchRegexps[] = $this->toRegex($pattern);
+ }
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Checks whether the string is a regex.
+ *
+ * @param string $str
+ *
+ * @return bool Whether the given string is a regex
+ */
+ protected function isRegex($str)
+ {
+ return Expression::create($str)->isRegex();
+ }
+
+ /**
+ * Converts string into regexp.
+ *
+ * @param string $str Pattern
+ *
+ * @return string regexp corresponding to a given string
+ */
+ abstract protected function toRegex($str);
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.php
new file mode 100644
index 0000000..2bb8ebd
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * PathFilterIterator filters files by path patterns (e.g. some/special/dir).
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Włodzimierz Gajda <gajdaw@gajdaw.pl>
+ */
+class PathFilterIterator extends MultiplePcreFilterIterator
+{
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $filename = $this->current()->getRelativePathname();
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $filename = strtr($filename, '\\', '/');
+ }
+
+ // should at least not match one rule to exclude
+ foreach ($this->noMatchRegexps as $regex) {
+ if (preg_match($regex, $filename)) {
+ return false;
+ }
+ }
+
+ // should at least match one rule
+ $match = true;
+ if ($this->matchRegexps) {
+ $match = false;
+ foreach ($this->matchRegexps as $regex) {
+ if (preg_match($regex, $filename)) {
+ return true;
+ }
+ }
+ }
+
+ return $match;
+ }
+
+ /**
+ * Converts strings to regexp.
+ *
+ * PCRE patterns are left unchanged.
+ *
+ * Default conversion:
+ * 'lorem/ipsum/dolor' ==> 'lorem\/ipsum\/dolor/'
+ *
+ * Use only / as directory separator (on Windows also).
+ *
+ * @param string $str Pattern: regexp or dirname.
+ *
+ * @return string regexp corresponding to a given string or regexp
+ */
+ protected function toRegex($str)
+ {
+ return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php
new file mode 100644
index 0000000..af824d0
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+use Symfony\Component\Finder\Exception\AccessDeniedException;
+use Symfony\Component\Finder\SplFileInfo;
+
+/**
+ * Extends the \RecursiveDirectoryIterator to support relative paths.
+ *
+ * @author Victor Berchet <victor@suumit.com>
+ */
+class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
+{
+ /**
+ * @var bool
+ */
+ private $ignoreUnreadableDirs;
+
+ /**
+ * @var bool
+ */
+ private $rewindable;
+
+ /**
+ * Constructor.
+ *
+ * @param string $path
+ * @param int $flags
+ * @param bool $ignoreUnreadableDirs
+ *
+ * @throws \RuntimeException
+ */
+ public function __construct($path, $flags, $ignoreUnreadableDirs = false)
+ {
+ if ($flags & (self::CURRENT_AS_PATHNAME | self::CURRENT_AS_SELF)) {
+ throw new \RuntimeException('This iterator only support returning current as fileinfo.');
+ }
+
+ parent::__construct($path, $flags);
+ $this->ignoreUnreadableDirs = $ignoreUnreadableDirs;
+ }
+
+ /**
+ * Return an instance of SplFileInfo with support for relative paths.
+ *
+ * @return SplFileInfo File information
+ */
+ public function current()
+ {
+ return new SplFileInfo(parent::current()->getPathname(), $this->getSubPath(), $this->getSubPathname());
+ }
+
+ /**
+ * @return \RecursiveIterator
+ *
+ * @throws AccessDeniedException
+ */
+ public function getChildren()
+ {
+ try {
+ $children = parent::getChildren();
+
+ if ($children instanceof self) {
+ // parent method will call the constructor with default arguments, so unreadable dirs won't be ignored anymore
+ $children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs;
+ }
+
+ return $children;
+ } catch (\UnexpectedValueException $e) {
+ if ($this->ignoreUnreadableDirs) {
+ // If directory is unreadable and finder is set to ignore it, a fake empty content is returned.
+ return new \RecursiveArrayIterator(array());
+ } else {
+ throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+ }
+
+ /**
+ * Do nothing for non rewindable stream.
+ */
+ public function rewind()
+ {
+ if (false === $this->isRewindable()) {
+ return;
+ }
+
+ // @see https://bugs.php.net/bug.php?id=49104
+ parent::next();
+
+ parent::rewind();
+ }
+
+ /**
+ * Checks if the stream is rewindable.
+ *
+ * @return bool true when the stream is rewindable, false otherwise
+ */
+ public function isRewindable()
+ {
+ if (null !== $this->rewindable) {
+ return $this->rewindable;
+ }
+
+ if (false !== $stream = @opendir($this->getPath())) {
+ $infos = stream_get_meta_data($stream);
+ closedir($stream);
+
+ if ($infos['seekable']) {
+ return $this->rewindable = true;
+ }
+ }
+
+ return $this->rewindable = false;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php
new file mode 100644
index 0000000..3d3140a
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+use Symfony\Component\Finder\Comparator\NumberComparator;
+
+/**
+ * SizeRangeFilterIterator filters out files that are not in the given size range.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class SizeRangeFilterIterator extends FilterIterator
+{
+ private $comparators = array();
+
+ /**
+ * Constructor.
+ *
+ * @param \Iterator $iterator The Iterator to filter
+ * @param NumberComparator[] $comparators An array of NumberComparator instances
+ */
+ public function __construct(\Iterator $iterator, array $comparators)
+ {
+ $this->comparators = $comparators;
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Filters the iterator values.
+ *
+ * @return bool true if the value should be kept, false otherwise
+ */
+ public function accept()
+ {
+ $fileinfo = $this->current();
+ if (!$fileinfo->isFile()) {
+ return true;
+ }
+
+ $filesize = $fileinfo->getSize();
+ foreach ($this->comparators as $compare) {
+ if (!$compare->test($filesize)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.php
new file mode 100644
index 0000000..b32ac8d
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Iterator;
+
+/**
+ * SortableIterator applies a sort on a given Iterator.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class SortableIterator implements \IteratorAggregate
+{
+ const SORT_BY_NAME = 1;
+ const SORT_BY_TYPE = 2;
+ const SORT_BY_ACCESSED_TIME = 3;
+ const SORT_BY_CHANGED_TIME = 4;
+ const SORT_BY_MODIFIED_TIME = 5;
+
+ private $iterator;
+ private $sort;
+
+ /**
+ * Constructor.
+ *
+ * @param \Traversable $iterator The Iterator to filter
+ * @param int|callable $sort The sort type (SORT_BY_NAME, SORT_BY_TYPE, or a PHP callback)
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function __construct(\Traversable $iterator, $sort)
+ {
+ $this->iterator = $iterator;
+
+ if (self::SORT_BY_NAME === $sort) {
+ $this->sort = function ($a, $b) {
+ return strcmp($a->getRealpath(), $b->getRealpath());
+ };
+ } elseif (self::SORT_BY_TYPE === $sort) {
+ $this->sort = function ($a, $b) {
+ if ($a->isDir() && $b->isFile()) {
+ return -1;
+ } elseif ($a->isFile() && $b->isDir()) {
+ return 1;
+ }
+
+ return strcmp($a->getRealpath(), $b->getRealpath());
+ };
+ } elseif (self::SORT_BY_ACCESSED_TIME === $sort) {
+ $this->sort = function ($a, $b) {
+ return ($a->getATime() - $b->getATime());
+ };
+ } elseif (self::SORT_BY_CHANGED_TIME === $sort) {
+ $this->sort = function ($a, $b) {
+ return ($a->getCTime() - $b->getCTime());
+ };
+ } elseif (self::SORT_BY_MODIFIED_TIME === $sort) {
+ $this->sort = function ($a, $b) {
+ return ($a->getMTime() - $b->getMTime());
+ };
+ } elseif (is_callable($sort)) {
+ $this->sort = $sort;
+ } else {
+ throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
+ }
+ }
+
+ public function getIterator()
+ {
+ $array = iterator_to_array($this->iterator, true);
+ uasort($array, $this->sort);
+
+ return new \ArrayIterator($array);
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/LICENSE b/vendor/symfony/finder/Symfony/Component/Finder/LICENSE
new file mode 100644
index 0000000..43028bc
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2015 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/vendor/symfony/finder/Symfony/Component/Finder/README.md b/vendor/symfony/finder/Symfony/Component/Finder/README.md
new file mode 100644
index 0000000..413cdf5
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/README.md
@@ -0,0 +1,53 @@
+Finder Component
+================
+
+Finder finds files and directories via an intuitive fluent interface.
+
+```php
+use Symfony\Component\Finder\Finder;
+
+$finder = new Finder();
+
+$iterator = $finder
+ ->files()
+ ->name('*.php')
+ ->depth(0)
+ ->size('>= 1K')
+ ->in(__DIR__);
+
+foreach ($iterator as $file) {
+ print $file->getRealpath()."\n";
+}
+```
+
+The iterator returns instances of [Symfony\Component\Finder\SplFileInfo\SplFileInfo][1].
+Besides the build-in methods inherited from [\SplFileInfo][2] (`getPerms()`, `getSize()`, ...),
+you can also use `getRelativePath()` and `getRelativePathname()`. Read the
+[official documentation][3] for more information.
+
+But you can also use it to find files stored remotely like in this example where
+we are looking for files on Amazon S3:
+
+```php
+$s3 = new \Zend_Service_Amazon_S3($key, $secret);
+$s3->registerStreamWrapper("s3");
+
+$finder = new Finder();
+$finder->name('photos*')->size('< 100K')->date('since 1 hour ago');
+foreach ($finder->in('s3://bucket-name') as $file) {
+ print $file->getFilename()."\n";
+}
+```
+
+Resources
+---------
+
+You can run the unit tests with the following command:
+
+ $ cd path/to/Symfony/Component/Finder/
+ $ composer install
+ $ phpunit
+
+[1]: http://api.symfony.com/2.5/Symfony/Component/Finder/SplFileInfo.html
+[2]: http://php.net/splfileinfo
+[3]: http://symfony.com/doc/current/components/finder.html#usage
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Shell/Command.php b/vendor/symfony/finder/Symfony/Component/Finder/Shell/Command.php
new file mode 100644
index 0000000..2f0c450
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Shell/Command.php
@@ -0,0 +1,294 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Shell;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class Command
+{
+ /**
+ * @var Command|null
+ */
+ private $parent;
+
+ /**
+ * @var array
+ */
+ private $bits = array();
+
+ /**
+ * @var array
+ */
+ private $labels = array();
+
+ /**
+ * @var \Closure|null
+ */
+ private $errorHandler;
+
+ /**
+ * Constructor.
+ *
+ * @param Command|null $parent Parent command
+ */
+ public function __construct(Command $parent = null)
+ {
+ $this->parent = $parent;
+ }
+
+ /**
+ * Returns command as string.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->join();
+ }
+
+ /**
+ * Creates a new Command instance.
+ *
+ * @param Command|null $parent Parent command
+ *
+ * @return Command New Command instance
+ */
+ public static function create(Command $parent = null)
+ {
+ return new self($parent);
+ }
+
+ /**
+ * Escapes special chars from input.
+ *
+ * @param string $input A string to escape
+ *
+ * @return string The escaped string
+ */
+ public static function escape($input)
+ {
+ return escapeshellcmd($input);
+ }
+
+ /**
+ * Quotes input.
+ *
+ * @param string $input An argument string
+ *
+ * @return string The quoted string
+ */
+ public static function quote($input)
+ {
+ return escapeshellarg($input);
+ }
+
+ /**
+ * Appends a string or a Command instance.
+ *
+ * @param string|Command $bit
+ *
+ * @return Command The current Command instance
+ */
+ public function add($bit)
+ {
+ $this->bits[] = $bit;
+
+ return $this;
+ }
+
+ /**
+ * Prepends a string or a command instance.
+ *
+ * @param string|Command $bit
+ *
+ * @return Command The current Command instance
+ */
+ public function top($bit)
+ {
+ array_unshift($this->bits, $bit);
+
+ foreach ($this->labels as $label => $index) {
+ $this->labels[$label] += 1;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Appends an argument, will be quoted.
+ *
+ * @param string $arg
+ *
+ * @return Command The current Command instance
+ */
+ public function arg($arg)
+ {
+ $this->bits[] = self::quote($arg);
+
+ return $this;
+ }
+
+ /**
+ * Appends escaped special command chars.
+ *
+ * @param string $esc
+ *
+ * @return Command The current Command instance
+ */
+ public function cmd($esc)
+ {
+ $this->bits[] = self::escape($esc);
+
+ return $this;
+ }
+
+ /**
+ * Inserts a labeled command to feed later.
+ *
+ * @param string $label The unique label
+ *
+ * @return Command The current Command instance
+ *
+ * @throws \RuntimeException If label already exists
+ */
+ public function ins($label)
+ {
+ if (isset($this->labels[$label])) {
+ throw new \RuntimeException(sprintf('Label "%s" already exists.', $label));
+ }
+
+ $this->bits[] = self::create($this);
+ $this->labels[$label] = count($this->bits) - 1;
+
+ return $this->bits[$this->labels[$label]];
+ }
+
+ /**
+ * Retrieves a previously labeled command.
+ *
+ * @param string $label
+ *
+ * @return Command The labeled command
+ *
+ * @throws \RuntimeException
+ */
+ public function get($label)
+ {
+ if (!isset($this->labels[$label])) {
+ throw new \RuntimeException(sprintf('Label "%s" does not exist.', $label));
+ }
+
+ return $this->bits[$this->labels[$label]];
+ }
+
+ /**
+ * Returns parent command (if any).
+ *
+ * @return Command Parent command
+ *
+ * @throws \RuntimeException If command has no parent
+ */
+ public function end()
+ {
+ if (null === $this->parent) {
+ throw new \RuntimeException('Calling end on root command doesn\'t make sense.');
+ }
+
+ return $this->parent;
+ }
+
+ /**
+ * Counts bits stored in command.
+ *
+ * @return int The bits count
+ */
+ public function length()
+ {
+ return count($this->bits);
+ }
+
+ /**
+ * @param \Closure $errorHandler
+ *
+ * @return Command
+ */
+ public function setErrorHandler(\Closure $errorHandler)
+ {
+ $this->errorHandler = $errorHandler;
+
+ return $this;
+ }
+
+ /**
+ * @return \Closure|null
+ */
+ public function getErrorHandler()
+ {
+ return $this->errorHandler;
+ }
+
+ /**
+ * Executes current command.
+ *
+ * @return array The command result
+ *
+ * @throws \RuntimeException
+ */
+ public function execute()
+ {
+ if (null === $errorHandler = $this->errorHandler) {
+ exec($this->join(), $output);
+ } else {
+ $process = proc_open($this->join(), array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes);
+ $output = preg_split('~(\r\n|\r|\n)~', stream_get_contents($pipes[1]), -1, PREG_SPLIT_NO_EMPTY);
+
+ if ($error = stream_get_contents($pipes[2])) {
+ $errorHandler($error);
+ }
+
+ proc_close($process);
+ }
+
+ return $output ?: array();
+ }
+
+ /**
+ * Joins bits.
+ *
+ * @return string
+ */
+ public function join()
+ {
+ return implode(' ', array_filter(
+ array_map(function ($bit) {
+ return $bit instanceof Command ? $bit->join() : ($bit ?: null);
+ }, $this->bits),
+ function ($bit) { return null !== $bit; }
+ ));
+ }
+
+ /**
+ * Insert a string or a Command instance before the bit at given position $index (index starts from 0).
+ *
+ * @param string|Command $bit
+ * @param int $index
+ *
+ * @return Command The current Command instance
+ */
+ public function addAtIndex($bit, $index)
+ {
+ array_splice($this->bits, $index, 0, $bit);
+
+ return $this;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Shell/Shell.php b/vendor/symfony/finder/Symfony/Component/Finder/Shell/Shell.php
new file mode 100644
index 0000000..6d7bff3
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Shell/Shell.php
@@ -0,0 +1,97 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Shell;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class Shell
+{
+ const TYPE_UNIX = 1;
+ const TYPE_DARWIN = 2;
+ const TYPE_CYGWIN = 3;
+ const TYPE_WINDOWS = 4;
+ const TYPE_BSD = 5;
+
+ /**
+ * @var string|null
+ */
+ private $type;
+
+ /**
+ * Returns guessed OS type.
+ *
+ * @return int
+ */
+ public function getType()
+ {
+ if (null === $this->type) {
+ $this->type = $this->guessType();
+ }
+
+ return $this->type;
+ }
+
+ /**
+ * Tests if a command is available.
+ *
+ * @param string $command
+ *
+ * @return bool
+ */
+ public function testCommand($command)
+ {
+ if (!function_exists('exec')) {
+ return false;
+ }
+
+ // todo: find a better way (command could not be available)
+ $testCommand = 'which ';
+ if (self::TYPE_WINDOWS === $this->type) {
+ $testCommand = 'where ';
+ }
+
+ $command = escapeshellcmd($command);
+
+ exec($testCommand.$command, $output, $code);
+
+ return 0 === $code && count($output) > 0;
+ }
+
+ /**
+ * Guesses OS type.
+ *
+ * @return int
+ */
+ private function guessType()
+ {
+ $os = strtolower(PHP_OS);
+
+ if (false !== strpos($os, 'cygwin')) {
+ return self::TYPE_CYGWIN;
+ }
+
+ if (false !== strpos($os, 'darwin')) {
+ return self::TYPE_DARWIN;
+ }
+
+ if (false !== strpos($os, 'bsd')) {
+ return self::TYPE_BSD;
+ }
+
+ if (0 === strpos($os, 'win')) {
+ return self::TYPE_WINDOWS;
+ }
+
+ return self::TYPE_UNIX;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/SplFileInfo.php b/vendor/symfony/finder/Symfony/Component/Finder/SplFileInfo.php
new file mode 100644
index 0000000..c7fbe02
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/SplFileInfo.php
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder;
+
+/**
+ * Extends \SplFileInfo to support relative paths.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class SplFileInfo extends \SplFileInfo
+{
+ private $relativePath;
+ private $relativePathname;
+
+ /**
+ * Constructor.
+ *
+ * @param string $file The file name
+ * @param string $relativePath The relative path
+ * @param string $relativePathname The relative path name
+ */
+ public function __construct($file, $relativePath, $relativePathname)
+ {
+ parent::__construct($file);
+ $this->relativePath = $relativePath;
+ $this->relativePathname = $relativePathname;
+ }
+
+ /**
+ * Returns the relative path.
+ *
+ * @return string the relative path
+ */
+ public function getRelativePath()
+ {
+ return $this->relativePath;
+ }
+
+ /**
+ * Returns the relative path name.
+ *
+ * @return string the relative path name
+ */
+ public function getRelativePathname()
+ {
+ return $this->relativePathname;
+ }
+
+ /**
+ * Returns the contents of the file.
+ *
+ * @return string the contents of the file
+ *
+ * @throws \RuntimeException
+ */
+ public function getContents()
+ {
+ $level = error_reporting(0);
+ $content = file_get_contents($this->getPathname());
+ error_reporting($level);
+ if (false === $content) {
+ $error = error_get_last();
+ throw new \RuntimeException($error['message']);
+ }
+
+ return $content;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/ComparatorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/ComparatorTest.php
new file mode 100644
index 0000000..bf59844
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/ComparatorTest.php
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Comparator;
+
+use Symfony\Component\Finder\Comparator\Comparator;
+
+class ComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetSetOperator()
+ {
+ $comparator = new Comparator();
+ try {
+ $comparator->setOperator('foo');
+ $this->fail('->setOperator() throws an \InvalidArgumentException if the operator is not valid.');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('InvalidArgumentException', $e, '->setOperator() throws an \InvalidArgumentException if the operator is not valid.');
+ }
+
+ $comparator = new Comparator();
+ $comparator->setOperator('>');
+ $this->assertEquals('>', $comparator->getOperator(), '->getOperator() returns the current operator');
+ }
+
+ public function testGetSetTarget()
+ {
+ $comparator = new Comparator();
+ $comparator->setTarget(8);
+ $this->assertEquals(8, $comparator->getTarget(), '->getTarget() returns the target');
+ }
+
+ /**
+ * @dataProvider getTestData
+ */
+ public function testTest($operator, $target, $match, $noMatch)
+ {
+ $c = new Comparator();
+ $c->setOperator($operator);
+ $c->setTarget($target);
+
+ foreach ($match as $m) {
+ $this->assertTrue($c->test($m), '->test() tests a string against the expression');
+ }
+
+ foreach ($noMatch as $m) {
+ $this->assertFalse($c->test($m), '->test() tests a string against the expression');
+ }
+ }
+
+ public function getTestData()
+ {
+ return array(
+ array('<', '1000', array('500', '999'), array('1000', '1500')),
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/DateComparatorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/DateComparatorTest.php
new file mode 100644
index 0000000..2739126
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/DateComparatorTest.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Comparator;
+
+use Symfony\Component\Finder\Comparator\DateComparator;
+
+class DateComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructor()
+ {
+ try {
+ new DateComparator('foobar');
+ $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.');
+ }
+
+ try {
+ new DateComparator('');
+ $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.');
+ }
+ }
+
+ /**
+ * @dataProvider getTestData
+ */
+ public function testTest($test, $match, $noMatch)
+ {
+ $c = new DateComparator($test);
+
+ foreach ($match as $m) {
+ $this->assertTrue($c->test($m), '->test() tests a string against the expression');
+ }
+
+ foreach ($noMatch as $m) {
+ $this->assertFalse($c->test($m), '->test() tests a string against the expression');
+ }
+ }
+
+ public function getTestData()
+ {
+ return array(
+ array('< 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))),
+ array('until 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))),
+ array('before 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))),
+ array('> 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))),
+ array('after 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))),
+ array('since 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))),
+ array('!= 2005-10-10', array(strtotime('2005-10-11')), array(strtotime('2005-10-10'))),
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/NumberComparatorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/NumberComparatorTest.php
new file mode 100644
index 0000000..8284d07
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/NumberComparatorTest.php
@@ -0,0 +1,107 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Comparator;
+
+use Symfony\Component\Finder\Comparator\NumberComparator;
+
+class NumberComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getConstructorTestData
+ */
+ public function testConstructor($successes, $failures)
+ {
+ foreach ($successes as $s) {
+ new NumberComparator($s);
+ }
+
+ foreach ($failures as $f) {
+ try {
+ new NumberComparator($f);
+ $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.');
+ }
+ }
+ }
+
+ /**
+ * @dataProvider getTestData
+ */
+ public function testTest($test, $match, $noMatch)
+ {
+ $c = new NumberComparator($test);
+
+ foreach ($match as $m) {
+ $this->assertTrue($c->test($m), '->test() tests a string against the expression');
+ }
+
+ foreach ($noMatch as $m) {
+ $this->assertFalse($c->test($m), '->test() tests a string against the expression');
+ }
+ }
+
+ public function getTestData()
+ {
+ return array(
+ array('< 1000', array('500', '999'), array('1000', '1500')),
+
+ array('< 1K', array('500', '999'), array('1000', '1500')),
+ array('<1k', array('500', '999'), array('1000', '1500')),
+ array(' < 1 K ', array('500', '999'), array('1000', '1500')),
+ array('<= 1K', array('1000'), array('1001')),
+ array('> 1K', array('1001'), array('1000')),
+ array('>= 1K', array('1000'), array('999')),
+
+ array('< 1KI', array('500', '1023'), array('1024', '1500')),
+ array('<= 1KI', array('1024'), array('1025')),
+ array('> 1KI', array('1025'), array('1024')),
+ array('>= 1KI', array('1024'), array('1023')),
+
+ array('1KI', array('1024'), array('1023', '1025')),
+ array('==1KI', array('1024'), array('1023', '1025')),
+
+ array('==1m', array('1000000'), array('999999', '1000001')),
+ array('==1mi', array(1024 * 1024), array(1024 * 1024 - 1, 1024 * 1024 + 1)),
+
+ array('==1g', array('1000000000'), array('999999999', '1000000001')),
+ array('==1gi', array(1024 * 1024 * 1024), array(1024 * 1024 * 1024 - 1, 1024 * 1024 * 1024 + 1)),
+
+ array('!= 1000', array('500', '999'), array('1000')),
+ );
+ }
+
+ public function getConstructorTestData()
+ {
+ return array(
+ array(
+ array(
+ '1', '0',
+ '3.5', '33.55', '123.456', '123456.78',
+ '.1', '.123',
+ '.0', '0.0',
+ '1.', '0.', '123.',
+ '==1', '!=1', '<1', '>1', '<=1', '>=1',
+ '==1k', '==1ki', '==1m', '==1mi', '==1g', '==1gi',
+ '1k', '1ki', '1m', '1mi', '1g', '1gi',
+ ),
+ array(
+ false, null, '',
+ ' ', 'foobar',
+ '=1', '===1',
+ '0 . 1', '123 .45', '234. 567',
+ '..', '.0.', '0.1.2',
+ ),
+ ),
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/ExpressionTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/ExpressionTest.php
new file mode 100644
index 0000000..4254a45
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/ExpressionTest.php
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Expression;
+
+use Symfony\Component\Finder\Expression\Expression;
+
+class ExpressionTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getTypeGuesserData
+ */
+ public function testTypeGuesser($expr, $type)
+ {
+ $this->assertEquals($type, Expression::create($expr)->getType());
+ }
+
+ /**
+ * @dataProvider getCaseSensitiveData
+ */
+ public function testCaseSensitive($expr, $isCaseSensitive)
+ {
+ $this->assertEquals($isCaseSensitive, Expression::create($expr)->isCaseSensitive());
+ }
+
+ /**
+ * @dataProvider getRegexRenderingData
+ */
+ public function testRegexRendering($expr, $body)
+ {
+ $this->assertEquals($body, Expression::create($expr)->renderPattern());
+ }
+
+ public function getTypeGuesserData()
+ {
+ return array(
+ array('{foo}', Expression::TYPE_REGEX),
+ array('/foo/', Expression::TYPE_REGEX),
+ array('foo', Expression::TYPE_GLOB),
+ array('foo*', Expression::TYPE_GLOB),
+ );
+ }
+
+ public function getCaseSensitiveData()
+ {
+ return array(
+ array('{foo}m', true),
+ array('/foo/i', false),
+ array('foo*', true),
+ );
+ }
+
+ public function getRegexRenderingData()
+ {
+ return array(
+ array('{foo}m', 'foo'),
+ array('/foo/i', 'foo'),
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/GlobTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/GlobTest.php
new file mode 100644
index 0000000..9d4c3e5
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/GlobTest.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Expression;
+
+use Symfony\Component\Finder\Expression\Expression;
+
+class GlobTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getToRegexData
+ */
+ public function testGlobToRegex($glob, $match, $noMatch)
+ {
+ foreach ($match as $m) {
+ $this->assertRegExp(Expression::create($glob)->getRegex()->render(), $m, '::toRegex() converts a glob to a regexp');
+ }
+
+ foreach ($noMatch as $m) {
+ $this->assertNotRegExp(Expression::create($glob)->getRegex()->render(), $m, '::toRegex() converts a glob to a regexp');
+ }
+ }
+
+ public function getToRegexData()
+ {
+ return array(
+ array('', array(''), array('f', '/')),
+ array('*', array('foo'), array('foo/', '/foo')),
+ array('foo.*', array('foo.php', 'foo.a', 'foo.'), array('fooo.php', 'foo.php/foo')),
+ array('fo?', array('foo', 'fot'), array('fooo', 'ffoo', 'fo/')),
+ array('fo{o,t}', array('foo', 'fot'), array('fob', 'fo/')),
+ array('foo(bar|foo)', array('foo(bar|foo)'), array('foobar', 'foofoo')),
+ array('foo,bar', array('foo,bar'), array('foo', 'bar')),
+ array('fo{o,\\,}', array('foo', 'fo,'), array()),
+ array('fo{o,\\\\}', array('foo', 'fo\\'), array()),
+ array('/foo', array('/foo'), array('foo')),
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/RegexTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/RegexTest.php
new file mode 100644
index 0000000..620ba10
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/RegexTest.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Expression;
+
+use Symfony\Component\Finder\Expression\Expression;
+
+class RegexTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getHasFlagsData
+ */
+ public function testHasFlags($regex, $start, $end)
+ {
+ $expr = new Expression($regex);
+
+ $this->assertEquals($start, $expr->getRegex()->hasStartFlag());
+ $this->assertEquals($end, $expr->getRegex()->hasEndFlag());
+ }
+
+ /**
+ * @dataProvider getHasJokersData
+ */
+ public function testHasJokers($regex, $start, $end)
+ {
+ $expr = new Expression($regex);
+
+ $this->assertEquals($start, $expr->getRegex()->hasStartJoker());
+ $this->assertEquals($end, $expr->getRegex()->hasEndJoker());
+ }
+
+ /**
+ * @dataProvider getSetFlagsData
+ */
+ public function testSetFlags($regex, $start, $end, $expected)
+ {
+ $expr = new Expression($regex);
+ $expr->getRegex()->setStartFlag($start)->setEndFlag($end);
+
+ $this->assertEquals($expected, $expr->render());
+ }
+
+ /**
+ * @dataProvider getSetJokersData
+ */
+ public function testSetJokers($regex, $start, $end, $expected)
+ {
+ $expr = new Expression($regex);
+ $expr->getRegex()->setStartJoker($start)->setEndJoker($end);
+
+ $this->assertEquals($expected, $expr->render());
+ }
+
+ public function testOptions()
+ {
+ $expr = new Expression('~abc~is');
+ $expr->getRegex()->removeOption('i')->addOption('m');
+
+ $this->assertEquals('~abc~sm', $expr->render());
+ }
+
+ public function testMixFlagsAndJokers()
+ {
+ $expr = new Expression('~^.*abc.*$~is');
+
+ $expr->getRegex()->setStartFlag(false)->setEndFlag(false)->setStartJoker(false)->setEndJoker(false);
+ $this->assertEquals('~abc~is', $expr->render());
+
+ $expr->getRegex()->setStartFlag(true)->setEndFlag(true)->setStartJoker(true)->setEndJoker(true);
+ $this->assertEquals('~^.*abc.*$~is', $expr->render());
+ }
+
+ /**
+ * @dataProvider getReplaceJokersTestData
+ */
+ public function testReplaceJokers($regex, $expected)
+ {
+ $expr = new Expression($regex);
+ $expr = $expr->getRegex()->replaceJokers('@');
+
+ $this->assertEquals($expected, $expr->renderPattern());
+ }
+
+ public function getHasFlagsData()
+ {
+ return array(
+ array('~^abc~', true, false),
+ array('~abc$~', false, true),
+ array('~abc~', false, false),
+ array('~^abc$~', true, true),
+ array('~^abc\\$~', true, false),
+ );
+ }
+
+ public function getHasJokersData()
+ {
+ return array(
+ array('~.*abc~', true, false),
+ array('~abc.*~', false, true),
+ array('~abc~', false, false),
+ array('~.*abc.*~', true, true),
+ array('~.*abc\\.*~', true, false),
+ );
+ }
+
+ public function getSetFlagsData()
+ {
+ return array(
+ array('~abc~', true, false, '~^abc~'),
+ array('~abc~', false, true, '~abc$~'),
+ array('~abc~', false, false, '~abc~'),
+ array('~abc~', true, true, '~^abc$~'),
+ );
+ }
+
+ public function getSetJokersData()
+ {
+ return array(
+ array('~abc~', true, false, '~.*abc~'),
+ array('~abc~', false, true, '~abc.*~'),
+ array('~abc~', false, false, '~abc~'),
+ array('~abc~', true, true, '~.*abc.*~'),
+ );
+ }
+
+ public function getReplaceJokersTestData()
+ {
+ return array(
+ array('~.abc~', '@abc'),
+ array('~\\.abc~', '\\.abc'),
+ array('~\\\\.abc~', '\\\\@abc'),
+ array('~\\\\\\.abc~', '\\\\\\.abc'),
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/DummyAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/DummyAdapter.php
new file mode 100644
index 0000000..0cbae14
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/DummyAdapter.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\FakeAdapter;
+
+use Symfony\Component\Finder\Adapter\AbstractAdapter;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class DummyAdapter extends AbstractAdapter
+{
+ /**
+ * @var \Iterator
+ */
+ private $iterator;
+
+ /**
+ * @param \Iterator $iterator
+ */
+ public function __construct(\Iterator $iterator)
+ {
+ $this->iterator = $iterator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ return $this->iterator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'yes';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return true;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/FailingAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/FailingAdapter.php
new file mode 100644
index 0000000..6e6ed24
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/FailingAdapter.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\FakeAdapter;
+
+use Symfony\Component\Finder\Adapter\AbstractAdapter;
+use Symfony\Component\Finder\Exception\AdapterFailureException;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class FailingAdapter extends AbstractAdapter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ throw new AdapterFailureException($this);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'failing';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return true;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/NamedAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/NamedAdapter.php
new file mode 100644
index 0000000..5a260b0
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/NamedAdapter.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\FakeAdapter;
+
+use Symfony\Component\Finder\Adapter\AbstractAdapter;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class NamedAdapter extends AbstractAdapter
+{
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @param string $name
+ */
+ public function __construct($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ return new \ArrayIterator(array());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return true;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/UnsupportedAdapter.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/UnsupportedAdapter.php
new file mode 100644
index 0000000..1f91b98
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/UnsupportedAdapter.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\FakeAdapter;
+
+use Symfony\Component\Finder\Adapter\AbstractAdapter;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class UnsupportedAdapter extends AbstractAdapter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function searchInDirectory($dir)
+ {
+ return new \ArrayIterator(array());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'unsupported';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function canBeUsed()
+ {
+ return false;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/FinderTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/FinderTest.php
new file mode 100644
index 0000000..fe0984d
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/FinderTest.php
@@ -0,0 +1,869 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests;
+
+use Symfony\Component\Finder\Finder;
+use Symfony\Component\Finder\Adapter;
+
+class FinderTest extends Iterator\RealIteratorTestCase
+{
+ public function testCreate()
+ {
+ $this->assertInstanceOf('Symfony\Component\Finder\Finder', Finder::create());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testDirectories($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->directories());
+ $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->directories();
+ $finder->files();
+ $finder->directories();
+ $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testFiles($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->files());
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->files();
+ $finder->directories();
+ $finder->files();
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testDepth($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->depth('< 1'));
+ $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->depth('<= 0'));
+ $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->depth('>= 1'));
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->depth('< 1')->depth('>= 1');
+ $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testName($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->name('*.php'));
+ $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->name('test.ph*');
+ $finder->name('test.py');
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->name('~^test~i');
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->name('~\\.php$~i');
+ $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->name('test.p{hp,y}');
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testNotName($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->notName('*.php'));
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->notName('*.php');
+ $finder->notName('*.py');
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->name('test.ph*');
+ $finder->name('test.py');
+ $finder->notName('*.php');
+ $finder->notName('*.py');
+ $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->name('test.ph*');
+ $finder->name('test.py');
+ $finder->notName('*.p{hp,y}');
+ $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getRegexNameTestData
+ *
+ * @group regexName
+ */
+ public function testRegexName($adapter, $regex)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->name($regex);
+ $this->assertIterator($this->toAbsolute(array('test.py', 'test.php')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSize($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->files()->size('< 1K')->size('> 500'));
+ $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testDate($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->files()->date('until last month'));
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testExclude($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->exclude('foo'));
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testIgnoreVCS($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->ignoreVCS(false)->ignoreDotFiles(false));
+ $this->assertIterator($this->toAbsolute(array('.git', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->ignoreVCS(false)->ignoreVCS(false)->ignoreDotFiles(false);
+ $this->assertIterator($this->toAbsolute(array('.git', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->ignoreVCS(true)->ignoreDotFiles(false));
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testIgnoreDotFiles($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->ignoreDotFiles(false)->ignoreVCS(false));
+ $this->assertIterator($this->toAbsolute(array('.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $finder->ignoreDotFiles(false)->ignoreDotFiles(false)->ignoreVCS(false);
+ $this->assertIterator($this->toAbsolute(array('.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->ignoreDotFiles(true)->ignoreVCS(false));
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSortByName($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->sortByName());
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSortByType($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->sortByType());
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'toto', 'foo/bar.tmp', 'test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSortByAccessedTime($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->sortByAccessedTime());
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSortByChangedTime($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->sortByChangedTime());
+ $this->assertIterator($this->toAbsolute(array('toto', 'test.py', 'test.php', 'foo/bar.tmp', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSortByModifiedTime($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->sortByModifiedTime());
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testSort($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->sort(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealpath(), $b->getRealpath()); }));
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testFilter($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->filter(function (\SplFileInfo $f) { return preg_match('/test/', $f) > 0; }));
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testFollowLinks($adapter)
+ {
+ if ('\\' == DIRECTORY_SEPARATOR) {
+ return;
+ }
+
+ $finder = $this->buildFinder($adapter);
+ $this->assertSame($finder, $finder->followLinks());
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testIn($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ try {
+ $finder->in('foobar');
+ $this->fail('->in() throws a \InvalidArgumentException if the directory does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('InvalidArgumentException', $e, '->in() throws a \InvalidArgumentException if the directory does not exist');
+ }
+
+ $finder = $this->buildFinder($adapter);
+ $iterator = $finder->files()->name('*.php')->depth('< 1')->in(array(self::$tmpDir, __DIR__))->getIterator();
+
+ $this->assertIterator(array(self::$tmpDir.DIRECTORY_SEPARATOR.'test.php', __DIR__.DIRECTORY_SEPARATOR.'FinderTest.php'), $iterator);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testInWithGlob($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(array(__DIR__.'/Fixtures/*/B/C', __DIR__.'/Fixtures/*/*/B/C'))->getIterator();
+
+ $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ * @expectedException \InvalidArgumentException
+ */
+ public function testInWithNonDirectoryGlob($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(__DIR__.'/Fixtures/A/a*');
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testInWithGlobBrace($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(array(__DIR__.'/Fixtures/{A,copy/A}/B/C'))->getIterator();
+
+ $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testGetIterator($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ try {
+ $finder->getIterator();
+ $this->fail('->getIterator() throws a \LogicException if the in() method has not been called');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('LogicException', $e, '->getIterator() throws a \LogicException if the in() method has not been called');
+ }
+
+ $finder = $this->buildFinder($adapter);
+ $dirs = array();
+ foreach ($finder->directories()->in(self::$tmpDir) as $dir) {
+ $dirs[] = (string) $dir;
+ }
+
+ $expected = $this->toAbsolute(array('foo', 'toto'));
+
+ sort($dirs);
+ sort($expected);
+
+ $this->assertEquals($expected, $dirs, 'implements the \IteratorAggregate interface');
+
+ $finder = $this->buildFinder($adapter);
+ $this->assertEquals(2, iterator_count($finder->directories()->in(self::$tmpDir)), 'implements the \IteratorAggregate interface');
+
+ $finder = $this->buildFinder($adapter);
+ $a = iterator_to_array($finder->directories()->in(self::$tmpDir));
+ $a = array_values(array_map(function ($a) { return (string) $a; }, $a));
+ sort($a);
+ $this->assertEquals($expected, $a, 'implements the \IteratorAggregate interface');
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testRelativePath($adapter)
+ {
+ $finder = $this->buildFinder($adapter)->in(self::$tmpDir);
+
+ $paths = array();
+
+ foreach ($finder as $file) {
+ $paths[] = $file->getRelativePath();
+ }
+
+ $ref = array('', '', '', '', 'foo', '');
+
+ sort($ref);
+ sort($paths);
+
+ $this->assertEquals($ref, $paths);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testRelativePathname($adapter)
+ {
+ $finder = $this->buildFinder($adapter)->in(self::$tmpDir)->sortByName();
+
+ $paths = array();
+
+ foreach ($finder as $file) {
+ $paths[] = $file->getRelativePathname();
+ }
+
+ $ref = array('test.php', 'toto', 'test.py', 'foo', 'foo'.DIRECTORY_SEPARATOR.'bar.tmp', 'foo bar');
+
+ sort($paths);
+ sort($ref);
+
+ $this->assertEquals($ref, $paths);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testAppendWithAFinder($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
+
+ $finder1 = $this->buildFinder($adapter);
+ $finder1->directories()->in(self::$tmpDir);
+
+ $finder = $finder->append($finder1);
+
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testAppendWithAnArray($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
+
+ $finder->append($this->toAbsolute(array('foo', 'toto')));
+
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testAppendReturnsAFinder($adapter)
+ {
+ $this->assertInstanceOf('Symfony\\Component\\Finder\\Finder', $this->buildFinder($adapter)->append(array()));
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testAppendDoesNotRequireIn($adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
+
+ $finder1 = Finder::create()->append($finder);
+
+ $this->assertIterator(iterator_to_array($finder->getIterator()), $finder1->getIterator());
+ }
+
+ public function testCountDirectories()
+ {
+ $directory = Finder::create()->directories()->in(self::$tmpDir);
+ $i = 0;
+
+ foreach ($directory as $dir) {
+ $i++;
+ }
+
+ $this->assertCount($i, $directory);
+ }
+
+ public function testCountFiles()
+ {
+ $files = Finder::create()->files()->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures');
+ $i = 0;
+
+ foreach ($files as $file) {
+ $i++;
+ }
+
+ $this->assertCount($i, $files);
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testCountWithoutIn()
+ {
+ $finder = Finder::create()->files();
+ count($finder);
+ }
+
+ /**
+ * @dataProvider getContainsTestData
+ * @group grep
+ */
+ public function testContains($adapter, $matchPatterns, $noMatchPatterns, $expected)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
+ ->name('*.txt')->sortByName()
+ ->contains($matchPatterns)
+ ->notContains($noMatchPatterns);
+
+ $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testContainsOnDirectory(Adapter\AdapterInterface $adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(__DIR__)
+ ->directories()
+ ->name('Fixtures')
+ ->contains('abc');
+ $this->assertIterator(array(), $finder);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testNotContainsOnDirectory(Adapter\AdapterInterface $adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(__DIR__)
+ ->directories()
+ ->name('Fixtures')
+ ->notContains('abc');
+ $this->assertIterator(array(), $finder);
+ }
+
+ /**
+ * Searching in multiple locations involves AppendIterator which does an unnecessary rewind which leaves FilterIterator
+ * with inner FilesystemIterator in an invalid state.
+ *
+ * @see https://bugs.php.net/bug.php?id=49104
+ *
+ * @dataProvider getAdaptersTestData
+ */
+ public function testMultipleLocations(Adapter\AdapterInterface $adapter)
+ {
+ $locations = array(
+ self::$tmpDir.'/',
+ self::$tmpDir.'/toto/',
+ );
+
+ // it is expected that there are test.py test.php in the tmpDir
+ $finder = $this->buildFinder($adapter);
+ $finder->in($locations)->depth('< 1')->name('test.php');
+
+ $this->assertCount(1, $finder);
+ }
+
+ /**
+ * Iterator keys must be the file pathname.
+ *
+ * @dataProvider getAdaptersTestData
+ */
+ public function testIteratorKeys(Adapter\AdapterInterface $adapter)
+ {
+ $finder = $this->buildFinder($adapter)->in(self::$tmpDir);
+ foreach ($finder as $key => $file) {
+ $this->assertEquals($file->getPathname(), $key);
+ }
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testRegexSpecialCharsLocationWithPathRestrictionContainingStartFlag(Adapter\AdapterInterface $adapter)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'r+e.gex[c]a(r)s')
+ ->path('/^dir/');
+
+ $expected = array('r+e.gex[c]a(r)s'.DIRECTORY_SEPARATOR.'dir',
+ 'r+e.gex[c]a(r)s'.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'bar.dat',);
+ $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
+ }
+
+ public function testAdaptersOrdering()
+ {
+ $finder = Finder::create()
+ ->removeAdapters()
+ ->addAdapter(new FakeAdapter\NamedAdapter('a'), 0)
+ ->addAdapter(new FakeAdapter\NamedAdapter('b'), -50)
+ ->addAdapter(new FakeAdapter\NamedAdapter('c'), 50)
+ ->addAdapter(new FakeAdapter\NamedAdapter('d'), -25)
+ ->addAdapter(new FakeAdapter\NamedAdapter('e'), 25);
+
+ $this->assertEquals(
+ array('c', 'e', 'a', 'd', 'b'),
+ array_map(function (Adapter\AdapterInterface $adapter) {
+ return $adapter->getName();
+ }, $finder->getAdapters())
+ );
+ }
+
+ public function testAdaptersChaining()
+ {
+ $iterator = new \ArrayIterator(array());
+ $filenames = $this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto'));
+ foreach ($filenames as $file) {
+ $iterator->append(new \Symfony\Component\Finder\SplFileInfo($file, null, null));
+ }
+
+ $finder = Finder::create()
+ ->removeAdapters()
+ ->addAdapter(new FakeAdapter\UnsupportedAdapter(), 3)
+ ->addAdapter(new FakeAdapter\FailingAdapter(), 2)
+ ->addAdapter(new FakeAdapter\DummyAdapter($iterator), 1);
+
+ $this->assertIterator($filenames, $finder->in(sys_get_temp_dir())->getIterator());
+ }
+
+ public function getAdaptersTestData()
+ {
+ return array_map(
+ function ($adapter) { return array($adapter); },
+ $this->getValidAdapters()
+ );
+ }
+
+ public function getContainsTestData()
+ {
+ $tests = array(
+ array('', '', array()),
+ array('foo', 'bar', array()),
+ array('', 'foobar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')),
+ array('lorem ipsum dolor sit amet', 'foobar', array('lorem.txt')),
+ array('sit', 'bar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')),
+ array('dolor sit amet', '@^L@m', array('dolor.txt', 'ipsum.txt')),
+ array('/^lorem ipsum dolor sit amet$/m', 'foobar', array('lorem.txt')),
+ array('lorem', 'foobar', array('lorem.txt')),
+ array('', 'lorem', array('dolor.txt', 'ipsum.txt')),
+ array('ipsum dolor sit amet', '/^IPSUM/m', array('lorem.txt')),
+ );
+
+ return $this->buildTestData($tests);
+ }
+
+ public function getRegexNameTestData()
+ {
+ $tests = array(
+ array('~.+\\.p.+~i'),
+ array('~t.*s~i'),
+ );
+
+ return $this->buildTestData($tests);
+ }
+
+ /**
+ * @dataProvider getTestPathData
+ */
+ public function testPath(Adapter\AdapterInterface $adapter, $matchPatterns, $noMatchPatterns, array $expected)
+ {
+ $finder = $this->buildFinder($adapter);
+ $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
+ ->path($matchPatterns)
+ ->notPath($noMatchPatterns);
+
+ $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
+ }
+
+ public function testAdapterSelection()
+ {
+ // test that by default, PhpAdapter is selected
+ $adapters = Finder::create()->getAdapters();
+ $this->assertTrue($adapters[0] instanceof Adapter\PhpAdapter);
+
+ // test another adapter selection
+ $adapters = Finder::create()->setAdapter('gnu_find')->getAdapters();
+ $this->assertTrue($adapters[0] instanceof Adapter\GnuFindAdapter);
+
+ // test that useBestAdapter method removes selection
+ $adapters = Finder::create()->useBestAdapter()->getAdapters();
+ $this->assertFalse($adapters[0] instanceof Adapter\PhpAdapter);
+ }
+
+ public function getTestPathData()
+ {
+ $tests = array(
+ array('', '', array()),
+ array('/^A\/B\/C/', '/C$/',
+ array('A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat'),
+ ),
+ array('/^A\/B/', 'foobar',
+ array(
+ 'A'.DIRECTORY_SEPARATOR.'B',
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
+ ),
+ ),
+ array('A/B/C', 'foobar',
+ array(
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
+ ),
+ ),
+ array('A/B', 'foobar',
+ array(
+ //dirs
+ 'A'.DIRECTORY_SEPARATOR.'B',
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B',
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
+ //files
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat.copy',
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
+ ),
+ ),
+ array('/^with space\//', 'foobar',
+ array(
+ 'with space'.DIRECTORY_SEPARATOR.'foo.txt',
+ ),
+ ),
+ );
+
+ return $this->buildTestData($tests);
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testAccessDeniedException(Adapter\AdapterInterface $adapter)
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('chmod is not supported on Windows');
+ }
+
+ $finder = $this->buildFinder($adapter);
+ $finder->files()->in(self::$tmpDir);
+
+ // make 'foo' directory non-readable
+ $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo';
+ chmod($testDir, 0333);
+
+ if (false === $couldRead = is_readable($testDir)) {
+ try {
+ $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator());
+ $this->fail('Finder should throw an exception when opening a non-readable directory.');
+ } catch (\Exception $e) {
+ $expectedExceptionClass = 'Symfony\\Component\\Finder\\Exception\\AccessDeniedException';
+ if ($e instanceof \PHPUnit_Framework_ExpectationFailedException) {
+ $this->fail(sprintf("Expected exception:\n%s\nGot:\n%s\nWith comparison failure:\n%s", $expectedExceptionClass, 'PHPUnit_Framework_ExpectationFailedException', $e->getComparisonFailure()->getExpectedAsString()));
+ }
+
+ $this->assertInstanceOf($expectedExceptionClass, $e);
+ }
+ }
+
+ // restore original permissions
+ chmod($testDir, 0777);
+ clearstatcache($testDir);
+
+ if ($couldRead) {
+ $this->markTestSkipped('could read test files while test requires unreadable');
+ }
+ }
+
+ /**
+ * @dataProvider getAdaptersTestData
+ */
+ public function testIgnoredAccessDeniedException(Adapter\AdapterInterface $adapter)
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('chmod is not supported on Windows');
+ }
+
+ $finder = $this->buildFinder($adapter);
+ $finder->files()->ignoreUnreadableDirs()->in(self::$tmpDir);
+
+ // make 'foo' directory non-readable
+ $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo';
+ chmod($testDir, 0333);
+
+ if (false === ($couldRead = is_readable($testDir))) {
+ $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator());
+ }
+
+ // restore original permissions
+ chmod($testDir, 0777);
+ clearstatcache($testDir);
+
+ if ($couldRead) {
+ $this->markTestSkipped('could read test files while test requires unreadable');
+ }
+ }
+
+ private function buildTestData(array $tests)
+ {
+ $data = array();
+ foreach ($this->getValidAdapters() as $adapter) {
+ foreach ($tests as $test) {
+ $data[] = array_merge(array($adapter), $test);
+ }
+ }
+
+ return $data;
+ }
+
+ private function buildFinder(Adapter\AdapterInterface $adapter)
+ {
+ return Finder::create()
+ ->removeAdapters()
+ ->addAdapter($adapter);
+ }
+
+ private function getValidAdapters()
+ {
+ return array_filter(
+ array(
+ new Adapter\BsdFindAdapter(),
+ new Adapter\GnuFindAdapter(),
+ new Adapter\PhpAdapter(),
+ ),
+ function (Adapter\AdapterInterface $adapter) {
+ return $adapter->isSupported();
+ }
+ );
+ }
+
+ /**
+ * Searching in multiple locations with sub directories involves
+ * AppendIterator which does an unnecessary rewind which leaves
+ * FilterIterator with inner FilesystemIterator in an invalid state.
+ *
+ * @see https://bugs.php.net/bug.php?id=49104
+ */
+ public function testMultipleLocationsWithSubDirectories()
+ {
+ $locations = array(
+ __DIR__.'/Fixtures/one',
+ self::$tmpDir.DIRECTORY_SEPARATOR.'toto',
+ );
+
+ $finder = new Finder();
+ $finder->in($locations)->depth('< 10')->name('*.neon');
+
+ $expected = array(
+ __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'c.neon',
+ __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'d.neon',
+ );
+
+ $this->assertIterator($expected, $finder);
+ $this->assertIteratorInForeach($expected, $finder);
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/C/abc.dat b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/C/abc.dat
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/C/abc.dat
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/ab.dat b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/ab.dat
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/ab.dat
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/a.dat b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/a.dat
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/a.dat
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/ab.dat.copy b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/ab.dat.copy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/ab.dat.copy
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/a.dat.copy b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/a.dat.copy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/a.dat.copy
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/dolor.txt b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/dolor.txt
new file mode 100644
index 0000000..658bec6
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/dolor.txt
@@ -0,0 +1,2 @@
+dolor sit amet
+DOLOR SIT AMET \ No newline at end of file
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/ipsum.txt b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/ipsum.txt
new file mode 100644
index 0000000..c7f392d
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/ipsum.txt
@@ -0,0 +1,2 @@
+ipsum dolor sit amet
+IPSUM DOLOR SIT AMET \ No newline at end of file
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/lorem.txt b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/lorem.txt
new file mode 100644
index 0000000..2991a2c
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/lorem.txt
@@ -0,0 +1,2 @@
+lorem ipsum dolor sit amet
+LOREM IPSUM DOLOR SIT AMET \ No newline at end of file
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/a b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/a
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/c.neon b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/c.neon
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/c.neon
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/d.neon b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/d.neon
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/d.neon
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.dat b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.dat
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.dat
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/with space/foo.txt b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/with space/foo.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/with space/foo.txt
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php
new file mode 100644
index 0000000..62629b1
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\CustomFilterIterator;
+
+class CustomFilterIteratorTest extends IteratorTestCase
+{
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testWithInvalidFilter()
+ {
+ new CustomFilterIterator(new Iterator(), array('foo'));
+ }
+
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($filters, $expected)
+ {
+ $inner = new Iterator(array('test.php', 'test.py', 'foo.php'));
+
+ $iterator = new CustomFilterIterator($inner, $filters);
+
+ $this->assertIterator($expected, $iterator);
+ }
+
+ public function getAcceptData()
+ {
+ return array(
+ array(array(function (\SplFileInfo $fileinfo) { return false; }), array()),
+ array(array(function (\SplFileInfo $fileinfo) { return preg_match('/^test/', $fileinfo) > 0; }), array('test.php', 'test.py')),
+ array(array('is_dir'), array()),
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DateRangeFilterIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DateRangeFilterIteratorTest.php
new file mode 100644
index 0000000..709d5fe
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DateRangeFilterIteratorTest.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\DateRangeFilterIterator;
+use Symfony\Component\Finder\Comparator\DateComparator;
+
+class DateRangeFilterIteratorTest extends RealIteratorTestCase
+{
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($size, $expected)
+ {
+ $files = self::$files;
+ $files[] = self::toAbsolute('doesnotexist');
+ $inner = new Iterator($files);
+
+ $iterator = new DateRangeFilterIterator($inner, $size);
+
+ $this->assertIterator($expected, $iterator);
+ }
+
+ public function getAcceptData()
+ {
+ $since20YearsAgo = array(
+ '.git',
+ 'test.py',
+ 'foo',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'toto',
+ '.bar',
+ '.foo',
+ '.foo/.bar',
+ 'foo bar',
+ '.foo/bar',
+ );
+
+ $since2MonthsAgo = array(
+ '.git',
+ 'test.py',
+ 'foo',
+ 'toto',
+ '.bar',
+ '.foo',
+ '.foo/.bar',
+ 'foo bar',
+ '.foo/bar',
+ );
+
+ $untilLastMonth = array(
+ 'foo/bar.tmp',
+ 'test.php',
+ );
+
+ return array(
+ array(array(new DateComparator('since 20 years ago')), $this->toAbsolute($since20YearsAgo)),
+ array(array(new DateComparator('since 2 months ago')), $this->toAbsolute($since2MonthsAgo)),
+ array(array(new DateComparator('until last month')), $this->toAbsolute($untilLastMonth)),
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php
new file mode 100644
index 0000000..5ec9832
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator;
+
+class DepthRangeFilterIteratorTest extends RealIteratorTestCase
+{
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($minDepth, $maxDepth, $expected)
+ {
+ $inner = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->toAbsolute(), \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
+
+ $iterator = new DepthRangeFilterIterator($inner, $minDepth, $maxDepth);
+
+ $actual = array_keys(iterator_to_array($iterator));
+ sort($expected);
+ sort($actual);
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function getAcceptData()
+ {
+ $lessThan1 = array(
+ '.git',
+ 'test.py',
+ 'foo',
+ 'test.php',
+ 'toto',
+ '.foo',
+ '.bar',
+ 'foo bar',
+ );
+
+ $lessThanOrEqualTo1 = array(
+ '.git',
+ 'test.py',
+ 'foo',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'toto',
+ '.foo',
+ '.foo/.bar',
+ '.bar',
+ 'foo bar',
+ '.foo/bar',
+ );
+
+ $graterThanOrEqualTo1 = array(
+ 'foo/bar.tmp',
+ '.foo/.bar',
+ '.foo/bar',
+ );
+
+ $equalTo1 = array(
+ 'foo/bar.tmp',
+ '.foo/.bar',
+ '.foo/bar',
+ );
+
+ return array(
+ array(0, 0, $this->toAbsolute($lessThan1)),
+ array(0, 1, $this->toAbsolute($lessThanOrEqualTo1)),
+ array(2, PHP_INT_MAX, array()),
+ array(1, PHP_INT_MAX, $this->toAbsolute($graterThanOrEqualTo1)),
+ array(1, 1, $this->toAbsolute($equalTo1)),
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php
new file mode 100644
index 0000000..693b733
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
+use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator;
+
+class ExcludeDirectoryFilterIteratorTest extends RealIteratorTestCase
+{
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($directories, $expected)
+ {
+ $inner = new \RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->toAbsolute(), \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
+
+ $iterator = new ExcludeDirectoryFilterIterator($inner, $directories);
+
+ $this->assertIterator($expected, $iterator);
+ }
+
+ public function getAcceptData()
+ {
+ $foo = array(
+ '.bar',
+ '.foo',
+ '.foo/.bar',
+ '.foo/bar',
+ '.git',
+ 'test.py',
+ 'test.php',
+ 'toto',
+ 'foo bar',
+ );
+
+ $fo = array(
+ '.bar',
+ '.foo',
+ '.foo/.bar',
+ '.foo/bar',
+ '.git',
+ 'test.py',
+ 'foo',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'toto',
+ 'foo bar',
+ );
+
+ return array(
+ array(array('foo'), $this->toAbsolute($foo)),
+ array(array('fo'), $this->toAbsolute($fo)),
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php
new file mode 100644
index 0000000..fdf810b
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\FilePathsIterator;
+
+class FilePathsIteratorTest extends RealIteratorTestCase
+{
+ /**
+ * @dataProvider getSubPathData
+ */
+ public function testSubPath($baseDir, array $paths, array $subPaths, array $subPathnames)
+ {
+ $iterator = new FilePathsIterator($paths, $baseDir);
+
+ foreach ($iterator as $index => $file) {
+ $this->assertEquals($paths[$index], $file->getPathname());
+ $this->assertEquals($subPaths[$index], $iterator->getSubPath());
+ $this->assertEquals($subPathnames[$index], $iterator->getSubPathname());
+ }
+ }
+
+ public function getSubPathData()
+ {
+ $tmpDir = sys_get_temp_dir().'/symfony_finder';
+
+ return array(
+ array(
+ $tmpDir,
+ array(
+ // paths
+ $tmpDir.DIRECTORY_SEPARATOR.'.git' => $tmpDir.DIRECTORY_SEPARATOR.'.git',
+ $tmpDir.DIRECTORY_SEPARATOR.'test.py' => $tmpDir.DIRECTORY_SEPARATOR.'test.py',
+ $tmpDir.DIRECTORY_SEPARATOR.'foo' => $tmpDir.DIRECTORY_SEPARATOR.'foo',
+ $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp',
+ $tmpDir.DIRECTORY_SEPARATOR.'test.php' => $tmpDir.DIRECTORY_SEPARATOR.'test.php',
+ $tmpDir.DIRECTORY_SEPARATOR.'toto' => $tmpDir.DIRECTORY_SEPARATOR.'toto',
+ ),
+ array(
+ // subPaths
+ $tmpDir.DIRECTORY_SEPARATOR.'.git' => '',
+ $tmpDir.DIRECTORY_SEPARATOR.'test.py' => '',
+ $tmpDir.DIRECTORY_SEPARATOR.'foo' => '',
+ $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => 'foo',
+ $tmpDir.DIRECTORY_SEPARATOR.'test.php' => '',
+ $tmpDir.DIRECTORY_SEPARATOR.'toto' => '',
+ ),
+ array(
+ // subPathnames
+ $tmpDir.DIRECTORY_SEPARATOR.'.git' => '.git',
+ $tmpDir.DIRECTORY_SEPARATOR.'test.py' => 'test.py',
+ $tmpDir.DIRECTORY_SEPARATOR.'foo' => 'foo',
+ $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => 'foo'.DIRECTORY_SEPARATOR.'bar.tmp',
+ $tmpDir.DIRECTORY_SEPARATOR.'test.php' => 'test.php',
+ $tmpDir.DIRECTORY_SEPARATOR.'toto' => 'toto',
+ ),
+ ),
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php
new file mode 100644
index 0000000..cfa8684
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\FileTypeFilterIterator;
+
+class FileTypeFilterIteratorTest extends RealIteratorTestCase
+{
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($mode, $expected)
+ {
+ $inner = new InnerTypeIterator(self::$files);
+
+ $iterator = new FileTypeFilterIterator($inner, $mode);
+
+ $this->assertIterator($expected, $iterator);
+ }
+
+ public function getAcceptData()
+ {
+ $onlyFiles = array(
+ 'test.py',
+ 'foo/bar.tmp',
+ 'test.php',
+ '.bar',
+ '.foo/.bar',
+ '.foo/bar',
+ 'foo bar',
+ );
+
+ $onlyDirectories = array(
+ '.git',
+ 'foo',
+ 'toto',
+ '.foo',
+ );
+
+ return array(
+ array(FileTypeFilterIterator::ONLY_FILES, $this->toAbsolute($onlyFiles)),
+ array(FileTypeFilterIterator::ONLY_DIRECTORIES, $this->toAbsolute($onlyDirectories)),
+ );
+ }
+}
+
+class InnerTypeIterator extends \ArrayIterator
+{
+ public function current()
+ {
+ return new \SplFileInfo(parent::current());
+ }
+
+ public function isFile()
+ {
+ return $this->current()->isFile();
+ }
+
+ public function isDir()
+ {
+ return $this->current()->isDir();
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php
new file mode 100644
index 0000000..744bdae
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
+
+class FilecontentFilterIteratorTest extends IteratorTestCase
+{
+ public function testAccept()
+ {
+ $inner = new MockFileListIterator(array('test.txt'));
+ $iterator = new FilecontentFilterIterator($inner, array(), array());
+ $this->assertIterator(array('test.txt'), $iterator);
+ }
+
+ public function testDirectory()
+ {
+ $inner = new MockFileListIterator(array('directory'));
+ $iterator = new FilecontentFilterIterator($inner, array('directory'), array());
+ $this->assertIterator(array(), $iterator);
+ }
+
+ public function testUnreadableFile()
+ {
+ $inner = new MockFileListIterator(array('file r-'));
+ $iterator = new FilecontentFilterIterator($inner, array('file r-'), array());
+ $this->assertIterator(array(), $iterator);
+ }
+
+ /**
+ * @dataProvider getTestFilterData
+ */
+ public function testFilter(\Iterator $inner, array $matchPatterns, array $noMatchPatterns, array $resultArray)
+ {
+ $iterator = new FilecontentFilterIterator($inner, $matchPatterns, $noMatchPatterns);
+ $this->assertIterator($resultArray, $iterator);
+ }
+
+ public function getTestFilterData()
+ {
+ $inner = new MockFileListIterator();
+
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'a.txt',
+ 'contents' => 'Lorem ipsum...',
+ 'type' => 'file',
+ 'mode' => 'r+', )
+ );
+
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'b.yml',
+ 'contents' => 'dolor sit...',
+ 'type' => 'file',
+ 'mode' => 'r+', )
+ );
+
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'some/other/dir/third.php',
+ 'contents' => 'amet...',
+ 'type' => 'file',
+ 'mode' => 'r+', )
+ );
+
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'unreadable-file.txt',
+ 'contents' => false,
+ 'type' => 'file',
+ 'mode' => 'r+', )
+ );
+
+ return array(
+ array($inner, array('.'), array(), array('a.txt', 'b.yml', 'some/other/dir/third.php')),
+ array($inner, array('ipsum'), array(), array('a.txt')),
+ array($inner, array('i', 'amet'), array('Lorem', 'amet'), array('b.yml')),
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilenameFilterIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilenameFilterIteratorTest.php
new file mode 100644
index 0000000..c4b9795
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilenameFilterIteratorTest.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\FilenameFilterIterator;
+
+class FilenameFilterIteratorTest extends IteratorTestCase
+{
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($matchPatterns, $noMatchPatterns, $expected)
+ {
+ $inner = new InnerNameIterator(array('test.php', 'test.py', 'foo.php'));
+
+ $iterator = new FilenameFilterIterator($inner, $matchPatterns, $noMatchPatterns);
+
+ $this->assertIterator($expected, $iterator);
+ }
+
+ public function getAcceptData()
+ {
+ return array(
+ array(array('test.*'), array(), array('test.php', 'test.py')),
+ array(array(), array('test.*'), array('foo.php')),
+ array(array('*.php'), array('test.*'), array('foo.php')),
+ array(array('*.php', '*.py'), array('foo.*'), array('test.php', 'test.py')),
+ array(array('/\.php$/'), array(), array('test.php', 'foo.php')),
+ array(array(), array('/\.php$/'), array('test.py')),
+ );
+ }
+}
+
+class InnerNameIterator extends \ArrayIterator
+{
+ public function current()
+ {
+ return new \SplFileInfo(parent::current());
+ }
+
+ public function getFilename()
+ {
+ return parent::current();
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php
new file mode 100644
index 0000000..029a266
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+/**
+ * @author Alex Bogomazov
+ */
+class FilterIteratorTest extends RealIteratorTestCase
+{
+ public function testFilterFilesystemIterators()
+ {
+ $i = new \FilesystemIterator($this->toAbsolute());
+
+ // it is expected that there are test.py test.php in the tmpDir
+ $i = $this->getMockForAbstractClass('Symfony\Component\Finder\Iterator\FilterIterator', array($i));
+ $i->expects($this->any())
+ ->method('accept')
+ ->will($this->returnCallback(function () use ($i) {
+ return (bool) preg_match('/\.php/', (string) $i->current());
+ })
+ );
+
+ $c = 0;
+ foreach ($i as $item) {
+ $c++;
+ }
+
+ $this->assertEquals(1, $c);
+
+ $i->rewind();
+
+ $c = 0;
+ foreach ($i as $item) {
+ $c++;
+ }
+
+ // This would fail with \FilterIterator but works with Symfony\Component\Finder\Iterator\FilterIterator
+ // see https://bugs.php.net/bug.php?id=49104
+ $this->assertEquals(1, $c);
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/Iterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/Iterator.php
new file mode 100644
index 0000000..849bf08
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/Iterator.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+class Iterator implements \Iterator
+{
+ protected $values = array();
+
+ public function __construct(array $values = array())
+ {
+ foreach ($values as $value) {
+ $this->attach(new \SplFileInfo($value));
+ }
+ $this->rewind();
+ }
+
+ public function attach(\SplFileInfo $fileinfo)
+ {
+ $this->values[] = $fileinfo;
+ }
+
+ public function rewind()
+ {
+ reset($this->values);
+ }
+
+ public function valid()
+ {
+ return false !== $this->current();
+ }
+
+ public function next()
+ {
+ next($this->values);
+ }
+
+ public function current()
+ {
+ return current($this->values);
+ }
+
+ public function key()
+ {
+ return key($this->values);
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php
new file mode 100644
index 0000000..ae7388e
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+abstract class IteratorTestCase extends \PHPUnit_Framework_TestCase
+{
+ protected function assertIterator($expected, \Traversable $iterator)
+ {
+ // set iterator_to_array $use_key to false to avoid values merge
+ // this made FinderTest::testAppendWithAnArray() failed with GnuFinderAdapter
+ $values = array_map(function (\SplFileInfo $fileinfo) { return str_replace('/', DIRECTORY_SEPARATOR, $fileinfo->getPathname()); }, iterator_to_array($iterator, false));
+
+ $expected = array_map(function ($path) { return str_replace('/', DIRECTORY_SEPARATOR, $path); }, $expected);
+
+ sort($values);
+ sort($expected);
+
+ $this->assertEquals($expected, array_values($values));
+ }
+
+ protected function assertOrderedIterator($expected, \Traversable $iterator)
+ {
+ $values = array_map(function (\SplFileInfo $fileinfo) { return $fileinfo->getPathname(); }, iterator_to_array($iterator));
+
+ $this->assertEquals($expected, array_values($values));
+ }
+
+ /**
+ * Same as assertOrderedIterator, but checks the order of groups of
+ * array elements.
+ *
+ * @param array $expected - an array of arrays. For any two subarrays
+ * $a and $b such that $a goes before $b in $expected, the method
+ * asserts that any element of $a goes before any element of $b
+ * in the sequence generated by $iterator
+ * @param \Traversable $iterator
+ */
+ protected function assertOrderedIteratorForGroups($expected, \Traversable $iterator)
+ {
+ $values = array_values(array_map(function (\SplFileInfo $fileinfo) { return $fileinfo->getPathname(); }, iterator_to_array($iterator)));
+
+ foreach ($expected as $subarray) {
+ $temp = array();
+ while (count($values) && count($temp) < count($subarray)) {
+ array_push($temp, array_shift($values));
+ }
+ sort($temp);
+ sort($subarray);
+ $this->assertEquals($subarray, $temp);
+ }
+ }
+
+ /**
+ * Same as IteratorTestCase::assertIterator with foreach usage.
+ *
+ * @param array $expected
+ * @param \Traversable $iterator
+ */
+ protected function assertIteratorInForeach($expected, \Traversable $iterator)
+ {
+ $values = array();
+ foreach ($iterator as $file) {
+ $this->assertInstanceOf('Symfony\\Component\\Finder\\SplFileInfo', $file);
+ $values[] = $file->getPathname();
+ }
+
+ sort($values);
+ sort($expected);
+
+ $this->assertEquals($expected, array_values($values));
+ }
+
+ /**
+ * Same as IteratorTestCase::assertOrderedIterator with foreach usage.
+ *
+ * @param array $expected
+ * @param \Traversable $iterator
+ */
+ protected function assertOrderedIteratorInForeach($expected, \Traversable $iterator)
+ {
+ $values = array();
+ foreach ($iterator as $file) {
+ $this->assertInstanceOf('Symfony\\Component\\Finder\\SplFileInfo', $file);
+ $values[] = $file->getPathname();
+ }
+
+ $this->assertEquals($expected, array_values($values));
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockFileListIterator.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockFileListIterator.php
new file mode 100644
index 0000000..eb0adfa
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockFileListIterator.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+class MockFileListIterator extends \ArrayIterator
+{
+ public function __construct(array $filesArray = array())
+ {
+ $files = array_map(function ($file) { return new MockSplFileInfo($file); }, $filesArray);
+ parent::__construct($files);
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php
new file mode 100644
index 0000000..f2e8f8e
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php
@@ -0,0 +1,134 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+class MockSplFileInfo extends \SplFileInfo
+{
+ const TYPE_DIRECTORY = 1;
+ const TYPE_FILE = 2;
+ const TYPE_UNKNOWN = 3;
+
+ private $contents = null;
+ private $mode = null;
+ private $type = null;
+ private $relativePath = null;
+ private $relativePathname = null;
+
+ public function __construct($param)
+ {
+ if (is_string($param)) {
+ parent::__construct($param);
+ } elseif (is_array($param)) {
+ $defaults = array(
+ 'name' => 'file.txt',
+ 'contents' => null,
+ 'mode' => null,
+ 'type' => null,
+ 'relativePath' => null,
+ 'relativePathname' => null,
+ );
+ $defaults = array_merge($defaults, $param);
+ parent::__construct($defaults['name']);
+ $this->setContents($defaults['contents']);
+ $this->setMode($defaults['mode']);
+ $this->setType($defaults['type']);
+ $this->setRelativePath($defaults['relativePath']);
+ $this->setRelativePathname($defaults['relativePathname']);
+ } else {
+ throw new \RuntimeException(sprintf('Incorrect parameter "%s"', $param));
+ }
+ }
+
+ public function isFile()
+ {
+ if (null === $this->type) {
+ return preg_match('/file/', $this->getFilename());
+ };
+
+ return self::TYPE_FILE === $this->type;
+ }
+
+ public function isDir()
+ {
+ if (null === $this->type) {
+ return preg_match('/directory/', $this->getFilename());
+ }
+
+ return self::TYPE_DIRECTORY === $this->type;
+ }
+
+ public function isReadable()
+ {
+ if (null === $this->mode) {
+ return preg_match('/r\+/', $this->getFilename());
+ }
+
+ return preg_match('/r\+/', $this->mode);
+ }
+
+ public function getContents()
+ {
+ return $this->contents;
+ }
+
+ public function setContents($contents)
+ {
+ $this->contents = $contents;
+ }
+
+ public function setMode($mode)
+ {
+ $this->mode = $mode;
+ }
+
+ public function setType($type)
+ {
+ if (is_string($type)) {
+ switch ($type) {
+ case 'directory':
+ $this->type = self::TYPE_DIRECTORY;
+ case 'd':
+ $this->type = self::TYPE_DIRECTORY;
+ break;
+ case 'file':
+ $this->type = self::TYPE_FILE;
+ case 'f':
+ $this->type = self::TYPE_FILE;
+ break;
+ default:
+ $this->type = self::TYPE_UNKNOWN;
+ }
+ } else {
+ $this->type = $type;
+ }
+ }
+
+ public function setRelativePath($relativePath)
+ {
+ $this->relativePath = $relativePath;
+ }
+
+ public function setRelativePathname($relativePathname)
+ {
+ $this->relativePathname = $relativePathname;
+ }
+
+ public function getRelativePath()
+ {
+ return $this->relativePath;
+ }
+
+ public function getRelativePathname()
+ {
+ return $this->relativePathname;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php
new file mode 100644
index 0000000..89d8edb
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\MultiplePcreFilterIterator;
+
+class MultiplePcreFilterIteratorTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getIsRegexFixtures
+ */
+ public function testIsRegex($string, $isRegex, $message)
+ {
+ $testIterator = new TestMultiplePcreFilterIterator();
+ $this->assertEquals($isRegex, $testIterator->isRegex($string), $message);
+ }
+
+ public function getIsRegexFixtures()
+ {
+ return array(
+ array('foo', false, 'string'),
+ array(' foo ', false, '" " is not a valid delimiter'),
+ array('\\foo\\', false, '"\\" is not a valid delimiter'),
+ array('afooa', false, '"a" is not a valid delimiter'),
+ array('//', false, 'the pattern should contain at least 1 character'),
+ array('/a/', true, 'valid regex'),
+ array('/foo/', true, 'valid regex'),
+ array('/foo/i', true, 'valid regex with a single modifier'),
+ array('/foo/imsxu', true, 'valid regex with multiple modifiers'),
+ array('#foo#', true, '"#" is a valid delimiter'),
+ array('{foo}', true, '"{,}" is a valid delimiter pair'),
+ array('*foo.*', false, '"*" is not considered as a valid delimiter'),
+ array('?foo.?', false, '"?" is not considered as a valid delimiter'),
+ );
+ }
+}
+
+class TestMultiplePcreFilterIterator extends MultiplePcreFilterIterator
+{
+ public function __construct()
+ {
+ }
+
+ public function accept()
+ {
+ throw new \BadFunctionCallException('Not implemented');
+ }
+
+ public function isRegex($str)
+ {
+ return parent::isRegex($str);
+ }
+
+ public function toRegex($str)
+ {
+ throw new \BadFunctionCallException('Not implemented');
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/PathFilterIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/PathFilterIteratorTest.php
new file mode 100644
index 0000000..579beed
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/PathFilterIteratorTest.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\PathFilterIterator;
+
+class PathFilterIteratorTest extends IteratorTestCase
+{
+ /**
+ * @dataProvider getTestFilterData
+ */
+ public function testFilter(\Iterator $inner, array $matchPatterns, array $noMatchPatterns, array $resultArray)
+ {
+ $iterator = new PathFilterIterator($inner, $matchPatterns, $noMatchPatterns);
+ $this->assertIterator($resultArray, $iterator);
+ }
+
+ public function getTestFilterData()
+ {
+ $inner = new MockFileListIterator();
+
+ //PATH: A/B/C/abc.dat
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'abc.dat',
+ 'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
+ ));
+
+ //PATH: A/B/ab.dat
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'ab.dat',
+ 'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
+ ));
+
+ //PATH: A/a.dat
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'a.dat',
+ 'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'a.dat',
+ ));
+
+ //PATH: copy/A/B/C/abc.dat.copy
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'abc.dat.copy',
+ 'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
+ ));
+
+ //PATH: copy/A/B/ab.dat.copy
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'ab.dat.copy',
+ 'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
+ ));
+
+ //PATH: copy/A/a.dat.copy
+ $inner[] = new MockSplFileInfo(array(
+ 'name' => 'a.dat.copy',
+ 'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'a.dat',
+ ));
+
+ return array(
+ array($inner, array('/^A/'), array(), array('abc.dat', 'ab.dat', 'a.dat')),
+ array($inner, array('/^A\/B/'), array(), array('abc.dat', 'ab.dat')),
+ array($inner, array('/^A\/B\/C/'), array(), array('abc.dat')),
+ array($inner, array('/A\/B\/C/'), array(), array('abc.dat', 'abc.dat.copy')),
+
+ array($inner, array('A'), array(), array('abc.dat', 'ab.dat', 'a.dat', 'abc.dat.copy', 'ab.dat.copy', 'a.dat.copy')),
+ array($inner, array('A/B'), array(), array('abc.dat', 'ab.dat', 'abc.dat.copy', 'ab.dat.copy')),
+ array($inner, array('A/B/C'), array(), array('abc.dat', 'abc.dat.copy')),
+
+ array($inner, array('copy/A'), array(), array('abc.dat.copy', 'ab.dat.copy', 'a.dat.copy')),
+ array($inner, array('copy/A/B'), array(), array('abc.dat.copy', 'ab.dat.copy')),
+ array($inner, array('copy/A/B/C'), array(), array('abc.dat.copy')),
+
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RealIteratorTestCase.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RealIteratorTestCase.php
new file mode 100644
index 0000000..e22476d
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RealIteratorTestCase.php
@@ -0,0 +1,109 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+abstract class RealIteratorTestCase extends IteratorTestCase
+{
+ protected static $tmpDir;
+ protected static $files;
+
+ public static function setUpBeforeClass()
+ {
+ self::$tmpDir = realpath(sys_get_temp_dir()).DIRECTORY_SEPARATOR.'symfony_finder';
+
+ self::$files = array(
+ '.git/',
+ '.foo/',
+ '.foo/.bar',
+ '.foo/bar',
+ '.bar',
+ 'test.py',
+ 'foo/',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'toto/',
+ 'foo bar',
+ );
+
+ self::$files = self::toAbsolute(self::$files);
+
+ if (is_dir(self::$tmpDir)) {
+ self::tearDownAfterClass();
+ } else {
+ mkdir(self::$tmpDir);
+ }
+
+ foreach (self::$files as $file) {
+ if (DIRECTORY_SEPARATOR === $file[strlen($file) - 1]) {
+ mkdir($file);
+ } else {
+ touch($file);
+ }
+ }
+
+ file_put_contents(self::toAbsolute('test.php'), str_repeat(' ', 800));
+ file_put_contents(self::toAbsolute('test.py'), str_repeat(' ', 2000));
+
+ touch(self::toAbsolute('foo/bar.tmp'), strtotime('2005-10-15'));
+ touch(self::toAbsolute('test.php'), strtotime('2005-10-15'));
+ }
+
+ public static function tearDownAfterClass()
+ {
+ foreach (array_reverse(self::$files) as $file) {
+ if (DIRECTORY_SEPARATOR === $file[strlen($file) - 1]) {
+ @rmdir($file);
+ } else {
+ @unlink($file);
+ }
+ }
+ }
+
+ protected static function toAbsolute($files = null)
+ {
+ /*
+ * Without the call to setUpBeforeClass() property can be null.
+ */
+ if (!self::$tmpDir) {
+ self::$tmpDir = realpath(sys_get_temp_dir()).DIRECTORY_SEPARATOR.'symfony_finder';
+ }
+
+ if (is_array($files)) {
+ $f = array();
+ foreach ($files as $file) {
+ if (is_array($file)) {
+ $f[] = self::toAbsolute($file);
+ } else {
+ $f[] = self::$tmpDir.DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $file);
+ }
+ }
+
+ return $f;
+ }
+
+ if (is_string($files)) {
+ return self::$tmpDir.DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $files);
+ }
+
+ return self::$tmpDir;
+ }
+
+ protected static function toAbsoluteFixtures($files)
+ {
+ $f = array();
+ foreach ($files as $file) {
+ $f[] = realpath(__DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.$file);
+ }
+
+ return $f;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php
new file mode 100644
index 0000000..412054b
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+*
+* (c) Fabien Potencier <fabien@symfony.com>
+*
+* For the full copyright and license information, please view the LICENSE
+* file that was distributed with this source code.
+*/
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator;
+
+class RecursiveDirectoryIteratorTest extends IteratorTestCase
+{
+ /**
+ * @dataProvider getPaths
+ *
+ * @param string $path
+ * @param bool $seekable
+ * @param array $contains
+ * @param string $message
+ */
+ public function testRewind($path, $seekable, $contains, $message = null)
+ {
+ try {
+ $i = new RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS);
+ } catch (\UnexpectedValueException $e) {
+ $this->markTestSkipped(sprintf('Unsupported stream "%s".', $path));
+ }
+
+ $i->rewind();
+
+ $this->assertTrue(true, $message);
+ }
+
+ /**
+ * @dataProvider getPaths
+ *
+ * @param string $path
+ * @param bool $seekable
+ * @param array $contains
+ * @param string $message
+ */
+ public function testSeek($path, $seekable, $contains, $message = null)
+ {
+ try {
+ $i = new RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS);
+ } catch (\UnexpectedValueException $e) {
+ $this->markTestSkipped(sprintf('Unsupported stream "%s".', $path));
+ }
+
+ $actual = array();
+
+ $i->seek(0);
+ $actual[] = $i->getPathname();
+
+ $i->seek(1);
+ $actual[] = $i->getPathname();
+
+ $i->seek(2);
+ $actual[] = $i->getPathname();
+
+ $this->assertEquals($contains, $actual);
+ }
+
+ public function getPaths()
+ {
+ $data = array();
+
+ // ftp
+ $contains = array(
+ 'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'README',
+ 'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'index.html',
+ 'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'pub',
+ );
+ $data[] = array('ftp://ftp.mozilla.org/', false, $contains);
+
+ return $data;
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SizeRangeFilterIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SizeRangeFilterIteratorTest.php
new file mode 100644
index 0000000..8780db4
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SizeRangeFilterIteratorTest.php
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator;
+use Symfony\Component\Finder\Comparator\NumberComparator;
+
+class SizeRangeFilterIteratorTest extends RealIteratorTestCase
+{
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($size, $expected)
+ {
+ $inner = new InnerSizeIterator(self::$files);
+
+ $iterator = new SizeRangeFilterIterator($inner, $size);
+
+ $this->assertIterator($expected, $iterator);
+ }
+
+ public function getAcceptData()
+ {
+ $lessThan1KGreaterThan05K = array(
+ '.foo',
+ '.git',
+ 'foo',
+ 'test.php',
+ 'toto',
+ );
+
+ return array(
+ array(array(new NumberComparator('< 1K'), new NumberComparator('> 0.5K')), $this->toAbsolute($lessThan1KGreaterThan05K)),
+ );
+ }
+}
+
+class InnerSizeIterator extends \ArrayIterator
+{
+ public function current()
+ {
+ return new \SplFileInfo(parent::current());
+ }
+
+ public function getFilename()
+ {
+ return parent::current();
+ }
+
+ public function isFile()
+ {
+ return $this->current()->isFile();
+ }
+
+ public function getSize()
+ {
+ return $this->current()->getSize();
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php
new file mode 100644
index 0000000..e2f433f
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php
@@ -0,0 +1,169 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Finder\Tests\Iterator;
+
+use Symfony\Component\Finder\Iterator\SortableIterator;
+
+class SortableIteratorTest extends RealIteratorTestCase
+{
+ public function testConstructor()
+ {
+ try {
+ new SortableIterator(new Iterator(array()), 'foobar');
+ $this->fail('__construct() throws an \InvalidArgumentException exception if the mode is not valid');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException exception if the mode is not valid');
+ }
+ }
+
+ /**
+ * @dataProvider getAcceptData
+ */
+ public function testAccept($mode, $expected)
+ {
+ if (!is_callable($mode)) {
+ switch ($mode) {
+ case SortableIterator::SORT_BY_ACCESSED_TIME :
+ file_get_contents(self::toAbsolute('.git'));
+ sleep(1);
+ file_get_contents(self::toAbsolute('.bar'));
+ break;
+ case SortableIterator::SORT_BY_CHANGED_TIME :
+ file_put_contents(self::toAbsolute('test.php'), 'foo');
+ sleep(1);
+ file_put_contents(self::toAbsolute('test.py'), 'foo');
+ break;
+ case SortableIterator::SORT_BY_MODIFIED_TIME :
+ file_put_contents(self::toAbsolute('test.php'), 'foo');
+ sleep(1);
+ file_put_contents(self::toAbsolute('test.py'), 'foo');
+ break;
+ }
+ }
+
+ $inner = new Iterator(self::$files);
+
+ $iterator = new SortableIterator($inner, $mode);
+
+ if ($mode === SortableIterator::SORT_BY_ACCESSED_TIME
+ || $mode === SortableIterator::SORT_BY_CHANGED_TIME
+ || $mode === SortableIterator::SORT_BY_MODIFIED_TIME) {
+ $this->assertOrderedIteratorForGroups($expected, $iterator);
+ } else {
+ $this->assertOrderedIterator($expected, $iterator);
+ }
+ }
+
+ public function getAcceptData()
+ {
+ $sortByName = array(
+ '.bar',
+ '.foo',
+ '.foo/.bar',
+ '.foo/bar',
+ '.git',
+ 'foo',
+ 'foo bar',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'test.py',
+ 'toto',
+ );
+
+ $sortByType = array(
+ '.foo',
+ '.git',
+ 'foo',
+ 'toto',
+ '.bar',
+ '.foo/.bar',
+ '.foo/bar',
+ 'foo bar',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'test.py',
+ );
+
+ $customComparison = array(
+ '.bar',
+ '.foo',
+ '.foo/.bar',
+ '.foo/bar',
+ '.git',
+ 'foo',
+ 'foo bar',
+ 'foo/bar.tmp',
+ 'test.php',
+ 'test.py',
+ 'toto',
+ );
+
+ $sortByAccessedTime = array(
+ // For these two files the access time was set to 2005-10-15
+ array('foo/bar.tmp', 'test.php'),
+ // These files were created more or less at the same time
+ array(
+ '.git',
+ '.foo',
+ '.foo/.bar',
+ '.foo/bar',
+ 'test.py',
+ 'foo',
+ 'toto',
+ 'foo bar',
+ ),
+ // This file was accessed after sleeping for 1 sec
+ array('.bar'),
+ );
+
+ $sortByChangedTime = array(
+ array(
+ '.git',
+ '.foo',
+ '.foo/.bar',
+ '.foo/bar',
+ '.bar',
+ 'foo',
+ 'foo/bar.tmp',
+ 'toto',
+ 'foo bar',
+ ),
+ array('test.php'),
+ array('test.py'),
+ );
+
+ $sortByModifiedTime = array(
+ array(
+ '.git',
+ '.foo',
+ '.foo/.bar',
+ '.foo/bar',
+ '.bar',
+ 'foo',
+ 'foo/bar.tmp',
+ 'toto',
+ 'foo bar',
+ ),
+ array('test.php'),
+ array('test.py'),
+ );
+
+ return array(
+ array(SortableIterator::SORT_BY_NAME, $this->toAbsolute($sortByName)),
+ array(SortableIterator::SORT_BY_TYPE, $this->toAbsolute($sortByType)),
+ array(SortableIterator::SORT_BY_ACCESSED_TIME, $this->toAbsolute($sortByAccessedTime)),
+ array(SortableIterator::SORT_BY_CHANGED_TIME, $this->toAbsolute($sortByChangedTime)),
+ array(SortableIterator::SORT_BY_MODIFIED_TIME, $this->toAbsolute($sortByModifiedTime)),
+ array(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealpath(), $b->getRealpath()); }, $this->toAbsolute($customComparison)),
+ );
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/composer.json b/vendor/symfony/finder/Symfony/Component/Finder/composer.json
new file mode 100644
index 0000000..9112218
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/composer.json
@@ -0,0 +1,34 @@
+{
+ "name": "symfony/finder",
+ "type": "library",
+ "description": "Symfony Finder Component",
+ "keywords": [],
+ "homepage": "http://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7"
+ },
+ "autoload": {
+ "psr-0": { "Symfony\\Component\\Finder\\": "" }
+ },
+ "target-dir": "Symfony/Component/Finder",
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ }
+}
diff --git a/vendor/symfony/finder/Symfony/Component/Finder/phpunit.xml.dist b/vendor/symfony/finder/Symfony/Component/Finder/phpunit.xml.dist
new file mode 100644
index 0000000..bc38cca
--- /dev/null
+++ b/vendor/symfony/finder/Symfony/Component/Finder/phpunit.xml.dist
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+ <testsuites>
+ <testsuite name="Symfony Finder Component Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Tests</directory>
+ <directory>./vendor</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/.gitignore b/vendor/symfony/translation/Symfony/Component/Translation/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/CHANGELOG.md b/vendor/symfony/translation/Symfony/Component/Translation/CHANGELOG.md
new file mode 100644
index 0000000..a13e573
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/CHANGELOG.md
@@ -0,0 +1,42 @@
+CHANGELOG
+=========
+
+2.6.0
+-----
+
+ * added possibility to cache catalogues
+ * added TranslatorBagInterface
+ * added LoggingTranslator
+ * added Translator::getMessages() for retrieving the message catalogue as an array
+
+2.5.0
+-----
+
+ * added relative file path template to the file dumpers
+ * added optional backup to the file dumpers
+ * changed IcuResFileDumper to extend FileDumper
+
+2.3.0
+-----
+
+ * added classes to make operations on catalogues (like making a diff or a merge on 2 catalogues)
+ * added Translator::getFallbackLocales()
+ * deprecated Translator::setFallbackLocale() in favor of the new Translator::setFallbackLocales() method
+
+2.2.0
+-----
+
+ * QtTranslationsLoader class renamed to QtFileLoader. QtTranslationsLoader is deprecated and will be removed in 2.3.
+ * [BC BREAK] uniformized the exception thrown by the load() method when an error occurs. The load() method now
+ throws Symfony\Component\Translation\Exception\NotFoundResourceException when a resource cannot be found
+ and Symfony\Component\Translation\Exception\InvalidResourceException when a resource is invalid.
+ * changed the exception class thrown by some load() methods from \RuntimeException to \InvalidArgumentException
+ (IcuDatFileLoader, IcuResFileLoader and QtFileLoader)
+
+2.1.0
+-----
+
+ * added support for more than one fallback locale
+ * added support for extracting translation messages from templates (Twig and PHP)
+ * added dumpers for translation catalogs
+ * added support for QT, gettext, and ResourceBundles
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Catalogue/AbstractOperation.php b/vendor/symfony/translation/Symfony/Component/Translation/Catalogue/AbstractOperation.php
new file mode 100644
index 0000000..062056b
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Catalogue/AbstractOperation.php
@@ -0,0 +1,146 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+/**
+ * Base catalogues binary operation class.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+abstract class AbstractOperation implements OperationInterface
+{
+ /**
+ * @var MessageCatalogueInterface
+ */
+ protected $source;
+
+ /**
+ * @var MessageCatalogueInterface
+ */
+ protected $target;
+
+ /**
+ * @var MessageCatalogue
+ */
+ protected $result;
+
+ /**
+ * @var null|array
+ */
+ private $domains;
+
+ /**
+ * @var array
+ */
+ protected $messages;
+
+ /**
+ * @param MessageCatalogueInterface $source
+ * @param MessageCatalogueInterface $target
+ *
+ * @throws \LogicException
+ */
+ public function __construct(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
+ {
+ if ($source->getLocale() !== $target->getLocale()) {
+ throw new \LogicException('Operated catalogues must belong to the same locale.');
+ }
+
+ $this->source = $source;
+ $this->target = $target;
+ $this->result = new MessageCatalogue($source->getLocale());
+ $this->domains = null;
+ $this->messages = array();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDomains()
+ {
+ if (null === $this->domains) {
+ $this->domains = array_values(array_unique(array_merge($this->source->getDomains(), $this->target->getDomains())));
+ }
+
+ return $this->domains;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMessages($domain)
+ {
+ if (!in_array($domain, $this->getDomains())) {
+ throw new \InvalidArgumentException(sprintf('Invalid domain: %s.', $domain));
+ }
+
+ if (!isset($this->messages[$domain]['all'])) {
+ $this->processDomain($domain);
+ }
+
+ return $this->messages[$domain]['all'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getNewMessages($domain)
+ {
+ if (!in_array($domain, $this->getDomains())) {
+ throw new \InvalidArgumentException(sprintf('Invalid domain: %s.', $domain));
+ }
+
+ if (!isset($this->messages[$domain]['new'])) {
+ $this->processDomain($domain);
+ }
+
+ return $this->messages[$domain]['new'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getObsoleteMessages($domain)
+ {
+ if (!in_array($domain, $this->getDomains())) {
+ throw new \InvalidArgumentException(sprintf('Invalid domain: %s.', $domain));
+ }
+
+ if (!isset($this->messages[$domain]['obsolete'])) {
+ $this->processDomain($domain);
+ }
+
+ return $this->messages[$domain]['obsolete'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getResult()
+ {
+ foreach ($this->getDomains() as $domain) {
+ if (!isset($this->messages[$domain])) {
+ $this->processDomain($domain);
+ }
+ }
+
+ return $this->result;
+ }
+
+ /**
+ * @param string $domain
+ */
+ abstract protected function processDomain($domain);
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Catalogue/DiffOperation.php b/vendor/symfony/translation/Symfony/Component/Translation/Catalogue/DiffOperation.php
new file mode 100644
index 0000000..2d1994e
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Catalogue/DiffOperation.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+/**
+ * Diff operation between two catalogues.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class DiffOperation extends AbstractOperation
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function processDomain($domain)
+ {
+ $this->messages[$domain] = array(
+ 'all' => array(),
+ 'new' => array(),
+ 'obsolete' => array(),
+ );
+
+ foreach ($this->source->all($domain) as $id => $message) {
+ if ($this->target->has($id, $domain)) {
+ $this->messages[$domain]['all'][$id] = $message;
+ $this->result->add(array($id => $message), $domain);
+ if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) {
+ $this->result->setMetadata($id, $keyMetadata, $domain);
+ }
+ } else {
+ $this->messages[$domain]['obsolete'][$id] = $message;
+ }
+ }
+
+ foreach ($this->target->all($domain) as $id => $message) {
+ if (!$this->source->has($id, $domain)) {
+ $this->messages[$domain]['all'][$id] = $message;
+ $this->messages[$domain]['new'][$id] = $message;
+ $this->result->add(array($id => $message), $domain);
+ if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) {
+ $this->result->setMetadata($id, $keyMetadata, $domain);
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Catalogue/MergeOperation.php b/vendor/symfony/translation/Symfony/Component/Translation/Catalogue/MergeOperation.php
new file mode 100644
index 0000000..562ca0e
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Catalogue/MergeOperation.php
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+/**
+ * Merge operation between two catalogues.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class MergeOperation extends AbstractOperation
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function processDomain($domain)
+ {
+ $this->messages[$domain] = array(
+ 'all' => array(),
+ 'new' => array(),
+ 'obsolete' => array(),
+ );
+
+ foreach ($this->source->all($domain) as $id => $message) {
+ $this->messages[$domain]['all'][$id] = $message;
+ $this->result->add(array($id => $message), $domain);
+ if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) {
+ $this->result->setMetadata($id, $keyMetadata, $domain);
+ }
+ }
+
+ foreach ($this->target->all($domain) as $id => $message) {
+ if (!$this->source->has($id, $domain)) {
+ $this->messages[$domain]['all'][$id] = $message;
+ $this->messages[$domain]['new'][$id] = $message;
+ $this->result->add(array($id => $message), $domain);
+ if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) {
+ $this->result->setMetadata($id, $keyMetadata, $domain);
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Catalogue/OperationInterface.php b/vendor/symfony/translation/Symfony/Component/Translation/Catalogue/OperationInterface.php
new file mode 100644
index 0000000..d72378a
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Catalogue/OperationInterface.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+/**
+ * Represents an operation on catalogue(s).
+ *
+ * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
+ */
+interface OperationInterface
+{
+ /**
+ * Returns domains affected by operation.
+ *
+ * @return array
+ */
+ public function getDomains();
+
+ /**
+ * Returns all valid messages after operation.
+ *
+ * @param string $domain
+ *
+ * @return array
+ */
+ public function getMessages($domain);
+
+ /**
+ * Returns new messages after operation.
+ *
+ * @param string $domain
+ *
+ * @return array
+ */
+ public function getNewMessages($domain);
+
+ /**
+ * Returns obsolete messages after operation.
+ *
+ * @param string $domain
+ *
+ * @return array
+ */
+ public function getObsoleteMessages($domain);
+
+ /**
+ * Returns resulting catalogue.
+ *
+ * @return MessageCatalogueInterface
+ */
+ public function getResult();
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Dumper/CsvFileDumper.php b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/CsvFileDumper.php
new file mode 100644
index 0000000..08005b0
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/CsvFileDumper.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * CsvFileDumper generates a csv formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class CsvFileDumper extends FileDumper
+{
+ private $delimiter = ';';
+ private $enclosure = '"';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function format(MessageCatalogue $messages, $domain = 'messages')
+ {
+ $handle = fopen('php://memory', 'rb+');
+
+ foreach ($messages->all($domain) as $source => $target) {
+ fputcsv($handle, array($source, $target), $this->delimiter, $this->enclosure);
+ }
+
+ rewind($handle);
+ $output = stream_get_contents($handle);
+ fclose($handle);
+
+ return $output;
+ }
+
+ /**
+ * Sets the delimiter and escape character for CSV.
+ *
+ * @param string $delimiter delimiter character
+ * @param string $enclosure enclosure character
+ */
+ public function setCsvControl($delimiter = ';', $enclosure = '"')
+ {
+ $this->delimiter = $delimiter;
+ $this->enclosure = $enclosure;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExtension()
+ {
+ return 'csv';
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Dumper/DumperInterface.php b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/DumperInterface.php
new file mode 100644
index 0000000..cebc65e
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/DumperInterface.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * DumperInterface is the interface implemented by all translation dumpers.
+ * There is no common option.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+interface DumperInterface
+{
+ /**
+ * Dumps the message catalogue.
+ *
+ * @param MessageCatalogue $messages The message catalogue
+ * @param array $options Options that are used by the dumper
+ */
+ public function dump(MessageCatalogue $messages, $options = array());
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Dumper/FileDumper.php b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/FileDumper.php
new file mode 100644
index 0000000..f2f17d6
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/FileDumper.php
@@ -0,0 +1,122 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * FileDumper is an implementation of DumperInterface that dump a message catalogue to file(s).
+ * Performs backup of already existing files.
+ *
+ * Options:
+ * - path (mandatory): the directory where the files should be saved
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+abstract class FileDumper implements DumperInterface
+{
+ /**
+ * A template for the relative paths to files.
+ *
+ * @var string
+ */
+ protected $relativePathTemplate = '%domain%.%locale%.%extension%';
+
+ /**
+ * Make file backup before the dump.
+ *
+ * @var bool
+ */
+ private $backup = true;
+
+ /**
+ * Sets the template for the relative paths to files.
+ *
+ * @param string $relativePathTemplate A template for the relative paths to files
+ */
+ public function setRelativePathTemplate($relativePathTemplate)
+ {
+ $this->relativePathTemplate = $relativePathTemplate;
+ }
+
+ /**
+ * Sets backup flag.
+ *
+ * @param bool
+ */
+ public function setBackup($backup)
+ {
+ $this->backup = $backup;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function dump(MessageCatalogue $messages, $options = array())
+ {
+ if (!array_key_exists('path', $options)) {
+ throw new \InvalidArgumentException('The file dumper needs a path option.');
+ }
+
+ // save a file for each domain
+ foreach ($messages->getDomains() as $domain) {
+ // backup
+ $fullpath = $options['path'].'/'.$this->getRelativePath($domain, $messages->getLocale());
+ if (file_exists($fullpath)) {
+ if ($this->backup) {
+ copy($fullpath, $fullpath.'~');
+ }
+ } else {
+ $directory = dirname($fullpath);
+ if (!file_exists($directory) && !@mkdir($directory, 0777, true)) {
+ throw new \RuntimeException(sprintf('Unable to create directory "%s".', $directory));
+ }
+ }
+ // save file
+ file_put_contents($fullpath, $this->format($messages, $domain));
+ }
+ }
+
+ /**
+ * Transforms a domain of a message catalogue to its string representation.
+ *
+ * @param MessageCatalogue $messages
+ * @param string $domain
+ *
+ * @return string representation
+ */
+ abstract protected function format(MessageCatalogue $messages, $domain);
+
+ /**
+ * Gets the file extension of the dumper.
+ *
+ * @return string file extension
+ */
+ abstract protected function getExtension();
+
+ /**
+ * Gets the relative file path using the template.
+ *
+ * @param string $domain The domain
+ * @param string $locale The locale
+ *
+ * @return string The relative file path
+ */
+ private function getRelativePath($domain, $locale)
+ {
+ return strtr($this->relativePathTemplate, array(
+ '%domain%' => $domain,
+ '%locale%' => $locale,
+ '%extension%' => $this->getExtension(),
+ ));
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Dumper/IcuResFileDumper.php b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/IcuResFileDumper.php
new file mode 100644
index 0000000..0a2ed9f
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/IcuResFileDumper.php
@@ -0,0 +1,112 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * IcuResDumper generates an ICU ResourceBundle formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class IcuResFileDumper extends FileDumper
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected $relativePathTemplate = '%domain%/%locale%.%extension%';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function format(MessageCatalogue $messages, $domain = 'messages')
+ {
+ $data = $indexes = $resources = '';
+
+ foreach ($messages->all($domain) as $source => $target) {
+ $indexes .= pack('v', strlen($data) + 28);
+ $data .= $source."\0";
+ }
+
+ $data .= $this->writePadding($data);
+
+ $keyTop = $this->getPosition($data);
+
+ foreach ($messages->all($domain) as $source => $target) {
+ $resources .= pack('V', $this->getPosition($data));
+
+ $data .= pack('V', strlen($target))
+ .mb_convert_encoding($target."\0", 'UTF-16LE', 'UTF-8')
+ .$this->writePadding($data)
+ ;
+ }
+
+ $resOffset = $this->getPosition($data);
+
+ $data .= pack('v', count($messages))
+ .$indexes
+ .$this->writePadding($data)
+ .$resources
+ ;
+
+ $bundleTop = $this->getPosition($data);
+
+ $root = pack('V7',
+ $resOffset + (2 << 28), // Resource Offset + Resource Type
+ 6, // Index length
+ $keyTop, // Index keys top
+ $bundleTop, // Index resources top
+ $bundleTop, // Index bundle top
+ count($messages), // Index max table length
+ 0 // Index attributes
+ );
+
+ $header = pack('vC2v4C12@32',
+ 32, // Header size
+ 0xDA, 0x27, // Magic number 1 and 2
+ 20, 0, 0, 2, // Rest of the header, ..., Size of a char
+ 0x52, 0x65, 0x73, 0x42, // Data format identifier
+ 1, 2, 0, 0, // Data version
+ 1, 4, 0, 0 // Unicode version
+ );
+
+ $output = $header
+ .$root
+ .$data;
+
+ return $output;
+ }
+
+ private function writePadding($data)
+ {
+ $padding = strlen($data) % 4;
+
+ if ($padding) {
+ return str_repeat("\xAA", 4 - $padding);
+ }
+ }
+
+ private function getPosition($data)
+ {
+ $position = (strlen($data) + 28) / 4;
+
+ return $position;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExtension()
+ {
+ return 'res';
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Dumper/IniFileDumper.php b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/IniFileDumper.php
new file mode 100644
index 0000000..45df389
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/IniFileDumper.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * IniFileDumper generates an ini formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class IniFileDumper extends FileDumper
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function format(MessageCatalogue $messages, $domain = 'messages')
+ {
+ $output = '';
+
+ foreach ($messages->all($domain) as $source => $target) {
+ $escapeTarget = str_replace('"', '\"', $target);
+ $output .= $source.'="'.$escapeTarget."\"\n";
+ }
+
+ return $output;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExtension()
+ {
+ return 'ini';
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Dumper/JsonFileDumper.php b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/JsonFileDumper.php
new file mode 100644
index 0000000..fea7827
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/JsonFileDumper.php
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+if (!defined('JSON_PRETTY_PRINT')) {
+ define('JSON_PRETTY_PRINT', 128);
+}
+
+/**
+ * JsonFileDumper generates an json formatted string representation of a message catalogue.
+ *
+ * @author singles
+ */
+class JsonFileDumper extends FileDumper
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function format(MessageCatalogue $messages, $domain = 'messages')
+ {
+ return json_encode($messages->all($domain), JSON_PRETTY_PRINT);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExtension()
+ {
+ return 'json';
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Dumper/MoFileDumper.php b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/MoFileDumper.php
new file mode 100644
index 0000000..f8dc6ac
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/MoFileDumper.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Loader\MoFileLoader;
+
+/**
+ * MoFileDumper generates a gettext formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class MoFileDumper extends FileDumper
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function format(MessageCatalogue $messages, $domain = 'messages')
+ {
+ $output = $sources = $targets = $sourceOffsets = $targetOffsets = '';
+ $offsets = array();
+ $size = 0;
+
+ foreach ($messages->all($domain) as $source => $target) {
+ $offsets[] = array_map('strlen', array($sources, $source, $targets, $target));
+ $sources .= "\0".$source;
+ $targets .= "\0".$target;
+ ++$size;
+ }
+
+ $header = array(
+ 'magicNumber' => MoFileLoader::MO_LITTLE_ENDIAN_MAGIC,
+ 'formatRevision' => 0,
+ 'count' => $size,
+ 'offsetId' => MoFileLoader::MO_HEADER_SIZE,
+ 'offsetTranslated' => MoFileLoader::MO_HEADER_SIZE + (8 * $size),
+ 'sizeHashes' => 0,
+ 'offsetHashes' => MoFileLoader::MO_HEADER_SIZE + (16 * $size),
+ );
+
+ $sourcesSize = strlen($sources);
+ $sourcesStart = $header['offsetHashes'] + 1;
+
+ foreach ($offsets as $offset) {
+ $sourceOffsets .= $this->writeLong($offset[1])
+ .$this->writeLong($offset[0] + $sourcesStart);
+ $targetOffsets .= $this->writeLong($offset[3])
+ .$this->writeLong($offset[2] + $sourcesStart + $sourcesSize);
+ }
+
+ $output = implode(array_map(array($this, 'writeLong'), $header))
+ .$sourceOffsets
+ .$targetOffsets
+ .$sources
+ .$targets
+ ;
+
+ return $output;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExtension()
+ {
+ return 'mo';
+ }
+
+ private function writeLong($str)
+ {
+ return pack('V*', $str);
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Dumper/PhpFileDumper.php b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/PhpFileDumper.php
new file mode 100644
index 0000000..b354c12
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/PhpFileDumper.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * PhpFileDumper generates PHP files from a message catalogue.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class PhpFileDumper extends FileDumper
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function format(MessageCatalogue $messages, $domain)
+ {
+ $output = "<?php\n\nreturn ".var_export($messages->all($domain), true).";\n";
+
+ return $output;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExtension()
+ {
+ return 'php';
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Dumper/PoFileDumper.php b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/PoFileDumper.php
new file mode 100644
index 0000000..983064b
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/PoFileDumper.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * PoFileDumper generates a gettext formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class PoFileDumper extends FileDumper
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function format(MessageCatalogue $messages, $domain = 'messages')
+ {
+ $output = 'msgid ""'."\n";
+ $output .= 'msgstr ""'."\n";
+ $output .= '"Content-Type: text/plain; charset=UTF-8\n"'."\n";
+ $output .= '"Content-Transfer-Encoding: 8bit\n"'."\n";
+ $output .= '"Language: '.$messages->getLocale().'\n"'."\n";
+ $output .= "\n";
+
+ $newLine = false;
+ foreach ($messages->all($domain) as $source => $target) {
+ if ($newLine) {
+ $output .= "\n";
+ } else {
+ $newLine = true;
+ }
+ $output .= sprintf('msgid "%s"'."\n", $this->escape($source));
+ $output .= sprintf('msgstr "%s"', $this->escape($target));
+ }
+
+ return $output;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExtension()
+ {
+ return 'po';
+ }
+
+ private function escape($str)
+ {
+ return addcslashes($str, "\0..\37\42\134");
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Dumper/QtFileDumper.php b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/QtFileDumper.php
new file mode 100644
index 0000000..42aa093
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/QtFileDumper.php
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * QtFileDumper generates ts files from a message catalogue.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class QtFileDumper extends FileDumper
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function format(MessageCatalogue $messages, $domain)
+ {
+ $dom = new \DOMDocument('1.0', 'utf-8');
+ $dom->formatOutput = true;
+ $ts = $dom->appendChild($dom->createElement('TS'));
+ $context = $ts->appendChild($dom->createElement('context'));
+ $context->appendChild($dom->createElement('name', $domain));
+
+ foreach ($messages->all($domain) as $source => $target) {
+ $message = $context->appendChild($dom->createElement('message'));
+ $message->appendChild($dom->createElement('source', $source));
+ $message->appendChild($dom->createElement('translation', $target));
+ }
+
+ return $dom->saveXML();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExtension()
+ {
+ return 'ts';
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Dumper/XliffFileDumper.php b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/XliffFileDumper.php
new file mode 100644
index 0000000..58d1973
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/XliffFileDumper.php
@@ -0,0 +1,109 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * XliffFileDumper generates xliff files from a message catalogue.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class XliffFileDumper extends FileDumper
+{
+ /**
+ * @var string
+ */
+ private $defaultLocale;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function dump(MessageCatalogue $messages, $options = array())
+ {
+ if (array_key_exists('default_locale', $options)) {
+ $this->defaultLocale = $options['default_locale'];
+ } else {
+ $this->defaultLocale = \Locale::getDefault();
+ }
+
+ parent::dump($messages, $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function format(MessageCatalogue $messages, $domain)
+ {
+ $dom = new \DOMDocument('1.0', 'utf-8');
+ $dom->formatOutput = true;
+
+ $xliff = $dom->appendChild($dom->createElement('xliff'));
+ $xliff->setAttribute('version', '1.2');
+ $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2');
+
+ $xliffFile = $xliff->appendChild($dom->createElement('file'));
+ $xliffFile->setAttribute('source-language', str_replace('_', '-', $this->defaultLocale));
+ $xliffFile->setAttribute('target-language', str_replace('_', '-', $messages->getLocale()));
+ $xliffFile->setAttribute('datatype', 'plaintext');
+ $xliffFile->setAttribute('original', 'file.ext');
+
+ $xliffBody = $xliffFile->appendChild($dom->createElement('body'));
+ foreach ($messages->all($domain) as $source => $target) {
+ $translation = $dom->createElement('trans-unit');
+
+ $translation->setAttribute('id', md5($source));
+ $translation->setAttribute('resname', $source);
+
+ $s = $translation->appendChild($dom->createElement('source'));
+ $s->appendChild($dom->createTextNode($source));
+
+ // Does the target contain characters requiring a CDATA section?
+ $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
+
+ $t = $translation->appendChild($dom->createElement('target'));
+ $t->appendChild($text);
+
+ $metadata = $messages->getMetadata($source, $domain);
+ if (null !== $metadata && array_key_exists('notes', $metadata) && is_array($metadata['notes'])) {
+ foreach ($metadata['notes'] as $note) {
+ if (!isset($note['content'])) {
+ continue;
+ }
+
+ $n = $translation->appendChild($dom->createElement('note'));
+ $n->appendChild($dom->createTextNode($note['content']));
+
+ if (isset($note['priority'])) {
+ $n->setAttribute('priority', $note['priority']);
+ }
+
+ if (isset($note['from'])) {
+ $n->setAttribute('from', $note['from']);
+ }
+ }
+ }
+
+ $xliffBody->appendChild($translation);
+ }
+
+ return $dom->saveXML();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExtension()
+ {
+ return 'xlf';
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Dumper/YamlFileDumper.php b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/YamlFileDumper.php
new file mode 100644
index 0000000..5920fef
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Dumper/YamlFileDumper.php
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * YamlFileDumper generates yaml files from a message catalogue.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class YamlFileDumper extends FileDumper
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function format(MessageCatalogue $messages, $domain)
+ {
+ return Yaml::dump($messages->all($domain));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getExtension()
+ {
+ return 'yml';
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Exception/ExceptionInterface.php b/vendor/symfony/translation/Symfony/Component/Translation/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..7757e66
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Exception/ExceptionInterface.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Exception interface for all exceptions thrown by the component.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface ExceptionInterface
+{
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Exception/InvalidResourceException.php b/vendor/symfony/translation/Symfony/Component/Translation/Exception/InvalidResourceException.php
new file mode 100644
index 0000000..6413f1a
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Exception/InvalidResourceException.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Thrown when a resource cannot be loaded.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class InvalidResourceException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Exception/NotFoundResourceException.php b/vendor/symfony/translation/Symfony/Component/Translation/Exception/NotFoundResourceException.php
new file mode 100644
index 0000000..7826e5c
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Exception/NotFoundResourceException.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Thrown when a resource does not exist.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class NotFoundResourceException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Extractor/ChainExtractor.php b/vendor/symfony/translation/Symfony/Component/Translation/Extractor/ChainExtractor.php
new file mode 100644
index 0000000..50e3c84
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Extractor/ChainExtractor.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * ChainExtractor extracts translation messages from template files.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class ChainExtractor implements ExtractorInterface
+{
+ /**
+ * The extractors.
+ *
+ * @var ExtractorInterface[]
+ */
+ private $extractors = array();
+
+ /**
+ * Adds a loader to the translation extractor.
+ *
+ * @param string $format The format of the loader
+ * @param ExtractorInterface $extractor The loader
+ */
+ public function addExtractor($format, ExtractorInterface $extractor)
+ {
+ $this->extractors[$format] = $extractor;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setPrefix($prefix)
+ {
+ foreach ($this->extractors as $extractor) {
+ $extractor->setPrefix($prefix);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function extract($directory, MessageCatalogue $catalogue)
+ {
+ foreach ($this->extractors as $extractor) {
+ $extractor->extract($directory, $catalogue);
+ }
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Extractor/ExtractorInterface.php b/vendor/symfony/translation/Symfony/Component/Translation/Extractor/ExtractorInterface.php
new file mode 100644
index 0000000..6f877c3
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Extractor/ExtractorInterface.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * Extracts translation messages from a template directory to the catalogue.
+ * New found messages are injected to the catalogue using the prefix.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+interface ExtractorInterface
+{
+ /**
+ * Extracts translation messages from a template directory to the catalogue.
+ *
+ * @param string $directory The path to look into
+ * @param MessageCatalogue $catalogue The catalogue
+ */
+ public function extract($directory, MessageCatalogue $catalogue);
+
+ /**
+ * Sets the prefix that should be used for new found messages.
+ *
+ * @param string $prefix The prefix
+ */
+ public function setPrefix($prefix);
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/IdentityTranslator.php b/vendor/symfony/translation/Symfony/Component/Translation/IdentityTranslator.php
new file mode 100644
index 0000000..9c9212e
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/IdentityTranslator.php
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * IdentityTranslator does not translate anything.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class IdentityTranslator implements TranslatorInterface
+{
+ private $selector;
+ private $locale;
+
+ /**
+ * Constructor.
+ *
+ * @param MessageSelector|null $selector The message selector for pluralization
+ *
+ * @api
+ */
+ public function __construct(MessageSelector $selector = null)
+ {
+ $this->selector = $selector ?: new MessageSelector();
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function setLocale($locale)
+ {
+ $this->locale = $locale;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function getLocale()
+ {
+ return $this->locale ?: \Locale::getDefault();
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function trans($id, array $parameters = array(), $domain = null, $locale = null)
+ {
+ return strtr((string) $id, $parameters);
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
+ {
+ return strtr($this->selector->choose((string) $id, (int) $number, $locale ?: $this->getLocale()), $parameters);
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Interval.php b/vendor/symfony/translation/Symfony/Component/Translation/Interval.php
new file mode 100644
index 0000000..2a51156
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Interval.php
@@ -0,0 +1,107 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * Tests if a given number belongs to a given math interval.
+ *
+ * An interval can represent a finite set of numbers:
+ *
+ * {1,2,3,4}
+ *
+ * An interval can represent numbers between two numbers:
+ *
+ * [1, +Inf]
+ * ]-1,2[
+ *
+ * The left delimiter can be [ (inclusive) or ] (exclusive).
+ * The right delimiter can be [ (exclusive) or ] (inclusive).
+ * Beside numbers, you can use -Inf and +Inf for the infinite.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @see http://en.wikipedia.org/wiki/Interval_%28mathematics%29#The_ISO_notation
+ */
+class Interval
+{
+ /**
+ * Tests if the given number is in the math interval.
+ *
+ * @param int $number A number
+ * @param string $interval An interval
+ *
+ * @return bool
+ *
+ * @throws \InvalidArgumentException
+ */
+ public static function test($number, $interval)
+ {
+ $interval = trim($interval);
+
+ if (!preg_match('/^'.self::getIntervalRegexp().'$/x', $interval, $matches)) {
+ throw new \InvalidArgumentException(sprintf('"%s" is not a valid interval.', $interval));
+ }
+
+ if ($matches[1]) {
+ foreach (explode(',', $matches[2]) as $n) {
+ if ($number == $n) {
+ return true;
+ }
+ }
+ } else {
+ $leftNumber = self::convertNumber($matches['left']);
+ $rightNumber = self::convertNumber($matches['right']);
+
+ return
+ ('[' === $matches['left_delimiter'] ? $number >= $leftNumber : $number > $leftNumber)
+ && (']' === $matches['right_delimiter'] ? $number <= $rightNumber : $number < $rightNumber)
+ ;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns a Regexp that matches valid intervals.
+ *
+ * @return string A Regexp (without the delimiters)
+ */
+ public static function getIntervalRegexp()
+ {
+ return <<<EOF
+ ({\s*
+ (\-?\d+(\.\d+)?[\s*,\s*\-?\d+(\.\d+)?]*)
+ \s*})
+
+ |
+
+ (?P<left_delimiter>[\[\]])
+ \s*
+ (?P<left>-Inf|\-?\d+(\.\d+)?)
+ \s*,\s*
+ (?P<right>\+?Inf|\-?\d+(\.\d+)?)
+ \s*
+ (?P<right_delimiter>[\[\]])
+EOF;
+ }
+
+ private static function convertNumber($number)
+ {
+ if ('-Inf' === $number) {
+ return log(0);
+ } elseif ('+Inf' === $number || 'Inf' === $number) {
+ return -log(0);
+ }
+
+ return (float) $number;
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/LICENSE b/vendor/symfony/translation/Symfony/Component/Translation/LICENSE
new file mode 100644
index 0000000..43028bc
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2015 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/vendor/symfony/translation/Symfony/Component/Translation/Loader/ArrayLoader.php b/vendor/symfony/translation/Symfony/Component/Translation/Loader/ArrayLoader.php
new file mode 100644
index 0000000..68ba81d
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/ArrayLoader.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * ArrayLoader loads translations from a PHP array.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class ArrayLoader implements LoaderInterface
+{
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function load($resource, $locale, $domain = 'messages')
+ {
+ $this->flatten($resource);
+ $catalogue = new MessageCatalogue($locale);
+ $catalogue->add($resource, $domain);
+
+ return $catalogue;
+ }
+
+ /**
+ * Flattens an nested array of translations.
+ *
+ * The scheme used is:
+ * 'key' => array('key2' => array('key3' => 'value'))
+ * Becomes:
+ * 'key.key2.key3' => 'value'
+ *
+ * This function takes an array by reference and will modify it
+ *
+ * @param array &$messages The array that will be flattened
+ * @param array $subnode Current subnode being parsed, used internally for recursive calls
+ * @param string $path Current path being parsed, used internally for recursive calls
+ */
+ private function flatten(array &$messages, array $subnode = null, $path = null)
+ {
+ if (null === $subnode) {
+ $subnode = &$messages;
+ }
+ foreach ($subnode as $key => $value) {
+ if (is_array($value)) {
+ $nodePath = $path ? $path.'.'.$key : $key;
+ $this->flatten($messages, $value, $nodePath);
+ if (null === $path) {
+ unset($messages[$key]);
+ }
+ } elseif (null !== $path) {
+ $messages[$path.'.'.$key] = $value;
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/CsvFileLoader.php b/vendor/symfony/translation/Symfony/Component/Translation/Loader/CsvFileLoader.php
new file mode 100644
index 0000000..ddcf595
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/CsvFileLoader.php
@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * CsvFileLoader loads translations from CSV files.
+ *
+ * @author Saša Stamenković <umpirsky@gmail.com>
+ *
+ * @api
+ */
+class CsvFileLoader extends ArrayLoader
+{
+ private $delimiter = ';';
+ private $enclosure = '"';
+ private $escape = '\\';
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function load($resource, $locale, $domain = 'messages')
+ {
+ if (!stream_is_local($resource)) {
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+ }
+
+ if (!file_exists($resource)) {
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+ }
+
+ $messages = array();
+
+ try {
+ $file = new \SplFileObject($resource, 'rb');
+ } catch (\RuntimeException $e) {
+ throw new NotFoundResourceException(sprintf('Error opening file "%s".', $resource), 0, $e);
+ }
+
+ $file->setFlags(\SplFileObject::READ_CSV | \SplFileObject::SKIP_EMPTY);
+ $file->setCsvControl($this->delimiter, $this->enclosure, $this->escape);
+
+ foreach ($file as $data) {
+ if (substr($data[0], 0, 1) === '#') {
+ continue;
+ }
+
+ if (!isset($data[1])) {
+ continue;
+ }
+
+ if (count($data) == 2) {
+ $messages[$data[0]] = $data[1];
+ } else {
+ continue;
+ }
+ }
+
+ $catalogue = parent::load($messages, $locale, $domain);
+ $catalogue->addResource(new FileResource($resource));
+
+ return $catalogue;
+ }
+
+ /**
+ * Sets the delimiter, enclosure, and escape character for CSV.
+ *
+ * @param string $delimiter delimiter character
+ * @param string $enclosure enclosure character
+ * @param string $escape escape character
+ */
+ public function setCsvControl($delimiter = ';', $enclosure = '"', $escape = '\\')
+ {
+ $this->delimiter = $delimiter;
+ $this->enclosure = $enclosure;
+ $this->escape = $escape;
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/IcuDatFileLoader.php b/vendor/symfony/translation/Symfony/Component/Translation/Loader/IcuDatFileLoader.php
new file mode 100644
index 0000000..a36cd76
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/IcuDatFileLoader.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * IcuResFileLoader loads translations from a resource bundle.
+ *
+ * @author stealth35
+ */
+class IcuDatFileLoader extends IcuResFileLoader
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function load($resource, $locale, $domain = 'messages')
+ {
+ if (!stream_is_local($resource.'.dat')) {
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+ }
+
+ if (!file_exists($resource.'.dat')) {
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+ }
+
+ try {
+ $rb = new \ResourceBundle($locale, $resource);
+ } catch (\Exception $e) {
+ // HHVM compatibility: constructor throws on invalid resource
+ $rb = null;
+ }
+
+ if (!$rb) {
+ throw new InvalidResourceException(sprintf('Cannot load resource "%s"', $resource));
+ } elseif (intl_is_failure($rb->getErrorCode())) {
+ throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
+ }
+
+ $messages = $this->flatten($rb);
+ $catalogue = new MessageCatalogue($locale);
+ $catalogue->add($messages, $domain);
+ $catalogue->addResource(new FileResource($resource.'.dat'));
+
+ return $catalogue;
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/IcuResFileLoader.php b/vendor/symfony/translation/Symfony/Component/Translation/Loader/IcuResFileLoader.php
new file mode 100644
index 0000000..d864c7b
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/IcuResFileLoader.php
@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\DirectoryResource;
+
+/**
+ * IcuResFileLoader loads translations from a resource bundle.
+ *
+ * @author stealth35
+ */
+class IcuResFileLoader implements LoaderInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function load($resource, $locale, $domain = 'messages')
+ {
+ if (!stream_is_local($resource)) {
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+ }
+
+ if (!is_dir($resource)) {
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+ }
+
+ try {
+ $rb = new \ResourceBundle($locale, $resource);
+ } catch (\Exception $e) {
+ // HHVM compatibility: constructor throws on invalid resource
+ $rb = null;
+ }
+
+ if (!$rb) {
+ throw new InvalidResourceException(sprintf('Cannot load resource "%s"', $resource));
+ } elseif (intl_is_failure($rb->getErrorCode())) {
+ throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
+ }
+
+ $messages = $this->flatten($rb);
+ $catalogue = new MessageCatalogue($locale);
+ $catalogue->add($messages, $domain);
+ $catalogue->addResource(new DirectoryResource($resource));
+
+ return $catalogue;
+ }
+
+ /**
+ * Flattens an ResourceBundle.
+ *
+ * The scheme used is:
+ * key { key2 { key3 { "value" } } }
+ * Becomes:
+ * 'key.key2.key3' => 'value'
+ *
+ * This function takes an array by reference and will modify it
+ *
+ * @param \ResourceBundle $rb the ResourceBundle that will be flattened
+ * @param array $messages used internally for recursive calls
+ * @param string $path current path being parsed, used internally for recursive calls
+ *
+ * @return array the flattened ResourceBundle
+ */
+ protected function flatten(\ResourceBundle $rb, array &$messages = array(), $path = null)
+ {
+ foreach ($rb as $key => $value) {
+ $nodePath = $path ? $path.'.'.$key : $key;
+ if ($value instanceof \ResourceBundle) {
+ $this->flatten($value, $messages, $nodePath);
+ } else {
+ $messages[$nodePath] = $value;
+ }
+ }
+
+ return $messages;
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/IniFileLoader.php b/vendor/symfony/translation/Symfony/Component/Translation/Loader/IniFileLoader.php
new file mode 100644
index 0000000..3f01ab4
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/IniFileLoader.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * IniFileLoader loads translations from an ini file.
+ *
+ * @author stealth35
+ */
+class IniFileLoader extends ArrayLoader
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function load($resource, $locale, $domain = 'messages')
+ {
+ if (!stream_is_local($resource)) {
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+ }
+
+ if (!file_exists($resource)) {
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+ }
+
+ $messages = parse_ini_file($resource, true);
+
+ $catalogue = parent::load($messages, $locale, $domain);
+ $catalogue->addResource(new FileResource($resource));
+
+ return $catalogue;
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/JsonFileLoader.php b/vendor/symfony/translation/Symfony/Component/Translation/Loader/JsonFileLoader.php
new file mode 100644
index 0000000..8327c63
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/JsonFileLoader.php
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * JsonFileLoader loads translations from an json file.
+ *
+ * @author singles
+ */
+class JsonFileLoader extends ArrayLoader implements LoaderInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function load($resource, $locale, $domain = 'messages')
+ {
+ if (!stream_is_local($resource)) {
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+ }
+
+ if (!file_exists($resource)) {
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+ }
+
+ $messages = json_decode(file_get_contents($resource), true);
+
+ if (0 < $errorCode = json_last_error()) {
+ throw new InvalidResourceException(sprintf('Error parsing JSON - %s', $this->getJSONErrorMessage($errorCode)));
+ }
+
+ if (null === $messages) {
+ $messages = array();
+ }
+
+ $catalogue = parent::load($messages, $locale, $domain);
+ $catalogue->addResource(new FileResource($resource));
+
+ return $catalogue;
+ }
+
+ /**
+ * Translates JSON_ERROR_* constant into meaningful message.
+ *
+ * @param int $errorCode Error code returned by json_last_error() call
+ *
+ * @return string Message string
+ */
+ private function getJSONErrorMessage($errorCode)
+ {
+ switch ($errorCode) {
+ case JSON_ERROR_DEPTH:
+ return 'Maximum stack depth exceeded';
+ case JSON_ERROR_STATE_MISMATCH:
+ return 'Underflow or the modes mismatch';
+ case JSON_ERROR_CTRL_CHAR:
+ return 'Unexpected control character found';
+ case JSON_ERROR_SYNTAX:
+ return 'Syntax error, malformed JSON';
+ case JSON_ERROR_UTF8:
+ return 'Malformed UTF-8 characters, possibly incorrectly encoded';
+ default:
+ return 'Unknown error';
+ }
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/LoaderInterface.php b/vendor/symfony/translation/Symfony/Component/Translation/Loader/LoaderInterface.php
new file mode 100644
index 0000000..0b28e14
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/LoaderInterface.php
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+
+/**
+ * LoaderInterface is the interface implemented by all translation loaders.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface LoaderInterface
+{
+ /**
+ * Loads a locale.
+ *
+ * @param mixed $resource A resource
+ * @param string $locale A locale
+ * @param string $domain The domain
+ *
+ * @return MessageCatalogue A MessageCatalogue instance
+ *
+ * @api
+ *
+ * @throws NotFoundResourceException when the resource cannot be found
+ * @throws InvalidResourceException when the resource cannot be loaded
+ */
+ public function load($resource, $locale, $domain = 'messages');
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/MoFileLoader.php b/vendor/symfony/translation/Symfony/Component/Translation/Loader/MoFileLoader.php
new file mode 100644
index 0000000..9cab3f0
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/MoFileLoader.php
@@ -0,0 +1,188 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
+ */
+class MoFileLoader extends ArrayLoader
+{
+ /**
+ * Magic used for validating the format of a MO file as well as
+ * detecting if the machine used to create that file was little endian.
+ *
+ * @var float
+ */
+ const MO_LITTLE_ENDIAN_MAGIC = 0x950412de;
+
+ /**
+ * Magic used for validating the format of a MO file as well as
+ * detecting if the machine used to create that file was big endian.
+ *
+ * @var float
+ */
+ const MO_BIG_ENDIAN_MAGIC = 0xde120495;
+
+ /**
+ * The size of the header of a MO file in bytes.
+ *
+ * @var int Number of bytes.
+ */
+ const MO_HEADER_SIZE = 28;
+
+ public function load($resource, $locale, $domain = 'messages')
+ {
+ if (!stream_is_local($resource)) {
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+ }
+
+ if (!file_exists($resource)) {
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+ }
+
+ $messages = $this->parse($resource);
+
+ // empty file
+ if (null === $messages) {
+ $messages = array();
+ }
+
+ // not an array
+ if (!is_array($messages)) {
+ throw new InvalidResourceException(sprintf('The file "%s" must contain a valid mo file.', $resource));
+ }
+
+ $catalogue = parent::load($messages, $locale, $domain);
+ $catalogue->addResource(new FileResource($resource));
+
+ return $catalogue;
+ }
+
+ /**
+ * Parses machine object (MO) format, independent of the machine's endian it
+ * was created on. Both 32bit and 64bit systems are supported.
+ *
+ * @param resource $resource
+ *
+ * @return array
+ *
+ * @throws InvalidResourceException If stream content has an invalid format.
+ */
+ private function parse($resource)
+ {
+ $stream = fopen($resource, 'r');
+
+ $stat = fstat($stream);
+
+ if ($stat['size'] < self::MO_HEADER_SIZE) {
+ throw new InvalidResourceException('MO stream content has an invalid format.');
+ }
+ $magic = unpack('V1', fread($stream, 4));
+ $magic = hexdec(substr(dechex(current($magic)), -8));
+
+ if ($magic == self::MO_LITTLE_ENDIAN_MAGIC) {
+ $isBigEndian = false;
+ } elseif ($magic == self::MO_BIG_ENDIAN_MAGIC) {
+ $isBigEndian = true;
+ } else {
+ throw new InvalidResourceException('MO stream content has an invalid format.');
+ }
+
+ // formatRevision
+ $this->readLong($stream, $isBigEndian);
+ $count = $this->readLong($stream, $isBigEndian);
+ $offsetId = $this->readLong($stream, $isBigEndian);
+ $offsetTranslated = $this->readLong($stream, $isBigEndian);
+ // sizeHashes
+ $this->readLong($stream, $isBigEndian);
+ // offsetHashes
+ $this->readLong($stream, $isBigEndian);
+
+ $messages = array();
+
+ for ($i = 0; $i < $count; $i++) {
+ $singularId = $pluralId = null;
+ $translated = null;
+
+ fseek($stream, $offsetId + $i * 8);
+
+ $length = $this->readLong($stream, $isBigEndian);
+ $offset = $this->readLong($stream, $isBigEndian);
+
+ if ($length < 1) {
+ continue;
+ }
+
+ fseek($stream, $offset);
+ $singularId = fread($stream, $length);
+
+ if (strpos($singularId, "\000") !== false) {
+ list($singularId, $pluralId) = explode("\000", $singularId);
+ }
+
+ fseek($stream, $offsetTranslated + $i * 8);
+ $length = $this->readLong($stream, $isBigEndian);
+ $offset = $this->readLong($stream, $isBigEndian);
+
+ if ($length < 1) {
+ continue;
+ }
+
+ fseek($stream, $offset);
+ $translated = fread($stream, $length);
+
+ if (strpos($translated, "\000") !== false) {
+ $translated = explode("\000", $translated);
+ }
+
+ $ids = array('singular' => $singularId, 'plural' => $pluralId);
+ $item = compact('ids', 'translated');
+
+ if (is_array($item['translated'])) {
+ $messages[$item['ids']['singular']] = stripcslashes($item['translated'][0]);
+ if (isset($item['ids']['plural'])) {
+ $plurals = array();
+ foreach ($item['translated'] as $plural => $translated) {
+ $plurals[] = sprintf('{%d} %s', $plural, $translated);
+ }
+ $messages[$item['ids']['plural']] = stripcslashes(implode('|', $plurals));
+ }
+ } elseif (!empty($item['ids']['singular'])) {
+ $messages[$item['ids']['singular']] = stripcslashes($item['translated']);
+ }
+ }
+
+ fclose($stream);
+
+ return array_filter($messages);
+ }
+
+ /**
+ * Reads an unsigned long from stream respecting endianess.
+ *
+ * @param resource $stream
+ * @param bool $isBigEndian
+ *
+ * @return int
+ */
+ private function readLong($stream, $isBigEndian)
+ {
+ $result = unpack($isBigEndian ? 'N1' : 'V1', fread($stream, 4));
+ $result = current($result);
+
+ return (int) substr($result, -8);
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/PhpFileLoader.php b/vendor/symfony/translation/Symfony/Component/Translation/Loader/PhpFileLoader.php
new file mode 100644
index 0000000..1cc9d06
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/PhpFileLoader.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * PhpFileLoader loads translations from PHP files returning an array of translations.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class PhpFileLoader extends ArrayLoader
+{
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function load($resource, $locale, $domain = 'messages')
+ {
+ if (!stream_is_local($resource)) {
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+ }
+
+ if (!file_exists($resource)) {
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+ }
+
+ $messages = require $resource;
+
+ $catalogue = parent::load($messages, $locale, $domain);
+ $catalogue->addResource(new FileResource($resource));
+
+ return $catalogue;
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/PoFileLoader.php b/vendor/symfony/translation/Symfony/Component/Translation/Loader/PoFileLoader.php
new file mode 100644
index 0000000..8c8f1a2
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/PoFileLoader.php
@@ -0,0 +1,177 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
+ * @copyright Copyright (c) 2012, Clemens Tolboom
+ */
+class PoFileLoader extends ArrayLoader
+{
+ public function load($resource, $locale, $domain = 'messages')
+ {
+ if (!stream_is_local($resource)) {
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+ }
+
+ if (!file_exists($resource)) {
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+ }
+
+ $messages = $this->parse($resource);
+
+ // empty file
+ if (null === $messages) {
+ $messages = array();
+ }
+
+ // not an array
+ if (!is_array($messages)) {
+ throw new InvalidResourceException(sprintf('The file "%s" must contain a valid po file.', $resource));
+ }
+
+ $catalogue = parent::load($messages, $locale, $domain);
+ $catalogue->addResource(new FileResource($resource));
+
+ return $catalogue;
+ }
+
+ /**
+ * Parses portable object (PO) format.
+ *
+ * From http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files
+ * we should be able to parse files having:
+ *
+ * white-space
+ * # translator-comments
+ * #. extracted-comments
+ * #: reference...
+ * #, flag...
+ * #| msgid previous-untranslated-string
+ * msgid untranslated-string
+ * msgstr translated-string
+ *
+ * extra or different lines are:
+ *
+ * #| msgctxt previous-context
+ * #| msgid previous-untranslated-string
+ * msgctxt context
+ *
+ * #| msgid previous-untranslated-string-singular
+ * #| msgid_plural previous-untranslated-string-plural
+ * msgid untranslated-string-singular
+ * msgid_plural untranslated-string-plural
+ * msgstr[0] translated-string-case-0
+ * ...
+ * msgstr[N] translated-string-case-n
+ *
+ * The definition states:
+ * - white-space and comments are optional.
+ * - msgid "" that an empty singleline defines a header.
+ *
+ * This parser sacrifices some features of the reference implementation the
+ * differences to that implementation are as follows.
+ * - No support for comments spanning multiple lines.
+ * - Translator and extracted comments are treated as being the same type.
+ * - Message IDs are allowed to have other encodings as just US-ASCII.
+ *
+ * Items with an empty id are ignored.
+ *
+ * @param resource $resource
+ *
+ * @return array
+ */
+ private function parse($resource)
+ {
+ $stream = fopen($resource, 'r');
+
+ $defaults = array(
+ 'ids' => array(),
+ 'translated' => null,
+ );
+
+ $messages = array();
+ $item = $defaults;
+
+ while ($line = fgets($stream)) {
+ $line = trim($line);
+
+ if ($line === '') {
+ // Whitespace indicated current item is done
+ $this->addMessage($messages, $item);
+ $item = $defaults;
+ } elseif (substr($line, 0, 7) === 'msgid "') {
+ // We start a new msg so save previous
+ // TODO: this fails when comments or contexts are added
+ $this->addMessage($messages, $item);
+ $item = $defaults;
+ $item['ids']['singular'] = substr($line, 7, -1);
+ } elseif (substr($line, 0, 8) === 'msgstr "') {
+ $item['translated'] = substr($line, 8, -1);
+ } elseif ($line[0] === '"') {
+ $continues = isset($item['translated']) ? 'translated' : 'ids';
+
+ if (is_array($item[$continues])) {
+ end($item[$continues]);
+ $item[$continues][key($item[$continues])] .= substr($line, 1, -1);
+ } else {
+ $item[$continues] .= substr($line, 1, -1);
+ }
+ } elseif (substr($line, 0, 14) === 'msgid_plural "') {
+ $item['ids']['plural'] = substr($line, 14, -1);
+ } elseif (substr($line, 0, 7) === 'msgstr[') {
+ $size = strpos($line, ']');
+ $item['translated'][(int) substr($line, 7, 1)] = substr($line, $size + 3, -1);
+ }
+ }
+ // save last item
+ $this->addMessage($messages, $item);
+ fclose($stream);
+
+ return $messages;
+ }
+
+ /**
+ * Save a translation item to the messages.
+ *
+ * A .po file could contain by error missing plural indexes. We need to
+ * fix these before saving them.
+ *
+ * @param array $messages
+ * @param array $item
+ */
+ private function addMessage(array &$messages, array $item)
+ {
+ if (is_array($item['translated'])) {
+ $messages[stripcslashes($item['ids']['singular'])] = stripcslashes($item['translated'][0]);
+ if (isset($item['ids']['plural'])) {
+ $plurals = $item['translated'];
+ // PO are by definition indexed so sort by index.
+ ksort($plurals);
+ // Make sure every index is filled.
+ end($plurals);
+ $count = key($plurals);
+ // Fill missing spots with '-'.
+ $empties = array_fill(0, $count + 1, '-');
+ $plurals += $empties;
+ ksort($plurals);
+ $messages[stripcslashes($item['ids']['plural'])] = stripcslashes(implode('|', $plurals));
+ }
+ } elseif (!empty($item['ids']['singular'])) {
+ $messages[stripcslashes($item['ids']['singular'])] = stripcslashes($item['translated']);
+ }
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/QtFileLoader.php b/vendor/symfony/translation/Symfony/Component/Translation/Loader/QtFileLoader.php
new file mode 100644
index 0000000..aacfb4a
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/QtFileLoader.php
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Util\XmlUtils;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * QtFileLoader loads translations from QT Translations XML files.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ *
+ * @api
+ */
+class QtFileLoader implements LoaderInterface
+{
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function load($resource, $locale, $domain = 'messages')
+ {
+ if (!stream_is_local($resource)) {
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+ }
+
+ if (!file_exists($resource)) {
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+ }
+
+ try {
+ $dom = XmlUtils::loadFile($resource);
+ } catch (\InvalidArgumentException $e) {
+ throw new InvalidResourceException(sprintf('Unable to load "%s".', $resource), $e->getCode(), $e);
+ }
+
+ $internalErrors = libxml_use_internal_errors(true);
+ libxml_clear_errors();
+
+ $xpath = new \DOMXPath($dom);
+ $nodes = $xpath->evaluate('//TS/context/name[text()="'.$domain.'"]');
+
+ $catalogue = new MessageCatalogue($locale);
+ if ($nodes->length == 1) {
+ $translations = $nodes->item(0)->nextSibling->parentNode->parentNode->getElementsByTagName('message');
+ foreach ($translations as $translation) {
+ $translationValue = (string) $translation->getElementsByTagName('translation')->item(0)->nodeValue;
+
+ if (!empty($translationValue)) {
+ $catalogue->set(
+ (string) $translation->getElementsByTagName('source')->item(0)->nodeValue,
+ $translationValue,
+ $domain
+ );
+ }
+ $translation = $translation->nextSibling;
+ }
+ $catalogue->addResource(new FileResource($resource));
+ }
+
+ libxml_use_internal_errors($internalErrors);
+
+ return $catalogue;
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/XliffFileLoader.php b/vendor/symfony/translation/Symfony/Component/Translation/Loader/XliffFileLoader.php
new file mode 100644
index 0000000..c3a50cd
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/XliffFileLoader.php
@@ -0,0 +1,185 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Util\XmlUtils;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * XliffFileLoader loads translations from XLIFF files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class XliffFileLoader implements LoaderInterface
+{
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function load($resource, $locale, $domain = 'messages')
+ {
+ if (!stream_is_local($resource)) {
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+ }
+
+ if (!file_exists($resource)) {
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+ }
+
+ list($xml, $encoding) = $this->parseFile($resource);
+ $xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:1.2');
+
+ $catalogue = new MessageCatalogue($locale);
+ foreach ($xml->xpath('//xliff:trans-unit') as $translation) {
+ $attributes = $translation->attributes();
+
+ if (!(isset($attributes['resname']) || isset($translation->source)) || !isset($translation->target)) {
+ continue;
+ }
+
+ $source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source;
+ // If the xlf file has another encoding specified, try to convert it because
+ // simple_xml will always return utf-8 encoded values
+ $target = $this->utf8ToCharset((string) $translation->target, $encoding);
+
+ $catalogue->set((string) $source, $target, $domain);
+
+ if (isset($translation->note)) {
+ $notes = array();
+ foreach ($translation->note as $xmlNote) {
+ $noteAttributes = $xmlNote->attributes();
+ $note = array('content' => $this->utf8ToCharset((string) $xmlNote, $encoding));
+ if (isset($noteAttributes['priority'])) {
+ $note['priority'] = (int) $noteAttributes['priority'];
+ }
+
+ if (isset($noteAttributes['from'])) {
+ $note['from'] = (string) $noteAttributes['from'];
+ }
+
+ $notes[] = $note;
+ }
+
+ $catalogue->setMetadata((string) $source, array('notes' => $notes), $domain);
+ }
+ }
+ $catalogue->addResource(new FileResource($resource));
+
+ return $catalogue;
+ }
+
+ /**
+ * Convert a UTF8 string to the specified encoding.
+ *
+ * @param string $content String to decode
+ * @param string $encoding Target encoding
+ *
+ * @return string
+ */
+ private function utf8ToCharset($content, $encoding = null)
+ {
+ if ('UTF-8' !== $encoding && !empty($encoding)) {
+ if (function_exists('mb_convert_encoding')) {
+ return mb_convert_encoding($content, $encoding, 'UTF-8');
+ }
+
+ if (function_exists('iconv')) {
+ return iconv('UTF-8', $encoding, $content);
+ }
+
+ throw new \RuntimeException('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
+ }
+
+ return $content;
+ }
+
+ /**
+ * Validates and parses the given file into a SimpleXMLElement.
+ *
+ * @param string $file
+ *
+ * @throws \RuntimeException
+ *
+ * @return \SimpleXMLElement
+ *
+ * @throws InvalidResourceException
+ */
+ private function parseFile($file)
+ {
+ try {
+ $dom = XmlUtils::loadFile($file);
+ } catch (\InvalidArgumentException $e) {
+ throw new InvalidResourceException(sprintf('Unable to load "%s": %s', $file, $e->getMessage()), $e->getCode(), $e);
+ }
+
+ $internalErrors = libxml_use_internal_errors(true);
+
+ $location = str_replace('\\', '/', __DIR__).'/schema/dic/xliff-core/xml.xsd';
+ $parts = explode('/', $location);
+ if (0 === stripos($location, 'phar://')) {
+ $tmpfile = tempnam(sys_get_temp_dir(), 'sf2');
+ if ($tmpfile) {
+ copy($location, $tmpfile);
+ $parts = explode('/', str_replace('\\', '/', $tmpfile));
+ }
+ }
+ $drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
+ $location = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts));
+
+ $source = file_get_contents(__DIR__.'/schema/dic/xliff-core/xliff-core-1.2-strict.xsd');
+ $source = str_replace('http://www.w3.org/2001/xml.xsd', $location, $source);
+
+ if (!@$dom->schemaValidateSource($source)) {
+ throw new InvalidResourceException(implode("\n", $this->getXmlErrors($internalErrors)));
+ }
+
+ $dom->normalizeDocument();
+
+ libxml_clear_errors();
+ libxml_use_internal_errors($internalErrors);
+
+ return array(simplexml_import_dom($dom), strtoupper($dom->encoding));
+ }
+
+ /**
+ * Returns the XML errors of the internal XML parser.
+ *
+ * @param bool $internalErrors
+ *
+ * @return array An array of errors
+ */
+ private function getXmlErrors($internalErrors)
+ {
+ $errors = array();
+ foreach (libxml_get_errors() as $error) {
+ $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
+ LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
+ $error->code,
+ trim($error->message),
+ $error->file ?: 'n/a',
+ $error->line,
+ $error->column
+ );
+ }
+
+ libxml_clear_errors();
+ libxml_use_internal_errors($internalErrors);
+
+ return $errors;
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/YamlFileLoader.php b/vendor/symfony/translation/Symfony/Component/Translation/Loader/YamlFileLoader.php
new file mode 100644
index 0000000..e50e0fa
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/YamlFileLoader.php
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Yaml\Parser as YamlParser;
+use Symfony\Component\Yaml\Exception\ParseException;
+
+/**
+ * YamlFileLoader loads translations from Yaml files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class YamlFileLoader extends ArrayLoader
+{
+ private $yamlParser;
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function load($resource, $locale, $domain = 'messages')
+ {
+ if (!stream_is_local($resource)) {
+ throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+ }
+
+ if (!file_exists($resource)) {
+ throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+ }
+
+ if (null === $this->yamlParser) {
+ $this->yamlParser = new YamlParser();
+ }
+
+ try {
+ $messages = $this->yamlParser->parse(file_get_contents($resource));
+ } catch (ParseException $e) {
+ throw new InvalidResourceException(sprintf('Error parsing YAML, invalid file "%s"', $resource), 0, $e);
+ }
+
+ // empty file
+ if (null === $messages) {
+ $messages = array();
+ }
+
+ // not an array
+ if (!is_array($messages)) {
+ throw new InvalidResourceException(sprintf('The file "%s" must contain a YAML array.', $resource));
+ }
+
+ $catalogue = parent::load($messages, $locale, $domain);
+ $catalogue->addResource(new FileResource($resource));
+
+ return $catalogue;
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd b/vendor/symfony/translation/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd
new file mode 100644
index 0000000..3ce2a8e
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd
@@ -0,0 +1,2223 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+
+May-19-2004:
+- Changed the <choice> for ElemType_header, moving minOccurs="0" maxOccurs="unbounded" from its elements
+to <choice> itself.
+- Added <choice> for ElemType_trans-unit to allow "any order" for <context-group>, <count-group>, <prop-group>, <note>, and
+<alt-trans>.
+
+Oct-2005
+- updated version info to 1.2
+- equiv-trans attribute to <trans-unit> element
+- merged-trans attribute for <group> element
+- Add the <seg-source> element as optional in the <trans-unit> and <alt-trans> content models, at the same level as <source>
+- Create a new value "seg" for the mtype attribute of the <mrk> element
+- Add mid as an optional attribute for the <alt-trans> element
+
+Nov-14-2005
+- Changed name attribute for <context-group> from required to optional
+- Added extension point at <xliff>
+
+Jan-9-2006
+- Added alttranstype type attribute to <alt-trans>, and values
+
+Jan-10-2006
+- Corrected error with overwritten purposeValueList
+- Corrected name="AttrType_Version", attribute should have been "name"
+
+-->
+<xsd:schema xmlns:xlf="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:oasis:names:tc:xliff:document:1.2" xml:lang="en">
+ <!-- Import for xml:lang and xml:space -->
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+ <!-- Attributes Lists -->
+ <xsd:simpleType name="XTend">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="x-[^\s]+"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="context-typeValueList">
+ <xsd:annotation>
+ <xsd:documentation>Values for the attribute 'context-type'.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="database">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a database content.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="element">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the content of an element within an XML document.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="elementtitle">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the name of an element within an XML document.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="linenumber">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the line number from the sourcefile (see context-type="sourcefile") where the &lt;source&gt; is found.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="numparams">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a the number of parameters contained within the &lt;source&gt;.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="paramnotes">
+ <xsd:annotation>
+ <xsd:documentation>Indicates notes pertaining to the parameters in the &lt;source&gt;.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="record">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the content of a record within a database.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="recordtitle">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the name of a record within a database.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="sourcefile">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the original source file in the case that multiple files are merged to form the original file from which the XLIFF file is created. This differs from the original &lt;file&gt; attribute in that this sourcefile is one of many that make up that file.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="count-typeValueList">
+ <xsd:annotation>
+ <xsd:documentation>Values for the attribute 'count-type'.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="num-usages">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the count units are items that are used X times in a certain context; example: this is a reusable text unit which is used 42 times in other texts.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="repetition">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the count units are translation units existing already in the same document.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="total">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a total count.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="InlineDelimitersValueList">
+ <xsd:annotation>
+ <xsd:documentation>Values for the attribute 'ctype' when used other elements than &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="bold">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a run of bolded text.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="italic">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a run of text in italics.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="underlined">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a run of underlined text.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="link">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a run of hyper-text.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="InlinePlaceholdersValueList">
+ <xsd:annotation>
+ <xsd:documentation>Values for the attribute 'ctype' when used with &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="image">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a inline image.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="pb">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a page break.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="lb">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a line break.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="mime-typeValueList">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="(text|multipart|message|application|image|audio|video|model)(/.+)*"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="datatypeValueList">
+ <xsd:annotation>
+ <xsd:documentation>Values for the attribute 'datatype'.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="asp">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Active Server Page data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="c">
+ <xsd:annotation>
+ <xsd:documentation>Indicates C source file data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="cdf">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Channel Definition Format (CDF) data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="cfm">
+ <xsd:annotation>
+ <xsd:documentation>Indicates ColdFusion data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="cpp">
+ <xsd:annotation>
+ <xsd:documentation>Indicates C++ source file data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="csharp">
+ <xsd:annotation>
+ <xsd:documentation>Indicates C-Sharp data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="cstring">
+ <xsd:annotation>
+ <xsd:documentation>Indicates strings from C, ASM, and driver files data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="csv">
+ <xsd:annotation>
+ <xsd:documentation>Indicates comma-separated values data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="database">
+ <xsd:annotation>
+ <xsd:documentation>Indicates database data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="documentfooter">
+ <xsd:annotation>
+ <xsd:documentation>Indicates portions of document that follows data and contains metadata.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="documentheader">
+ <xsd:annotation>
+ <xsd:documentation>Indicates portions of document that precedes data and contains metadata.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="filedialog">
+ <xsd:annotation>
+ <xsd:documentation>Indicates data from standard UI file operations dialogs (e.g., Open, Save, Save As, Export, Import).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="form">
+ <xsd:annotation>
+ <xsd:documentation>Indicates standard user input screen data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="html">
+ <xsd:annotation>
+ <xsd:documentation>Indicates HyperText Markup Language (HTML) data - document instance.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="htmlbody">
+ <xsd:annotation>
+ <xsd:documentation>Indicates content within an HTML document’s &lt;body&gt; element.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="ini">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Windows INI file data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="interleaf">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Interleaf data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="javaclass">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Java source file data (extension '.java').</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="javapropertyresourcebundle">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Java property resource bundle data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="javalistresourcebundle">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Java list resource bundle data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="javascript">
+ <xsd:annotation>
+ <xsd:documentation>Indicates JavaScript source file data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="jscript">
+ <xsd:annotation>
+ <xsd:documentation>Indicates JScript source file data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="layout">
+ <xsd:annotation>
+ <xsd:documentation>Indicates information relating to formatting.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="lisp">
+ <xsd:annotation>
+ <xsd:documentation>Indicates LISP source file data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="margin">
+ <xsd:annotation>
+ <xsd:documentation>Indicates information relating to margin formats.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="menufile">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a file containing menu.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="messagefile">
+ <xsd:annotation>
+ <xsd:documentation>Indicates numerically identified string table.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="mif">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Maker Interchange Format (MIF) data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="mimetype">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that the datatype attribute value is a MIME Type value and is defined in the mime-type attribute.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="mo">
+ <xsd:annotation>
+ <xsd:documentation>Indicates GNU Machine Object data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="msglib">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Message Librarian strings created by Novell's Message Librarian Tool.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="pagefooter">
+ <xsd:annotation>
+ <xsd:documentation>Indicates information to be displayed at the bottom of each page of a document.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="pageheader">
+ <xsd:annotation>
+ <xsd:documentation>Indicates information to be displayed at the top of each page of a document.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="parameters">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a list of property values (e.g., settings within INI files or preferences dialog).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="pascal">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Pascal source file data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="php">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Hypertext Preprocessor data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="plaintext">
+ <xsd:annotation>
+ <xsd:documentation>Indicates plain text file (no formatting other than, possibly, wrapping).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="po">
+ <xsd:annotation>
+ <xsd:documentation>Indicates GNU Portable Object file.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="report">
+ <xsd:annotation>
+ <xsd:documentation>Indicates dynamically generated user defined document. e.g. Oracle Report, Crystal Report, etc.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="resources">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Windows .NET binary resources.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="resx">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Windows .NET Resources.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="rtf">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Rich Text Format (RTF) data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="sgml">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - document instance.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="sgmldtd">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - Document Type Definition (DTD).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="svg">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Scalable Vector Graphic (SVG) data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="vbscript">
+ <xsd:annotation>
+ <xsd:documentation>Indicates VisualBasic Script source file.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="warning">
+ <xsd:annotation>
+ <xsd:documentation>Indicates warning message.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="winres">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Windows (Win32) resources (i.e. resources extracted from an RC script, a message file, or a compiled file).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="xhtml">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Extensible HyperText Markup Language (XHTML) data - document instance.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="xml">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Extensible Markup Language (XML) data - document instance.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="xmldtd">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Extensible Markup Language (XML) data - Document Type Definition (DTD).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="xsl">
+ <xsd:annotation>
+ <xsd:documentation>Indicates Extensible Stylesheet Language (XSL) data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="xul">
+ <xsd:annotation>
+ <xsd:documentation>Indicates XUL elements.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="mtypeValueList">
+ <xsd:annotation>
+ <xsd:documentation>Values for the attribute 'mtype'.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="abbrev">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the marked text is an abbreviation.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="abbreviated-form">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.8: A term resulting from the omission of any part of the full term while designating the same concept.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="abbreviation">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.8.1: An abbreviated form of a simple term resulting from the omission of some of its letters (e.g. 'adj.' for 'adjective').</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="acronym">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.8.4: An abbreviated form of a term made up of letters from the full form of a multiword term strung together into a sequence pronounced only syllabically (e.g. 'radar' for 'radio detecting and ranging').</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="appellation">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620: A proper-name term, such as the name of an agency or other proper entity.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="collocation">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.18.1: A recurrent word combination characterized by cohesion in that the components of the collocation must co-occur within an utterance or series of utterances, even though they do not necessarily have to maintain immediate proximity to one another.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="common-name">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.5: A synonym for an international scientific term that is used in general discourse in a given language.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="datetime">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the marked text is a date and/or time.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="equation">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.15: An expression used to represent a concept based on a statement that two mathematical expressions are, for instance, equal as identified by the equal sign (=), or assigned to one another by a similar sign.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="expanded-form">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.7: The complete representation of a term for which there is an abbreviated form.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="formula">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.14: Figures, symbols or the like used to express a concept briefly, such as a mathematical or chemical formula.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="head-term">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.1: The concept designation that has been chosen to head a terminological record.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="initialism">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.8.3: An abbreviated form of a term consisting of some of the initial letters of the words making up a multiword term or the term elements making up a compound term when these letters are pronounced individually (e.g. 'BSE' for 'bovine spongiform encephalopathy').</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="international-scientific-term">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.4: A term that is part of an international scientific nomenclature as adopted by an appropriate scientific body.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="internationalism">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.6: A term that has the same or nearly identical orthographic or phonemic form in many languages.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="logical-expression">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.16: An expression used to represent a concept based on mathematical or logical relations, such as statements of inequality, set relationships, Boolean operations, and the like.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="materials-management-unit">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.17: A unit to track object.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="name">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the marked text is a name.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="near-synonym">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.3: A term that represents the same or a very similar concept as another term in the same language, but for which interchangeability is limited to some contexts and inapplicable in others.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="part-number">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.17.2: A unique alphanumeric designation assigned to an object in a manufacturing system.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="phrase">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the marked text is a phrase.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="phraseological-unit">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.18: Any group of two or more words that form a unit, the meaning of which frequently cannot be deduced based on the combined sense of the words making up the phrase.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="protected">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the marked text should not be translated.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="romanized-form">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.12: A form of a term resulting from an operation whereby non-Latin writing systems are converted to the Latin alphabet.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="seg">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that the marked text represents a segment.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="set-phrase">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.18.2: A fixed, lexicalized phrase.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="short-form">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.8.2: A variant of a multiword term that includes fewer words than the full form of the term (e.g. 'Group of Twenty-four' for 'Intergovernmental Group of Twenty-four on International Monetary Affairs').</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="sku">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.17.1: Stock keeping unit, an inventory item identified by a unique alphanumeric designation assigned to an object in an inventory control system.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="standard-text">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.19: A fixed chunk of recurring text.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="symbol">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.13: A designation of a concept by letters, numerals, pictograms or any combination thereof.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="synonym">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.2: Any term that represents the same or a very similar concept as the main entry term in a term entry.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="synonymous-phrase">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.18.3: Phraseological unit in a language that expresses the same semantic content as another phrase in that same language.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="term">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the marked text is a term.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="transcribed-form">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.11: A form of a term resulting from an operation whereby the characters of one writing system are represented by characters from another writing system, taking into account the pronunciation of the characters converted.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="transliterated-form">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.10: A form of a term resulting from an operation whereby the characters of an alphabetic writing system are represented by characters from another alphabetic writing system.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="truncated-term">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.8.5: An abbreviated form of a term resulting from the omission of one or more term elements or syllables (e.g. 'flu' for 'influenza').</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="variant">
+ <xsd:annotation>
+ <xsd:documentation>ISO-12620 2.1.9: One of the alternate forms of a term.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="restypeValueList">
+ <xsd:annotation>
+ <xsd:documentation>Values for the attribute 'restype'.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="auto3state">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC AUTO3STATE control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="autocheckbox">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC AUTOCHECKBOX control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="autoradiobutton">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC AUTORADIOBUTTON control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="bedit">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC BEDIT control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="bitmap">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a bitmap, for example a BITMAP resource in Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="button">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a button object, for example a BUTTON control Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="caption">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a caption, such as the caption of a dialog box.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="cell">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the cell in a table, for example the content of the &lt;td&gt; element in HTML.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="checkbox">
+ <xsd:annotation>
+ <xsd:documentation>Indicates check box object, for example a CHECKBOX control in Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="checkboxmenuitem">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a menu item with an associated checkbox.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="checkedlistbox">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a list box, but with a check-box for each item.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="colorchooser">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a color selection dialog.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="combobox">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a combination of edit box and listbox object, for example a COMBOBOX control in Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="comboboxexitem">
+ <xsd:annotation>
+ <xsd:documentation>Indicates an initialization entry of an extended combobox DLGINIT resource block. (code 0x1234).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="comboboxitem">
+ <xsd:annotation>
+ <xsd:documentation>Indicates an initialization entry of a combobox DLGINIT resource block (code 0x0403).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="component">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a UI base class element that cannot be represented by any other element.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="contextmenu">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a context menu.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="ctext">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC CTEXT control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="cursor">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a cursor, for example a CURSOR resource in Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="datetimepicker">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a date/time picker.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="defpushbutton">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC DEFPUSHBUTTON control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="dialog">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a dialog box.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="dlginit">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC DLGINIT resource block.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="edit">
+ <xsd:annotation>
+ <xsd:documentation>Indicates an edit box object, for example an EDIT control in Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="file">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a filename.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="filechooser">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a file dialog.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="fn">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a footnote.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="font">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a font name.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="footer">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a footer.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="frame">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a frame object.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="grid">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a XUL grid element.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="groupbox">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a groupbox object, for example a GROUPBOX control in Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="header">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a header item.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="heading">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a heading, such has the content of &lt;h1&gt;, &lt;h2&gt;, etc. in HTML.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="hedit">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC HEDIT control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="hscrollbar">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a horizontal scrollbar.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="icon">
+ <xsd:annotation>
+ <xsd:documentation>Indicates an icon, for example an ICON resource in Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="iedit">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC IEDIT control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="keywords">
+ <xsd:annotation>
+ <xsd:documentation>Indicates keyword list, such as the content of the Keywords meta-data in HTML, or a K footnote in WinHelp RTF.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="label">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a label object.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="linklabel">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a label that is also a HTML link (not necessarily a URL).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="list">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a list (a group of list-items, for example an &lt;ol&gt; or &lt;ul&gt; element in HTML).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="listbox">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a listbox object, for example an LISTBOX control in Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="listitem">
+ <xsd:annotation>
+ <xsd:documentation>Indicates an list item (an entry in a list).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="ltext">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC LTEXT control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="menu">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a menu (a group of menu-items).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="menubar">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a toolbar containing one or more tope level menus.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="menuitem">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a menu item (an entry in a menu).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="menuseparator">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a XUL menuseparator element.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="message">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a message, for example an entry in a MESSAGETABLE resource in Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="monthcalendar">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a calendar control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="numericupdown">
+ <xsd:annotation>
+ <xsd:documentation>Indicates an edit box beside a spin control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="panel">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a catch all for rectangular areas.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="popupmenu">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a standalone menu not necessarily associated with a menubar.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="pushbox">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a pushbox object, for example a PUSHBOX control in Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="pushbutton">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC PUSHBUTTON control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="radio">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a radio button object.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="radiobuttonmenuitem">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a menuitem with associated radio button.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="rcdata">
+ <xsd:annotation>
+ <xsd:documentation>Indicates raw data resources for an application.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="row">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a row in a table.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="rtext">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC RTEXT control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="scrollpane">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a user navigable container used to show a portion of a document.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="separator">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a generic divider object (e.g. menu group separator).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="shortcut">
+ <xsd:annotation>
+ <xsd:documentation>Windows accelerators, shortcuts in resource or property files.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="spinner">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a UI control to indicate process activity but not progress.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="splitter">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a splitter bar.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="state3">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC STATE3 control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="statusbar">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a window for providing feedback to the users, like 'read-only', etc.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="string">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a string, for example an entry in a STRINGTABLE resource in Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="tabcontrol">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a layers of controls with a tab to select layers.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="table">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a display and edits regular two-dimensional tables of cells.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="textbox">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a XUL textbox element.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="togglebutton">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a UI button that can be toggled to on or off state.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="toolbar">
+ <xsd:annotation>
+ <xsd:documentation>Indicates an array of controls, usually buttons.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="tooltip">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a pop up tool tip text.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="trackbar">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a bar with a pointer indicating a position within a certain range.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="tree">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a control that displays a set of hierarchical data.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="uri">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a URI (URN or URL).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="userbutton">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a Windows RC USERBUTTON control.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="usercontrol">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a user-defined control like CONTROL control in Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="var">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the text of a variable.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="versioninfo">
+ <xsd:annotation>
+ <xsd:documentation>Indicates version information about a resource like VERSIONINFO in Windows.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="vscrollbar">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a vertical scrollbar.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="window">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a graphical window.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="size-unitValueList">
+ <xsd:annotation>
+ <xsd:documentation>Values for the attribute 'size-unit'.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="byte">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in 8-bit bytes.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="char">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in Unicode characters.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="col">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in columns. Used for HTML text area.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="cm">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in centimeters.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="dlgunit">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in dialog units, as defined in Windows resources.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="em">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in 'font-size' units (as defined in CSS).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="ex">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in 'x-height' units (as defined in CSS).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="glyph">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in glyphs. A glyph is considered to be one or more combined Unicode characters that represent a single displayable text character. Sometimes referred to as a 'grapheme cluster'</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="in">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in inches.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="mm">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in millimeters.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="percent">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in percentage.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="pixel">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in pixels.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="point">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in point.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="row">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a size in rows. Used for HTML text area.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="stateValueList">
+ <xsd:annotation>
+ <xsd:documentation>Values for the attribute 'state'.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="final">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the terminating state.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="needs-adaptation">
+ <xsd:annotation>
+ <xsd:documentation>Indicates only non-textual information needs adaptation.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="needs-l10n">
+ <xsd:annotation>
+ <xsd:documentation>Indicates both text and non-textual information needs adaptation.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="needs-review-adaptation">
+ <xsd:annotation>
+ <xsd:documentation>Indicates only non-textual information needs review.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="needs-review-l10n">
+ <xsd:annotation>
+ <xsd:documentation>Indicates both text and non-textual information needs review.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="needs-review-translation">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that only the text of the item needs to be reviewed.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="needs-translation">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that the item needs to be translated.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="new">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that the item is new. For example, translation units that were not in a previous version of the document.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="signed-off">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that changes are reviewed and approved.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="translated">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that the item has been translated.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="state-qualifierValueList">
+ <xsd:annotation>
+ <xsd:documentation>Values for the attribute 'state-qualifier'.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="exact-match">
+ <xsd:annotation>
+ <xsd:documentation>Indicates an exact match. An exact match occurs when a source text of a segment is exactly the same as the source text of a segment that was translated previously.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="fuzzy-match">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a fuzzy match. A fuzzy match occurs when a source text of a segment is very similar to the source text of a segment that was translated previously (e.g. when the difference is casing, a few changed words, white-space discripancy, etc.).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="id-match">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a match based on matching IDs (in addition to matching text).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="leveraged-glossary">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a translation derived from a glossary.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="leveraged-inherited">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a translation derived from existing translation.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="leveraged-mt">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a translation derived from machine translation.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="leveraged-repository">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a translation derived from a translation repository.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="leveraged-tm">
+ <xsd:annotation>
+ <xsd:documentation>Indicates a translation derived from a translation memory.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="mt-suggestion">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the translation is suggested by machine translation.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="rejected-grammar">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that the item has been rejected because of incorrect grammar.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="rejected-inaccurate">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that the item has been rejected because it is incorrect.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="rejected-length">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that the item has been rejected because it is too long or too short.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="rejected-spelling">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that the item has been rejected because of incorrect spelling.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="tm-suggestion">
+ <xsd:annotation>
+ <xsd:documentation>Indicates the translation is suggested by translation memory.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="unitValueList">
+ <xsd:annotation>
+ <xsd:documentation>Values for the attribute 'unit'.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="word">
+ <xsd:annotation>
+ <xsd:documentation>Refers to words.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="page">
+ <xsd:annotation>
+ <xsd:documentation>Refers to pages.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="trans-unit">
+ <xsd:annotation>
+ <xsd:documentation>Refers to &lt;trans-unit&gt; elements.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="bin-unit">
+ <xsd:annotation>
+ <xsd:documentation>Refers to &lt;bin-unit&gt; elements.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="glyph">
+ <xsd:annotation>
+ <xsd:documentation>Refers to glyphs.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="item">
+ <xsd:annotation>
+ <xsd:documentation>Refers to &lt;trans-unit&gt; and/or &lt;bin-unit&gt; elements.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="instance">
+ <xsd:annotation>
+ <xsd:documentation>Refers to the occurrences of instances defined by the count-type value.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="character">
+ <xsd:annotation>
+ <xsd:documentation>Refers to characters.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="line">
+ <xsd:annotation>
+ <xsd:documentation>Refers to lines.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="sentence">
+ <xsd:annotation>
+ <xsd:documentation>Refers to sentences.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="paragraph">
+ <xsd:annotation>
+ <xsd:documentation>Refers to paragraphs.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="segment">
+ <xsd:annotation>
+ <xsd:documentation>Refers to segments.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="placeable">
+ <xsd:annotation>
+ <xsd:documentation>Refers to placeables (inline elements).</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="priorityValueList">
+ <xsd:annotation>
+ <xsd:documentation>Values for the attribute 'priority'.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:positiveInteger">
+ <xsd:enumeration value="1">
+ <xsd:annotation>
+ <xsd:documentation>Highest priority.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="2">
+ <xsd:annotation>
+ <xsd:documentation>High priority.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="3">
+ <xsd:annotation>
+ <xsd:documentation>High priority, but not as important as 2.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="4">
+ <xsd:annotation>
+ <xsd:documentation>High priority, but not as important as 3.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="5">
+ <xsd:annotation>
+ <xsd:documentation>Medium priority, but more important than 6.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="6">
+ <xsd:annotation>
+ <xsd:documentation>Medium priority, but less important than 5.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="7">
+ <xsd:annotation>
+ <xsd:documentation>Low priority, but more important than 8.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="8">
+ <xsd:annotation>
+ <xsd:documentation>Low priority, but more important than 9.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="9">
+ <xsd:annotation>
+ <xsd:documentation>Low priority.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="10">
+ <xsd:annotation>
+ <xsd:documentation>Lowest priority.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="reformatValueYesNo">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="yes">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that all properties can be reformatted. This value must be used alone.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="no">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that no properties should be reformatted. This value must be used alone.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="reformatValueList">
+ <xsd:list>
+ <xsd:simpleType>
+ <xsd:union memberTypes="xlf:XTend">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="coord">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that all information in the coord attribute can be modified.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="coord-x">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that the x information in the coord attribute can be modified.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="coord-y">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that the y information in the coord attribute can be modified.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="coord-cx">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that the cx information in the coord attribute can be modified.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="coord-cy">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that the cy information in the coord attribute can be modified.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="font">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that all the information in the font attribute can be modified.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="font-name">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that the name information in the font attribute can be modified.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="font-size">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that the size information in the font attribute can be modified.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="font-weight">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that the weight information in the font attribute can be modified.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="css-style">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that the information in the css-style attribute can be modified.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="style">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that the information in the style attribute can be modified.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="ex-style">
+ <xsd:annotation>
+ <xsd:documentation>This value indicates that the information in the exstyle attribute can be modified.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:union>
+ </xsd:simpleType>
+ </xsd:list>
+ </xsd:simpleType>
+ <xsd:simpleType name="purposeValueList">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="information">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that the context is informational in nature, specifying for example, how a term should be translated. Thus, should be displayed to anyone editing the XLIFF document.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="location">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that the context-group is used to specify where the term was found in the translatable source. Thus, it is not displayed.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="match">
+ <xsd:annotation>
+ <xsd:documentation>Indicates that the context information should be used during translation memory lookups. Thus, it is not displayed.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="alttranstypeValueList">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="proposal">
+ <xsd:annotation>
+ <xsd:documentation>Represents a translation proposal from a translation memory or other resource.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="previous-version">
+ <xsd:annotation>
+ <xsd:documentation>Represents a previous version of the target element.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="rejected">
+ <xsd:annotation>
+ <xsd:documentation>Represents a rejected version of the target element.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="reference">
+ <xsd:annotation>
+ <xsd:documentation>Represents a translation to be used for reference purposes only, for example from a related product or a different language.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ <xsd:enumeration value="accepted">
+ <xsd:annotation>
+ <xsd:documentation>Represents a proposed translation that was used for the translation of the trans-unit, possibly modified.</xsd:documentation>
+ </xsd:annotation>
+ </xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!-- Other Types -->
+ <xsd:complexType name="ElemType_ExternalReference">
+ <xsd:choice>
+ <xsd:element ref="xlf:internal-file"/>
+ <xsd:element ref="xlf:external-file"/>
+ </xsd:choice>
+ </xsd:complexType>
+ <xsd:simpleType name="AttrType_purpose">
+ <xsd:list>
+ <xsd:simpleType>
+ <xsd:union memberTypes="xlf:purposeValueList xlf:XTend"/>
+ </xsd:simpleType>
+ </xsd:list>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_datatype">
+ <xsd:union memberTypes="xlf:datatypeValueList xlf:XTend"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_restype">
+ <xsd:union memberTypes="xlf:restypeValueList xlf:XTend"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_alttranstype">
+ <xsd:union memberTypes="xlf:alttranstypeValueList xlf:XTend"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_context-type">
+ <xsd:union memberTypes="xlf:context-typeValueList xlf:XTend"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_state">
+ <xsd:union memberTypes="xlf:stateValueList xlf:XTend"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_state-qualifier">
+ <xsd:union memberTypes="xlf:state-qualifierValueList xlf:XTend"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_count-type">
+ <xsd:union memberTypes="xlf:restypeValueList xlf:count-typeValueList xlf:datatypeValueList xlf:stateValueList xlf:state-qualifierValueList xlf:XTend"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_InlineDelimiters">
+ <xsd:union memberTypes="xlf:InlineDelimitersValueList xlf:XTend"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_InlinePlaceholders">
+ <xsd:union memberTypes="xlf:InlinePlaceholdersValueList xlf:XTend"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_size-unit">
+ <xsd:union memberTypes="xlf:size-unitValueList xlf:XTend"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_mtype">
+ <xsd:union memberTypes="xlf:mtypeValueList xlf:XTend"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_unit">
+ <xsd:union memberTypes="xlf:unitValueList xlf:XTend"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_priority">
+ <xsd:union memberTypes="xlf:priorityValueList"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_reformat">
+ <xsd:union memberTypes="xlf:reformatValueYesNo xlf:reformatValueList"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_YesNo">
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="yes"/>
+ <xsd:enumeration value="no"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_Position">
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="open"/>
+ <xsd:enumeration value="close"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_assoc">
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="preceding"/>
+ <xsd:enumeration value="following"/>
+ <xsd:enumeration value="both"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_annotates">
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="source"/>
+ <xsd:enumeration value="target"/>
+ <xsd:enumeration value="general"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_Coordinates">
+ <xsd:annotation>
+ <xsd:documentation>Values for the attribute 'coord'.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="(-?\d+|#);(-?\d+|#);(-?\d+|#);(-?\d+|#)"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="AttrType_Version">
+ <xsd:annotation>
+ <xsd:documentation>Version values: 1.0 and 1.1 are allowed for backward compatibility.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="1.2"/>
+ <xsd:enumeration value="1.1"/>
+ <xsd:enumeration value="1.0"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!-- Groups -->
+ <xsd:group name="ElemGroup_TextContent">
+ <xsd:choice>
+ <xsd:element ref="xlf:g"/>
+ <xsd:element ref="xlf:bpt"/>
+ <xsd:element ref="xlf:ept"/>
+ <xsd:element ref="xlf:ph"/>
+ <xsd:element ref="xlf:it"/>
+ <xsd:element ref="xlf:mrk"/>
+ <xsd:element ref="xlf:x"/>
+ <xsd:element ref="xlf:bx"/>
+ <xsd:element ref="xlf:ex"/>
+ </xsd:choice>
+ </xsd:group>
+ <xsd:attributeGroup name="AttrGroup_TextContent">
+ <xsd:attribute name="id" type="xsd:string" use="required"/>
+ <xsd:attribute name="xid" type="xsd:string" use="optional"/>
+ <xsd:attribute name="equiv-text" type="xsd:string" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:attributeGroup>
+ <!-- XLIFF Structure -->
+ <xsd:element name="xliff">
+ <xsd:complexType>
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+ <xsd:element ref="xlf:file"/>
+ </xsd:sequence>
+ <xsd:attribute name="version" type="xlf:AttrType_Version" use="required"/>
+ <xsd:attribute ref="xml:lang" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="file">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element minOccurs="0" ref="xlf:header"/>
+ <xsd:element ref="xlf:body"/>
+ </xsd:sequence>
+ <xsd:attribute name="original" type="xsd:string" use="required"/>
+ <xsd:attribute name="source-language" type="xsd:language" use="required"/>
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="required"/>
+ <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
+ <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
+ <xsd:attribute ref="xml:space" use="optional"/>
+ <xsd:attribute name="category" type="xsd:string" use="optional"/>
+ <xsd:attribute name="target-language" type="xsd:language" use="optional"/>
+ <xsd:attribute name="product-name" type="xsd:string" use="optional"/>
+ <xsd:attribute name="product-version" type="xsd:string" use="optional"/>
+ <xsd:attribute name="build-num" type="xsd:string" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+ <xsd:unique name="U_group_id">
+ <xsd:selector xpath=".//xlf:group"/>
+ <xsd:field xpath="@id"/>
+ </xsd:unique>
+ <xsd:key name="K_unit_id">
+ <xsd:selector xpath=".//xlf:trans-unit|.//xlf:bin-unit"/>
+ <xsd:field xpath="@id"/>
+ </xsd:key>
+ <xsd:keyref name="KR_unit_id" refer="xlf:K_unit_id">
+ <xsd:selector xpath=".//bpt|.//ept|.//it|.//ph|.//g|.//x|.//bx|.//ex|.//sub"/>
+ <xsd:field xpath="@xid"/>
+ </xsd:keyref>
+ <xsd:key name="K_tool-id">
+ <xsd:selector xpath="xlf:header/xlf:tool"/>
+ <xsd:field xpath="@tool-id"/>
+ </xsd:key>
+ <xsd:keyref name="KR_file_tool-id" refer="xlf:K_tool-id">
+ <xsd:selector xpath="."/>
+ <xsd:field xpath="@tool-id"/>
+ </xsd:keyref>
+ <xsd:keyref name="KR_phase_tool-id" refer="xlf:K_tool-id">
+ <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
+ <xsd:field xpath="@tool-id"/>
+ </xsd:keyref>
+ <xsd:keyref name="KR_alt-trans_tool-id" refer="xlf:K_tool-id">
+ <xsd:selector xpath=".//xlf:trans-unit/xlf:alt-trans"/>
+ <xsd:field xpath="@tool-id"/>
+ </xsd:keyref>
+ <xsd:key name="K_count-group_name">
+ <xsd:selector xpath=".//xlf:count-group"/>
+ <xsd:field xpath="@name"/>
+ </xsd:key>
+ <xsd:unique name="U_context-group_name">
+ <xsd:selector xpath=".//xlf:context-group"/>
+ <xsd:field xpath="@name"/>
+ </xsd:unique>
+ <xsd:key name="K_phase-name">
+ <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
+ <xsd:field xpath="@phase-name"/>
+ </xsd:key>
+ <xsd:keyref name="KR_phase-name" refer="xlf:K_phase-name">
+ <xsd:selector xpath=".//xlf:count|.//xlf:trans-unit|.//xlf:target|.//bin-unit|.//bin-target"/>
+ <xsd:field xpath="@phase-name"/>
+ </xsd:keyref>
+ <xsd:unique name="U_uid">
+ <xsd:selector xpath=".//xlf:external-file"/>
+ <xsd:field xpath="@uid"/>
+ </xsd:unique>
+ </xsd:element>
+ <xsd:element name="header">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element minOccurs="0" name="skl" type="xlf:ElemType_ExternalReference"/>
+ <xsd:element minOccurs="0" ref="xlf:phase-group"/>
+ <xsd:choice maxOccurs="unbounded" minOccurs="0">
+ <xsd:element name="glossary" type="xlf:ElemType_ExternalReference"/>
+ <xsd:element name="reference" type="xlf:ElemType_ExternalReference"/>
+ <xsd:element ref="xlf:count-group"/>
+ <xsd:element ref="xlf:note"/>
+ <xsd:element ref="xlf:tool"/>
+ </xsd:choice>
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="internal-file">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="form" type="xsd:string"/>
+ <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="external-file">
+ <xsd:complexType>
+ <xsd:attribute name="href" type="xsd:string" use="required"/>
+ <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
+ <xsd:attribute name="uid" type="xsd:NMTOKEN"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="note">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute ref="xml:lang" use="optional"/>
+ <xsd:attribute default="1" name="priority" type="xlf:AttrType_priority" use="optional"/>
+ <xsd:attribute name="from" type="xsd:string" use="optional"/>
+ <xsd:attribute default="general" name="annotates" type="xlf:AttrType_annotates" use="optional"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="phase-group">
+ <xsd:complexType>
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element ref="xlf:phase"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="phase">
+ <xsd:complexType>
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+ <xsd:element ref="xlf:note"/>
+ </xsd:sequence>
+ <xsd:attribute name="phase-name" type="xsd:string" use="required"/>
+ <xsd:attribute name="process-name" type="xsd:string" use="required"/>
+ <xsd:attribute name="company-name" type="xsd:string" use="optional"/>
+ <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
+ <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
+ <xsd:attribute name="job-id" type="xsd:string" use="optional"/>
+ <xsd:attribute name="contact-name" type="xsd:string" use="optional"/>
+ <xsd:attribute name="contact-email" type="xsd:string" use="optional"/>
+ <xsd:attribute name="contact-phone" type="xsd:string" use="optional"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="count-group">
+ <xsd:complexType>
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+ <xsd:element ref="xlf:count"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="count">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="count-type" type="xlf:AttrType_count-type" use="optional"/>
+ <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
+ <xsd:attribute default="word" name="unit" type="xlf:AttrType_unit" use="optional"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="context-group">
+ <xsd:complexType>
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element ref="xlf:context"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="optional"/>
+ <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="purpose" type="xlf:AttrType_purpose" use="optional"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="context">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="context-type" type="xlf:AttrType_context-type" use="required"/>
+ <xsd:attribute default="no" name="match-mandatory" type="xlf:AttrType_YesNo" use="optional"/>
+ <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="tool">
+ <xsd:complexType mixed="true">
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="tool-id" type="xsd:string" use="required"/>
+ <xsd:attribute name="tool-name" type="xsd:string" use="required"/>
+ <xsd:attribute name="tool-version" type="xsd:string" use="optional"/>
+ <xsd:attribute name="tool-company" type="xsd:string" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="body">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded" minOccurs="0">
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="group">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:sequence>
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:count-group"/>
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+ </xsd:sequence>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
+ </xsd:choice>
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:string" use="optional"/>
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+ <xsd:attribute default="default" ref="xml:space" use="optional"/>
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+ <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
+ <xsd:attribute name="extype" type="xsd:string" use="optional"/>
+ <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="menu" type="xsd:string" use="optional"/>
+ <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
+ <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
+ <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+ <xsd:attribute name="font" type="xsd:string" use="optional"/>
+ <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+ <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
+ <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
+ <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
+ <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
+ <xsd:attribute default="no" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="trans-unit">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="xlf:source"/>
+ <xsd:element minOccurs="0" ref="xlf:seg-source"/>
+ <xsd:element minOccurs="0" ref="xlf:target"/>
+ <xsd:choice maxOccurs="unbounded" minOccurs="0">
+ <xsd:element ref="xlf:context-group"/>
+ <xsd:element ref="xlf:count-group"/>
+ <xsd:element ref="xlf:note"/>
+ <xsd:element ref="xlf:alt-trans"/>
+ </xsd:choice>
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:string" use="required"/>
+ <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
+ <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
+ <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
+ <xsd:attribute default="default" ref="xml:space" use="optional"/>
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+ <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+ <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
+ <xsd:attribute name="extype" type="xsd:string" use="optional"/>
+ <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="menu" type="xsd:string" use="optional"/>
+ <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
+ <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
+ <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+ <xsd:attribute name="font" type="xsd:string" use="optional"/>
+ <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+ <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
+ <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
+ <xsd:attribute default="yes" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+ <xsd:unique name="U_tu_segsrc_mid">
+ <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
+ <xsd:field xpath="@mid"/>
+ </xsd:unique>
+ <xsd:keyref name="KR_tu_segsrc_mid" refer="xlf:U_tu_segsrc_mid">
+ <xsd:selector xpath="./xlf:target/xlf:mrk|./xlf:alt-trans"/>
+ <xsd:field xpath="@mid"/>
+ </xsd:keyref>
+ </xsd:element>
+ <xsd:element name="source">
+ <xsd:complexType mixed="true">
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+ <xsd:attribute ref="xml:lang" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+ <xsd:unique name="U_source_bpt_rid">
+ <xsd:selector xpath=".//xlf:bpt"/>
+ <xsd:field xpath="@rid"/>
+ </xsd:unique>
+ <xsd:keyref name="KR_source_ept_rid" refer="xlf:U_source_bpt_rid">
+ <xsd:selector xpath=".//xlf:ept"/>
+ <xsd:field xpath="@rid"/>
+ </xsd:keyref>
+ <xsd:unique name="U_source_bx_rid">
+ <xsd:selector xpath=".//xlf:bx"/>
+ <xsd:field xpath="@rid"/>
+ </xsd:unique>
+ <xsd:keyref name="KR_source_ex_rid" refer="xlf:U_source_bx_rid">
+ <xsd:selector xpath=".//xlf:ex"/>
+ <xsd:field xpath="@rid"/>
+ </xsd:keyref>
+ </xsd:element>
+ <xsd:element name="seg-source">
+ <xsd:complexType mixed="true">
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+ <xsd:attribute ref="xml:lang" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+ <xsd:unique name="U_segsrc_bpt_rid">
+ <xsd:selector xpath=".//xlf:bpt"/>
+ <xsd:field xpath="@rid"/>
+ </xsd:unique>
+ <xsd:keyref name="KR_segsrc_ept_rid" refer="xlf:U_segsrc_bpt_rid">
+ <xsd:selector xpath=".//xlf:ept"/>
+ <xsd:field xpath="@rid"/>
+ </xsd:keyref>
+ <xsd:unique name="U_segsrc_bx_rid">
+ <xsd:selector xpath=".//xlf:bx"/>
+ <xsd:field xpath="@rid"/>
+ </xsd:unique>
+ <xsd:keyref name="KR_segsrc_ex_rid" refer="xlf:U_segsrc_bx_rid">
+ <xsd:selector xpath=".//xlf:ex"/>
+ <xsd:field xpath="@rid"/>
+ </xsd:keyref>
+ </xsd:element>
+ <xsd:element name="target">
+ <xsd:complexType mixed="true">
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+ <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
+ <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
+ <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute ref="xml:lang" use="optional"/>
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+ <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+ <xsd:attribute name="font" type="xsd:string" use="optional"/>
+ <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+ <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute default="yes" name="equiv-trans" type="xlf:AttrType_YesNo" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+ <xsd:unique name="U_target_bpt_rid">
+ <xsd:selector xpath=".//xlf:bpt"/>
+ <xsd:field xpath="@rid"/>
+ </xsd:unique>
+ <xsd:keyref name="KR_target_ept_rid" refer="xlf:U_target_bpt_rid">
+ <xsd:selector xpath=".//xlf:ept"/>
+ <xsd:field xpath="@rid"/>
+ </xsd:keyref>
+ <xsd:unique name="U_target_bx_rid">
+ <xsd:selector xpath=".//xlf:bx"/>
+ <xsd:field xpath="@rid"/>
+ </xsd:unique>
+ <xsd:keyref name="KR_target_ex_rid" refer="xlf:U_target_bx_rid">
+ <xsd:selector xpath=".//xlf:ex"/>
+ <xsd:field xpath="@rid"/>
+ </xsd:keyref>
+ </xsd:element>
+ <xsd:element name="alt-trans">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element minOccurs="0" ref="xlf:source"/>
+ <xsd:element minOccurs="0" ref="xlf:seg-source"/>
+ <xsd:element maxOccurs="1" ref="xlf:target"/>
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
+ <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+ </xsd:sequence>
+ <xsd:attribute name="match-quality" type="xsd:string" use="optional"/>
+ <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
+ <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute ref="xml:lang" use="optional"/>
+ <xsd:attribute name="origin" type="xsd:string" use="optional"/>
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+ <xsd:attribute default="default" ref="xml:space" use="optional"/>
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+ <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
+ <xsd:attribute name="extype" type="xsd:string" use="optional"/>
+ <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="menu" type="xsd:string" use="optional"/>
+ <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
+ <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
+ <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+ <xsd:attribute name="font" type="xsd:string" use="optional"/>
+ <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+ <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute default="proposal" name="alttranstype" type="xlf:AttrType_alttranstype" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+ <xsd:unique name="U_at_segsrc_mid">
+ <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
+ <xsd:field xpath="@mid"/>
+ </xsd:unique>
+ <xsd:keyref name="KR_at_segsrc_mid" refer="xlf:U_at_segsrc_mid">
+ <xsd:selector xpath="./xlf:target/xlf:mrk"/>
+ <xsd:field xpath="@mid"/>
+ </xsd:keyref>
+ </xsd:element>
+ <xsd:element name="bin-unit">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="xlf:bin-source"/>
+ <xsd:element minOccurs="0" ref="xlf:bin-target"/>
+ <xsd:choice maxOccurs="unbounded" minOccurs="0">
+ <xsd:element ref="xlf:context-group"/>
+ <xsd:element ref="xlf:count-group"/>
+ <xsd:element ref="xlf:note"/>
+ <xsd:element ref="xlf:trans-unit"/>
+ </xsd:choice>
+ <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:string" use="required"/>
+ <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="required"/>
+ <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
+ <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
+ <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+ <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="bin-source">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element ref="xlf:internal-file"/>
+ <xsd:element ref="xlf:external-file"/>
+ </xsd:choice>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="bin-target">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element ref="xlf:internal-file"/>
+ <xsd:element ref="xlf:external-file"/>
+ </xsd:choice>
+ <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="optional"/>
+ <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
+ <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
+ <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+ <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+ </xsd:element>
+ <!-- Element for inline codes -->
+ <xsd:element name="g">
+ <xsd:complexType mixed="true">
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+ <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="x">
+ <xsd:complexType>
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
+ <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="bx">
+ <xsd:complexType>
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+ <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="ex">
+ <xsd:complexType>
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="ph">
+ <xsd:complexType mixed="true">
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+ <xsd:element ref="xlf:sub"/>
+ </xsd:sequence>
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
+ <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+ <xsd:attribute name="assoc" type="xlf:AttrType_assoc" use="optional"/>
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="bpt">
+ <xsd:complexType mixed="true">
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+ <xsd:element ref="xlf:sub"/>
+ </xsd:sequence>
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+ <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="ept">
+ <xsd:complexType mixed="true">
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+ <xsd:element ref="xlf:sub"/>
+ </xsd:sequence>
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="it">
+ <xsd:complexType mixed="true">
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+ <xsd:element ref="xlf:sub"/>
+ </xsd:sequence>
+ <xsd:attribute name="pos" type="xlf:AttrType_Position" use="required"/>
+ <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+ <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+ <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="sub">
+ <xsd:complexType mixed="true">
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+ <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+ <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+ <xsd:attribute name="xid" type="xsd:string" use="optional"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="mrk">
+ <xsd:complexType mixed="true">
+ <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+ <xsd:attribute name="mtype" type="xlf:AttrType_mtype" use="required"/>
+ <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
+ <xsd:attribute name="comment" type="xsd:string" use="optional"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+ </xsd:element>
+</xsd:schema>
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xml.xsd b/vendor/symfony/translation/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xml.xsd
new file mode 100644
index 0000000..a46162a
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xml.xsd
@@ -0,0 +1,309 @@
+<?xml version='1.0'?>
+<?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns ="http://www.w3.org/1999/xhtml"
+ xml:lang="en">
+
+ <xs:annotation>
+ <xs:documentation>
+ <div>
+ <h1>About the XML namespace</h1>
+
+ <div class="bodytext">
+ <p>
+
+ This schema document describes the XML namespace, in a form
+ suitable for import by other schema documents.
+ </p>
+ <p>
+ See <a href="http://www.w3.org/XML/1998/namespace.html">
+ http://www.w3.org/XML/1998/namespace.html</a> and
+ <a href="http://www.w3.org/TR/REC-xml">
+ http://www.w3.org/TR/REC-xml</a> for information
+ about this namespace.
+ </p>
+
+ <p>
+ Note that local names in this namespace are intended to be
+ defined only by the World Wide Web Consortium or its subgroups.
+ The names currently defined in this namespace are listed below.
+ They should not be used with conflicting semantics by any Working
+ Group, specification, or document instance.
+ </p>
+ <p>
+ See further below in this document for more information about <a
+ href="#usage">how to refer to this schema document from your own
+ XSD schema documents</a> and about <a href="#nsversioning">the
+ namespace-versioning policy governing this schema document</a>.
+ </p>
+ </div>
+ </div>
+
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+ <xs:annotation>
+ <xs:documentation>
+ <div>
+
+ <h3>lang (as an attribute name)</h3>
+ <p>
+
+ denotes an attribute whose value
+ is a language code for the natural language of the content of
+ any element; its value is inherited. This name is reserved
+ by virtue of its definition in the XML specification.</p>
+
+ </div>
+ <div>
+ <h4>Notes</h4>
+ <p>
+ Attempting to install the relevant ISO 2- and 3-letter
+ codes as the enumerated possible values is probably never
+ going to be a realistic possibility.
+ </p>
+ <p>
+
+ See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
+ http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a>
+ and the IANA language subtag registry at
+ <a href="http://www.iana.org/assignments/language-subtag-registry">
+ http://www.iana.org/assignments/language-subtag-registry</a>
+ for further information.
+ </p>
+ <p>
+
+ The union allows for the 'un-declaration' of xml:lang with
+ the empty string.
+ </p>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:union memberTypes="xs:language">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value=""/>
+
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:union>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="space">
+ <xs:annotation>
+ <xs:documentation>
+
+ <div>
+
+ <h3>space (as an attribute name)</h3>
+ <p>
+ denotes an attribute whose
+ value is a keyword indicating what whitespace processing
+ discipline is intended for the content of the element; its
+ value is inherited. This name is reserved by virtue of its
+ definition in the XML specification.</p>
+
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI"> <xs:annotation>
+ <xs:documentation>
+
+ <div>
+
+ <h3>base (as an attribute name)</h3>
+ <p>
+ denotes an attribute whose value
+ provides a URI to be used as the base for interpreting any
+ relative URIs in the scope of the element on which it
+ appears; its value is inherited. This name is reserved
+ by virtue of its definition in the XML Base specification.</p>
+
+ <p>
+ See <a
+ href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a>
+ for information about this attribute.
+ </p>
+
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="id" type="xs:ID">
+ <xs:annotation>
+ <xs:documentation>
+ <div>
+
+ <h3>id (as an attribute name)</h3>
+ <p>
+
+ denotes an attribute whose value
+ should be interpreted as if declared to be of type ID.
+ This name is reserved by virtue of its definition in the
+ xml:id specification.</p>
+
+ <p>
+ See <a
+ href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a>
+ for information about this attribute.
+ </p>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ <xs:attribute ref="xml:id"/>
+ </xs:attributeGroup>
+
+ <xs:annotation>
+
+ <xs:documentation>
+ <div>
+
+ <h3>Father (in any context at all)</h3>
+
+ <div class="bodytext">
+ <p>
+ denotes Jon Bosak, the chair of
+ the original XML Working Group. This name is reserved by
+ the following decision of the W3C XML Plenary and
+ XML Coordination groups:
+ </p>
+ <blockquote>
+ <p>
+
+ In appreciation for his vision, leadership and
+ dedication the W3C XML Plenary on this 10th day of
+ February, 2000, reserves for Jon Bosak in perpetuity
+ the XML name "xml:Father".
+ </p>
+ </blockquote>
+ </div>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>
+
+ <div xml:id="usage" id="usage">
+ <h2><a name="usage">About this schema document</a></h2>
+
+ <div class="bodytext">
+ <p>
+ This schema defines attributes and an attribute group suitable
+ for use by schemas wishing to allow <code>xml:base</code>,
+ <code>xml:lang</code>, <code>xml:space</code> or
+ <code>xml:id</code> attributes on elements they define.
+ </p>
+
+ <p>
+ To enable this, such a schema must import this schema for
+ the XML namespace, e.g. as follows:
+ </p>
+ <pre>
+ &lt;schema.. .>
+ .. .
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+ </pre>
+ <p>
+ or
+ </p>
+ <pre>
+
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
+ </pre>
+ <p>
+ Subsequently, qualified reference to any of the attributes or the
+ group defined below will have the desired effect, e.g.
+ </p>
+ <pre>
+ &lt;type.. .>
+ .. .
+ &lt;attributeGroup ref="xml:specialAttrs"/>
+ </pre>
+ <p>
+ will define a type which will schema-validate an instance element
+ with any of those attributes.
+ </p>
+
+ </div>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>
+ <div id="nsversioning" xml:id="nsversioning">
+ <h2><a name="nsversioning">Versioning policy for this schema document</a></h2>
+
+ <div class="bodytext">
+ <p>
+ In keeping with the XML Schema WG's standard versioning
+ policy, this schema document will persist at
+ <a href="http://www.w3.org/2009/01/xml.xsd">
+ http://www.w3.org/2009/01/xml.xsd</a>.
+ </p>
+ <p>
+ At the date of issue it can also be found at
+ <a href="http://www.w3.org/2001/xml.xsd">
+ http://www.w3.org/2001/xml.xsd</a>.
+ </p>
+
+ <p>
+ The schema document at that URI may however change in the future,
+ in order to remain compatible with the latest version of XML
+ Schema itself, or with the XML namespace itself. In other words,
+ if the XML Schema or XML namespaces change, the version of this
+ document at <a href="http://www.w3.org/2001/xml.xsd">
+ http://www.w3.org/2001/xml.xsd
+ </a>
+ will change accordingly; the version at
+ <a href="http://www.w3.org/2009/01/xml.xsd">
+ http://www.w3.org/2009/01/xml.xsd
+ </a>
+ will not change.
+ </p>
+ <p>
+
+ Previous dated (and unchanging) versions of this schema
+ document are at:
+ </p>
+ <ul>
+ <li><a href="http://www.w3.org/2009/01/xml.xsd">
+ http://www.w3.org/2009/01/xml.xsd</a></li>
+ <li><a href="http://www.w3.org/2007/08/xml.xsd">
+ http://www.w3.org/2007/08/xml.xsd</a></li>
+ <li><a href="http://www.w3.org/2004/10/xml.xsd">
+
+ http://www.w3.org/2004/10/xml.xsd</a></li>
+ <li><a href="http://www.w3.org/2001/03/xml.xsd">
+ http://www.w3.org/2001/03/xml.xsd</a></li>
+ </ul>
+ </div>
+ </div>
+ </xs:documentation>
+ </xs:annotation>
+
+</xs:schema>
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/LoggingTranslator.php b/vendor/symfony/translation/Symfony/Component/Translation/LoggingTranslator.php
new file mode 100644
index 0000000..8511882
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/LoggingTranslator.php
@@ -0,0 +1,132 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Psr\Log\LoggerInterface;
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface
+{
+ /**
+ * @var TranslatorInterface
+ */
+ private $translator;
+
+ /**
+ * @var LoggerInterface
+ */
+ private $logger;
+
+ /**
+ * @param Translator $translator
+ * @param LoggerInterface $logger
+ */
+ public function __construct($translator, LoggerInterface $logger)
+ {
+ if (!($translator instanceof TranslatorInterface && $translator instanceof TranslatorBagInterface)) {
+ throw new \InvalidArgumentException(sprintf('The Translator "%s" must implements TranslatorInterface and TranslatorBagInterface.', get_class($translator)));
+ }
+
+ $this->translator = $translator;
+ $this->logger = $logger;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function trans($id, array $parameters = array(), $domain = null, $locale = null)
+ {
+ $trans = $this->translator->trans($id, $parameters, $domain, $locale);
+ $this->log($id, $domain, $locale);
+
+ return $trans;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
+ {
+ $trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
+ $this->log($id, $domain, $locale);
+
+ return $trans;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function setLocale($locale)
+ {
+ $this->translator->setLocale($locale);
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function getLocale()
+ {
+ return $this->translator->getLocale();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCatalogue($locale = null)
+ {
+ return $this->translator->getCatalogue($locale);
+ }
+
+ /**
+ * Passes through all unknown calls onto the translator object.
+ */
+ public function __call($method, $args)
+ {
+ return call_user_func_array(array($this->translator, $method), $args);
+ }
+
+ /**
+ * Logs for missing translations.
+ *
+ * @param string $id
+ * @param string|null $domain
+ * @param string|null $locale
+ */
+ private function log($id, $domain, $locale)
+ {
+ if (null === $locale) {
+ $locale = $this->getLocale();
+ }
+
+ if (null === $domain) {
+ $domain = 'messages';
+ }
+
+ $id = (string) $id;
+ $catalogue = $this->translator->getCatalogue($locale);
+ if ($catalogue->defines($id, $domain)) {
+ return;
+ }
+
+ if ($catalogue->has($id, $domain)) {
+ $this->logger->debug('Translation use fallback catalogue.', array('id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()));
+ } else {
+ $this->logger->warning('Translation not found.', array('id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()));
+ }
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/MessageCatalogue.php b/vendor/symfony/translation/Symfony/Component/Translation/MessageCatalogue.php
new file mode 100644
index 0000000..aa92a58
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/MessageCatalogue.php
@@ -0,0 +1,293 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Config\Resource\ResourceInterface;
+
+/**
+ * MessageCatalogue.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterface
+{
+ private $messages = array();
+ private $metadata = array();
+ private $resources = array();
+ private $locale;
+ private $fallbackCatalogue;
+ private $parent;
+
+ /**
+ * Constructor.
+ *
+ * @param string $locale The locale
+ * @param array $messages An array of messages classified by domain
+ *
+ * @api
+ */
+ public function __construct($locale, array $messages = array())
+ {
+ $this->locale = $locale;
+ $this->messages = $messages;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function getLocale()
+ {
+ return $this->locale;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function getDomains()
+ {
+ return array_keys($this->messages);
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function all($domain = null)
+ {
+ if (null === $domain) {
+ return $this->messages;
+ }
+
+ return isset($this->messages[$domain]) ? $this->messages[$domain] : array();
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function set($id, $translation, $domain = 'messages')
+ {
+ $this->add(array($id => $translation), $domain);
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function has($id, $domain = 'messages')
+ {
+ if (isset($this->messages[$domain][$id])) {
+ return true;
+ }
+
+ if (null !== $this->fallbackCatalogue) {
+ return $this->fallbackCatalogue->has($id, $domain);
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function defines($id, $domain = 'messages')
+ {
+ return isset($this->messages[$domain][$id]);
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function get($id, $domain = 'messages')
+ {
+ if (isset($this->messages[$domain][$id])) {
+ return $this->messages[$domain][$id];
+ }
+
+ if (null !== $this->fallbackCatalogue) {
+ return $this->fallbackCatalogue->get($id, $domain);
+ }
+
+ return $id;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function replace($messages, $domain = 'messages')
+ {
+ $this->messages[$domain] = array();
+
+ $this->add($messages, $domain);
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function add($messages, $domain = 'messages')
+ {
+ if (!isset($this->messages[$domain])) {
+ $this->messages[$domain] = $messages;
+ } else {
+ $this->messages[$domain] = array_replace($this->messages[$domain], $messages);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function addCatalogue(MessageCatalogueInterface $catalogue)
+ {
+ if ($catalogue->getLocale() !== $this->locale) {
+ throw new \LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s"', $catalogue->getLocale(), $this->locale));
+ }
+
+ foreach ($catalogue->all() as $domain => $messages) {
+ $this->add($messages, $domain);
+ }
+
+ foreach ($catalogue->getResources() as $resource) {
+ $this->addResource($resource);
+ }
+
+ if ($catalogue instanceof MetadataAwareInterface) {
+ $metadata = $catalogue->getMetadata('', '');
+ $this->addMetadata($metadata);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function addFallbackCatalogue(MessageCatalogueInterface $catalogue)
+ {
+ // detect circular references
+ $c = $this;
+ do {
+ if ($c->getLocale() === $catalogue->getLocale()) {
+ throw new \LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
+ }
+ } while ($c = $c->parent);
+
+ $catalogue->parent = $this;
+ $this->fallbackCatalogue = $catalogue;
+
+ foreach ($catalogue->getResources() as $resource) {
+ $this->addResource($resource);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function getFallbackCatalogue()
+ {
+ return $this->fallbackCatalogue;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function getResources()
+ {
+ return array_values($this->resources);
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function addResource(ResourceInterface $resource)
+ {
+ $this->resources[$resource->__toString()] = $resource;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadata($key = '', $domain = 'messages')
+ {
+ if ('' == $domain) {
+ return $this->metadata;
+ }
+
+ if (isset($this->metadata[$domain])) {
+ if ('' == $key) {
+ return $this->metadata[$domain];
+ }
+
+ if (isset($this->metadata[$domain][$key])) {
+ return $this->metadata[$domain][$key];
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMetadata($key, $value, $domain = 'messages')
+ {
+ $this->metadata[$domain][$key] = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteMetadata($key = '', $domain = 'messages')
+ {
+ if ('' == $domain) {
+ $this->metadata = array();
+ } elseif ('' == $key) {
+ unset($this->metadata[$domain]);
+ } else {
+ unset($this->metadata[$domain][$key]);
+ }
+ }
+
+ /**
+ * Adds current values with the new values.
+ *
+ * @param array $values Values to add
+ */
+ private function addMetadata(array $values)
+ {
+ foreach ($values as $domain => $keys) {
+ foreach ($keys as $key => $value) {
+ $this->setMetadata($key, $value, $domain);
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/MessageCatalogueInterface.php b/vendor/symfony/translation/Symfony/Component/Translation/MessageCatalogueInterface.php
new file mode 100644
index 0000000..647e337
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/MessageCatalogueInterface.php
@@ -0,0 +1,172 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Config\Resource\ResourceInterface;
+
+/**
+ * MessageCatalogueInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface MessageCatalogueInterface
+{
+ /**
+ * Gets the catalogue locale.
+ *
+ * @return string The locale
+ *
+ * @api
+ */
+ public function getLocale();
+
+ /**
+ * Gets the domains.
+ *
+ * @return array An array of domains
+ *
+ * @api
+ */
+ public function getDomains();
+
+ /**
+ * Gets the messages within a given domain.
+ *
+ * If $domain is null, it returns all messages.
+ *
+ * @param string $domain The domain name
+ *
+ * @return array An array of messages
+ *
+ * @api
+ */
+ public function all($domain = null);
+
+ /**
+ * Sets a message translation.
+ *
+ * @param string $id The message id
+ * @param string $translation The messages translation
+ * @param string $domain The domain name
+ *
+ * @api
+ */
+ public function set($id, $translation, $domain = 'messages');
+
+ /**
+ * Checks if a message has a translation.
+ *
+ * @param string $id The message id
+ * @param string $domain The domain name
+ *
+ * @return bool true if the message has a translation, false otherwise
+ *
+ * @api
+ */
+ public function has($id, $domain = 'messages');
+
+ /**
+ * Checks if a message has a translation (it does not take into account the fallback mechanism).
+ *
+ * @param string $id The message id
+ * @param string $domain The domain name
+ *
+ * @return bool true if the message has a translation, false otherwise
+ *
+ * @api
+ */
+ public function defines($id, $domain = 'messages');
+
+ /**
+ * Gets a message translation.
+ *
+ * @param string $id The message id
+ * @param string $domain The domain name
+ *
+ * @return string The message translation
+ *
+ * @api
+ */
+ public function get($id, $domain = 'messages');
+
+ /**
+ * Sets translations for a given domain.
+ *
+ * @param array $messages An array of translations
+ * @param string $domain The domain name
+ *
+ * @api
+ */
+ public function replace($messages, $domain = 'messages');
+
+ /**
+ * Adds translations for a given domain.
+ *
+ * @param array $messages An array of translations
+ * @param string $domain The domain name
+ *
+ * @api
+ */
+ public function add($messages, $domain = 'messages');
+
+ /**
+ * Merges translations from the given Catalogue into the current one.
+ *
+ * The two catalogues must have the same locale.
+ *
+ * @param MessageCatalogueInterface $catalogue A MessageCatalogueInterface instance
+ *
+ * @api
+ */
+ public function addCatalogue(MessageCatalogueInterface $catalogue);
+
+ /**
+ * Merges translations from the given Catalogue into the current one
+ * only when the translation does not exist.
+ *
+ * This is used to provide default translations when they do not exist for the current locale.
+ *
+ * @param MessageCatalogueInterface $catalogue A MessageCatalogueInterface instance
+ *
+ * @api
+ */
+ public function addFallbackCatalogue(MessageCatalogueInterface $catalogue);
+
+ /**
+ * Gets the fallback catalogue.
+ *
+ * @return MessageCatalogueInterface|null A MessageCatalogueInterface instance or null when no fallback has been set
+ *
+ * @api
+ */
+ public function getFallbackCatalogue();
+
+ /**
+ * Returns an array of resources loaded to build this collection.
+ *
+ * @return ResourceInterface[] An array of resources
+ *
+ * @api
+ */
+ public function getResources();
+
+ /**
+ * Adds a resource for this collection.
+ *
+ * @param ResourceInterface $resource A resource instance
+ *
+ * @api
+ */
+ public function addResource(ResourceInterface $resource);
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/MessageSelector.php b/vendor/symfony/translation/Symfony/Component/Translation/MessageSelector.php
new file mode 100644
index 0000000..9f5430c
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/MessageSelector.php
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * MessageSelector.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class MessageSelector
+{
+ /**
+ * Given a message with different plural translations separated by a
+ * pipe (|), this method returns the correct portion of the message based
+ * on the given number, locale and the pluralization rules in the message
+ * itself.
+ *
+ * The message supports two different types of pluralization rules:
+ *
+ * interval: {0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples
+ * indexed: There is one apple|There are %count% apples
+ *
+ * The indexed solution can also contain labels (e.g. one: There is one apple).
+ * This is purely for making the translations more clear - it does not
+ * affect the functionality.
+ *
+ * The two methods can also be mixed:
+ * {0} There are no apples|one: There is one apple|more: There are %count% apples
+ *
+ * @param string $message The message being translated
+ * @param int $number The number of items represented for the message
+ * @param string $locale The locale to use for choosing
+ *
+ * @return string
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @api
+ */
+ public function choose($message, $number, $locale)
+ {
+ $parts = explode('|', $message);
+ $explicitRules = array();
+ $standardRules = array();
+ foreach ($parts as $part) {
+ $part = trim($part);
+
+ if (preg_match('/^(?P<interval>'.Interval::getIntervalRegexp().')\s*(?P<message>.*?)$/x', $part, $matches)) {
+ $explicitRules[$matches['interval']] = $matches['message'];
+ } elseif (preg_match('/^\w+\:\s*(.*?)$/', $part, $matches)) {
+ $standardRules[] = $matches[1];
+ } else {
+ $standardRules[] = $part;
+ }
+ }
+
+ // try to match an explicit rule, then fallback to the standard ones
+ foreach ($explicitRules as $interval => $m) {
+ if (Interval::test($number, $interval)) {
+ return $m;
+ }
+ }
+
+ $position = PluralizationRules::get($number, $locale);
+
+ if (!isset($standardRules[$position])) {
+ // when there's exactly one rule given, and that rule is a standard
+ // rule, use this rule
+ if (1 === count($parts) && isset($standardRules[0])) {
+ return $standardRules[0];
+ }
+
+ throw new \InvalidArgumentException(sprintf('Unable to choose a translation for "%s" with locale "%s" for value "%d". Double check that this translation has the correct plural options (e.g. "There is one apple|There are %%count%% apples").', $message, $locale, $number));
+ }
+
+ return $standardRules[$position];
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/MetadataAwareInterface.php b/vendor/symfony/translation/Symfony/Component/Translation/MetadataAwareInterface.php
new file mode 100644
index 0000000..e93c6fb
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/MetadataAwareInterface.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * MetadataAwareInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface MetadataAwareInterface
+{
+ /**
+ * Gets metadata for the given domain and key.
+ *
+ * Passing an empty domain will return an array with all metadata indexed by
+ * domain and then by key. Passing an empty key will return an array with all
+ * metadata for the given domain.
+ *
+ * @param string $key The key
+ * @param string $domain The domain name
+ *
+ * @return mixed The value that was set or an array with the domains/keys or null
+ */
+ public function getMetadata($key = '', $domain = 'messages');
+
+ /**
+ * Adds metadata to a message domain.
+ *
+ * @param string $key The key
+ * @param mixed $value The value
+ * @param string $domain The domain name
+ */
+ public function setMetadata($key, $value, $domain = 'messages');
+
+ /**
+ * Deletes metadata for the given key and domain.
+ *
+ * Passing an empty domain will delete all metadata. Passing an empty key will
+ * delete all metadata for the given domain.
+ *
+ * @param string $key The key
+ * @param string $domain The domain name
+ */
+ public function deleteMetadata($key = '', $domain = 'messages');
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/PluralizationRules.php b/vendor/symfony/translation/Symfony/Component/Translation/PluralizationRules.php
new file mode 100644
index 0000000..e1eac82
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/PluralizationRules.php
@@ -0,0 +1,214 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * Returns the plural rules for a given locale.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class PluralizationRules
+{
+ private static $rules = array();
+
+ /**
+ * Returns the plural position to use for the given locale and number.
+ *
+ * @param int $number The number
+ * @param string $locale The locale
+ *
+ * @return int The plural position
+ */
+ public static function get($number, $locale)
+ {
+ if ('pt_BR' === $locale) {
+ // temporary set a locale for brazilian
+ $locale = 'xbr';
+ }
+
+ if (strlen($locale) > 3) {
+ $locale = substr($locale, 0, -strlen(strrchr($locale, '_')));
+ }
+
+ if (isset(self::$rules[$locale])) {
+ $return = call_user_func(self::$rules[$locale], $number);
+
+ if (!is_int($return) || $return < 0) {
+ return 0;
+ }
+
+ return $return;
+ }
+
+ /*
+ * The plural rules are derived from code of the Zend Framework (2010-09-25),
+ * which is subject to the new BSD license (http://framework.zend.com/license/new-bsd).
+ * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ */
+ switch ($locale) {
+ case 'bo':
+ case 'dz':
+ case 'id':
+ case 'ja':
+ case 'jv':
+ case 'ka':
+ case 'km':
+ case 'kn':
+ case 'ko':
+ case 'ms':
+ case 'th':
+ case 'tr':
+ case 'vi':
+ case 'zh':
+ return 0;
+ break;
+
+ case 'af':
+ case 'az':
+ case 'bn':
+ case 'bg':
+ case 'ca':
+ case 'da':
+ case 'de':
+ case 'el':
+ case 'en':
+ case 'eo':
+ case 'es':
+ case 'et':
+ case 'eu':
+ case 'fa':
+ case 'fi':
+ case 'fo':
+ case 'fur':
+ case 'fy':
+ case 'gl':
+ case 'gu':
+ case 'ha':
+ case 'he':
+ case 'hu':
+ case 'is':
+ case 'it':
+ case 'ku':
+ case 'lb':
+ case 'ml':
+ case 'mn':
+ case 'mr':
+ case 'nah':
+ case 'nb':
+ case 'ne':
+ case 'nl':
+ case 'nn':
+ case 'no':
+ case 'om':
+ case 'or':
+ case 'pa':
+ case 'pap':
+ case 'ps':
+ case 'pt':
+ case 'so':
+ case 'sq':
+ case 'sv':
+ case 'sw':
+ case 'ta':
+ case 'te':
+ case 'tk':
+ case 'ur':
+ case 'zu':
+ return ($number == 1) ? 0 : 1;
+
+ case 'am':
+ case 'bh':
+ case 'fil':
+ case 'fr':
+ case 'gun':
+ case 'hi':
+ case 'ln':
+ case 'mg':
+ case 'nso':
+ case 'xbr':
+ case 'ti':
+ case 'wa':
+ return (($number == 0) || ($number == 1)) ? 0 : 1;
+
+ case 'be':
+ case 'bs':
+ case 'hr':
+ case 'ru':
+ case 'sr':
+ case 'uk':
+ return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
+
+ case 'cs':
+ case 'sk':
+ return ($number == 1) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2);
+
+ case 'ga':
+ return ($number == 1) ? 0 : (($number == 2) ? 1 : 2);
+
+ case 'lt':
+ return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
+
+ case 'sl':
+ return ($number % 100 == 1) ? 0 : (($number % 100 == 2) ? 1 : ((($number % 100 == 3) || ($number % 100 == 4)) ? 2 : 3));
+
+ case 'mk':
+ return ($number % 10 == 1) ? 0 : 1;
+
+ case 'mt':
+ return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 1) && ($number % 100 < 11))) ? 1 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 2 : 3));
+
+ case 'lv':
+ return ($number == 0) ? 0 : ((($number % 10 == 1) && ($number % 100 != 11)) ? 1 : 2);
+
+ case 'pl':
+ return ($number == 1) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 1 : 2);
+
+ case 'cy':
+ return ($number == 1) ? 0 : (($number == 2) ? 1 : ((($number == 8) || ($number == 11)) ? 2 : 3));
+
+ case 'ro':
+ return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 0) && ($number % 100 < 20))) ? 1 : 2);
+
+ case 'ar':
+ return ($number == 0) ? 0 : (($number == 1) ? 1 : (($number == 2) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : 5))));
+
+ default:
+ return 0;
+ }
+ }
+
+ /**
+ * Overrides the default plural rule for a given locale.
+ *
+ * @param string $rule A PHP callable
+ * @param string $locale The locale
+ *
+ * @throws \LogicException
+ */
+ public static function set($rule, $locale)
+ {
+ if ('pt_BR' === $locale) {
+ // temporary set a locale for brazilian
+ $locale = 'xbr';
+ }
+
+ if (strlen($locale) > 3) {
+ $locale = substr($locale, 0, -strlen(strrchr($locale, '_')));
+ }
+
+ if (!is_callable($rule)) {
+ throw new \LogicException('The given rule can not be called');
+ }
+
+ self::$rules[$locale] = $rule;
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/README.md b/vendor/symfony/translation/Symfony/Component/Translation/README.md
new file mode 100644
index 0000000..7017062
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/README.md
@@ -0,0 +1,37 @@
+Translation Component
+=====================
+
+Translation provides tools for loading translation files and generating
+translated strings from these including support for pluralization.
+
+```php
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\MessageSelector;
+use Symfony\Component\Translation\Loader\ArrayLoader;
+
+$translator = new Translator('fr_FR', new MessageSelector());
+$translator->setFallbackLocales(array('fr'));
+$translator->addLoader('array', new ArrayLoader());
+$translator->addResource('array', array(
+ 'Hello World!' => 'Bonjour',
+), 'fr');
+
+echo $translator->trans('Hello World!')."\n";
+```
+
+Resources
+---------
+
+Silex integration:
+
+https://github.com/fabpot/Silex/blob/master/src/Silex/Provider/TranslationServiceProvider.php
+
+Documentation:
+
+http://symfony.com/doc/2.6/book/translation.html
+
+You can run the unit tests with the following command:
+
+ $ cd path/to/Symfony/Component/Translation/
+ $ composer install
+ $ phpunit
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/AbstractOperationTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/AbstractOperationTest.php
new file mode 100644
index 0000000..30c21af
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/AbstractOperationTest.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Catalogue;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+abstract class AbstractOperationTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetEmptyDomains()
+ {
+ $this->assertEquals(
+ array(),
+ $this->createOperation(
+ new MessageCatalogue('en'),
+ new MessageCatalogue('en')
+ )->getDomains()
+ );
+ }
+
+ public function testGetMergedDomains()
+ {
+ $this->assertEquals(
+ array('a', 'b', 'c'),
+ $this->createOperation(
+ new MessageCatalogue('en', array('a' => array(), 'b' => array())),
+ new MessageCatalogue('en', array('b' => array(), 'c' => array()))
+ )->getDomains()
+ );
+ }
+
+ public function testGetMessagesFromUnknownDomain()
+ {
+ $this->setExpectedException('InvalidArgumentException');
+ $this->createOperation(
+ new MessageCatalogue('en'),
+ new MessageCatalogue('en')
+ )->getMessages('domain');
+ }
+
+ public function testGetEmptyMessages()
+ {
+ $this->assertEquals(
+ array(),
+ $this->createOperation(
+ new MessageCatalogue('en', array('a' => array())),
+ new MessageCatalogue('en')
+ )->getMessages('a')
+ );
+ }
+
+ public function testGetEmptyResult()
+ {
+ $this->assertEquals(
+ new MessageCatalogue('en'),
+ $this->createOperation(
+ new MessageCatalogue('en'),
+ new MessageCatalogue('en')
+ )->getResult()
+ );
+ }
+
+ abstract protected function createOperation(MessageCatalogueInterface $source, MessageCatalogueInterface $target);
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/DiffOperationTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/DiffOperationTest.php
new file mode 100644
index 0000000..26bd582
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/DiffOperationTest.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Catalogue;
+
+use Symfony\Component\Translation\Catalogue\DiffOperation;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+class DiffOperationTest extends AbstractOperationTest
+{
+ public function testGetMessagesFromSingleDomain()
+ {
+ $operation = $this->createOperation(
+ new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))),
+ new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c')))
+ );
+
+ $this->assertEquals(
+ array('a' => 'old_a', 'c' => 'new_c'),
+ $operation->getMessages('messages')
+ );
+
+ $this->assertEquals(
+ array('c' => 'new_c'),
+ $operation->getNewMessages('messages')
+ );
+
+ $this->assertEquals(
+ array('b' => 'old_b'),
+ $operation->getObsoleteMessages('messages')
+ );
+ }
+
+ public function testGetResultFromSingleDomain()
+ {
+ $this->assertEquals(
+ new MessageCatalogue('en', array(
+ 'messages' => array('a' => 'old_a', 'c' => 'new_c'),
+ )),
+ $this->createOperation(
+ new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))),
+ new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c')))
+ )->getResult()
+ );
+ }
+
+ public function testGetResultWithMetadata()
+ {
+ $leftCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b')));
+ $leftCatalogue->setMetadata('a', 'foo', 'messages');
+ $leftCatalogue->setMetadata('b', 'bar', 'messages');
+ $rightCatalogue = new MessageCatalogue('en', array('messages' => array('b' => 'new_b', 'c' => 'new_c')));
+ $rightCatalogue->setMetadata('b', 'baz', 'messages');
+ $rightCatalogue->setMetadata('c', 'qux', 'messages');
+
+ $diffCatalogue = new MessageCatalogue('en', array('messages' => array('b' => 'old_b', 'c' => 'new_c')));
+ $diffCatalogue->setMetadata('b', 'bar', 'messages');
+ $diffCatalogue->setMetadata('c', 'qux', 'messages');
+
+ $this->assertEquals(
+ $diffCatalogue,
+ $this->createOperation(
+ $leftCatalogue,
+ $rightCatalogue
+ )->getResult()
+ );
+ }
+
+ protected function createOperation(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
+ {
+ return new DiffOperation($source, $target);
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/MergeOperationTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/MergeOperationTest.php
new file mode 100644
index 0000000..8b51c15
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Catalogue/MergeOperationTest.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Catalogue;
+
+use Symfony\Component\Translation\Catalogue\MergeOperation;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+class MergeOperationTest extends AbstractOperationTest
+{
+ public function testGetMessagesFromSingleDomain()
+ {
+ $operation = $this->createOperation(
+ new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))),
+ new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c')))
+ );
+
+ $this->assertEquals(
+ array('a' => 'old_a', 'b' => 'old_b', 'c' => 'new_c'),
+ $operation->getMessages('messages')
+ );
+
+ $this->assertEquals(
+ array('c' => 'new_c'),
+ $operation->getNewMessages('messages')
+ );
+
+ $this->assertEquals(
+ array(),
+ $operation->getObsoleteMessages('messages')
+ );
+ }
+
+ public function testGetResultFromSingleDomain()
+ {
+ $this->assertEquals(
+ new MessageCatalogue('en', array(
+ 'messages' => array('a' => 'old_a', 'b' => 'old_b', 'c' => 'new_c'),
+ )),
+ $this->createOperation(
+ new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))),
+ new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c')))
+ )->getResult()
+ );
+ }
+
+ public function testGetResultWithMetadata()
+ {
+ $leftCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b')));
+ $leftCatalogue->setMetadata('a', 'foo', 'messages');
+ $leftCatalogue->setMetadata('b', 'bar', 'messages');
+ $rightCatalogue = new MessageCatalogue('en', array('messages' => array('b' => 'new_b', 'c' => 'new_c')));
+ $rightCatalogue->setMetadata('b', 'baz', 'messages');
+ $rightCatalogue->setMetadata('c', 'qux', 'messages');
+
+ $mergedCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b', 'c' => 'new_c')));
+ $mergedCatalogue->setMetadata('a', 'foo', 'messages');
+ $mergedCatalogue->setMetadata('b', 'bar', 'messages');
+ $mergedCatalogue->setMetadata('c', 'qux', 'messages');
+
+ $this->assertEquals(
+ $mergedCatalogue,
+ $this->createOperation(
+ $leftCatalogue,
+ $rightCatalogue
+ )->getResult()
+ );
+ }
+
+ protected function createOperation(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
+ {
+ return new MergeOperation($source, $target);
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/CsvFileDumperTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/CsvFileDumperTest.php
new file mode 100644
index 0000000..29177ff
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/CsvFileDumperTest.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\CsvFileDumper;
+
+class CsvFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDump()
+ {
+ $catalogue = new MessageCatalogue('en');
+ $catalogue->add(array('foo' => 'bar', 'bar' => 'foo
+foo', 'foo;foo' => 'bar'));
+
+ $tempDir = sys_get_temp_dir();
+ $dumper = new CsvFileDumper();
+ $dumper->dump($catalogue, array('path' => $tempDir));
+
+ $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/valid.csv'), file_get_contents($tempDir.'/messages.en.csv'));
+
+ unlink($tempDir.'/messages.en.csv');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php
new file mode 100644
index 0000000..9682089
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/FileDumperTest.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\FileDumper;
+
+class FileDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDumpBackupsFileIfExisting()
+ {
+ $tempDir = sys_get_temp_dir();
+ $file = $tempDir.'/messages.en.concrete';
+ $backupFile = $file.'~';
+
+ @touch($file);
+
+ $catalogue = new MessageCatalogue('en');
+ $catalogue->add(array('foo' => 'bar'));
+
+ $dumper = new ConcreteFileDumper();
+ $dumper->dump($catalogue, array('path' => $tempDir));
+
+ $this->assertTrue(file_exists($backupFile));
+
+ @unlink($file);
+ @unlink($backupFile);
+ }
+
+ public function testDumpCreatesNestedDirectoriesAndFile()
+ {
+ $tempDir = sys_get_temp_dir();
+ $translationsDir = $tempDir.'/test/translations';
+ $file = $translationsDir.'/messages.en.concrete';
+
+ $catalogue = new MessageCatalogue('en');
+ $catalogue->add(array('foo' => 'bar'));
+
+ $dumper = new ConcreteFileDumper();
+ $dumper->setRelativePathTemplate('test/translations/%domain%.%locale%.%extension%');
+ $dumper->dump($catalogue, array('path' => $tempDir));
+
+ $this->assertTrue(file_exists($file));
+
+ @unlink($file);
+ @rmdir($translationsDir);
+ }
+}
+
+class ConcreteFileDumper extends FileDumper
+{
+ protected function format(MessageCatalogue $messages, $domain)
+ {
+ return '';
+ }
+
+ protected function getExtension()
+ {
+ return 'concrete';
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/IcuResFileDumperTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/IcuResFileDumperTest.php
new file mode 100644
index 0000000..7be7dfb
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/IcuResFileDumperTest.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\IcuResFileDumper;
+
+class IcuResFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDump()
+ {
+ if (!function_exists('mb_convert_encoding')) {
+ $this->markTestSkipped('This test requires mbstring to work.');
+ }
+
+ $catalogue = new MessageCatalogue('en');
+ $catalogue->add(array('foo' => 'bar'));
+
+ $tempDir = sys_get_temp_dir().'/IcuResFileDumperTest';
+ $dumper = new IcuResFileDumper();
+ $dumper->dump($catalogue, array('path' => $tempDir));
+
+ $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resourcebundle/res/en.res'), file_get_contents($tempDir.'/messages/en.res'));
+
+ @unlink($tempDir.'/messages/en.res');
+ @rmdir($tempDir.'/messages');
+ @rmdir($tempDir);
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/IniFileDumperTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/IniFileDumperTest.php
new file mode 100644
index 0000000..2a2cefd
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/IniFileDumperTest.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\IniFileDumper;
+
+class IniFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDump()
+ {
+ $catalogue = new MessageCatalogue('en');
+ $catalogue->add(array('foo' => 'bar'));
+
+ $tempDir = sys_get_temp_dir();
+ $dumper = new IniFileDumper();
+ $dumper->dump($catalogue, array('path' => $tempDir));
+
+ $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.ini'), file_get_contents($tempDir.'/messages.en.ini'));
+
+ unlink($tempDir.'/messages.en.ini');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/JsonFileDumperTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/JsonFileDumperTest.php
new file mode 100644
index 0000000..697cd93
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/JsonFileDumperTest.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\JsonFileDumper;
+
+class JsonFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDump()
+ {
+ if (PHP_VERSION_ID < 50400) {
+ $this->markTestIncomplete('PHP below 5.4 doesn\'t support JSON pretty printing');
+ }
+
+ $catalogue = new MessageCatalogue('en');
+ $catalogue->add(array('foo' => 'bar'));
+
+ $tempDir = sys_get_temp_dir();
+ $dumper = new JsonFileDumper();
+ $dumper->dump($catalogue, array('path' => $tempDir));
+
+ $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.json'), file_get_contents($tempDir.'/messages.en.json'));
+
+ unlink($tempDir.'/messages.en.json');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/MoFileDumperTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/MoFileDumperTest.php
new file mode 100644
index 0000000..439a25c
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/MoFileDumperTest.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\MoFileDumper;
+
+class MoFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDump()
+ {
+ $catalogue = new MessageCatalogue('en');
+ $catalogue->add(array('foo' => 'bar'));
+
+ $tempDir = sys_get_temp_dir();
+ $dumper = new MoFileDumper();
+ $dumper->dump($catalogue, array('path' => $tempDir));
+ $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.mo'), file_get_contents($tempDir.'/messages.en.mo'));
+
+ unlink($tempDir.'/messages.en.mo');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/PhpFileDumperTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/PhpFileDumperTest.php
new file mode 100644
index 0000000..18be5a0
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/PhpFileDumperTest.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\PhpFileDumper;
+
+class PhpFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDump()
+ {
+ $catalogue = new MessageCatalogue('en');
+ $catalogue->add(array('foo' => 'bar'));
+
+ $tempDir = sys_get_temp_dir();
+ $dumper = new PhpFileDumper();
+ $dumper->dump($catalogue, array('path' => $tempDir));
+
+ $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.php'), file_get_contents($tempDir.'/messages.en.php'));
+
+ unlink($tempDir.'/messages.en.php');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/PoFileDumperTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/PoFileDumperTest.php
new file mode 100644
index 0000000..0296d6b
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/PoFileDumperTest.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\PoFileDumper;
+
+class PoFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDump()
+ {
+ $catalogue = new MessageCatalogue('en');
+ $catalogue->add(array('foo' => 'bar'));
+
+ $tempDir = sys_get_temp_dir();
+ $dumper = new PoFileDumper();
+ $dumper->dump($catalogue, array('path' => $tempDir));
+ $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.po'), file_get_contents($tempDir.'/messages.en.po'));
+
+ unlink($tempDir.'/messages.en.po');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/QtFileDumperTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/QtFileDumperTest.php
new file mode 100644
index 0000000..d7d8fb7
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/QtFileDumperTest.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\QtFileDumper;
+
+class QtFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDump()
+ {
+ $catalogue = new MessageCatalogue('en');
+ $catalogue->add(array('foo' => 'bar'), 'resources');
+
+ $tempDir = sys_get_temp_dir();
+ $dumper = new QtFileDumper();
+ $dumper->dump($catalogue, array('path' => $tempDir));
+
+ $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.ts'), file_get_contents($tempDir.'/resources.en.ts'));
+
+ unlink($tempDir.'/resources.en.ts');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php
new file mode 100644
index 0000000..dff2cc4
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\XliffFileDumper;
+
+class XliffFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDump()
+ {
+ $catalogue = new MessageCatalogue('en_US');
+ $catalogue->add(array(
+ 'foo' => 'bar',
+ 'key' => '',
+ 'key.with.cdata' => '<source> & <target>',
+ ));
+ $catalogue->setMetadata('foo', array('notes' => array(array('priority' => 1, 'from' => 'bar', 'content' => 'baz'))));
+ $catalogue->setMetadata('key', array('notes' => array(array('content' => 'baz'), array('content' => 'qux'))));
+
+ $tempDir = sys_get_temp_dir();
+ $dumper = new XliffFileDumper();
+ $dumper->dump($catalogue, array('path' => $tempDir, 'default_locale' => 'fr_FR'));
+
+ $this->assertEquals(
+ file_get_contents(__DIR__.'/../fixtures/resources-clean.xlf'),
+ file_get_contents($tempDir.'/messages.en_US.xlf')
+ );
+
+ unlink($tempDir.'/messages.en_US.xlf');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/YamlFileDumperTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/YamlFileDumperTest.php
new file mode 100644
index 0000000..3c68ade
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Dumper/YamlFileDumperTest.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\YamlFileDumper;
+
+class YamlFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDump()
+ {
+ $catalogue = new MessageCatalogue('en');
+ $catalogue->add(array('foo' => 'bar'));
+
+ $tempDir = sys_get_temp_dir();
+ $dumper = new YamlFileDumper();
+ $dumper->dump($catalogue, array('path' => $tempDir));
+
+ $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.yml'), file_get_contents($tempDir.'/messages.en.yml'));
+
+ unlink($tempDir.'/messages.en.yml');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php
new file mode 100644
index 0000000..352dd31
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Intl\Util\IntlTestHelper;
+use Symfony\Component\Translation\IdentityTranslator;
+
+class IdentityTranslatorTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getTransTests
+ */
+ public function testTrans($expected, $id, $parameters)
+ {
+ $translator = new IdentityTranslator();
+
+ $this->assertEquals($expected, $translator->trans($id, $parameters));
+ }
+
+ /**
+ * @dataProvider getTransChoiceTests
+ */
+ public function testTransChoiceWithExplicitLocale($expected, $id, $number, $parameters)
+ {
+ $translator = new IdentityTranslator();
+ $translator->setLocale('en');
+
+ $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters));
+ }
+
+ /**
+ * @dataProvider getTransChoiceTests
+ */
+ public function testTransChoiceWithDefaultLocale($expected, $id, $number, $parameters)
+ {
+ \Locale::setDefault('en');
+
+ $translator = new IdentityTranslator();
+
+ $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters));
+ }
+
+ public function testGetSetLocale()
+ {
+ $translator = new IdentityTranslator();
+ $translator->setLocale('en');
+
+ $this->assertEquals('en', $translator->getLocale());
+ }
+
+ public function testGetLocaleReturnsDefaultLocaleIfNotSet()
+ {
+ // in order to test with "pt_BR"
+ IntlTestHelper::requireFullIntl($this);
+
+ $translator = new IdentityTranslator();
+
+ \Locale::setDefault('en');
+ $this->assertEquals('en', $translator->getLocale());
+
+ \Locale::setDefault('pt_BR');
+ $this->assertEquals('pt_BR', $translator->getLocale());
+ }
+
+ public function getTransTests()
+ {
+ return array(
+ array('Symfony is great!', 'Symfony is great!', array()),
+ array('Symfony is awesome!', 'Symfony is %what%!', array('%what%' => 'awesome')),
+ );
+ }
+
+ public function getTransChoiceTests()
+ {
+ return array(
+ array('There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0, array('%count%' => 0)),
+ array('There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1, array('%count%' => 1)),
+ array('There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10, array('%count%' => 10)),
+ array('There are 0 apples', 'There is 1 apple|There are %count% apples', 0, array('%count%' => 0)),
+ array('There is 1 apple', 'There is 1 apple|There are %count% apples', 1, array('%count%' => 1)),
+ array('There are 10 apples', 'There is 1 apple|There are %count% apples', 10, array('%count%' => 10)),
+ // custom validation messages may be coded with a fixed value
+ array('There are 2 apples', 'There are 2 apples', 2, array('%count%' => 2)),
+ );
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/IntervalTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/IntervalTest.php
new file mode 100644
index 0000000..075c98b
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/IntervalTest.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\Interval;
+
+class IntervalTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getTests
+ */
+ public function testTest($expected, $number, $interval)
+ {
+ $this->assertEquals($expected, Interval::test($number, $interval));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testTestException()
+ {
+ Interval::test(1, 'foobar');
+ }
+
+ public function getTests()
+ {
+ return array(
+ array(true, 3, '{1,2, 3 ,4}'),
+ array(false, 10, '{1,2, 3 ,4}'),
+ array(false, 3, '[1,2]'),
+ array(true, 1, '[1,2]'),
+ array(true, 2, '[1,2]'),
+ array(false, 1, ']1,2['),
+ array(false, 2, ']1,2['),
+ array(true, log(0), '[-Inf,2['),
+ array(true, -log(0), '[-2,+Inf]'),
+ );
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/CsvFileLoaderTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/CsvFileLoaderTest.php
new file mode 100644
index 0000000..463d3b5
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/CsvFileLoaderTest.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\CsvFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class CsvFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testLoad()
+ {
+ $loader = new CsvFileLoader();
+ $resource = __DIR__.'/../fixtures/resources.csv';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ public function testLoadDoesNothingIfEmpty()
+ {
+ $loader = new CsvFileLoader();
+ $resource = __DIR__.'/../fixtures/empty.csv';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array(), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+ */
+ public function testLoadNonExistingResource()
+ {
+ $loader = new CsvFileLoader();
+ $resource = __DIR__.'/../fixtures/not-exists.csv';
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ */
+ public function testLoadNonLocalResource()
+ {
+ $loader = new CsvFileLoader();
+ $resource = 'http://example.com/resources.csv';
+ $loader->load($resource, 'en', 'domain1');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IcuDatFileLoaderTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IcuDatFileLoaderTest.php
new file mode 100644
index 0000000..ea9643d
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IcuDatFileLoaderTest.php
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\IcuDatFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class IcuDatFileLoaderTest extends LocalizedTestCase
+{
+ protected function setUp()
+ {
+ if (!extension_loaded('intl')) {
+ $this->markTestSkipped('This test requires intl extension to work.');
+ }
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ */
+ public function testLoadInvalidResource()
+ {
+ $loader = new IcuDatFileLoader();
+ $loader->load(__DIR__.'/../fixtures/resourcebundle/corrupted/resources', 'es', 'domain2');
+ }
+
+ public function testDatEnglishLoad()
+ {
+ // bundled resource is build using pkgdata command which at least in ICU 4.2 comes in extremely! buggy form
+ // you must specify an temporary build directory which is not the same as current directory and
+ // MUST reside on the same partition. pkgdata -p resources -T /srv -d.packagelist.txt
+ $loader = new IcuDatFileLoader();
+ $resource = __DIR__.'/../fixtures/resourcebundle/dat/resources';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array('symfony' => 'Symfony 2 is great'), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource.'.dat')), $catalogue->getResources());
+ }
+
+ public function testDatFrenchLoad()
+ {
+ $loader = new IcuDatFileLoader();
+ $resource = __DIR__.'/../fixtures/resourcebundle/dat/resources';
+ $catalogue = $loader->load($resource, 'fr', 'domain1');
+
+ $this->assertEquals(array('symfony' => 'Symfony 2 est génial'), $catalogue->all('domain1'));
+ $this->assertEquals('fr', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource.'.dat')), $catalogue->getResources());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+ */
+ public function testLoadNonExistingResource()
+ {
+ $loader = new IcuDatFileLoader();
+ $loader->load(__DIR__.'/../fixtures/non-existing.txt', 'en', 'domain1');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IcuResFileLoaderTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IcuResFileLoaderTest.php
new file mode 100644
index 0000000..1a935c0
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IcuResFileLoaderTest.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\IcuResFileLoader;
+use Symfony\Component\Config\Resource\DirectoryResource;
+
+class IcuResFileLoaderTest extends LocalizedTestCase
+{
+ protected function setUp()
+ {
+ if (!extension_loaded('intl')) {
+ $this->markTestSkipped('This test requires intl extension to work.');
+ }
+ }
+
+ public function testLoad()
+ {
+ // resource is build using genrb command
+ $loader = new IcuResFileLoader();
+ $resource = __DIR__.'/../fixtures/resourcebundle/res';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new DirectoryResource($resource)), $catalogue->getResources());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+ */
+ public function testLoadNonExistingResource()
+ {
+ $loader = new IcuResFileLoader();
+ $loader->load(__DIR__.'/../fixtures/non-existing.txt', 'en', 'domain1');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ */
+ public function testLoadInvalidResource()
+ {
+ $loader = new IcuResFileLoader();
+ $loader->load(__DIR__.'/../fixtures/resourcebundle/corrupted', 'en', 'domain1');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IniFileLoaderTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IniFileLoaderTest.php
new file mode 100644
index 0000000..1a5de0e
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/IniFileLoaderTest.php
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\IniFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class IniFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testLoad()
+ {
+ $loader = new IniFileLoader();
+ $resource = __DIR__.'/../fixtures/resources.ini';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ public function testLoadDoesNothingIfEmpty()
+ {
+ $loader = new IniFileLoader();
+ $resource = __DIR__.'/../fixtures/empty.ini';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array(), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+ */
+ public function testLoadNonExistingResource()
+ {
+ $loader = new IniFileLoader();
+ $resource = __DIR__.'/../fixtures/non-existing.ini';
+ $loader->load($resource, 'en', 'domain1');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/JsonFileLoaderTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/JsonFileLoaderTest.php
new file mode 100644
index 0000000..6d4f353
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/JsonFileLoaderTest.php
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\JsonFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class JsonFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ protected function setUp()
+ {
+ if (!class_exists('Symfony\Component\Config\Loader\Loader')) {
+ $this->markTestSkipped('The "Config" component is not available');
+ }
+ }
+
+ public function testLoad()
+ {
+ $loader = new JsonFileLoader();
+ $resource = __DIR__.'/../fixtures/resources.json';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ public function testLoadDoesNothingIfEmpty()
+ {
+ $loader = new JsonFileLoader();
+ $resource = __DIR__.'/../fixtures/empty.json';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array(), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+ */
+ public function testLoadNonExistingResource()
+ {
+ $loader = new JsonFileLoader();
+ $resource = __DIR__.'/../fixtures/non-existing.json';
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ * @expectedExceptionMessage Error parsing JSON - Syntax error, malformed JSON
+ */
+ public function testParseException()
+ {
+ $loader = new JsonFileLoader();
+ $resource = __DIR__.'/../fixtures/malformed.json';
+ $loader->load($resource, 'en', 'domain1');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/LocalizedTestCase.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/LocalizedTestCase.php
new file mode 100644
index 0000000..9d7c5d7
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/LocalizedTestCase.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+abstract class LocalizedTestCase extends \PHPUnit_Framework_TestCase
+{
+ protected function setUp()
+ {
+ if (!extension_loaded('intl')) {
+ $this->markTestSkipped('The "intl" extension is not available');
+ }
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/MoFileLoaderTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/MoFileLoaderTest.php
new file mode 100644
index 0000000..34078d0
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/MoFileLoaderTest.php
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\MoFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class MoFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testLoad()
+ {
+ $loader = new MoFileLoader();
+ $resource = __DIR__.'/../fixtures/resources.mo';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ public function testLoadPlurals()
+ {
+ $loader = new MoFileLoader();
+ $resource = __DIR__.'/../fixtures/plurals.mo';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array('foo' => 'bar', 'foos' => '{0} bar|{1} bars'), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+ */
+ public function testLoadNonExistingResource()
+ {
+ $loader = new MoFileLoader();
+ $resource = __DIR__.'/../fixtures/non-existing.mo';
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ */
+ public function testLoadInvalidResource()
+ {
+ $loader = new MoFileLoader();
+ $resource = __DIR__.'/../fixtures/empty.mo';
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ public function testLoadEmptyTranslation()
+ {
+ $loader = new MoFileLoader();
+ $resource = __DIR__.'/../fixtures/empty-translation.mo';
+ $catalogue = $loader->load($resource, 'en', 'message');
+
+ $this->assertEquals(array(), $catalogue->all('message'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/PhpFileLoaderTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/PhpFileLoaderTest.php
new file mode 100644
index 0000000..0816b0f
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/PhpFileLoaderTest.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\PhpFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class PhpFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testLoad()
+ {
+ $loader = new PhpFileLoader();
+ $resource = __DIR__.'/../fixtures/resources.php';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+ */
+ public function testLoadNonExistingResource()
+ {
+ $loader = new PhpFileLoader();
+ $resource = __DIR__.'/../fixtures/non-existing.php';
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ */
+ public function testLoadThrowsAnExceptionIfFileNotLocal()
+ {
+ $loader = new PhpFileLoader();
+ $resource = 'http://example.com/resources.php';
+ $loader->load($resource, 'en', 'domain1');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/PoFileLoaderTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/PoFileLoaderTest.php
new file mode 100644
index 0000000..87090eb
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/PoFileLoaderTest.php
@@ -0,0 +1,96 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\PoFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class PoFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testLoad()
+ {
+ $loader = new PoFileLoader();
+ $resource = __DIR__.'/../fixtures/resources.po';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ public function testLoadPlurals()
+ {
+ $loader = new PoFileLoader();
+ $resource = __DIR__.'/../fixtures/plurals.po';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array('foo' => 'bar', 'foos' => 'bar|bars'), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ public function testLoadDoesNothingIfEmpty()
+ {
+ $loader = new PoFileLoader();
+ $resource = __DIR__.'/../fixtures/empty.po';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array(), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+ */
+ public function testLoadNonExistingResource()
+ {
+ $loader = new PoFileLoader();
+ $resource = __DIR__.'/../fixtures/non-existing.po';
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ public function testLoadEmptyTranslation()
+ {
+ $loader = new PoFileLoader();
+ $resource = __DIR__.'/../fixtures/empty-translation.po';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array('foo' => ''), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ public function testEscapedId()
+ {
+ $loader = new PoFileLoader();
+ $resource = __DIR__.'/../fixtures/escaped-id.po';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $messages = $catalogue->all('domain1');
+ $this->assertArrayHasKey('escaped "foo"', $messages);
+ $this->assertEquals('escaped "bar"', $messages['escaped "foo"']);
+ }
+
+ public function testEscapedIdPlurals()
+ {
+ $loader = new PoFileLoader();
+ $resource = __DIR__.'/../fixtures/escaped-id-plurals.po';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $messages = $catalogue->all('domain1');
+ $this->assertArrayHasKey('escaped "foo"', $messages);
+ $this->assertArrayHasKey('escaped "foos"', $messages);
+ $this->assertEquals('escaped "bar"', $messages['escaped "foo"']);
+ $this->assertEquals('escaped "bar"|escaped "bars"', $messages['escaped "foos"']);
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/QtFileLoaderTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/QtFileLoaderTest.php
new file mode 100644
index 0000000..3aca86a
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/QtFileLoaderTest.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\QtFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class QtFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testLoad()
+ {
+ $loader = new QtFileLoader();
+ $resource = __DIR__.'/../fixtures/resources.ts';
+ $catalogue = $loader->load($resource, 'en', 'resources');
+
+ $this->assertEquals(array('foo' => 'bar'), $catalogue->all('resources'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+ */
+ public function testLoadNonExistingResource()
+ {
+ $loader = new QtFileLoader();
+ $resource = __DIR__.'/../fixtures/non-existing.ts';
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ */
+ public function testLoadNonLocalResource()
+ {
+ $loader = new QtFileLoader();
+ $resource = 'http://domain1.com/resources.ts';
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ */
+ public function testLoadInvalidResource()
+ {
+ $loader = new QtFileLoader();
+ $resource = __DIR__.'/../fixtures/invalid-xml-resources.xlf';
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ public function testLoadEmptyResource()
+ {
+ $loader = new QtFileLoader();
+ $resource = __DIR__.'/../fixtures/empty.xlf';
+ $this->setExpectedException('Symfony\Component\Translation\Exception\InvalidResourceException', sprintf('Unable to load "%s".', $resource));
+ $loader->load($resource, 'en', 'domain1');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php
new file mode 100644
index 0000000..c3d65b4
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php
@@ -0,0 +1,142 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\XliffFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testLoad()
+ {
+ $loader = new XliffFileLoader();
+ $resource = __DIR__.'/../fixtures/resources.xlf';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ $this->assertSame(array(), libxml_get_errors());
+ }
+
+ public function testLoadWithInternalErrorsEnabled()
+ {
+ libxml_use_internal_errors(true);
+
+ $this->assertSame(array(), libxml_get_errors());
+
+ $loader = new XliffFileLoader();
+ $resource = __DIR__.'/../fixtures/resources.xlf';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ $this->assertSame(array(), libxml_get_errors());
+ }
+
+ public function testLoadWithResname()
+ {
+ $loader = new XliffFileLoader();
+ $catalogue = $loader->load(__DIR__.'/../fixtures/resname.xlf', 'en', 'domain1');
+
+ $this->assertEquals(array('foo' => 'bar', 'bar' => 'baz', 'baz' => 'foo'), $catalogue->all('domain1'));
+ }
+
+ public function testIncompleteResource()
+ {
+ $loader = new XliffFileLoader();
+ $catalogue = $loader->load(__DIR__.'/../fixtures/resources.xlf', 'en', 'domain1');
+
+ $this->assertEquals(array('foo' => 'bar', 'key' => '', 'test' => 'with'), $catalogue->all('domain1'));
+ $this->assertFalse($catalogue->has('extra', 'domain1'));
+ }
+
+ public function testEncoding()
+ {
+ if (!function_exists('iconv') && !function_exists('mb_convert_encoding')) {
+ $this->markTestSkipped('The iconv and mbstring extensions are not available.');
+ }
+
+ $loader = new XliffFileLoader();
+ $catalogue = $loader->load(__DIR__.'/../fixtures/encoding.xlf', 'en', 'domain1');
+
+ $this->assertEquals(utf8_decode('föö'), $catalogue->get('bar', 'domain1'));
+ $this->assertEquals(utf8_decode('bär'), $catalogue->get('foo', 'domain1'));
+ $this->assertEquals(array('notes' => array(array('content' => utf8_decode('bäz')))), $catalogue->getMetadata('foo', 'domain1'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ */
+ public function testLoadInvalidResource()
+ {
+ $loader = new XliffFileLoader();
+ $loader->load(__DIR__.'/../fixtures/resources.php', 'en', 'domain1');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ */
+ public function testLoadResourceDoesNotValidate()
+ {
+ $loader = new XliffFileLoader();
+ $loader->load(__DIR__.'/../fixtures/non-valid.xlf', 'en', 'domain1');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+ */
+ public function testLoadNonExistingResource()
+ {
+ $loader = new XliffFileLoader();
+ $resource = __DIR__.'/../fixtures/non-existing.xlf';
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ */
+ public function testLoadThrowsAnExceptionIfFileNotLocal()
+ {
+ $loader = new XliffFileLoader();
+ $resource = 'http://example.com/resources.xlf';
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ * @expectedExceptionMessage Document types are not allowed.
+ */
+ public function testDocTypeIsNotAllowed()
+ {
+ $loader = new XliffFileLoader();
+ $loader->load(__DIR__.'/../fixtures/withdoctype.xlf', 'en', 'domain1');
+ }
+
+ public function testParseEmptyFile()
+ {
+ $loader = new XliffFileLoader();
+ $resource = __DIR__.'/../fixtures/empty.xlf';
+ $this->setExpectedException('Symfony\Component\Translation\Exception\InvalidResourceException', sprintf('Unable to load "%s":', $resource));
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ public function testLoadNotes()
+ {
+ $loader = new XliffFileLoader();
+ $catalogue = $loader->load(__DIR__.'/../fixtures/withnote.xlf', 'en', 'domain1');
+
+ $this->assertEquals(array('notes' => array(array('priority' => 1, 'content' => 'foo'))), $catalogue->getMetadata('foo', 'domain1'));
+ // message without target
+ $this->assertNull($catalogue->getMetadata('extra', 'domain1'));
+ $this->assertEquals(array('notes' => array(array('content' => 'baz'), array('priority' => 2, 'from' => 'bar', 'content' => 'qux'))), $catalogue->getMetadata('key', 'domain1'));
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/YamlFileLoaderTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/YamlFileLoaderTest.php
new file mode 100644
index 0000000..00f7163
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/Loader/YamlFileLoaderTest.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\YamlFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testLoad()
+ {
+ $loader = new YamlFileLoader();
+ $resource = __DIR__.'/../fixtures/resources.yml';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ public function testLoadDoesNothingIfEmpty()
+ {
+ $loader = new YamlFileLoader();
+ $resource = __DIR__.'/../fixtures/empty.yml';
+ $catalogue = $loader->load($resource, 'en', 'domain1');
+
+ $this->assertEquals(array(), $catalogue->all('domain1'));
+ $this->assertEquals('en', $catalogue->getLocale());
+ $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+ */
+ public function testLoadNonExistingResource()
+ {
+ $loader = new YamlFileLoader();
+ $resource = __DIR__.'/../fixtures/non-existing.yml';
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ */
+ public function testLoadThrowsAnExceptionIfFileNotLocal()
+ {
+ $loader = new YamlFileLoader();
+ $resource = 'http://example.com/resources.yml';
+ $loader->load($resource, 'en', 'domain1');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+ */
+ public function testLoadThrowsAnExceptionIfNotAnArray()
+ {
+ $loader = new YamlFileLoader();
+ $resource = __DIR__.'/../fixtures/non-valid.yml';
+ $loader->load($resource, 'en', 'domain1');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/LoggingTranslatorTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/LoggingTranslatorTest.php
new file mode 100644
index 0000000..ab98d72
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/LoggingTranslatorTest.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\LoggingTranslator;
+use Symfony\Component\Translation\Loader\ArrayLoader;
+
+class LoggingTranslatorTest extends \PHPUnit_Framework_TestCase
+{
+ protected function setUp()
+ {
+ if (!interface_exists('Psr\Log\LoggerInterface')) {
+ $this->markTestSkipped('The "LoggerInterface" is not available');
+ }
+ }
+
+ public function testTransWithNoTranslationIsLogged()
+ {
+ $logger = $this->getMock('Psr\Log\LoggerInterface');
+ $logger->expects($this->exactly(2))
+ ->method('warning')
+ ->with('Translation not found.')
+ ;
+
+ $translator = new Translator('ar');
+ $loggableTranslator = new LoggingTranslator($translator, $logger);
+ $loggableTranslator->transChoice('some_message2', 10, array('%count%' => 10));
+ $loggableTranslator->trans('bar');
+ }
+
+ public function testTransChoiceFallbackIsLogged()
+ {
+ $logger = $this->getMock('Psr\Log\LoggerInterface');
+ $logger->expects($this->once())
+ ->method('debug')
+ ->with('Translation use fallback catalogue.')
+ ;
+
+ $translator = new Translator('ar');
+ $translator->setFallbackLocales(array('en'));
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en');
+ $loggableTranslator = new LoggingTranslator($translator, $logger);
+ $loggableTranslator->transChoice('some_message2', 10, array('%count%' => 10));
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/MessageCatalogueTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/MessageCatalogueTest.php
new file mode 100644
index 0000000..7d95655
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/MessageCatalogueTest.php
@@ -0,0 +1,200 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+class MessageCatalogueTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetLocale()
+ {
+ $catalogue = new MessageCatalogue('en');
+
+ $this->assertEquals('en', $catalogue->getLocale());
+ }
+
+ public function testGetDomains()
+ {
+ $catalogue = new MessageCatalogue('en', array('domain1' => array(), 'domain2' => array()));
+
+ $this->assertEquals(array('domain1', 'domain2'), $catalogue->getDomains());
+ }
+
+ public function testAll()
+ {
+ $catalogue = new MessageCatalogue('en', $messages = array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+
+ $this->assertEquals(array('foo' => 'foo'), $catalogue->all('domain1'));
+ $this->assertEquals(array(), $catalogue->all('domain88'));
+ $this->assertEquals($messages, $catalogue->all());
+ }
+
+ public function testHas()
+ {
+ $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+
+ $this->assertTrue($catalogue->has('foo', 'domain1'));
+ $this->assertFalse($catalogue->has('bar', 'domain1'));
+ $this->assertFalse($catalogue->has('foo', 'domain88'));
+ }
+
+ public function testGetSet()
+ {
+ $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+ $catalogue->set('foo1', 'foo1', 'domain1');
+
+ $this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
+ $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));
+ }
+
+ public function testAdd()
+ {
+ $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+ $catalogue->add(array('foo1' => 'foo1'), 'domain1');
+
+ $this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
+ $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));
+
+ $catalogue->add(array('foo' => 'bar'), 'domain1');
+ $this->assertEquals('bar', $catalogue->get('foo', 'domain1'));
+ $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));
+
+ $catalogue->add(array('foo' => 'bar'), 'domain88');
+ $this->assertEquals('bar', $catalogue->get('foo', 'domain88'));
+ }
+
+ public function testReplace()
+ {
+ $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+ $catalogue->replace($messages = array('foo1' => 'foo1'), 'domain1');
+
+ $this->assertEquals($messages, $catalogue->all('domain1'));
+ }
+
+ public function testAddCatalogue()
+ {
+ $r = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
+ $r->expects($this->any())->method('__toString')->will($this->returnValue('r'));
+
+ $r1 = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
+ $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1'));
+
+ $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+ $catalogue->addResource($r);
+
+ $catalogue1 = new MessageCatalogue('en', array('domain1' => array('foo1' => 'foo1')));
+ $catalogue1->addResource($r1);
+
+ $catalogue->addCatalogue($catalogue1);
+
+ $this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
+ $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));
+
+ $this->assertEquals(array($r, $r1), $catalogue->getResources());
+ }
+
+ public function testAddFallbackCatalogue()
+ {
+ $r = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
+ $r->expects($this->any())->method('__toString')->will($this->returnValue('r'));
+
+ $r1 = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
+ $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1'));
+
+ $catalogue = new MessageCatalogue('en_US', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+ $catalogue->addResource($r);
+
+ $catalogue1 = new MessageCatalogue('en', array('domain1' => array('foo' => 'bar', 'foo1' => 'foo1')));
+ $catalogue1->addResource($r1);
+
+ $catalogue->addFallbackCatalogue($catalogue1);
+
+ $this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
+ $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));
+
+ $this->assertEquals(array($r, $r1), $catalogue->getResources());
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testAddFallbackCatalogueWithCircularReference()
+ {
+ $main = new MessageCatalogue('en_US');
+ $fallback = new MessageCatalogue('fr_FR');
+
+ $fallback->addFallbackCatalogue($main);
+ $main->addFallbackCatalogue($fallback);
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testAddCatalogueWhenLocaleIsNotTheSameAsTheCurrentOne()
+ {
+ $catalogue = new MessageCatalogue('en');
+ $catalogue->addCatalogue(new MessageCatalogue('fr', array()));
+ }
+
+ public function testGetAddResource()
+ {
+ $catalogue = new MessageCatalogue('en');
+ $r = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
+ $r->expects($this->any())->method('__toString')->will($this->returnValue('r'));
+ $catalogue->addResource($r);
+ $catalogue->addResource($r);
+ $r1 = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
+ $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1'));
+ $catalogue->addResource($r1);
+
+ $this->assertEquals(array($r, $r1), $catalogue->getResources());
+ }
+
+ public function testMetadataDelete()
+ {
+ $catalogue = new MessageCatalogue('en');
+ $this->assertEquals(array(), $catalogue->getMetadata('', ''), 'Metadata is empty');
+ $catalogue->deleteMetadata('key', 'messages');
+ $catalogue->deleteMetadata('', 'messages');
+ $catalogue->deleteMetadata();
+ }
+
+ public function testMetadataSetGetDelete()
+ {
+ $catalogue = new MessageCatalogue('en');
+ $catalogue->setMetadata('key', 'value');
+ $this->assertEquals('value', $catalogue->getMetadata('key', 'messages'), "Metadata 'key' = 'value'");
+
+ $catalogue->setMetadata('key2', array());
+ $this->assertEquals(array(), $catalogue->getMetadata('key2', 'messages'), 'Metadata key2 is array');
+
+ $catalogue->deleteMetadata('key2', 'messages');
+ $this->assertEquals(null, $catalogue->getMetadata('key2', 'messages'), 'Metadata key2 should is deleted.');
+
+ $catalogue->deleteMetadata('key2', 'domain');
+ $this->assertEquals(null, $catalogue->getMetadata('key2', 'domain'), 'Metadata key2 should is deleted.');
+ }
+
+ public function testMetadataMerge()
+ {
+ $cat1 = new MessageCatalogue('en');
+ $cat1->setMetadata('a', 'b');
+ $this->assertEquals(array('messages' => array('a' => 'b')), $cat1->getMetadata('', ''), 'Cat1 contains messages metadata.');
+
+ $cat2 = new MessageCatalogue('en');
+ $cat2->setMetadata('b', 'c', 'domain');
+ $this->assertEquals(array('domain' => array('b' => 'c')), $cat2->getMetadata('', ''), 'Cat2 contains domain metadata.');
+
+ $cat1->addCatalogue($cat2);
+ $this->assertEquals(array('messages' => array('a' => 'b'), 'domain' => array('b' => 'c')), $cat1->getMetadata('', ''), 'Cat1 contains merged metadata.');
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/MessageSelectorTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/MessageSelectorTest.php
new file mode 100644
index 0000000..d5a4f3e
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/MessageSelectorTest.php
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\MessageSelector;
+
+class MessageSelectorTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getChooseTests
+ */
+ public function testChoose($expected, $id, $number)
+ {
+ $selector = new MessageSelector();
+
+ $this->assertEquals($expected, $selector->choose($id, $number, 'en'));
+ }
+
+ public function testReturnMessageIfExactlyOneStandardRuleIsGiven()
+ {
+ $selector = new MessageSelector();
+
+ $this->assertEquals('There are two apples', $selector->choose('There are two apples', 2, 'en'));
+ }
+
+ /**
+ * @dataProvider getNonMatchingMessages
+ * @expectedException \InvalidArgumentException
+ */
+ public function testThrowExceptionIfMatchingMessageCannotBeFound($id, $number)
+ {
+ $selector = new MessageSelector();
+
+ $selector->choose($id, $number, 'en');
+ }
+
+ public function getNonMatchingMessages()
+ {
+ return array(
+ array('{0} There are no apples|{1} There is one apple', 2),
+ array('{1} There is one apple|]1,Inf] There are %count% apples', 0),
+ array('{1} There is one apple|]2,Inf] There are %count% apples', 2),
+ array('{0} There are no apples|There is one apple', 2),
+ );
+ }
+
+ public function getChooseTests()
+ {
+ return array(
+ array('There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0),
+ array('There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0),
+ array('There are no apples', '{0}There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0),
+
+ array('There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1),
+
+ array('There are %count% apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10),
+ array('There are %count% apples', '{0} There are no apples|{1} There is one apple|]1,Inf]There are %count% apples', 10),
+ array('There are %count% apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10),
+
+ array('There are %count% apples', 'There is one apple|There are %count% apples', 0),
+ array('There is one apple', 'There is one apple|There are %count% apples', 1),
+ array('There are %count% apples', 'There is one apple|There are %count% apples', 10),
+
+ array('There are %count% apples', 'one: There is one apple|more: There are %count% apples', 0),
+ array('There is one apple', 'one: There is one apple|more: There are %count% apples', 1),
+ array('There are %count% apples', 'one: There is one apple|more: There are %count% apples', 10),
+
+ array('There are no apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 0),
+ array('There is one apple', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 1),
+ array('There are %count% apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 10),
+
+ array('', '{0}|{1} There is one apple|]1,Inf] There are %count% apples', 0),
+ array('', '{0} There are no apples|{1}|]1,Inf] There are %count% apples', 1),
+
+ // Indexed only tests which are Gettext PoFile* compatible strings.
+ array('There are %count% apples', 'There is one apple|There are %count% apples', 0),
+ array('There is one apple', 'There is one apple|There are %count% apples', 1),
+ array('There are %count% apples', 'There is one apple|There are %count% apples', 2),
+
+ // Tests for float numbers
+ array('There is almost one apple', '{0} There are no apples|]0,1[ There is almost one apple|{1} There is one apple|[1,Inf] There is more than one apple', 0.7),
+ array('There is one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1),
+ array('There is more than one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1.7),
+ array('There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0),
+ array('There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0.0),
+ array('There are no apples', '{0.0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0),
+ );
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/PluralizationRulesTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/PluralizationRulesTest.php
new file mode 100644
index 0000000..1e8ee70
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/PluralizationRulesTest.php
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\PluralizationRules;
+
+/**
+ * Test should cover all languages mentioned on http://translate.sourceforge.net/wiki/l10n/pluralforms
+ * and Plural forms mentioned on http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms.
+ *
+ * See also https://developer.mozilla.org/en/Localization_and_Plurals which mentions 15 rules having a maximum of 6 forms.
+ * The mozilla code is also interesting to check for.
+ *
+ * As mentioned by chx http://drupal.org/node/1273968 we can cover all by testing number from 0 to 199
+ *
+ * The goal to cover all languages is to far fetched so this test case is smaller.
+ *
+ * @author Clemens Tolboom clemens@build2be.nl
+ */
+class PluralizationRulesTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * We test failed langcode here.
+ *
+ * TODO: The languages mentioned in the data provide need to get fixed somehow within PluralizationRules.
+ *
+ * @dataProvider failingLangcodes
+ */
+ public function testFailedLangcodes($nplural, $langCodes)
+ {
+ $matrix = $this->generateTestData($nplural, $langCodes);
+ $this->validateMatrix($nplural, $matrix, false);
+ }
+
+ /**
+ * @dataProvider successLangcodes
+ */
+ public function testLangcodes($nplural, $langCodes)
+ {
+ $matrix = $this->generateTestData($nplural, $langCodes);
+ $this->validateMatrix($nplural, $matrix);
+ }
+
+ /**
+ * This array should contain all currently known langcodes.
+ *
+ * As it is impossible to have this ever complete we should try as hard as possible to have it almost complete.
+ *
+ * @return array
+ */
+ public function successLangcodes()
+ {
+ return array(
+ array('1', array('ay','bo', 'cgg','dz','id', 'ja', 'jbo', 'ka','kk','km','ko','ky')),
+ array('2', array('nl', 'fr', 'en', 'de', 'de_GE')),
+ array('3', array('be','bs','cs','hr')),
+ array('4', array('cy','mt', 'sl')),
+ array('5', array()),
+ array('6', array('ar')),
+ );
+ }
+
+ /**
+ * This array should be at least empty within the near future.
+ *
+ * This both depends on a complete list trying to add above as understanding
+ * the plural rules of the current failing languages.
+ *
+ * @return array with nplural together with langcodes
+ */
+ public function failingLangcodes()
+ {
+ return array(
+ array('1', array('fa')),
+ array('2', array('jbo')),
+ array('3', array('cbs')),
+ array('4', array('gd','kw')),
+ array('5', array('ga')),
+ array('6', array()),
+ );
+ }
+
+ /**
+ * We validate only on the plural coverage. Thus the real rules is not tested.
+ *
+ * @param string $nplural plural expected
+ * @param array $matrix containing langcodes and their plural index values.
+ * @param bool $expectSuccess
+ */
+ protected function validateMatrix($nplural, $matrix, $expectSuccess = true)
+ {
+ foreach ($matrix as $langCode => $data) {
+ $indexes = array_flip($data);
+ if ($expectSuccess) {
+ $this->assertEquals($nplural, count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
+ } else {
+ $this->assertNotEquals((int) $nplural, count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
+ }
+ }
+ }
+
+ protected function generateTestData($plural, $langCodes)
+ {
+ $matrix = array();
+ foreach ($langCodes as $langCode) {
+ for ($count = 0; $count < 200; $count++) {
+ $plural = PluralizationRules::get($count, $langCode);
+ $matrix[$langCode][$count] = $plural;
+ }
+ }
+
+ return $matrix;
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/TranslatorCacheTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/TranslatorCacheTest.php
new file mode 100644
index 0000000..8b913f3
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/TranslatorCacheTest.php
@@ -0,0 +1,231 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\MessageSelector;
+
+class TranslatorCacheTest extends \PHPUnit_Framework_TestCase
+{
+ protected $tmpDir;
+
+ protected function setUp()
+ {
+ $this->tmpDir = sys_get_temp_dir().'/sf2_translation';
+ $this->deleteTmpDir();
+ }
+
+ protected function tearDown()
+ {
+ $this->deleteTmpDir();
+ }
+
+ protected function deleteTmpDir()
+ {
+ if (!file_exists($dir = $this->tmpDir)) {
+ return;
+ }
+
+ $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->tmpDir), \RecursiveIteratorIterator::CHILD_FIRST);
+ foreach ($iterator as $path) {
+ if (preg_match('#[/\\\\]\.\.?$#', $path->__toString())) {
+ continue;
+ }
+ if ($path->isDir()) {
+ rmdir($path->__toString());
+ } else {
+ unlink($path->__toString());
+ }
+ }
+ rmdir($this->tmpDir);
+ }
+
+ public function testTransWithoutCaching()
+ {
+ $translator = $this->getTranslator($this->getLoader());
+ $translator->setLocale('fr');
+ $translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR', 'fr.UTF-8', 'sr@latin'));
+
+ $this->assertEquals('foo (FR)', $translator->trans('foo'));
+ $this->assertEquals('bar (EN)', $translator->trans('bar'));
+ $this->assertEquals('foobar (ES)', $translator->trans('foobar'));
+ $this->assertEquals('choice 0 (EN)', $translator->transChoice('choice', 0));
+ $this->assertEquals('no translation', $translator->trans('no translation'));
+ $this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
+ $this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
+ $this->assertEquals('foobarbaz (fr.UTF-8)', $translator->trans('foobarbaz'));
+ $this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
+ }
+
+ public function testTransWithCaching()
+ {
+ // prime the cache
+ $translator = $this->getTranslator($this->getLoader(), $this->tmpDir);
+ $translator->setLocale('fr');
+ $translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR', 'fr.UTF-8', 'sr@latin'));
+
+ $this->assertEquals('foo (FR)', $translator->trans('foo'));
+ $this->assertEquals('bar (EN)', $translator->trans('bar'));
+ $this->assertEquals('foobar (ES)', $translator->trans('foobar'));
+ $this->assertEquals('choice 0 (EN)', $translator->transChoice('choice', 0));
+ $this->assertEquals('no translation', $translator->trans('no translation'));
+ $this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
+ $this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
+ $this->assertEquals('foobarbaz (fr.UTF-8)', $translator->trans('foobarbaz'));
+ $this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
+
+ // do it another time as the cache is primed now
+ $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
+ $translator = $this->getTranslator($loader, $this->tmpDir);
+ $translator->setLocale('fr');
+ $translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR', 'fr.UTF-8', 'sr@latin'));
+
+ $this->assertEquals('foo (FR)', $translator->trans('foo'));
+ $this->assertEquals('bar (EN)', $translator->trans('bar'));
+ $this->assertEquals('foobar (ES)', $translator->trans('foobar'));
+ $this->assertEquals('choice 0 (EN)', $translator->transChoice('choice', 0));
+ $this->assertEquals('no translation', $translator->trans('no translation'));
+ $this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
+ $this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
+ $this->assertEquals('foobarbaz (fr.UTF-8)', $translator->trans('foobarbaz'));
+ $this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
+ }
+
+ public function testTransWithCachingWithInvalidLocale()
+ {
+ $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
+ $translator = $this->getTranslator($loader, $this->tmpDir, 'Symfony\Component\Translation\Tests\TranslatorWithInvalidLocale');
+
+ $translator->setLocale('invalid locale');
+
+ try {
+ $translator->trans('foo');
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertFalse(file_exists($this->tmpDir.'/catalogue.invalid locale.php'));
+ }
+ }
+
+ public function testLoadCatalogueWithCachingWithInvalidLocale()
+ {
+ $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
+ $translator = $this->getTranslator($loader, $this->tmpDir, 'Symfony\Component\Translation\Tests\TranslatorWithInvalidLocale');
+
+ try {
+ $translator->proxyLoadCatalogue('invalid locale');
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertFalse(file_exists($this->tmpDir.'/catalogue.invalid locale.php'));
+ }
+ }
+
+ protected function getCatalogue($locale, $messages)
+ {
+ $catalogue = new MessageCatalogue($locale);
+ foreach ($messages as $key => $translation) {
+ $catalogue->set($key, $translation);
+ }
+
+ return $catalogue;
+ }
+
+ protected function getLoader()
+ {
+ $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
+ $loader
+ ->expects($this->at(0))
+ ->method('load')
+ ->will($this->returnValue($this->getCatalogue('fr', array(
+ 'foo' => 'foo (FR)',
+ ))))
+ ;
+ $loader
+ ->expects($this->at(1))
+ ->method('load')
+ ->will($this->returnValue($this->getCatalogue('en', array(
+ 'foo' => 'foo (EN)',
+ 'bar' => 'bar (EN)',
+ 'choice' => '{0} choice 0 (EN)|{1} choice 1 (EN)|]1,Inf] choice inf (EN)',
+ ))))
+ ;
+ $loader
+ ->expects($this->at(2))
+ ->method('load')
+ ->will($this->returnValue($this->getCatalogue('es', array(
+ 'foobar' => 'foobar (ES)',
+ ))))
+ ;
+ $loader
+ ->expects($this->at(3))
+ ->method('load')
+ ->will($this->returnValue($this->getCatalogue('pt-PT', array(
+ 'foobarfoo' => 'foobarfoo (PT-PT)',
+ ))))
+ ;
+ $loader
+ ->expects($this->at(4))
+ ->method('load')
+ ->will($this->returnValue($this->getCatalogue('pt_BR', array(
+ 'other choice' => '{0} other choice 0 (PT-BR)|{1} other choice 1 (PT-BR)|]1,Inf] other choice inf (PT-BR)',
+ ))))
+ ;
+ $loader
+ ->expects($this->at(5))
+ ->method('load')
+ ->will($this->returnValue($this->getCatalogue('fr.UTF-8', array(
+ 'foobarbaz' => 'foobarbaz (fr.UTF-8)',
+ ))))
+ ;
+ $loader
+ ->expects($this->at(6))
+ ->method('load')
+ ->will($this->returnValue($this->getCatalogue('sr@latin', array(
+ 'foobarbax' => 'foobarbax (sr@latin)',
+ ))))
+ ;
+
+ return $loader;
+ }
+
+ public function getTranslator($loader, $cacheDir = null, $translatorClass = '\Symfony\Component\Translation\Translator')
+ {
+ $translator = new $translatorClass('fr', new MessageSelector(), $cacheDir);
+
+ $translator->addLoader('loader', $loader);
+ $translator->addResource('loader', 'foo', 'fr');
+ $translator->addResource('loader', 'foo', 'en');
+ $translator->addResource('loader', 'foo', 'es');
+ $translator->addResource('loader', 'foo', 'pt-PT'); // European Portuguese
+ $translator->addResource('loader', 'foo', 'pt_BR'); // Brazilian Portuguese
+ $translator->addResource('loader', 'foo', 'fr.UTF-8');
+ $translator->addResource('loader', 'foo', 'sr@latin'); // Latin Serbian
+
+ return $translator;
+ }
+}
+
+class TranslatorWithInvalidLocale extends Translator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function setLocale($locale)
+ {
+ $this->locale = $locale;
+ }
+
+ public function proxyLoadCatalogue($locale)
+ {
+ $this->loadCatalogue($locale);
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/TranslatorTest.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/TranslatorTest.php
new file mode 100644
index 0000000..e60d8fa
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/TranslatorTest.php
@@ -0,0 +1,604 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\MessageSelector;
+use Symfony\Component\Translation\Loader\ArrayLoader;
+use Symfony\Component\Translation\MessageCatalogue;
+
+class TranslatorTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getInvalidLocalesTests
+ * @expectedException \InvalidArgumentException
+ */
+ public function testConstructorInvalidLocale($locale)
+ {
+ $translator = new Translator($locale, new MessageSelector());
+ }
+
+ /**
+ * @dataProvider getValidLocalesTests
+ */
+ public function testConstructorValidLocale($locale)
+ {
+ $translator = new Translator($locale, new MessageSelector());
+
+ $this->assertEquals($locale, $translator->getLocale());
+ }
+
+ public function testConstructorWithoutLocale()
+ {
+ $translator = new Translator(null, new MessageSelector());
+
+ $this->assertNull($translator->getLocale());
+ }
+
+ public function testSetGetLocale()
+ {
+ $translator = new Translator('en');
+
+ $this->assertEquals('en', $translator->getLocale());
+
+ $translator->setLocale('fr');
+ $this->assertEquals('fr', $translator->getLocale());
+ }
+
+ /**
+ * @dataProvider getInvalidLocalesTests
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetInvalidLocale($locale)
+ {
+ $translator = new Translator('fr', new MessageSelector());
+ $translator->setLocale($locale);
+ }
+
+ /**
+ * @dataProvider getValidLocalesTests
+ */
+ public function testSetValidLocale($locale)
+ {
+ $translator = new Translator($locale, new MessageSelector());
+ $translator->setLocale($locale);
+
+ $this->assertEquals($locale, $translator->getLocale());
+ }
+
+ public function testGetCatalogue()
+ {
+ $translator = new Translator('en');
+
+ $this->assertEquals(new MessageCatalogue('en'), $translator->getCatalogue());
+
+ $translator->setLocale('fr');
+ $this->assertEquals(new MessageCatalogue('fr'), $translator->getCatalogue('fr'));
+ }
+
+ public function testSetFallbackLocales()
+ {
+ $translator = new Translator('en');
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+ $translator->addResource('array', array('bar' => 'foobar'), 'fr');
+
+ // force catalogue loading
+ $translator->trans('bar');
+
+ $translator->setFallbackLocales(array('fr'));
+ $this->assertEquals('foobar', $translator->trans('bar'));
+ }
+
+ public function testSetFallbackLocalesMultiple()
+ {
+ $translator = new Translator('en');
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array('foo' => 'foo (en)'), 'en');
+ $translator->addResource('array', array('bar' => 'bar (fr)'), 'fr');
+
+ // force catalogue loading
+ $translator->trans('bar');
+
+ $translator->setFallbackLocales(array('fr_FR', 'fr'));
+ $this->assertEquals('bar (fr)', $translator->trans('bar'));
+ }
+
+ /**
+ * @dataProvider getInvalidLocalesTests
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetFallbackInvalidLocales($locale)
+ {
+ $translator = new Translator('fr', new MessageSelector());
+ $translator->setFallbackLocales(array('fr', $locale));
+ }
+
+ /**
+ * @dataProvider getValidLocalesTests
+ */
+ public function testSetFallbackValidLocales($locale)
+ {
+ $translator = new Translator($locale, new MessageSelector());
+ $translator->setFallbackLocales(array('fr', $locale));
+ // no assertion. this method just asserts that no exception is thrown
+ }
+
+ public function testTransWithFallbackLocale()
+ {
+ $translator = new Translator('fr_FR');
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array('foo' => 'foofoo'), 'en_US');
+ $translator->addResource('array', array('bar' => 'foobar'), 'en');
+
+ $translator->setFallbackLocales(array('en'));
+
+ $this->assertEquals('foobar', $translator->trans('bar'));
+ }
+
+ /**
+ * @dataProvider getInvalidLocalesTests
+ * @expectedException \InvalidArgumentException
+ */
+ public function testAddResourceInvalidLocales($locale)
+ {
+ $translator = new Translator('fr', new MessageSelector());
+ $translator->addResource('array', array('foo' => 'foofoo'), $locale);
+ }
+
+ /**
+ * @dataProvider getValidLocalesTests
+ */
+ public function testAddResourceValidLocales($locale)
+ {
+ $translator = new Translator('fr', new MessageSelector());
+ $translator->addResource('array', array('foo' => 'foofoo'), $locale);
+ // no assertion. this method just asserts that no exception is thrown
+ }
+
+ public function testAddResourceAfterTrans()
+ {
+ $translator = new Translator('fr');
+ $translator->addLoader('array', new ArrayLoader());
+
+ $translator->setFallbackLocales(array('en'));
+
+ $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+ $this->assertEquals('foofoo', $translator->trans('foo'));
+
+ $translator->addResource('array', array('bar' => 'foobar'), 'en');
+ $this->assertEquals('foobar', $translator->trans('bar'));
+ }
+
+ /**
+ * @dataProvider getTransFileTests
+ * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+ */
+ public function testTransWithoutFallbackLocaleFile($format, $loader)
+ {
+ $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader;
+ $translator = new Translator('en');
+ $translator->addLoader($format, new $loaderClass());
+ $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en');
+ $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en');
+
+ // force catalogue loading
+ $translator->trans('foo');
+ }
+
+ /**
+ * @dataProvider getTransFileTests
+ */
+ public function testTransWithFallbackLocaleFile($format, $loader)
+ {
+ $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader;
+ $translator = new Translator('en_GB');
+ $translator->addLoader($format, new $loaderClass());
+ $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en_GB');
+ $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en', 'resources');
+
+ $this->assertEquals('bar', $translator->trans('foo', array(), 'resources'));
+ }
+
+ public function testTransWithFallbackLocaleBis()
+ {
+ $translator = new Translator('en_US');
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array('foo' => 'foofoo'), 'en_US');
+ $translator->addResource('array', array('bar' => 'foobar'), 'en');
+ $this->assertEquals('foobar', $translator->trans('bar'));
+ }
+
+ public function testTransWithFallbackLocaleTer()
+ {
+ $translator = new Translator('fr_FR');
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array('foo' => 'foo (en_US)'), 'en_US');
+ $translator->addResource('array', array('bar' => 'bar (en)'), 'en');
+
+ $translator->setFallbackLocales(array('en_US', 'en'));
+
+ $this->assertEquals('foo (en_US)', $translator->trans('foo'));
+ $this->assertEquals('bar (en)', $translator->trans('bar'));
+ }
+
+ public function testTransNonExistentWithFallback()
+ {
+ $translator = new Translator('fr');
+ $translator->setFallbackLocales(array('en'));
+ $translator->addLoader('array', new ArrayLoader());
+ $this->assertEquals('non-existent', $translator->trans('non-existent'));
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testWhenAResourceHasNoRegisteredLoader()
+ {
+ $translator = new Translator('en');
+ $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+
+ $translator->trans('foo');
+ }
+
+ /**
+ * @dataProvider getTransTests
+ */
+ public function testTrans($expected, $id, $translation, $parameters, $locale, $domain)
+ {
+ $translator = new Translator('en');
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array((string) $id => $translation), $locale, $domain);
+
+ $this->assertEquals($expected, $translator->trans($id, $parameters, $domain, $locale));
+ }
+
+ /**
+ * @dataProvider getInvalidLocalesTests
+ * @expectedException \InvalidArgumentException
+ */
+ public function testTransInvalidLocale($locale)
+ {
+ $translator = new Translator('en', new MessageSelector());
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+
+ $translator->trans('foo', array(), '', $locale);
+ }
+
+ /**
+ * @dataProvider getValidLocalesTests
+ */
+ public function testTransValidLocale($locale)
+ {
+ $translator = new Translator('en', new MessageSelector());
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+
+ $translator->trans('foo', array(), '', $locale);
+ // no assertion. this method just asserts that no exception is thrown
+ }
+
+ /**
+ * @dataProvider getFlattenedTransTests
+ */
+ public function testFlattenedTrans($expected, $messages, $id)
+ {
+ $translator = new Translator('en');
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', $messages, 'fr', '');
+
+ $this->assertEquals($expected, $translator->trans($id, array(), '', 'fr'));
+ }
+
+ /**
+ * @dataProvider getTransChoiceTests
+ */
+ public function testTransChoice($expected, $id, $translation, $number, $parameters, $locale, $domain)
+ {
+ $translator = new Translator('en');
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array((string) $id => $translation), $locale, $domain);
+
+ $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters, $domain, $locale));
+ }
+
+ /**
+ * @dataProvider getInvalidLocalesTests
+ * @expectedException \InvalidArgumentException
+ */
+ public function testTransChoiceInvalidLocale($locale)
+ {
+ $translator = new Translator('en', new MessageSelector());
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+
+ $translator->transChoice('foo', 1, array(), '', $locale);
+ }
+
+ /**
+ * @dataProvider getValidLocalesTests
+ */
+ public function testTransChoiceValidLocale($locale)
+ {
+ $translator = new Translator('en', new MessageSelector());
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+
+ $translator->transChoice('foo', 1, array(), '', $locale);
+ // no assertion. this method just asserts that no exception is thrown
+ }
+
+ public function getTransFileTests()
+ {
+ return array(
+ array('csv', 'CsvFileLoader'),
+ array('ini', 'IniFileLoader'),
+ array('mo', 'MoFileLoader'),
+ array('po', 'PoFileLoader'),
+ array('php', 'PhpFileLoader'),
+ array('ts', 'QtFileLoader'),
+ array('xlf', 'XliffFileLoader'),
+ array('yml', 'YamlFileLoader'),
+ array('json', 'JsonFileLoader'),
+ );
+ }
+
+ public function getTransTests()
+ {
+ return array(
+ array('Symfony est super !', 'Symfony is great!', 'Symfony est super !', array(), 'fr', ''),
+ array('Symfony est awesome !', 'Symfony is %what%!', 'Symfony est %what% !', array('%what%' => 'awesome'), 'fr', ''),
+ array('Symfony est super !', new StringClass('Symfony is great!'), 'Symfony est super !', array(), 'fr', ''),
+ );
+ }
+
+ public function getFlattenedTransTests()
+ {
+ $messages = array(
+ 'symfony' => array(
+ 'is' => array(
+ 'great' => 'Symfony est super!',
+ ),
+ ),
+ 'foo' => array(
+ 'bar' => array(
+ 'baz' => 'Foo Bar Baz',
+ ),
+ 'baz' => 'Foo Baz',
+ ),
+ );
+
+ return array(
+ array('Symfony est super!', $messages, 'symfony.is.great'),
+ array('Foo Bar Baz', $messages, 'foo.bar.baz'),
+ array('Foo Baz', $messages, 'foo.baz'),
+ );
+ }
+
+ public function getTransChoiceTests()
+ {
+ return array(
+ array('Il y a 0 pomme', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
+ array('Il y a 1 pomme', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''),
+ array('Il y a 10 pommes', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''),
+
+ array('Il y a 0 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
+ array('Il y a 1 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''),
+ array('Il y a 10 pommes', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''),
+
+ array('Il y a 0 pomme', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
+ array('Il y a 1 pomme', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''),
+ array('Il y a 10 pommes', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''),
+
+ array('Il n\'y a aucune pomme', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
+ array('Il y a 1 pomme', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''),
+ array('Il y a 10 pommes', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''),
+
+ array('Il y a 0 pomme', new StringClass('{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples'), '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
+ );
+ }
+
+ public function getInvalidLocalesTests()
+ {
+ return array(
+ array('fr FR'),
+ array('français'),
+ array('fr+en'),
+ array('utf#8'),
+ array('fr&en'),
+ array('fr~FR'),
+ array(' fr'),
+ array('fr '),
+ array('fr*'),
+ array('fr/FR'),
+ array('fr\\FR'),
+ );
+ }
+
+ public function getValidLocalesTests()
+ {
+ return array(
+ array(''),
+ array(null),
+ array('fr'),
+ array('francais'),
+ array('FR'),
+ array('frFR'),
+ array('fr-FR'),
+ array('fr_FR'),
+ array('fr.FR'),
+ array('fr-FR.UTF8'),
+ array('sr@latin'),
+ );
+ }
+
+ public function testTransChoiceFallback()
+ {
+ $translator = new Translator('ru');
+ $translator->setFallbackLocales(array('en'));
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en');
+
+ $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
+ }
+
+ public function testTransChoiceFallbackBis()
+ {
+ $translator = new Translator('ru');
+ $translator->setFallbackLocales(array('en_US', 'en'));
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en_US');
+
+ $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
+ }
+
+ public function testTransChoiceFallbackWithNoTranslation()
+ {
+ $translator = new Translator('ru');
+ $translator->setFallbackLocales(array('en'));
+ $translator->addLoader('array', new ArrayLoader());
+
+ // consistent behavior with Translator::trans(), which returns the string
+ // unchanged if it can't be found
+ $this->assertEquals('some_message2', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
+ }
+
+ /**
+ * @dataProvider dataProviderGetMessages
+ */
+ public function testGetMessages($resources, $locale, $expected)
+ {
+ $locales = array_keys($resources);
+ $_locale = !is_null($locale) ? $locale : reset($locales);
+ $locales = array_slice($locales, 0, array_search($_locale, $locales));
+
+ $translator = new Translator($_locale, new MessageSelector());
+ $translator->setFallbackLocales(array_reverse($locales));
+ $translator->addLoader('array', new ArrayLoader());
+ foreach ($resources as $_locale => $domainMessages) {
+ foreach ($domainMessages as $domain => $messages) {
+ $translator->addResource('array', $messages, $_locale, $domain);
+ }
+ }
+ $result = $translator->getMessages($locale);
+
+ $this->assertEquals($expected, $result);
+ }
+
+ public function dataProviderGetMessages()
+ {
+ $resources = array(
+ 'en' => array(
+ 'jsmessages' => array(
+ 'foo' => 'foo (EN)',
+ 'bar' => 'bar (EN)',
+ ),
+ 'messages' => array(
+ 'foo' => 'foo messages (EN)',
+ ),
+ 'validators' => array(
+ 'int' => 'integer (EN)',
+ ),
+ ),
+ 'pt-PT' => array(
+ 'messages' => array(
+ 'foo' => 'foo messages (PT)',
+ ),
+ 'validators' => array(
+ 'str' => 'integer (PT)',
+ ),
+ ),
+ 'pt_BR' => array(
+ 'validators' => array(
+ 'int' => 'integer (BR)',
+ ),
+ ),
+ );
+
+ return array(
+ array($resources, null,
+ array(
+ 'jsmessages' => array(
+ 'foo' => 'foo (EN)',
+ 'bar' => 'bar (EN)',
+ ),
+ 'messages' => array(
+ 'foo' => 'foo messages (EN)',
+ ),
+ 'validators' => array(
+ 'int' => 'integer (EN)',
+ ),
+ ),
+ ),
+ array($resources, 'en',
+ array(
+ 'jsmessages' => array(
+ 'foo' => 'foo (EN)',
+ 'bar' => 'bar (EN)',
+ ),
+ 'messages' => array(
+ 'foo' => 'foo messages (EN)',
+ ),
+ 'validators' => array(
+ 'int' => 'integer (EN)',
+ ),
+ ),
+ ),
+ array($resources, 'pt-PT',
+ array(
+ 'jsmessages' => array(
+ 'foo' => 'foo (EN)',
+ 'bar' => 'bar (EN)',
+ ),
+ 'messages' => array(
+ 'foo' => 'foo messages (PT)',
+ ),
+ 'validators' => array(
+ 'int' => 'integer (EN)',
+ 'str' => 'integer (PT)',
+ ),
+ ),
+ ),
+ array($resources, 'pt_BR',
+ array(
+ 'jsmessages' => array(
+ 'foo' => 'foo (EN)',
+ 'bar' => 'bar (EN)',
+ ),
+ 'messages' => array(
+ 'foo' => 'foo messages (PT)',
+ ),
+ 'validators' => array(
+ 'int' => 'integer (BR)',
+ 'str' => 'integer (PT)',
+ ),
+ ),
+ ),
+ );
+ }
+}
+
+class StringClass
+{
+ protected $str;
+
+ public function __construct($str)
+ {
+ $this->str = $str;
+ }
+
+ public function __toString()
+ {
+ return $this->str;
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty-translation.mo b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty-translation.mo
new file mode 100644
index 0000000..ed01000
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty-translation.mo
Binary files differ
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty-translation.po b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty-translation.po
new file mode 100644
index 0000000..ff6f22a
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty-translation.po
@@ -0,0 +1,3 @@
+msgid "foo"
+msgstr ""
+
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.csv b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.csv
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.csv
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.ini b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.ini
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.ini
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.json b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.json
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.json
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.mo b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.mo
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.mo
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.po b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.po
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.po
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.xlf b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.xlf
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.xlf
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.yml b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.yml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/empty.yml
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/encoding.xlf b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/encoding.xlf
new file mode 100644
index 0000000..0a88f92
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/encoding.xlf
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1" resname="foo">
+ <source>foo</source>
+ <target>br</target>
+ <note>bz</note>
+ </trans-unit>
+ <trans-unit id="2" resname="bar">
+ <source>bar</source>
+ <target>f</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/escaped-id-plurals.po b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/escaped-id-plurals.po
new file mode 100644
index 0000000..c412aa2
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/escaped-id-plurals.po
@@ -0,0 +1,10 @@
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en\n"
+
+msgid "escaped \"foo\""
+msgid_plural "escaped \"foos\""
+msgstr[0] "escaped \"bar\""
+msgstr[1] "escaped \"bars\""
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/escaped-id.po b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/escaped-id.po
new file mode 100644
index 0000000..308eadd
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/escaped-id.po
@@ -0,0 +1,8 @@
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en\n"
+
+msgid "escaped \"foo\""
+msgstr "escaped \"bar\""
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/invalid-xml-resources.xlf b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/invalid-xml-resources.xlf
new file mode 100644
index 0000000..7bf6c98
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/invalid-xml-resources.xlf
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>foo</source>
+ <target>bar
+ </trans-unit>
+ <trans-unit id="2">
+ <source>extra</source>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>key</source>
+ <target></target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>test</source>
+ <target>with</target>
+ <note>note</note>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/malformed.json b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/malformed.json
new file mode 100644
index 0000000..1ee47ff
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/malformed.json
@@ -0,0 +1,3 @@
+{
+ "foo": "bar" "
+} \ No newline at end of file
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/non-valid.xlf b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/non-valid.xlf
new file mode 100644
index 0000000..734fc97
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/non-valid.xlf
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit>
+ <source>foo</source>
+ <target>bar</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/non-valid.yml b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/non-valid.yml
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/non-valid.yml
@@ -0,0 +1 @@
+foo
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/plurals.mo b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/plurals.mo
new file mode 100644
index 0000000..6445e77
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/plurals.mo
Binary files differ
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/plurals.po b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/plurals.po
new file mode 100644
index 0000000..439c41a
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/plurals.po
@@ -0,0 +1,5 @@
+msgid "foo"
+msgid_plural "foos"
+msgstr[0] "bar"
+msgstr[1] "bars"
+
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resname.xlf b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resname.xlf
new file mode 100644
index 0000000..2df16af
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resname.xlf
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1" resname="foo">
+ <source></source>
+ <target>bar</target>
+ </trans-unit>
+ <trans-unit id="2" resname="bar">
+ <source>bar source</source>
+ <target>baz</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>baz</source>
+ <target>foo</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/corrupted/resources.dat b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/corrupted/resources.dat
new file mode 100644
index 0000000..391250c
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/corrupted/resources.dat
@@ -0,0 +1 @@
+XXX \ No newline at end of file
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.res b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.res
new file mode 100644
index 0000000..1fc1436
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.res
Binary files differ
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.txt b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.txt
new file mode 100644
index 0000000..3d9e9ea
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.txt
@@ -0,0 +1,3 @@
+en{
+ symfony{"Symfony is great"}
+} \ No newline at end of file
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.res b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.res
new file mode 100644
index 0000000..f584160
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.res
Binary files differ
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.txt b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.txt
new file mode 100644
index 0000000..182d0a0
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.txt
@@ -0,0 +1,3 @@
+fr{
+ symfony{"Symfony est génial"}
+} \ No newline at end of file
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/packagelist.txt b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/packagelist.txt
new file mode 100644
index 0000000..c5783ed
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/packagelist.txt
@@ -0,0 +1,2 @@
+en.res
+fr.res
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/resources.dat b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/resources.dat
new file mode 100644
index 0000000..563b0ea
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/resources.dat
Binary files differ
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/res/en.res b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/res/en.res
new file mode 100644
index 0000000..ad894a9
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resourcebundle/res/en.res
Binary files differ
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources-clean.xlf b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources-clean.xlf
new file mode 100644
index 0000000..4ce15af
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources-clean.xlf
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="fr-FR" target-language="en-US" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="acbd18db4cc2f85cedef654fccc4a4d8" resname="foo">
+ <source>foo</source>
+ <target>bar</target>
+ <note priority="1" from="bar">baz</note>
+ </trans-unit>
+ <trans-unit id="3c6e0b8a9c15224a8228b9a98ca1531d" resname="key">
+ <source>key</source>
+ <target></target>
+ <note>baz</note>
+ <note>qux</note>
+ </trans-unit>
+ <trans-unit id="18e6a493872558d949b4c16ea1fa6ab6" resname="key.with.cdata">
+ <source>key.with.cdata</source>
+ <target><![CDATA[<source> & <target>]]></target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.csv b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.csv
new file mode 100644
index 0000000..374b9eb
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.csv
@@ -0,0 +1,4 @@
+"foo"; "bar"
+#"bar"; "foo"
+"incorrect"; "number"; "columns"; "will"; "be"; "ignored"
+"incorrect" \ No newline at end of file
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.ini b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.ini
new file mode 100644
index 0000000..4953062
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.ini
@@ -0,0 +1 @@
+foo="bar"
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.json b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.json
new file mode 100644
index 0000000..8a79687
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.json
@@ -0,0 +1,3 @@
+{
+ "foo": "bar"
+} \ No newline at end of file
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.mo b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.mo
new file mode 100644
index 0000000..0a96602
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.mo
Binary files differ
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.php b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.php
new file mode 100644
index 0000000..c291398
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.php
@@ -0,0 +1,5 @@
+<?php
+
+return array (
+ 'foo' => 'bar',
+);
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.po b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.po
new file mode 100644
index 0000000..ccfce6b
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.po
@@ -0,0 +1,8 @@
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en\n"
+
+msgid "foo"
+msgstr "bar" \ No newline at end of file
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.ts b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.ts
new file mode 100644
index 0000000..40e1852
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.ts
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TS>
+ <context>
+ <name>resources</name>
+ <message>
+ <source>foo</source>
+ <translation>bar</translation>
+ </message>
+ </context>
+</TS>
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.xlf b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.xlf
new file mode 100644
index 0000000..b0e5988
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.xlf
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>foo</source>
+ <target>bar</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>extra</source>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>key</source>
+ <target></target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>test</source>
+ <target>with</target>
+ <note>note</note>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.yml b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.yml
new file mode 100644
index 0000000..20e9ff3
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/resources.yml
@@ -0,0 +1 @@
+foo: bar
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/valid.csv b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/valid.csv
new file mode 100644
index 0000000..59882e5
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/valid.csv
@@ -0,0 +1,4 @@
+foo;bar
+bar;"foo
+foo"
+"foo;foo";bar
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/withdoctype.xlf b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/withdoctype.xlf
new file mode 100644
index 0000000..f83e834
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/withdoctype.xlf
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!DOCTYPE foo>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>foo</source>
+ <target>bar</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/withnote.xlf b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/withnote.xlf
new file mode 100644
index 0000000..b1d3f83
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Tests/fixtures/withnote.xlf
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>foo</source>
+ <target>bar</target>
+ <note priority="1">foo</note>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>extra</source>
+ <note from="foo">bar</note>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>key</source>
+ <target></target>
+ <note>baz</note>
+ <note priority="2" from="bar">qux</note>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Translator.php b/vendor/symfony/translation/Symfony/Component/Translation/Translator.php
new file mode 100644
index 0000000..30bdc53
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Translator.php
@@ -0,0 +1,466 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Translation\Loader\LoaderInterface;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\ConfigCache;
+
+/**
+ * Translator.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class Translator implements TranslatorInterface, TranslatorBagInterface
+{
+ /**
+ * @var MessageCatalogueInterface[]
+ */
+ protected $catalogues = array();
+
+ /**
+ * @var string
+ */
+ protected $locale;
+
+ /**
+ * @var array
+ */
+ private $fallbackLocales = array();
+
+ /**
+ * @var LoaderInterface[]
+ */
+ private $loaders = array();
+
+ /**
+ * @var array
+ */
+ private $resources = array();
+
+ /**
+ * @var MessageSelector
+ */
+ private $selector;
+
+ /**
+ * @var string
+ */
+ private $cacheDir;
+
+ /**
+ * @var bool
+ */
+ private $debug;
+
+ /**
+ * Constructor.
+ *
+ * @param string $locale The locale
+ * @param MessageSelector|null $selector The message selector for pluralization
+ * @param string|null $cacheDir The directory to use for the cache
+ * @param bool $debug Use cache in debug mode ?
+ *
+ * @throws \InvalidArgumentException If a locale contains invalid characters
+ *
+ * @api
+ */
+ public function __construct($locale, MessageSelector $selector = null, $cacheDir = null, $debug = false)
+ {
+ $this->setLocale($locale);
+ $this->selector = $selector ?: new MessageSelector();
+ $this->cacheDir = $cacheDir;
+ $this->debug = $debug;
+ }
+
+ /**
+ * Adds a Loader.
+ *
+ * @param string $format The name of the loader (@see addResource())
+ * @param LoaderInterface $loader A LoaderInterface instance
+ *
+ * @api
+ */
+ public function addLoader($format, LoaderInterface $loader)
+ {
+ $this->loaders[$format] = $loader;
+ }
+
+ /**
+ * Adds a Resource.
+ *
+ * @param string $format The name of the loader (@see addLoader())
+ * @param mixed $resource The resource name
+ * @param string $locale The locale
+ * @param string $domain The domain
+ *
+ * @throws \InvalidArgumentException If the locale contains invalid characters
+ *
+ * @api
+ */
+ public function addResource($format, $resource, $locale, $domain = null)
+ {
+ if (null === $domain) {
+ $domain = 'messages';
+ }
+
+ $this->assertValidLocale($locale);
+
+ $this->resources[$locale][] = array($format, $resource, $domain);
+
+ if (in_array($locale, $this->fallbackLocales)) {
+ $this->catalogues = array();
+ } else {
+ unset($this->catalogues[$locale]);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function setLocale($locale)
+ {
+ $this->assertValidLocale($locale);
+ $this->locale = $locale;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function getLocale()
+ {
+ return $this->locale;
+ }
+
+ /**
+ * Sets the fallback locale(s).
+ *
+ * @param string|array $locales The fallback locale(s)
+ *
+ * @throws \InvalidArgumentException If a locale contains invalid characters
+ *
+ * @deprecated since 2.3, to be removed in 3.0. Use setFallbackLocales() instead.
+ *
+ * @api
+ */
+ public function setFallbackLocale($locales)
+ {
+ $this->setFallbackLocales(is_array($locales) ? $locales : array($locales));
+ }
+
+ /**
+ * Sets the fallback locales.
+ *
+ * @param array $locales The fallback locales
+ *
+ * @throws \InvalidArgumentException If a locale contains invalid characters
+ *
+ * @api
+ */
+ public function setFallbackLocales(array $locales)
+ {
+ // needed as the fallback locales are linked to the already loaded catalogues
+ $this->catalogues = array();
+
+ foreach ($locales as $locale) {
+ $this->assertValidLocale($locale);
+ }
+
+ $this->fallbackLocales = $locales;
+ }
+
+ /**
+ * Gets the fallback locales.
+ *
+ * @return array $locales The fallback locales
+ *
+ * @api
+ */
+ public function getFallbackLocales()
+ {
+ return $this->fallbackLocales;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function trans($id, array $parameters = array(), $domain = null, $locale = null)
+ {
+ if (null === $locale) {
+ $locale = $this->getLocale();
+ } else {
+ $this->assertValidLocale($locale);
+ }
+
+ if (null === $domain) {
+ $domain = 'messages';
+ }
+
+ if (!isset($this->catalogues[$locale])) {
+ $this->loadCatalogue($locale);
+ }
+
+ return strtr($this->catalogues[$locale]->get((string) $id, $domain), $parameters);
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
+ {
+ if (null === $locale) {
+ $locale = $this->getLocale();
+ } else {
+ $this->assertValidLocale($locale);
+ }
+
+ if (null === $domain) {
+ $domain = 'messages';
+ }
+
+ if (!isset($this->catalogues[$locale])) {
+ $this->loadCatalogue($locale);
+ }
+
+ $id = (string) $id;
+
+ $catalogue = $this->catalogues[$locale];
+ while (!$catalogue->defines($id, $domain)) {
+ if ($cat = $catalogue->getFallbackCatalogue()) {
+ $catalogue = $cat;
+ $locale = $catalogue->getLocale();
+ } else {
+ break;
+ }
+ }
+
+ return strtr($this->selector->choose($catalogue->get($id, $domain), (int) $number, $locale), $parameters);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCatalogue($locale = null)
+ {
+ if (null === $locale) {
+ $locale = $this->getLocale();
+ }
+
+ if (!isset($this->catalogues[$locale])) {
+ $this->loadCatalogue($locale);
+ }
+
+ return $this->catalogues[$locale];
+ }
+
+ /**
+ * Gets the loaders.
+ *
+ * @return array LoaderInterface[]
+ */
+ protected function getLoaders()
+ {
+ return $this->loaders;
+ }
+
+ /**
+ * Collects all messages for the given locale.
+ *
+ * @param string|null $locale Locale of translations, by default is current locale
+ *
+ * @return array[array] indexed by catalog
+ */
+ public function getMessages($locale = null)
+ {
+ if (null === $locale) {
+ $locale = $this->getLocale();
+ }
+
+ if (!isset($this->catalogues[$locale])) {
+ $this->loadCatalogue($locale);
+ }
+
+ $catalogues = array();
+ $catalogues[] = $catalogue = $this->catalogues[$locale];
+ while ($catalogue = $catalogue->getFallbackCatalogue()) {
+ $catalogues[] = $catalogue;
+ }
+ $messages = array();
+ for ($i = count($catalogues) - 1; $i >= 0; $i--) {
+ $localeMessages = $catalogues[$i]->all();
+ $messages = array_replace_recursive($messages, $localeMessages);
+ }
+
+ return $messages;
+ }
+
+ /*
+ * @param string $locale
+ */
+ protected function loadCatalogue($locale)
+ {
+ if (null === $this->cacheDir) {
+ $this->initializeCatalogue($locale);
+ } else {
+ $this->initializeCacheCatalogue($locale);
+ }
+ }
+
+ /**
+ * @param string $locale
+ */
+ protected function initializeCatalogue($locale)
+ {
+ $this->assertValidLocale($locale);
+
+ try {
+ $this->doLoadCatalogue($locale);
+ } catch (NotFoundResourceException $e) {
+ if (!$this->computeFallbackLocales($locale)) {
+ throw $e;
+ }
+ }
+ $this->loadFallbackCatalogues($locale);
+ }
+
+ /**
+ * @param string $locale
+ */
+ private function initializeCacheCatalogue($locale)
+ {
+ if (isset($this->catalogues[$locale])) {
+ return;
+ }
+
+ $this->assertValidLocale($locale);
+ $cache = new ConfigCache($this->cacheDir.'/catalogue.'.$locale.'.php', $this->debug);
+ if (!$cache->isFresh()) {
+ $this->initializeCatalogue($locale);
+
+ $fallbackContent = '';
+ $current = '';
+ $replacementPattern = '/[^a-z0-9_]/i';
+ foreach ($this->computeFallbackLocales($locale) as $fallback) {
+ $fallbackSuffix = ucfirst(preg_replace($replacementPattern, '_', $fallback));
+ $currentSuffix = ucfirst(preg_replace($replacementPattern, '_', $current));
+
+ $fallbackContent .= sprintf(<<<EOF
+\$catalogue%s = new MessageCatalogue('%s', %s);
+\$catalogue%s->addFallbackCatalogue(\$catalogue%s);
+
+
+EOF
+ ,
+ $fallbackSuffix,
+ $fallback,
+ var_export($this->catalogues[$fallback]->all(), true),
+ $currentSuffix,
+ $fallbackSuffix
+ );
+ $current = $fallback;
+ }
+
+ $content = sprintf(<<<EOF
+<?php
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+\$catalogue = new MessageCatalogue('%s', %s);
+
+%s
+return \$catalogue;
+
+EOF
+ ,
+ $locale,
+ var_export($this->catalogues[$locale]->all(), true),
+ $fallbackContent
+ );
+
+ $cache->write($content, $this->catalogues[$locale]->getResources());
+
+ return;
+ }
+
+ $this->catalogues[$locale] = include $cache;
+ }
+
+ private function doLoadCatalogue($locale)
+ {
+ $this->catalogues[$locale] = new MessageCatalogue($locale);
+
+ if (isset($this->resources[$locale])) {
+ foreach ($this->resources[$locale] as $resource) {
+ if (!isset($this->loaders[$resource[0]])) {
+ throw new \RuntimeException(sprintf('The "%s" translation loader is not registered.', $resource[0]));
+ }
+ $this->catalogues[$locale]->addCatalogue($this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2]));
+ }
+ }
+ }
+
+ private function loadFallbackCatalogues($locale)
+ {
+ $current = $this->catalogues[$locale];
+
+ foreach ($this->computeFallbackLocales($locale) as $fallback) {
+ if (!isset($this->catalogues[$fallback])) {
+ $this->doLoadCatalogue($fallback);
+ }
+
+ $current->addFallbackCatalogue($this->catalogues[$fallback]);
+ $current = $this->catalogues[$fallback];
+ }
+ }
+
+ protected function computeFallbackLocales($locale)
+ {
+ $locales = array();
+ foreach ($this->fallbackLocales as $fallback) {
+ if ($fallback === $locale) {
+ continue;
+ }
+
+ $locales[] = $fallback;
+ }
+
+ if (strrchr($locale, '_') !== false) {
+ array_unshift($locales, substr($locale, 0, -strlen(strrchr($locale, '_'))));
+ }
+
+ return array_unique($locales);
+ }
+
+ /**
+ * Asserts that the locale is valid, throws an Exception if not.
+ *
+ * @param string $locale Locale to tests
+ *
+ * @throws \InvalidArgumentException If the locale contains invalid characters
+ */
+ protected function assertValidLocale($locale)
+ {
+ if (1 !== preg_match('/^[a-z0-9@_\\.\\-]*$/i', $locale)) {
+ throw new \InvalidArgumentException(sprintf('Invalid "%s" locale.', $locale));
+ }
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/TranslatorBagInterface.php b/vendor/symfony/translation/Symfony/Component/Translation/TranslatorBagInterface.php
new file mode 100644
index 0000000..e0312d9
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/TranslatorBagInterface.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * TranslatorBagInterface
+ *
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+interface TranslatorBagInterface
+{
+ /**
+ * Gets the catalogue by locale.
+ *
+ * @param string|null $locale The locale or null to use the default
+ *
+ * @return MessageCatalogueInterface
+ */
+ public function getCatalogue($locale = null);
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/TranslatorInterface.php b/vendor/symfony/translation/Symfony/Component/Translation/TranslatorInterface.php
new file mode 100644
index 0000000..fe1a865
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/TranslatorInterface.php
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * TranslatorInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface TranslatorInterface
+{
+ /**
+ * Translates the given message.
+ *
+ * @param string $id The message id (may also be an object that can be cast to string)
+ * @param array $parameters An array of parameters for the message
+ * @param string|null $domain The domain for the message or null to use the default
+ * @param string|null $locale The locale or null to use the default
+ *
+ * @throws \InvalidArgumentException If the locale contains invalid characters
+ *
+ * @return string The translated string
+ *
+ * @api
+ */
+ public function trans($id, array $parameters = array(), $domain = null, $locale = null);
+
+ /**
+ * Translates the given choice message by choosing a translation according to a number.
+ *
+ * @param string $id The message id (may also be an object that can be cast to string)
+ * @param int $number The number to use to find the indice of the message
+ * @param array $parameters An array of parameters for the message
+ * @param string|null $domain The domain for the message or null to use the default
+ * @param string|null $locale The locale or null to use the default
+ *
+ * @throws \InvalidArgumentException If the locale contains invalid characters
+ *
+ * @return string The translated string
+ *
+ * @api
+ */
+ public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null);
+
+ /**
+ * Sets the current locale.
+ *
+ * @param string $locale The locale
+ *
+ * @throws \InvalidArgumentException If the locale contains invalid characters
+ *
+ * @api
+ */
+ public function setLocale($locale);
+
+ /**
+ * Returns the current locale.
+ *
+ * @return string The locale
+ *
+ * @api
+ */
+ public function getLocale();
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/Writer/TranslationWriter.php b/vendor/symfony/translation/Symfony/Component/Translation/Writer/TranslationWriter.php
new file mode 100644
index 0000000..44ac182
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/Writer/TranslationWriter.php
@@ -0,0 +1,87 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Writer;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\DumperInterface;
+
+/**
+ * TranslationWriter writes translation messages.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class TranslationWriter
+{
+ /**
+ * Dumpers used for export.
+ *
+ * @var array
+ */
+ private $dumpers = array();
+
+ /**
+ * Adds a dumper to the writer.
+ *
+ * @param string $format The format of the dumper
+ * @param DumperInterface $dumper The dumper
+ */
+ public function addDumper($format, DumperInterface $dumper)
+ {
+ $this->dumpers[$format] = $dumper;
+ }
+
+ /**
+ * Disables dumper backup.
+ */
+ public function disableBackup()
+ {
+ foreach ($this->dumpers as $dumper) {
+ $dumper->setBackup(false);
+ }
+ }
+
+ /**
+ * Obtains the list of supported formats.
+ *
+ * @return array
+ */
+ public function getFormats()
+ {
+ return array_keys($this->dumpers);
+ }
+
+ /**
+ * Writes translation from the catalogue according to the selected format.
+ *
+ * @param MessageCatalogue $catalogue The message catalogue to dump
+ * @param string $format The format to use to dump the messages
+ * @param array $options Options that are passed to the dumper
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function writeTranslations(MessageCatalogue $catalogue, $format, $options = array())
+ {
+ if (!isset($this->dumpers[$format])) {
+ throw new \InvalidArgumentException(sprintf('There is no dumper associated with format "%s".', $format));
+ }
+
+ // get the right dumper
+ $dumper = $this->dumpers[$format];
+
+ if (isset($options['path']) && !is_dir($options['path'])) {
+ mkdir($options['path'], 0777, true);
+ }
+
+ // save
+ $dumper->dump($catalogue, $options);
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/composer.json b/vendor/symfony/translation/Symfony/Component/Translation/composer.json
new file mode 100644
index 0000000..8b3f17e
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/composer.json
@@ -0,0 +1,43 @@
+{
+ "name": "symfony/translation",
+ "type": "library",
+ "description": "Symfony Translation Component",
+ "keywords": [],
+ "homepage": "http://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7",
+ "symfony/config": "~2.3,>=2.3.12",
+ "symfony/intl": "~2.3",
+ "symfony/yaml": "~2.2",
+ "psr/log": "~1.0"
+ },
+ "suggest": {
+ "symfony/config": "",
+ "symfony/yaml": "",
+ "psr/log": "To use logging capability in translator"
+ },
+ "autoload": {
+ "psr-0": { "Symfony\\Component\\Translation\\": "" }
+ },
+ "target-dir": "Symfony/Component/Translation",
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ }
+}
diff --git a/vendor/symfony/translation/Symfony/Component/Translation/phpunit.xml.dist b/vendor/symfony/translation/Symfony/Component/Translation/phpunit.xml.dist
new file mode 100644
index 0000000..16cca4a
--- /dev/null
+++ b/vendor/symfony/translation/Symfony/Component/Translation/phpunit.xml.dist
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+
+ <testsuites>
+ <testsuite name="Symfony Translation Component Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./vendor</directory>
+ <directory>./Tests</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/.gitignore b/vendor/symfony/validator/Symfony/Component/Validator/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/CHANGELOG.md b/vendor/symfony/validator/Symfony/Component/Validator/CHANGELOG.md
new file mode 100644
index 0000000..329eaf3
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/CHANGELOG.md
@@ -0,0 +1,159 @@
+CHANGELOG
+=========
+
+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()`
+
+
+2.4.0
+-----
+
+ * added a constraint the uses the expression language
+ * added `minRatio`, `maxRatio`, `allowSquare`, `allowLandscape`, and `allowPortrait` to Image validator
+
+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/vendor/symfony/validator/Symfony/Component/Validator/ClassBasedInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/ClassBasedInterface.php
new file mode 100644
index 0000000..fe532ef
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ClassBasedInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * An object backed by a PHP class.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Mapping\ClassMetadataInterface} instead.
+ */
+interface ClassBasedInterface
+{
+ /**
+ * Returns the name of the backing PHP class.
+ *
+ * @return string The name of the backing class.
+ */
+ public function getClassName();
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraint.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraint.php
new file mode 100644
index 0000000..a8ae634
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraint.php
@@ -0,0 +1,321 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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, an option or a getter method.
+ * The Constraint class encapsulates all the configuration required for
+ * validating this class, option or getter result successfully.
+ *
+ * Constraint instances are immutable and serializable.
+ *
+ * @property array $groups The groups that the constraint belongs to
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+abstract class Constraint
+{
+ /**
+ * The name of the group given to all constraints with no explicit group.
+ *
+ * @var string
+ */
+ const DEFAULT_GROUP = 'Default';
+
+ /**
+ * Marks a constraint that can be put onto classes.
+ *
+ * @var string
+ */
+ const CLASS_CONSTRAINT = 'class';
+
+ /**
+ * Marks a constraint that can be put onto properties.
+ *
+ * @var string
+ */
+ const PROPERTY_CONSTRAINT = 'property';
+
+ /**
+ * Maps error codes to the names of their constants
+ * @var array
+ */
+ protected static $errorNames = array();
+
+ /**
+ * Domain-specific data attached to a constraint
+ * @var mixed
+ */
+ public $payload;
+
+ /**
+ * Returns the name of the given error code.
+ *
+ * @param int $errorCode The error code
+ *
+ * @return string The name of the error code
+ *
+ * @throws InvalidArgumentException If the error code does not exist
+ */
+ public static function getErrorName($errorCode)
+ {
+ if (!isset(static::$errorNames[$errorCode])) {
+ throw new InvalidArgumentException(sprintf(
+ 'The error code "%s" does not exist for constraint of type "%s".',
+ $errorCode,
+ get_called_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)
+ *
+ * @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
+ *
+ * @api
+ */
+ public function __construct($options = null)
+ {
+ $invalidOptions = array();
+ $missingOptions = array_flip((array) $this->getRequiredOptions());
+ $knownOptions = get_object_vars($this);
+
+ // The "groups" option is added to the object lazily
+ $knownOptions['groups'] = true;
+
+ if (is_array($options) && count($options) >= 1 && isset($options['value']) && !property_exists($this, 'value')) {
+ $options[$this->getDefaultOption()] = $options['value'];
+ unset($options['value']);
+ }
+
+ if (is_array($options) && count($options) > 0 && is_string(key($options))) {
+ foreach ($options as $option => $value) {
+ if (array_key_exists($option, $knownOptions)) {
+ $this->$option = $value;
+ unset($missingOptions[$option]);
+ } else {
+ $invalidOptions[] = $option;
+ }
+ }
+ } elseif (null !== $options && !(is_array($options) && count($options) === 0)) {
+ $option = $this->getDefaultOption();
+
+ if (null === $option) {
+ throw new ConstraintDefinitionException(
+ sprintf('No default option is configured for constraint %s', get_class($this))
+ );
+ }
+
+ if (array_key_exists($option, $knownOptions)) {
+ $this->$option = $options;
+ unset($missingOptions[$option]);
+ } else {
+ $invalidOptions[] = $option;
+ }
+ }
+
+ if (count($invalidOptions) > 0) {
+ throw new InvalidOptionsException(
+ sprintf('The options "%s" do not exist in constraint %s', implode('", "', $invalidOptions), get_class($this)),
+ $invalidOptions
+ );
+ }
+
+ if (count($missingOptions) > 0) {
+ throw new MissingOptionsException(
+ sprintf('The options "%s" must be set for constraint %s', implode('", "', array_keys($missingOptions)), get_class($this)),
+ array_keys($missingOptions)
+ );
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * @param string $option The option name
+ * @param mixed $value The value to set
+ *
+ * @throws InvalidOptionsException If an invalid option name is given
+ */
+ public function __set($option, $value)
+ {
+ if ('groups' === $option) {
+ $this->groups = (array) $value;
+
+ return;
+ }
+
+ throw new InvalidOptionsException(sprintf('The option "%s" does not exist in constraint %s', $option, get_class($this)), array($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.
+ *
+ * @param string $option The option name
+ *
+ * @return mixed The value of the option
+ *
+ * @throws InvalidOptionsException If an invalid option name is given
+ *
+ * @internal This method should not be used or overwritten in userland code.
+ *
+ * @since 2.6
+ */
+ public function __get($option)
+ {
+ if ('groups' === $option) {
+ $this->groups = array(self::DEFAULT_GROUP);
+
+ return $this->groups;
+ }
+
+ throw new InvalidOptionsException(sprintf('The option "%s" does not exist in constraint %s', $option, get_class($this)), array($option));
+ }
+
+ /**
+ * Adds the given group if this constraint is in the Default group.
+ *
+ * @param string $group
+ *
+ * @api
+ */
+ public function addImplicitGroupName($group)
+ {
+ if (in_array(Constraint::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
+ *
+ * @see __construct()
+ *
+ * @api
+ */
+ public function getDefaultOption()
+ {
+ }
+
+ /**
+ * Returns the name of the required options.
+ *
+ * Override this method if you want to define required options.
+ *
+ * @return array
+ *
+ * @see __construct()
+ *
+ * @api
+ */
+ public function getRequiredOptions()
+ {
+ return array();
+ }
+
+ /**
+ * 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
+ * behaviour.
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function validatedBy()
+ {
+ return get_class($this).'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|array One or more constant values
+ *
+ * @api
+ */
+ public function getTargets()
+ {
+ return self::PROPERTY_CONSTRAINT;
+ }
+
+ /**
+ * Optimizes the serialized value to minimize storage space.
+ *
+ * @return array The properties to serialize
+ *
+ * @internal This method may be replaced by an implementation of
+ * {@link \Serializable} in the future. Please don't use or
+ * overwrite it.
+ *
+ * @since 2.6
+ */
+ public function __sleep()
+ {
+ // Initialize "groups" option if it is not set
+ $this->groups;
+
+ return array_keys(get_object_vars($this));
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidator.php
new file mode 100644
index 0000000..61c994a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidator.php
@@ -0,0 +1,216 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+use Symfony\Component\Validator\Context\ExecutionContextInterface as ExecutionContextInterface2Dot5;
+use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
+use Symfony\Component\Validator\Violation\LegacyConstraintViolationBuilder;
+
+/**
+ * Base class for constraint validators.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+abstract class ConstraintValidator implements ConstraintValidatorInterface
+{
+ /**
+ * Whether to format {@link \DateTime} objects as RFC-3339 dates
+ * ("Y-m-d H:i:s").
+ *
+ * @var int
+ */
+ const PRETTY_DATE = 1;
+
+ /**
+ * Whether to cast objects with a "__toString()" method to strings.
+ *
+ * @var int
+ */
+ const OBJECT_TO_STRING = 2;
+
+ /**
+ * @var ExecutionContextInterface
+ */
+ protected $context;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function initialize(ExecutionContextInterface $context)
+ {
+ $this->context = $context;
+ }
+
+ /**
+ * Wrapper for {@link ExecutionContextInterface::buildViolation} that
+ * supports the 2.4 context API.
+ *
+ * @param string $message The violation message
+ * @param array $parameters The message parameters
+ *
+ * @return ConstraintViolationBuilderInterface The violation builder
+ *
+ * @deprecated This method will be removed in Symfony 3.0.
+ */
+ protected function buildViolation($message, array $parameters = array())
+ {
+ if ($this->context instanceof ExecutionContextInterface2Dot5) {
+ return $this->context->buildViolation($message, $parameters);
+ }
+
+ return new LegacyConstraintViolationBuilder($this->context, $message, $parameters);
+ }
+
+ /**
+ * Wrapper for {@link ExecutionContextInterface::buildViolation} that
+ * supports the 2.4 context API.
+ *
+ * @param ExecutionContextInterface $context The context to use
+ * @param string $message The violation message
+ * @param array $parameters The message parameters
+ *
+ * @return ConstraintViolationBuilderInterface The violation builder
+ *
+ * @deprecated This method will be removed in Symfony 3.0.
+ */
+ protected function buildViolationInContext(ExecutionContextInterface $context, $message, array $parameters = array())
+ {
+ if ($context instanceof ExecutionContextInterface2Dot5) {
+ return $context->buildViolation($message, $parameters);
+ }
+
+ return new LegacyConstraintViolationBuilder($context, $message, $parameters);
+ }
+
+ /**
+ * 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.
+ *
+ * @param mixed $value The value to return the type of
+ *
+ * @return string The type of the value
+ */
+ protected function formatTypeOf($value)
+ {
+ return is_object($value) ? get_class($value) : gettype($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 parameter $prettyDateTime
+ * is set to true, {@link \DateTime} objects 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 mixed $value The value to format as string
+ * @param int $format A bitwise combination of the format
+ * constants in this class
+ *
+ * @return string The string representation of the passed value
+ */
+ protected function formatValue($value, $format = 0)
+ {
+ $isDateTime = $value instanceof \DateTime || $value instanceof \DateTimeInterface;
+
+ if (($format & self::PRETTY_DATE) && $isDateTime) {
+ if (class_exists('IntlDateFormatter')) {
+ $locale = \Locale::getDefault();
+ $formatter = new \IntlDateFormatter($locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT);
+
+ // neither the native nor the stub IntlDateFormatter support
+ // DateTimeImmutable as of yet
+ if (!$value instanceof \DateTime) {
+ $value = new \DateTime(
+ $value->format('Y-m-d H:i:s.u e'),
+ $value->getTimezone()
+ );
+ }
+
+ return $formatter->format($value);
+ }
+
+ return $value->format('Y-m-d H:i:s');
+ }
+
+ if (is_object($value)) {
+ if ($format & self::OBJECT_TO_STRING && method_exists($value, '__toString')) {
+ 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';
+ }
+
+ 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
+ *
+ * @return string The string representation of the value list
+ *
+ * @see formatValue()
+ */
+ protected function formatValues(array $values, $format = 0)
+ {
+ foreach ($values as $key => $value) {
+ $values[$key] = $this->formatValue($value, $format);
+ }
+
+ return implode(', ', $values);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactory.php b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactory.php
new file mode 100644
index 0000000..cc6981b
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactory.php
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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 <bschussek@gmail.com>
+ */
+class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface
+{
+ protected $validators = array();
+
+ private $propertyAccessor;
+
+ public function __construct($propertyAccessor = null)
+ {
+ $this->propertyAccessor = $propertyAccessor;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getInstance(Constraint $constraint)
+ {
+ $className = $constraint->validatedBy();
+
+ if (!isset($this->validators[$className])) {
+ $this->validators[$className] = 'validator.expression' === $className
+ ? new ExpressionValidator($this->propertyAccessor)
+ : new $className();
+ }
+
+ return $this->validators[$className];
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactoryInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactoryInterface.php
new file mode 100644
index 0000000..5e21627
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactoryInterface.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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.
+ *
+ * @param Constraint $constraint The source constraint
+ *
+ * @return ConstraintValidatorInterface
+ */
+ public function getInstance(Constraint $constraint);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorInterface.php
new file mode 100644
index 0000000..f7538a1
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorInterface.php
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+interface ConstraintValidatorInterface
+{
+ /**
+ * Initializes the constraint validator.
+ *
+ * @param ExecutionContextInterface $context The current validation context
+ */
+ public function initialize(ExecutionContextInterface $context);
+
+ /**
+ * Checks if the passed value is valid.
+ *
+ * @param mixed $value The value that should be validated
+ * @param Constraint $constraint The constraint for the validation
+ *
+ * @api
+ */
+ public function validate($value, Constraint $constraint);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolation.php b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolation.php
new file mode 100644
index 0000000..8f4744f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolation.php
@@ -0,0 +1,233 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * Default implementation of {@ConstraintViolationInterface}.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ConstraintViolation implements ConstraintViolationInterface
+{
+ /**
+ * @var string
+ */
+ private $message;
+
+ /**
+ * @var string
+ */
+ private $messageTemplate;
+
+ /**
+ * @var array
+ */
+ private $parameters;
+
+ /**
+ * @var int|null
+ */
+ private $plural;
+
+ /**
+ * @var mixed
+ */
+ private $root;
+
+ /**
+ * @var string
+ */
+ private $propertyPath;
+
+ /**
+ * @var mixed
+ */
+ private $invalidValue;
+
+ /**
+ * @var Constraint|null
+ */
+ private $constraint;
+
+ /**
+ * @var mixed
+ */
+ private $code;
+
+ /**
+ * @var mixed
+ */
+ private $cause;
+
+ /**
+ * Creates a new constraint violation.
+ *
+ * @param string $message The violation message
+ * @param string $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 $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 mixed $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($message, $messageTemplate, array $parameters, $root, $propertyPath, $invalidValue, $plural = null, $code = null, Constraint $constraint = null, $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;
+ }
+
+ /**
+ * Converts the violation into a string for debugging purposes.
+ *
+ * @return string The violation as string.
+ */
+ public function __toString()
+ {
+ if (is_object($this->root)) {
+ $class = 'Object('.get_class($this->root).')';
+ } elseif (is_array($this->root)) {
+ $class = 'Array';
+ } else {
+ $class = (string) $this->root;
+ }
+
+ $propertyPath = (string) $this->propertyPath;
+ $code = $this->code;
+
+ if ('' !== $propertyPath && '[' !== $propertyPath[0] && '' !== $class) {
+ $class .= '.';
+ }
+
+ if (!empty($code)) {
+ $code = ' (code '.$code.')';
+ }
+
+ return $class.$propertyPath.":\n ".$this->getMessage().$code;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMessageTemplate()
+ {
+ return $this->messageTemplate;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMessageParameters()
+ {
+ return $this->parameters;
+ }
+
+ /**
+ * Alias of {@link getMessageParameters()}.
+ */
+ public function getParameters()
+ {
+ return $this->parameters;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMessagePluralization()
+ {
+ return $this->plural;
+ }
+
+ /**
+ * Alias of {@link getMessagePluralization()}.
+ */
+ public function getPlural()
+ {
+ return $this->plural;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRoot()
+ {
+ return $this->root;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPropertyPath()
+ {
+ return $this->propertyPath;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getInvalidValue()
+ {
+ return $this->invalidValue;
+ }
+
+ /**
+ * Returns the constraint whose validation caused the violation.
+ *
+ * @return Constraint|null The constraint or null if it is not known
+ */
+ public function getConstraint()
+ {
+ return $this->constraint;
+ }
+
+ /**
+ * Returns the cause of the violation.
+ *
+ * @return mixed
+ */
+ public function getCause()
+ {
+ return $this->cause;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCode()
+ {
+ return $this->code;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationInterface.php
new file mode 100644
index 0000000..232fb55
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationInterface.php
@@ -0,0 +1,136 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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:
+ *
+ * <pre>
+ * (Person)---(firstName: string)
+ * \
+ * (address: Address)---(street: string)
+ * </pre>
+ *
+ * If the <tt>Person</tt> object is validated and validation fails for the
+ * "firstName" property, the generated violation has the <tt>Person</tt>
+ * instance as root and the property path "firstName". If validation fails
+ * for the "street" property of the related <tt>Address</tt> instance, the root
+ * element is still the person, but the property path is "address.street".
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+interface ConstraintViolationInterface
+{
+ /**
+ * Returns the violation message.
+ *
+ * @return string The violation message.
+ *
+ * @api
+ */
+ public function getMessage();
+
+ /**
+ * Returns the raw violation message.
+ *
+ * The raw violation message contains placeholders for the parameters
+ * returned by {@link getMessageParameters}. Typically you'll pass the
+ * message template and parameters to a translation engine.
+ *
+ * @return string The raw violation message.
+ *
+ * @api
+ */
+ public function getMessageTemplate();
+
+ /**
+ * 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()
+ *
+ * @api
+ */
+ public function getMessageParameters();
+
+ /**
+ * Returns a number for pluralizing the violation message.
+ *
+ * For example, the message template could have different translation based
+ * on a parameter "choices":
+ *
+ * <ul>
+ * <li>Please select exactly one entry. (choices=1)</li>
+ * <li>Please select two entries. (choices=2)</li>
+ * </ul>
+ *
+ * This method returns the value of the parameter for choosing the right
+ * pluralization form (in this case "choices").
+ *
+ * @return int|null The number to use to pluralize of the message.
+ */
+ public function getMessagePluralization();
+
+ /**
+ * 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.
+ *
+ * @api
+ */
+ public function getRoot();
+
+ /**
+ * 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 <tt>Person</tt> instance with a property
+ * "address" that contains an <tt>Address</tt> 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".
+ *
+ * @api
+ */
+ public function getPropertyPath();
+
+ /**
+ * Returns the value that caused the violation.
+ *
+ * @return mixed The invalid value that caused the validated constraint to
+ * fail.
+ *
+ * @api
+ */
+ public function getInvalidValue();
+
+ /**
+ * Returns a machine-digestible error code for the violation.
+ *
+ * @return mixed The error code.
+ */
+ public function getCode();
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationList.php b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationList.php
new file mode 100644
index 0000000..cccfa86
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationList.php
@@ -0,0 +1,159 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * Default implementation of {@ConstraintViolationListInterface}.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ConstraintViolationList implements \IteratorAggregate, ConstraintViolationListInterface
+{
+ /**
+ * @var ConstraintViolationInterface[]
+ */
+ private $violations = array();
+
+ /**
+ * Creates a new constraint violation list.
+ *
+ * @param ConstraintViolationInterface[] $violations The constraint violations to add to the list
+ */
+ public function __construct(array $violations = array())
+ {
+ foreach ($violations as $violation) {
+ $this->add($violation);
+ }
+ }
+
+ /**
+ * Converts the violation into a string for debugging purposes.
+ *
+ * @return string The violation as string.
+ */
+ public function __toString()
+ {
+ $string = '';
+
+ foreach ($this->violations as $violation) {
+ $string .= $violation."\n";
+ }
+
+ return $string;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function add(ConstraintViolationInterface $violation)
+ {
+ $this->violations[] = $violation;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addAll(ConstraintViolationListInterface $otherList)
+ {
+ foreach ($otherList as $violation) {
+ $this->violations[] = $violation;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($offset)
+ {
+ if (!isset($this->violations[$offset])) {
+ throw new \OutOfBoundsException(sprintf('The offset "%s" does not exist.', $offset));
+ }
+
+ return $this->violations[$offset];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($offset)
+ {
+ return isset($this->violations[$offset]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($offset, ConstraintViolationInterface $violation)
+ {
+ $this->violations[$offset] = $violation;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function remove($offset)
+ {
+ unset($this->violations[$offset]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->violations);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function count()
+ {
+ return count($this->violations);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function offsetExists($offset)
+ {
+ return $this->has($offset);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function offsetGet($offset)
+ {
+ return $this->get($offset);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function offsetSet($offset, $violation)
+ {
+ if (null === $offset) {
+ $this->add($violation);
+ } else {
+ $this->set($offset, $violation);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function offsetUnset($offset)
+ {
+ $this->remove($offset);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationListInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationListInterface.php
new file mode 100644
index 0000000..088c70c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationListInterface.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * A list of constraint violations.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+interface ConstraintViolationListInterface extends \Traversable, \Countable, \ArrayAccess
+{
+ /**
+ * Adds a constraint violation to this list.
+ *
+ * @param ConstraintViolationInterface $violation The violation to add.
+ *
+ * @api
+ */
+ public function add(ConstraintViolationInterface $violation);
+
+ /**
+ * Merges an existing violation list into this list.
+ *
+ * @param ConstraintViolationListInterface $otherList The list to merge.
+ *
+ * @api
+ */
+ public function addAll(ConstraintViolationListInterface $otherList);
+
+ /**
+ * Returns the violation at a given offset.
+ *
+ * @param int $offset The offset of the violation.
+ *
+ * @return ConstraintViolationInterface The violation.
+ *
+ * @throws \OutOfBoundsException If the offset does not exist.
+ *
+ * @api
+ */
+ public function get($offset);
+
+ /**
+ * Returns whether the given offset exists.
+ *
+ * @param int $offset The violation offset.
+ *
+ * @return bool Whether the offset exists.
+ *
+ * @api
+ */
+ public function has($offset);
+
+ /**
+ * Sets a violation at a given offset.
+ *
+ * @param int $offset The violation offset.
+ * @param ConstraintViolationInterface $violation The violation.
+ *
+ * @api
+ */
+ public function set($offset, ConstraintViolationInterface $violation);
+
+ /**
+ * Removes a violation at a given offset.
+ *
+ * @param int $offset The offset to remove.
+ *
+ * @api
+ */
+ public function remove($offset);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AbstractComparison.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AbstractComparison.php
new file mode 100644
index 0000000..fb1f1f3
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AbstractComparison.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+/**
+ * Used for the comparison of values.
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+abstract class AbstractComparison extends Constraint
+{
+ public $message;
+ public $value;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct($options = null)
+ {
+ if (is_array($options) && !isset($options['value'])) {
+ throw new ConstraintDefinitionException(sprintf(
+ 'The %s constraint requires the "value" option to be set.',
+ get_class($this)
+ ));
+ }
+
+ parent::__construct($options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultOption()
+ {
+ return 'value';
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php
new file mode 100644
index 0000000..ec734b3
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Provides a base class for the validation of property comparisons.
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+abstract class AbstractComparisonValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof AbstractComparison) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\AbstractComparison');
+ }
+
+ if (null === $value) {
+ return;
+ }
+
+ $comparedValue = $constraint->value;
+
+ // Convert strings to DateTimes if comparing another DateTime
+ // This allows to compare with any date/time value supported by
+ // the DateTime constructor:
+ // http://php.net/manual/en/datetime.formats.php
+ if (is_string($comparedValue)) {
+ if ($value instanceof \DatetimeImmutable) {
+ // If $value is immutable, convert the compared value to a
+ // DateTimeImmutable too
+ $comparedValue = new \DatetimeImmutable($comparedValue);
+ } elseif ($value instanceof \DateTime || $value instanceof \DateTimeInterface) {
+ // Otherwise use DateTime
+ $comparedValue = new \DateTime($comparedValue);
+ }
+ }
+
+ if (!$this->compareValues($value, $comparedValue)) {
+ $this->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))
+ ->addViolation();
+ }
+ }
+
+ /**
+ * Compares the two given values to find if their relationship is valid.
+ *
+ * @param mixed $value1 The first value to compare
+ * @param mixed $value2 The second value to compare
+ *
+ * @return bool true if the relationship is valid, false otherwise
+ */
+ abstract protected function compareValues($value1, $value2);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/All.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/All.php
new file mode 100644
index 0000000..3250fcf
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/All.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class All extends Composite
+{
+ public $constraints = array();
+
+ public function getDefaultOption()
+ {
+ return 'constraints';
+ }
+
+ public function getRequiredOptions()
+ {
+ return array('constraints');
+ }
+
+ protected function getCompositeOption()
+ {
+ return 'constraints';
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AllValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AllValidator.php
new file mode 100644
index 0000000..a655afc
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AllValidator.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Context\ExecutionContextInterface;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class AllValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof All) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\All');
+ }
+
+ if (null === $value) {
+ return;
+ }
+
+ if (!is_array($value) && !$value instanceof \Traversable) {
+ throw new UnexpectedTypeException($value, 'array or Traversable');
+ }
+
+ $context = $this->context;
+
+ if ($context instanceof ExecutionContextInterface) {
+ $validator = $context->getValidator()->inContext($context);
+
+ foreach ($value as $key => $element) {
+ $validator->atPath('['.$key.']')->validate($element, $constraint->constraints);
+ }
+ } else {
+ // 2.4 API
+ foreach ($value as $key => $element) {
+ $context->validateValue($element, $constraint->constraints, '['.$key.']');
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Blank.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Blank.php
new file mode 100644
index 0000000..766ce6c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Blank.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Blank extends Constraint
+{
+ public $message = 'This value should be blank.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/BlankValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/BlankValidator.php
new file mode 100644
index 0000000..031c7a5
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/BlankValidator.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class BlankValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Blank) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Blank');
+ }
+
+ if ('' !== $value && null !== $value) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Callback.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Callback.php
new file mode 100644
index 0000000..312952a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Callback.php
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"CLASS", "PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Callback extends Constraint
+{
+ /**
+ * @var string|callable
+ *
+ * @since 2.4
+ */
+ public $callback;
+
+ /**
+ * @var array
+ *
+ * @deprecated Deprecated since version 2.4, to be removed in Symfony 3.0.
+ */
+ public $methods;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct($options = null)
+ {
+ // Invocation through annotations with an array parameter only
+ if (is_array($options) && 1 === count($options) && isset($options['value'])) {
+ $options = $options['value'];
+ }
+
+ if (is_array($options) && !isset($options['callback']) && !isset($options['methods']) && !isset($options['groups'])) {
+ if (is_callable($options)) {
+ $options = array('callback' => $options);
+ } else {
+ // BC with Symfony < 2.4
+ $options = array('methods' => $options);
+ }
+ }
+
+ parent::__construct($options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultOption()
+ {
+ return 'callback';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getTargets()
+ {
+ return array(self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CallbackValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CallbackValidator.php
new file mode 100644
index 0000000..9939306
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CallbackValidator.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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 <bschussek@gmail.com>
+ *
+ * @api
+ */
+class CallbackValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($object, Constraint $constraint)
+ {
+ if (!$constraint instanceof Callback) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Callback');
+ }
+
+ if (null !== $constraint->callback && null !== $constraint->methods) {
+ throw new ConstraintDefinitionException(
+ 'The Callback constraint supports either the option "callback" '.
+ 'or "methods", but not both at the same time.'
+ );
+ }
+
+ // has to be an array so that we can differentiate between callables
+ // and method names
+ if (null !== $constraint->methods && !is_array($constraint->methods)) {
+ throw new UnexpectedTypeException($constraint->methods, 'array');
+ }
+
+ $methods = $constraint->methods ?: array($constraint->callback);
+
+ foreach ($methods as $method) {
+ if ($method instanceof \Closure) {
+ $method($object, $this->context);
+ } elseif (is_array($method)) {
+ if (!is_callable($method)) {
+ throw new ConstraintDefinitionException(sprintf('"%s::%s" targeted by Callback constraint is not a valid callable', $method[0], $method[1]));
+ }
+
+ call_user_func($method, $object, $this->context);
+ } elseif (null !== $object) {
+ if (!method_exists($object, $method)) {
+ throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist', $method));
+ }
+
+ $reflMethod = new \ReflectionMethod($object, $method);
+
+ if ($reflMethod->isStatic()) {
+ $reflMethod->invoke(null, $object, $this->context);
+ } else {
+ $reflMethod->invoke($object, $this->context);
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardScheme.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardScheme.php
new file mode 100644
index 0000000..14f3b5d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardScheme.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Metadata for the CardSchemeValidator.
+ *
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Tim Nagel <t.nagel@infinite.net.au>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CardScheme extends Constraint
+{
+ const NOT_NUMERIC_ERROR = 1;
+ const INVALID_FORMAT_ERROR = 2;
+
+ protected static $errorNames = array(
+ self::NOT_NUMERIC_ERROR => 'NOT_NUMERIC_ERROR',
+ self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR',
+ );
+
+ public $message = 'Unsupported card type or invalid card number.';
+ public $schemes;
+
+ public function getDefaultOption()
+ {
+ return 'schemes';
+ }
+
+ public function getRequiredOptions()
+ {
+ return array('schemes');
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardSchemeValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardSchemeValidator.php
new file mode 100644
index 0000000..0e7de08
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardSchemeValidator.php
@@ -0,0 +1,122 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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 <t.nagel@infinite.net.au>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see http://en.wikipedia.org/wiki/Bank_card_number
+ * @see http://www.regular-expressions.info/creditcard.html
+ */
+class CardSchemeValidator extends ConstraintValidator
+{
+ protected $schemes = array(
+ // American Express card numbers start with 34 or 37 and have 15 digits.
+ 'AMEX' => array(
+ '/^3[47][0-9]{13}$/',
+ ),
+ // 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.
+ 'CHINA_UNIONPAY' => array(
+ '/^62[0-9]{14,17}$/',
+ ),
+ // 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.
+ 'DINERS' => array(
+ '/^3(?:0[0-5]|[68][0-9])[0-9]{11}$/',
+ ),
+ // Discover card numbers begin with 6011, 622126 through 622925, 644 through 649 or 65.
+ // All have 16 digits.
+ 'DISCOVER' => array(
+ '/^6011[0-9]{12}$/',
+ '/^64[4-9][0-9]{13}$/',
+ '/^65[0-9]{14}$/',
+ '/^622(12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|91[0-9]|92[0-5])[0-9]{10}$/',
+ ),
+ // InstaPayment cards begin with 637 through 639 and have 16 digits.
+ 'INSTAPAYMENT' => array(
+ '/^63[7-9][0-9]{13}$/',
+ ),
+ // JCB cards beginning with 2131 or 1800 have 15 digits.
+ // JCB cards beginning with 35 have 16 digits.
+ 'JCB' => array(
+ '/^(?:2131|1800|35[0-9]{3})[0-9]{11}$/',
+ ),
+ // Laser cards begin with either 6304, 6706, 6709 or 6771 and have between 16 and 19 digits.
+ 'LASER' => array(
+ '/^(6304|670[69]|6771)[0-9]{12,15}$/',
+ ),
+ // Maestro cards begin with either 5018, 5020, 5038, 5893, 6304, 6759, 6761, 6762, 6763 or 0604
+ // They have between 12 and 19 digits.
+ 'MAESTRO' => array(
+ '/^(5018|5020|5038|6304|6759|6761|676[23]|0604)[0-9]{8,15}$/',
+ ),
+ // All MasterCard numbers start with the numbers 51 through 55. All have 16 digits.
+ 'MASTERCARD' => array(
+ '/^5[1-5][0-9]{14}$/',
+ ),
+ // All Visa card numbers start with a 4. New cards have 16 digits. Old cards have 13.
+ 'VISA' => array(
+ '/^4([0-9]{12}|[0-9]{15})$/',
+ ),
+ );
+
+ /**
+ * Validates a creditcard belongs to a specified scheme.
+ *
+ * @param mixed $value
+ * @param Constraint $constraint
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof CardScheme) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\CardScheme');
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_numeric($value)) {
+ $this->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->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(CardScheme::INVALID_FORMAT_ERROR)
+ ->addViolation();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Choice.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Choice.php
new file mode 100644
index 0000000..39a6457
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Choice.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Choice extends Constraint
+{
+ const NO_SUCH_CHOICE_ERROR = 1;
+ const TOO_FEW_ERROR = 2;
+ const TOO_MANY_ERROR = 3;
+
+ protected static $errorNames = array(
+ self::NO_SUCH_CHOICE_ERROR => 'NO_SUCH_CHOICE_ERROR',
+ self::TOO_FEW_ERROR => 'TOO_FEW_ERROR',
+ self::TOO_MANY_ERROR => 'TOO_MANY_ERROR',
+ );
+
+ public $choices;
+ public $callback;
+ public $multiple = false;
+ public $strict = false;
+ 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.';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultOption()
+ {
+ return 'choices';
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ChoiceValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ChoiceValidator.php
new file mode 100644
index 0000000..cf5774c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ChoiceValidator.php
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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;
+
+/**
+ * ChoiceValidator validates that the value is one of the expected values.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Florian Eckerstorfer <florian@eckerstorfer.org>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class ChoiceValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Choice) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Choice');
+ }
+
+ if (!$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 UnexpectedTypeException($value, 'array');
+ }
+
+ if ($constraint->callback) {
+ if (!is_callable($choices = array($this->context->getClassName(), $constraint->callback))
+ && !is_callable($choices = $constraint->callback)
+ ) {
+ throw new ConstraintDefinitionException('The Choice constraint expects a valid callback');
+ }
+ $choices = call_user_func($choices);
+ } else {
+ $choices = $constraint->choices;
+ }
+
+ if ($constraint->multiple) {
+ foreach ($value as $_value) {
+ if (!in_array($_value, $choices, $constraint->strict)) {
+ $this->buildViolation($constraint->multipleMessage)
+ ->setParameter('{{ value }}', $this->formatValue($_value))
+ ->setCode(Choice::NO_SUCH_CHOICE_ERROR)
+ ->setInvalidValue($_value)
+ ->addViolation();
+
+ return;
+ }
+ }
+
+ $count = count($value);
+
+ if ($constraint->min !== null && $count < $constraint->min) {
+ $this->buildViolation($constraint->minMessage)
+ ->setParameter('{{ limit }}', $constraint->min)
+ ->setPlural((int) $constraint->min)
+ ->setCode(Choice::TOO_FEW_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ if ($constraint->max !== null && $count > $constraint->max) {
+ $this->buildViolation($constraint->maxMessage)
+ ->setParameter('{{ limit }}', $constraint->max)
+ ->setPlural((int) $constraint->max)
+ ->setCode(Choice::TOO_MANY_ERROR)
+ ->addViolation();
+
+ return;
+ }
+ } elseif (!in_array($value, $choices, $constraint->strict)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Choice::NO_SUCH_CHOICE_ERROR)
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection.php
new file mode 100644
index 0000000..708c8ed
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection.php
@@ -0,0 +1,87 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Collection extends Composite
+{
+ const MISSING_FIELD_ERROR = 1;
+ const NO_SUCH_FIELD_ERROR = 2;
+
+ protected static $errorNames = array(
+ self::MISSING_FIELD_ERROR => 'MISSING_FIELD_ERROR',
+ self::NO_SUCH_FIELD_ERROR => 'NO_SUCH_FIELD_ERROR',
+ );
+
+ public $fields = array();
+ public $allowExtraFields = false;
+ public $allowMissingFields = false;
+ public $extraFieldsMessage = 'This field was not expected.';
+ public $missingFieldsMessage = 'This field is missing.';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct($options = null)
+ {
+ // no known options set? $options is the fields array
+ if (is_array($options)
+ && !array_intersect(array_keys($options), array('groups', 'fields', 'allowExtraFields', 'allowMissingFields', 'extraFieldsMessage', 'missingFieldsMessage'))) {
+ $options = array('fields' => $options);
+ }
+
+ parent::__construct($options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ 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) && count($field) == 1) {
+ $this->fields[$fieldName] = $field = $field[0];
+ }
+
+ if (!$field instanceof Optional && !$field instanceof Required) {
+ $this->fields[$fieldName] = $field = new Required($field);
+ }
+ }
+ }
+
+ public function getRequiredOptions()
+ {
+ return array('fields');
+ }
+
+ protected function getCompositeOption()
+ {
+ return 'fields';
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Optional.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Optional.php
new file mode 100644
index 0000000..f7a9204
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Optional.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints\Collection;
+
+use Symfony\Component\Validator\Constraints\Optional as BaseOptional;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated in 2.3, to be removed in 3.0. Use
+ * {@link \Symfony\Component\Validator\Constraints\Optional} instead.
+ */
+class Optional extends BaseOptional
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Required.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Required.php
new file mode 100644
index 0000000..e358343
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Required.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints\Collection;
+
+use Symfony\Component\Validator\Constraints\Required as BaseRequired;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated in 2.3, to be removed in 3.0. Use
+ * {@link \Symfony\Component\Validator\Constraints\Required} instead.
+ */
+class Required extends BaseRequired
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CollectionValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CollectionValidator.php
new file mode 100644
index 0000000..c3180d2
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CollectionValidator.php
@@ -0,0 +1,94 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Context\ExecutionContextInterface;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class CollectionValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Collection) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Collection');
+ }
+
+ if (null === $value) {
+ return;
+ }
+
+ if (!is_array($value) && !($value instanceof \Traversable && $value instanceof \ArrayAccess)) {
+ throw new UnexpectedTypeException($value, 'array or Traversable and 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) {
+ // bug fix issue #2779
+ $existsInArray = is_array($value) && array_key_exists($field, $value);
+ $existsInArrayAccess = $value instanceof \ArrayAccess && $value->offsetExists($field);
+
+ if ($existsInArray || $existsInArrayAccess) {
+ if (count($fieldConstraint->constraints) > 0) {
+ if ($context instanceof ExecutionContextInterface) {
+ $context->getValidator()
+ ->inContext($context)
+ ->atPath('['.$field.']')
+ ->validate($value[$field], $fieldConstraint->constraints);
+ } else {
+ // 2.4 API
+ $context->validateValue($value[$field], $fieldConstraint->constraints, '['.$field.']');
+ }
+ }
+ } elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) {
+ $this->buildViolationInContext($context, $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])) {
+ $this->buildViolationInContext($context, $constraint->extraFieldsMessage)
+ ->atPath('['.$field.']')
+ ->setParameter('{{ field }}', $this->formatValue($field))
+ ->setInvalidValue($fieldValue)
+ ->setCode(Collection::NO_SUCH_FIELD_ERROR)
+ ->addViolation();
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Composite.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Composite.php
new file mode 100644
index 0000000..22a748c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Composite.php
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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.
+ *
+ * @since 2.6
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+abstract class Composite extends Constraint
+{
+ /**
+ * {@inheritdoc}
+ *
+ * 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($options = null)
+ {
+ parent::__construct($options);
+
+ $this->initializeNestedConstraints();
+
+ /** @var Constraint[] $nestedConstraints */
+ $compositeOption = $this->getCompositeOption();
+ $nestedConstraints = $this->$compositeOption;
+
+ if (!is_array($nestedConstraints)) {
+ $nestedConstraints = array($nestedConstraints);
+ }
+
+ foreach ($nestedConstraints as $constraint) {
+ if (!$constraint instanceof Constraint) {
+ throw new ConstraintDefinitionException(sprintf('The value %s is not an instance of Constraint in constraint %s', $constraint, get_class($this)));
+ }
+
+ 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.', get_class($this)));
+ }
+ }
+
+ if (!property_exists($this, 'groups')) {
+ $mergedGroups = array();
+
+ foreach ($nestedConstraints as $constraint) {
+ foreach ($constraint->groups as $group) {
+ $mergedGroups[$group] = true;
+ }
+ }
+
+ $this->groups = array_keys($mergedGroups);
+ $this->$compositeOption = $nestedConstraints;
+
+ return;
+ }
+
+ foreach ($nestedConstraints as $constraint) {
+ if (property_exists($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_class($constraint),
+ get_class($this)
+ ));
+ }
+ } else {
+ $constraint->groups = $this->groups;
+ }
+ }
+
+ $this->$compositeOption = $nestedConstraints;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * Implicit group names are forwarded to nested constraints.
+ *
+ * @param string $group
+ */
+ public function addImplicitGroupName($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.
+ *
+ * @return string The property name
+ */
+ abstract protected function 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()
+ */
+ protected function initializeNestedConstraints()
+ {
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Count.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Count.php
new file mode 100644
index 0000000..a3e12fe
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Count.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\MissingOptionsException;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Count extends Constraint
+{
+ const TOO_FEW_ERROR = 1;
+ const TOO_MANY_ERROR = 2;
+
+ protected static $errorNames = array(
+ self::TOO_FEW_ERROR => 'TOO_FEW_ERROR',
+ self::TOO_MANY_ERROR => 'TOO_MANY_ERROR',
+ );
+
+ 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 $min;
+ public $max;
+
+ public function __construct($options = null)
+ {
+ if (null !== $options && !is_array($options)) {
+ $options = array(
+ 'min' => $options,
+ 'max' => $options,
+ );
+ }
+
+ parent::__construct($options);
+
+ if (null === $this->min && null === $this->max) {
+ throw new MissingOptionsException(sprintf('Either option "min" or "max" must be given for constraint %s', __CLASS__), array('min', 'max'));
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountValidator.php
new file mode 100644
index 0000000..d44f537
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountValidator.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CountValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (null === $value) {
+ return;
+ }
+
+ if (!is_array($value) && !$value instanceof \Countable) {
+ throw new UnexpectedTypeException($value, 'array or \Countable');
+ }
+
+ $count = count($value);
+
+ if (null !== $constraint->max && $count > $constraint->max) {
+ $this->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->maxMessage)
+ ->setParameter('{{ count }}', $count)
+ ->setParameter('{{ limit }}', $constraint->max)
+ ->setInvalidValue($value)
+ ->setPlural((int) $constraint->max)
+ ->setCode(Count::TOO_MANY_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ if (null !== $constraint->min && $count < $constraint->min) {
+ $this->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->minMessage)
+ ->setParameter('{{ count }}', $count)
+ ->setParameter('{{ limit }}', $constraint->min)
+ ->setInvalidValue($value)
+ ->setPlural((int) $constraint->min)
+ ->setCode(Count::TOO_FEW_ERROR)
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Country.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Country.php
new file mode 100644
index 0000000..ff6f3d0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Country.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Country extends Constraint
+{
+ public $message = 'This value is not a valid country.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountryValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountryValidator.php
new file mode 100644
index 0000000..0d001f7
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountryValidator.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Intl\Intl;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether a value is a valid country code.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class CountryValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Country) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Country');
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+ $countries = Intl::getRegionBundle()->getCountryNames();
+
+ if (!isset($countries[$value])) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Currency.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Currency.php
new file mode 100644
index 0000000..c09fe88
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Currency.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Miha Vrhovnik <miha.vrhovnik@pagein.si>
+ *
+ * @api
+ */
+class Currency extends Constraint
+{
+ public $message = 'This value is not a valid currency.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CurrencyValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CurrencyValidator.php
new file mode 100644
index 0000000..5585426
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CurrencyValidator.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Intl\Intl;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether a value is a valid currency.
+ *
+ * @author Miha Vrhovnik <miha.vrhovnik@pagein.si>
+ *
+ * @api
+ */
+class CurrencyValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Currency) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Currency');
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+ $currencies = Intl::getCurrencyBundle()->getCurrencyNames();
+
+ if (!isset($currencies[$value])) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Date.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Date.php
new file mode 100644
index 0000000..2bc444f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Date.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Date extends Constraint
+{
+ const INVALID_FORMAT_ERROR = 1;
+ const INVALID_DATE_ERROR = 2;
+
+ protected static $errorNames = array(
+ self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR',
+ self::INVALID_DATE_ERROR => 'INVALID_DATE_ERROR',
+ );
+
+ public $message = 'This value is not a valid date.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTime.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTime.php
new file mode 100644
index 0000000..ae67ff3
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTime.php
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class DateTime extends Constraint
+{
+ const INVALID_FORMAT_ERROR = 1;
+ const INVALID_DATE_ERROR = 2;
+ const INVALID_TIME_ERROR = 3;
+
+ protected static $errorNames = array(
+ self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR',
+ self::INVALID_DATE_ERROR => 'INVALID_DATE_ERROR',
+ self::INVALID_TIME_ERROR => 'INVALID_TIME_ERROR',
+ );
+
+ public $message = 'This value is not a valid datetime.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTimeValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTimeValidator.php
new file mode 100644
index 0000000..b459c78
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTimeValidator.php
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class DateTimeValidator extends DateValidator
+{
+ const PATTERN = '/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof DateTime) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\DateTime');
+ }
+
+ if (null === $value || '' === $value || $value instanceof \DateTime) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+
+ if (!preg_match(static::PATTERN, $value, $matches)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(DateTime::INVALID_FORMAT_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ if (!DateValidator::checkDate($matches[1], $matches[2], $matches[3])) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(DateTime::INVALID_DATE_ERROR)
+ ->addViolation();
+ }
+
+ if (!TimeValidator::checkTime($matches[4], $matches[5], $matches[6])) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(DateTime::INVALID_TIME_ERROR)
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateValidator.php
new file mode 100644
index 0000000..77f0111
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateValidator.php
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class DateValidator extends ConstraintValidator
+{
+ const PATTERN = '/^(\d{4})-(\d{2})-(\d{2})$/';
+
+ /**
+ * Checks whether a date is valid.
+ *
+ * @param int $year The year
+ * @param int $month The month
+ * @param int $day The day
+ *
+ * @return bool Whether the date is valid
+ *
+ * @internal
+ */
+ public static function checkDate($year, $month, $day)
+ {
+ return checkdate($month, $day, $year);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Date) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Date');
+ }
+
+ if (null === $value || '' === $value || $value instanceof \DateTime) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+
+ if (!preg_match(static::PATTERN, $value, $matches)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Date::INVALID_FORMAT_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ if (!self::checkDate($matches[1], $matches[2], $matches[3])) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Date::INVALID_DATE_ERROR)
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Email.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Email.php
new file mode 100644
index 0000000..3697717
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Email.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Email extends Constraint
+{
+ const INVALID_FORMAT_ERROR = 1;
+ const MX_CHECK_FAILED_ERROR = 2;
+ const HOST_CHECK_FAILED_ERROR = 3;
+
+ protected static $errorNames = array(
+ self::INVALID_FORMAT_ERROR => 'STRICT_CHECK_FAILED_ERROR',
+ self::MX_CHECK_FAILED_ERROR => 'MX_CHECK_FAILED_ERROR',
+ self::HOST_CHECK_FAILED_ERROR => 'HOST_CHECK_FAILED_ERROR',
+ );
+
+ public $message = 'This value is not a valid email address.';
+ public $checkMX = false;
+ public $checkHost = false;
+ public $strict;
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/EmailValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/EmailValidator.php
new file mode 100644
index 0000000..8d3a7c5
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/EmailValidator.php
@@ -0,0 +1,130 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\RuntimeException;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class EmailValidator extends ConstraintValidator
+{
+ /**
+ * isStrict
+ *
+ * @var bool
+ */
+ private $isStrict;
+
+ public function __construct($strict = false)
+ {
+ $this->isStrict = $strict;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Email) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Email');
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+
+ if (null === $constraint->strict) {
+ $constraint->strict = $this->isStrict;
+ }
+
+ if ($constraint->strict) {
+ if (!class_exists('\Egulias\EmailValidator\EmailValidator')) {
+ throw new RuntimeException('Strict email validation requires egulias/email-validator');
+ }
+
+ $strictValidator = new \Egulias\EmailValidator\EmailValidator();
+
+ if (!$strictValidator->isValid($value, false, true)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Email::INVALID_FORMAT_ERROR)
+ ->addViolation();
+
+ return;
+ }
+ } elseif (!preg_match('/.+\@.+\..+/', $value)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Email::INVALID_FORMAT_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ $host = substr($value, strpos($value, '@') + 1);
+
+ // Check for host DNS resource records
+ if ($constraint->checkMX) {
+ if (!$this->checkMX($host)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Email::MX_CHECK_FAILED_ERROR)
+ ->addViolation();
+ }
+
+ return;
+ }
+
+ if ($constraint->checkHost && !$this->checkHost($host)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Email::HOST_CHECK_FAILED_ERROR)
+ ->addViolation();
+ }
+ }
+
+ /**
+ * Check DNS Records for MX type.
+ *
+ * @param string $host Host
+ *
+ * @return bool
+ */
+ private function checkMX($host)
+ {
+ return checkdnsrr($host, 'MX');
+ }
+
+ /**
+ * Check if one of MX, A or AAAA DNS RR exists.
+ *
+ * @param string $host Host
+ *
+ * @return bool
+ */
+ private function checkHost($host)
+ {
+ return $this->checkMX($host) || (checkdnsrr($host, 'A') || checkdnsrr($host, 'AAAA'));
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/EqualTo.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/EqualTo.php
new file mode 100644
index 0000000..8d3d752
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/EqualTo.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class EqualTo extends AbstractComparison
+{
+ public $message = 'This value should be equal to {{ compared_value }}.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/EqualToValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/EqualToValidator.php
new file mode 100644
index 0000000..3739dbe
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/EqualToValidator.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * Validates values are equal (==).
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class EqualToValidator extends AbstractComparisonValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function compareValues($value1, $value2)
+ {
+ return $value1 == $value2;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Existence.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Existence.php
new file mode 100644
index 0000000..5ea6ffe
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Existence.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+abstract class Existence extends Composite
+{
+ public $constraints = array();
+
+ public function getDefaultOption()
+ {
+ return 'constraints';
+ }
+
+ protected function getCompositeOption()
+ {
+ return 'constraints';
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Expression.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Expression.php
new file mode 100644
index 0000000..dfa242c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Expression.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"CLASS", "PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class Expression extends Constraint
+{
+ public $message = 'This value is not valid.';
+ public $expression;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultOption()
+ {
+ return 'expression';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRequiredOptions()
+ {
+ return array('expression');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getTargets()
+ {
+ return array(self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validatedBy()
+ {
+ return 'validator.expression';
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ExpressionValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ExpressionValidator.php
new file mode 100644
index 0000000..fd3e903
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ExpressionValidator.php
@@ -0,0 +1,117 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
+use Symfony\Component\PropertyAccess\PropertyAccess;
+use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
+use Symfony\Component\PropertyAccess\PropertyPath;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Context\ExecutionContextInterface;
+use Symfony\Component\Validator\Exception\RuntimeException;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bernhard Schussek <bschussek@symfony.com>
+ */
+class ExpressionValidator extends ConstraintValidator
+{
+ /**
+ * @var PropertyAccessorInterface
+ */
+ private $propertyAccessor;
+
+ /**
+ * @var ExpressionLanguage
+ */
+ private $expressionLanguage;
+
+ /**
+ * @param PropertyAccessorInterface|null $propertyAccessor Optional as of Symfony 2.5
+ *
+ * @throws UnexpectedTypeException If the property accessor is invalid
+ */
+ public function __construct($propertyAccessor = null)
+ {
+ if (null !== $propertyAccessor && !$propertyAccessor instanceof PropertyAccessorInterface) {
+ throw new UnexpectedTypeException($propertyAccessor, 'null or \Symfony\Component\PropertyAccess\PropertyAccessorInterface');
+ }
+
+ $this->propertyAccessor = $propertyAccessor;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Expression) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Expression');
+ }
+
+ $variables = array();
+
+ // Symfony 2.5+
+ if ($this->context instanceof ExecutionContextInterface) {
+ $variables['value'] = $value;
+ $variables['this'] = $this->context->getObject();
+ } elseif (null === $this->context->getPropertyName()) {
+ $variables['value'] = $value;
+ $variables['this'] = $value;
+ } else {
+ $root = $this->context->getRoot();
+ $variables['value'] = $value;
+
+ if (is_object($root)) {
+ // Extract the object that the property belongs to from the object
+ // graph
+ $path = new PropertyPath($this->context->getPropertyPath());
+ $parentPath = $path->getParent();
+ $variables['this'] = $parentPath ? $this->getPropertyAccessor()->getValue($root, $parentPath) : $root;
+ } else {
+ $variables['this'] = null;
+ }
+ }
+
+ if (!$this->getExpressionLanguage()->evaluate($constraint->expression, $variables)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->addViolation();
+ }
+ }
+
+ private function getExpressionLanguage()
+ {
+ if (null === $this->expressionLanguage) {
+ if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
+ throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
+ }
+ $this->expressionLanguage = new ExpressionLanguage();
+ }
+
+ return $this->expressionLanguage;
+ }
+
+ private function getPropertyAccessor()
+ {
+ if (null === $this->propertyAccessor) {
+ if (!class_exists('Symfony\Component\PropertyAccess\PropertyAccess')) {
+ throw new RuntimeException('Unable to use expressions as the Symfony PropertyAccess component is not installed.');
+ }
+ $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
+ }
+
+ return $this->propertyAccessor;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/False.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/False.php
new file mode 100644
index 0000000..fc2e3e4
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/False.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class False extends Constraint
+{
+ public $message = 'This value should be false.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/FalseValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/FalseValidator.php
new file mode 100644
index 0000000..206780c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/FalseValidator.php
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class FalseValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof False) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\False');
+ }
+
+ if (null === $value || false === $value || 0 === $value || '0' === $value) {
+ return;
+ }
+
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->addViolation();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/File.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/File.php
new file mode 100644
index 0000000..ae0ad67
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/File.php
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class File extends Constraint
+{
+ // Check the Image constraint for clashes if adding new constants here
+
+ const NOT_FOUND_ERROR = 1;
+ const NOT_READABLE_ERROR = 2;
+ const EMPTY_ERROR = 3;
+ const TOO_LARGE_ERROR = 4;
+ const INVALID_MIME_TYPE_ERROR = 5;
+
+ protected static $errorNames = array(
+ 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',
+ );
+
+ public $maxSize;
+ public $binaryFormat;
+ public $mimeTypes = array();
+ 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 $disallowEmptyMessage = 'An empty file is not allowed.';
+
+ 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.';
+
+ public function __construct($options = null)
+ {
+ parent::__construct($options);
+
+ if ($this->maxSize) {
+ if (ctype_digit((string) $this->maxSize)) {
+ $this->maxSize = (int) $this->maxSize;
+ $this->binaryFormat = null === $this->binaryFormat ? false : $this->binaryFormat;
+ } elseif (preg_match('/^\d++k$/i', $this->maxSize)) {
+ $this->maxSize = $this->maxSize * 1000;
+ $this->binaryFormat = null === $this->binaryFormat ? false : $this->binaryFormat;
+ } elseif (preg_match('/^\d++M$/i', $this->maxSize)) {
+ $this->maxSize = $this->maxSize * 1000000;
+ $this->binaryFormat = null === $this->binaryFormat ? false : $this->binaryFormat;
+ } elseif (preg_match('/^\d++Ki$/i', $this->maxSize)) {
+ $this->maxSize = $this->maxSize << 10;
+ $this->binaryFormat = null === $this->binaryFormat ? true : $this->binaryFormat;
+ } elseif (preg_match('/^\d++Mi$/i', $this->maxSize)) {
+ $this->maxSize = $this->maxSize << 20;
+ $this->binaryFormat = null === $this->binaryFormat ? true : $this->binaryFormat;
+ } else {
+ throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum size', $this->maxSize));
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/FileValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/FileValidator.php
new file mode 100644
index 0000000..9d225a9
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/FileValidator.php
@@ -0,0 +1,240 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\HttpFoundation\File\File as FileObject;
+use Symfony\Component\HttpFoundation\File\UploadedFile;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class FileValidator extends ConstraintValidator
+{
+ const KB_BYTES = 1000;
+ const MB_BYTES = 1000000;
+ const KIB_BYTES = 1024;
+ const MIB_BYTES = 1048576;
+
+ private static $suffices = array(
+ 1 => 'bytes',
+ self::KB_BYTES => 'kB',
+ self::MB_BYTES => 'MB',
+ self::KIB_BYTES => 'KiB',
+ self::MIB_BYTES => 'MiB',
+ );
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof File) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\File');
+ }
+
+ 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 = true;
+ }
+
+ list($sizeAsString, $limitAsString, $suffix) = $this->factorizeSizes(0, $limitInBytes, $binaryFormat);
+ $this->buildViolation($constraint->uploadIniSizeErrorMessage)
+ ->setParameter('{{ limit }}', $limitAsString)
+ ->setParameter('{{ suffix }}', $suffix)
+ ->setCode(UPLOAD_ERR_INI_SIZE)
+ ->addViolation();
+
+ return;
+ case UPLOAD_ERR_FORM_SIZE:
+ $this->buildViolation($constraint->uploadFormSizeErrorMessage)
+ ->setCode(UPLOAD_ERR_FORM_SIZE)
+ ->addViolation();
+
+ return;
+ case UPLOAD_ERR_PARTIAL:
+ $this->buildViolation($constraint->uploadPartialErrorMessage)
+ ->setCode(UPLOAD_ERR_PARTIAL)
+ ->addViolation();
+
+ return;
+ case UPLOAD_ERR_NO_FILE:
+ $this->buildViolation($constraint->uploadNoFileErrorMessage)
+ ->setCode(UPLOAD_ERR_NO_FILE)
+ ->addViolation();
+
+ return;
+ case UPLOAD_ERR_NO_TMP_DIR:
+ $this->buildViolation($constraint->uploadNoTmpDirErrorMessage)
+ ->setCode(UPLOAD_ERR_NO_TMP_DIR)
+ ->addViolation();
+
+ return;
+ case UPLOAD_ERR_CANT_WRITE:
+ $this->buildViolation($constraint->uploadCantWriteErrorMessage)
+ ->setCode(UPLOAD_ERR_CANT_WRITE)
+ ->addViolation();
+
+ return;
+ case UPLOAD_ERR_EXTENSION:
+ $this->buildViolation($constraint->uploadExtensionErrorMessage)
+ ->setCode(UPLOAD_ERR_EXTENSION)
+ ->addViolation();
+
+ return;
+ default:
+ $this->buildViolation($constraint->uploadErrorMessage)
+ ->setCode($value->getError())
+ ->addViolation();
+
+ return;
+ }
+ }
+
+ if (!is_scalar($value) && !$value instanceof FileObject && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $path = $value instanceof FileObject ? $value->getPathname() : (string) $value;
+
+ if (!is_file($path)) {
+ $this->buildViolation($constraint->notFoundMessage)
+ ->setParameter('{{ file }}', $this->formatValue($path))
+ ->setCode(File::NOT_FOUND_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ if (!is_readable($path)) {
+ $this->buildViolation($constraint->notReadableMessage)
+ ->setParameter('{{ file }}', $this->formatValue($path))
+ ->setCode(File::NOT_READABLE_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ $sizeInBytes = filesize($path);
+
+ if (0 === $sizeInBytes) {
+ $this->buildViolation($constraint->disallowEmptyMessage)
+ ->setParameter('{{ file }}', $this->formatValue($path))
+ ->setCode(File::EMPTY_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ if ($constraint->maxSize) {
+ $limitInBytes = $constraint->maxSize;
+
+ if ($sizeInBytes > $limitInBytes) {
+ list($sizeAsString, $limitAsString, $suffix) = $this->factorizeSizes($sizeInBytes, $limitInBytes, $constraint->binaryFormat);
+ $this->buildViolation($constraint->maxSizeMessage)
+ ->setParameter('{{ file }}', $this->formatValue($path))
+ ->setParameter('{{ size }}', $sizeAsString)
+ ->setParameter('{{ limit }}', $limitAsString)
+ ->setParameter('{{ suffix }}', $suffix)
+ ->setCode(File::TOO_LARGE_ERROR)
+ ->addViolation();
+
+ return;
+ }
+ }
+
+ if ($constraint->mimeTypes) {
+ if (!$value instanceof FileObject) {
+ $value = new FileObject($value);
+ }
+
+ $mimeTypes = (array) $constraint->mimeTypes;
+ $mime = $value->getMimeType();
+
+ foreach ($mimeTypes as $mimeType) {
+ if ($mimeType === $mime) {
+ return;
+ }
+
+ if ($discrete = strstr($mimeType, '/*', true)) {
+ if (strstr($mime, '/', true) === $discrete) {
+ return;
+ }
+ }
+ }
+
+ $this->buildViolation($constraint->mimeTypesMessage)
+ ->setParameter('{{ file }}', $this->formatValue($path))
+ ->setParameter('{{ type }}', $this->formatValue($mime))
+ ->setParameter('{{ types }}', $this->formatValues($mimeTypes))
+ ->setCode(File::INVALID_MIME_TYPE_ERROR)
+ ->addViolation();
+ }
+ }
+
+ private static function moreDecimalsThan($double, $numberOfDecimals)
+ {
+ return strlen((string) $double) > strlen(round($double, $numberOfDecimals));
+ }
+
+ /**
+ * Convert the limit to the smallest possible number
+ * (i.e. try "MB", then "kB", then "bytes")
+ */
+ private function factorizeSizes($size, $limit, $binaryFormat)
+ {
+ if ($binaryFormat) {
+ $coef = self::MIB_BYTES;
+ $coefFactor = self::KIB_BYTES;
+ } else {
+ $coef = self::MB_BYTES;
+ $coefFactor = self::KB_BYTES;
+ }
+
+ $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 array($sizeAsString, $limitAsString, self::$suffices[$coef]);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThan.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThan.php
new file mode 100644
index 0000000..ec7fafb
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThan.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class GreaterThan extends AbstractComparison
+{
+ public $message = 'This value should be greater than {{ compared_value }}.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanOrEqual.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanOrEqual.php
new file mode 100644
index 0000000..36fdd9c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanOrEqual.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class GreaterThanOrEqual extends AbstractComparison
+{
+ public $message = 'This value should be greater than or equal to {{ compared_value }}.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanOrEqualValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanOrEqualValidator.php
new file mode 100644
index 0000000..2363204
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanOrEqualValidator.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * Validates values are greater than or equal to the previous (>=).
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class GreaterThanOrEqualValidator extends AbstractComparisonValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function compareValues($value1, $value2)
+ {
+ return $value1 >= $value2;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanValidator.php
new file mode 100644
index 0000000..fdcf0c1
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GreaterThanValidator.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * Validates values are greater than the previous (>).
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class GreaterThanValidator extends AbstractComparisonValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function compareValues($value1, $value2)
+ {
+ return $value1 > $value2;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequence.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequence.php
new file mode 100644
index 0000000..72bfb16
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequence.php
@@ -0,0 +1,196 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Exception\OutOfBoundsException;
+
+/**
+ * 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 <bschussek@gmail.com>
+ *
+ * @api
+ *
+ * Implementing \ArrayAccess, \IteratorAggregate and \Countable is @deprecated since 2.5 and will be removed in 3.0.
+ */
+class GroupSequence implements \ArrayAccess, \IteratorAggregate, \Countable
+{
+ /**
+ * The groups in the sequence.
+ *
+ * @var string[]|GroupSequence[]
+ */
+ 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 string[] $groups The groups in the sequence
+ */
+ public function __construct(array $groups)
+ {
+ // Support for Doctrine annotations
+ $this->groups = isset($groups['value']) ? $groups['value'] : $groups;
+ }
+
+ /**
+ * Returns an iterator for this group.
+ *
+ * @return \Traversable The iterator
+ *
+ * @see \IteratorAggregate::getIterator()
+ *
+ * @deprecated Implemented for backwards compatibility with Symfony < 2.5.
+ * To be removed in Symfony 3.0.
+ */
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->groups);
+ }
+
+ /**
+ * Returns whether the given offset exists in the sequence.
+ *
+ * @param int $offset The offset
+ *
+ * @return bool Whether the offset exists
+ *
+ * @deprecated Implemented for backwards compatibility with Symfony < 2.5.
+ * To be removed in Symfony 3.0.
+ */
+ public function offsetExists($offset)
+ {
+ return isset($this->groups[$offset]);
+ }
+
+ /**
+ * Returns the group at the given offset.
+ *
+ * @param int $offset The offset
+ *
+ * @return string The group a the given offset
+ *
+ * @throws OutOfBoundsException If the object does not exist
+ *
+ * @deprecated Implemented for backwards compatibility with Symfony < 2.5.
+ * To be removed in Symfony 3.0.
+ */
+ public function offsetGet($offset)
+ {
+ if (!isset($this->groups[$offset])) {
+ throw new OutOfBoundsException(sprintf(
+ 'The offset "%s" does not exist.',
+ $offset
+ ));
+ }
+
+ return $this->groups[$offset];
+ }
+
+ /**
+ * Sets the group at the given offset.
+ *
+ * @param int $offset The offset
+ * @param string $value The group name
+ *
+ * @deprecated Implemented for backwards compatibility with Symfony < 2.5.
+ * To be removed in Symfony 3.0.
+ */
+ public function offsetSet($offset, $value)
+ {
+ if (null !== $offset) {
+ $this->groups[$offset] = $value;
+
+ return;
+ }
+
+ $this->groups[] = $value;
+ }
+
+ /**
+ * Removes the group at the given offset.
+ *
+ * @param int $offset The offset
+ *
+ * @deprecated Implemented for backwards compatibility with Symfony < 2.5.
+ * To be removed in Symfony 3.0.
+ */
+ public function offsetUnset($offset)
+ {
+ unset($this->groups[$offset]);
+ }
+
+ /**
+ * Returns the number of groups in the sequence.
+ *
+ * @return int The number of groups
+ *
+ * @deprecated Implemented for backwards compatibility with Symfony < 2.5.
+ * To be removed in Symfony 3.0.
+ */
+ public function count()
+ {
+ return count($this->groups);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php
new file mode 100644
index 0000000..3904473
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * Annotation to define a group sequence provider.
+ *
+ * @Annotation
+ * @Target({"CLASS", "ANNOTATION"})
+ */
+class GroupSequenceProvider
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Iban.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Iban.php
new file mode 100644
index 0000000..66ce09a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Iban.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Manuel Reinhard <manu@sprain.ch>
+ * @author Michael Schummel
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class Iban extends Constraint
+{
+ const TOO_SHORT_ERROR = 1;
+ const INVALID_COUNTRY_CODE_ERROR = 2;
+ const INVALID_CHARACTERS_ERROR = 3;
+ const INVALID_CASE_ERROR = 4;
+ const CHECKSUM_FAILED_ERROR = 5;
+
+ protected static $errorNames = array(
+ self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR',
+ self::INVALID_COUNTRY_CODE_ERROR => 'INVALID_COUNTRY_CODE_ERROR',
+ self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR',
+ self::INVALID_CASE_ERROR => 'INVALID_CASE_ERROR',
+ self::CHECKSUM_FAILED_ERROR => 'CHECKSUM_FAILED_ERROR',
+ );
+
+ public $message = 'This is not a valid International Bank Account Number (IBAN).';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IbanValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IbanValidator.php
new file mode 100644
index 0000000..35995d2
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IbanValidator.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Manuel Reinhard <manu@sprain.ch>
+ * @author Michael Schummel
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @link http://www.michael-schummel.de/2007/10/05/iban-prufung-mit-php/
+ */
+class IbanValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Iban) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Iban');
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+
+ // Remove spaces
+ $canonicalized = str_replace(' ', '', $value);
+
+ // The IBAN must have at least 4 characters...
+ if (strlen($canonicalized) < 4) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Iban::TOO_SHORT_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ // ...start with a country code...
+ if (!ctype_alpha($canonicalized{0}) || !ctype_alpha($canonicalized{1})) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Iban::INVALID_COUNTRY_CODE_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ // ...contain only digits and characters...
+ if (!ctype_alnum($canonicalized)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Iban::INVALID_CHARACTERS_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ // ...and contain uppercase characters only
+ if ($canonicalized !== strtoupper($canonicalized)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Iban::INVALID_CASE_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 = $this->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 !== $this->bigModulo97($checkSum)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Iban::CHECKSUM_FAILED_ERROR)
+ ->addViolation();
+ }
+ }
+
+ private function toBigInt($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 function bigModulo97($bigInt)
+ {
+ $parts = str_split($bigInt, 7);
+ $rest = 0;
+
+ foreach ($parts as $part) {
+ $rest = ($rest.$part) % 97;
+ }
+
+ return $rest;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IdenticalTo.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IdenticalTo.php
new file mode 100644
index 0000000..6d00286
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IdenticalTo.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class IdenticalTo extends AbstractComparison
+{
+ public $message = 'This value should be identical to {{ compared_value_type }} {{ compared_value }}.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IdenticalToValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IdenticalToValidator.php
new file mode 100644
index 0000000..a186726
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IdenticalToValidator.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * Validates values are identical (===).
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class IdenticalToValidator extends AbstractComparisonValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function compareValues($value1, $value2)
+ {
+ return $value1 === $value2;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Image.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Image.php
new file mode 100644
index 0000000..904ef97
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Image.php
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Benjamin Dulau <benjamin.dulau@gmail.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Image extends File
+{
+ // Don't reuse values used in File
+
+ const SIZE_NOT_DETECTED_ERROR = 10;
+ const TOO_WIDE_ERROR = 11;
+ const TOO_NARROW_ERROR = 12;
+ const TOO_HIGH_ERROR = 13;
+ const TOO_LOW_ERROR = 14;
+ const RATIO_TOO_BIG_ERROR = 15;
+ const RATIO_TOO_SMALL_ERROR = 16;
+ const SQUARE_NOT_ALLOWED_ERROR = 17;
+ const LANDSCAPE_NOT_ALLOWED_ERROR = 18;
+ const PORTRAIT_NOT_ALLOWED_ERROR = 19;
+
+ // Include the mapping from the base class
+
+ protected static $errorNames = array(
+ 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::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::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',
+ );
+
+ public $mimeTypes = 'image/*';
+ public $minWidth;
+ public $maxWidth;
+ public $maxHeight;
+ public $minHeight;
+ public $maxRatio;
+ public $minRatio;
+ public $allowSquare = true;
+ public $allowLandscape = true;
+ public $allowPortrait = true;
+
+ // 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 $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.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ImageValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ImageValidator.php
new file mode 100644
index 0000000..e183e27
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ImageValidator.php
@@ -0,0 +1,182 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+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 <benjamin.dulau@gmail.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ImageValidator extends FileValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Image) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Image');
+ }
+
+ $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->minRatio && null === $constraint->maxRatio
+ && $constraint->allowSquare && $constraint->allowLandscape && $constraint->allowPortrait) {
+ return;
+ }
+
+ $size = @getimagesize($value);
+
+ if (empty($size) || ($size[0] === 0) || ($size[1] === 0)) {
+ $this->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->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->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->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->buildViolation($constraint->maxHeightMessage)
+ ->setParameter('{{ height }}', $height)
+ ->setParameter('{{ max_height }}', $constraint->maxHeight)
+ ->setCode(Image::TOO_HIGH_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 < $constraint->minRatio) {
+ $this->buildViolation($constraint->minRatioMessage)
+ ->setParameter('{{ ratio }}', $ratio)
+ ->setParameter('{{ min_ratio }}', $constraint->minRatio)
+ ->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 > $constraint->maxRatio) {
+ $this->buildViolation($constraint->maxRatioMessage)
+ ->setParameter('{{ ratio }}', $ratio)
+ ->setParameter('{{ max_ratio }}', $constraint->maxRatio)
+ ->setCode(Image::RATIO_TOO_BIG_ERROR)
+ ->addViolation();
+ }
+ }
+
+ if (!$constraint->allowSquare && $width == $height) {
+ $this->buildViolation($constraint->allowSquareMessage)
+ ->setParameter('{{ width }}', $width)
+ ->setParameter('{{ height }}', $height)
+ ->setCode(Image::SQUARE_NOT_ALLOWED_ERROR)
+ ->addViolation();
+ }
+
+ if (!$constraint->allowLandscape && $width > $height) {
+ $this->buildViolation($constraint->allowLandscapeMessage)
+ ->setParameter('{{ width }}', $width)
+ ->setParameter('{{ height }}', $height)
+ ->setCode(Image::LANDSCAPE_NOT_ALLOWED_ERROR)
+ ->addViolation();
+ }
+
+ if (!$constraint->allowPortrait && $width < $height) {
+ $this->buildViolation($constraint->allowPortraitMessage)
+ ->setParameter('{{ width }}', $width)
+ ->setParameter('{{ height }}', $height)
+ ->setCode(Image::PORTRAIT_NOT_ALLOWED_ERROR)
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Ip.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Ip.php
new file mode 100644
index 0000000..27f0b2d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Ip.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+/**
+ * Validates that a value is a valid IP address.
+ *
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @author Joseph Bielawski <stloyd@gmail.com>
+ *
+ * @api
+ */
+class Ip extends Constraint
+{
+ const V4 = '4';
+ const V6 = '6';
+ const ALL = 'all';
+
+ // adds FILTER_FLAG_NO_PRIV_RANGE flag (skip private ranges)
+ const V4_NO_PRIV = '4_no_priv';
+ const V6_NO_PRIV = '6_no_priv';
+ const ALL_NO_PRIV = 'all_no_priv';
+
+ // adds FILTER_FLAG_NO_RES_RANGE flag (skip reserved ranges)
+ const V4_NO_RES = '4_no_res';
+ const V6_NO_RES = '6_no_res';
+ const ALL_NO_RES = 'all_no_res';
+
+ // adds FILTER_FLAG_NO_PRIV_RANGE and FILTER_FLAG_NO_RES_RANGE flags (skip both)
+ const V4_ONLY_PUBLIC = '4_public';
+ const V6_ONLY_PUBLIC = '6_public';
+ const ALL_ONLY_PUBLIC = 'all_public';
+
+ protected static $versions = array(
+ 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,
+ );
+
+ public $version = self::V4;
+
+ public $message = 'This is not a valid IP address.';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct($options = null)
+ {
+ parent::__construct($options);
+
+ if (!in_array($this->version, self::$versions)) {
+ throw new ConstraintDefinitionException(sprintf('The option "version" must be one of "%s"', implode('", "', self::$versions)));
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IpValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IpValidator.php
new file mode 100644
index 0000000..2bbe7e4
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IpValidator.php
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether a value is a valid IP address.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @author Joseph Bielawski <stloyd@gmail.com>
+ *
+ * @api
+ */
+class IpValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Ip) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Ip');
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+
+ switch ($constraint->version) {
+ case Ip::V4:
+ $flag = FILTER_FLAG_IPV4;
+ break;
+
+ case Ip::V6:
+ $flag = FILTER_FLAG_IPV6;
+ break;
+
+ case Ip::V4_NO_PRIV:
+ $flag = FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE;
+ break;
+
+ case Ip::V6_NO_PRIV:
+ $flag = FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE;
+ break;
+
+ case Ip::ALL_NO_PRIV:
+ $flag = FILTER_FLAG_NO_PRIV_RANGE;
+ break;
+
+ case Ip::V4_NO_RES:
+ $flag = FILTER_FLAG_IPV4 | FILTER_FLAG_NO_RES_RANGE;
+ break;
+
+ case Ip::V6_NO_RES:
+ $flag = FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE;
+ break;
+
+ case Ip::ALL_NO_RES:
+ $flag = FILTER_FLAG_NO_RES_RANGE;
+ break;
+
+ case Ip::V4_ONLY_PUBLIC:
+ $flag = FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
+ break;
+
+ case Ip::V6_ONLY_PUBLIC:
+ $flag = FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
+ break;
+
+ case Ip::ALL_ONLY_PUBLIC:
+ $flag = FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
+ break;
+
+ default:
+ $flag = null;
+ break;
+ }
+
+ if (!filter_var($value, FILTER_VALIDATE_IP, $flag)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Isbn.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Isbn.php
new file mode 100644
index 0000000..67d177f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Isbn.php
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author The Whole Life To Learn <thewholelifetolearn@gmail.com>
+ * @author Manuel Reinhard <manu@sprain.ch>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class Isbn extends Constraint
+{
+ const TOO_SHORT_ERROR = 1;
+ const TOO_LONG_ERROR = 2;
+ const INVALID_CHARACTERS_ERROR = 3;
+ const CHECKSUM_FAILED_ERROR = 4;
+ const TYPE_NOT_RECOGNIZED_ERROR = 5;
+
+ protected static $errorNames = array(
+ 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',
+ );
+
+ 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;
+
+ /**
+ * @deprecated Deprecated since version 2.5, to be removed in 3.0. Use option "type" instead.
+ * @var bool
+ */
+ public $isbn10 = false;
+
+ /**
+ * @deprecated Deprecated since version 2.5, to be removed in 3.0. Use option "type" instead.
+ * @var bool
+ */
+ public $isbn13 = false;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultOption()
+ {
+ return 'type';
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IsbnValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IsbnValidator.php
new file mode 100644
index 0000000..5980857
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IsbnValidator.php
@@ -0,0 +1,192 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether the value is a valid ISBN-10 or ISBN-13
+ *
+ * @author The Whole Life To Learn <thewholelifetolearn@gmail.com>
+ * @author Manuel Reinhard <manu@sprain.ch>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see https://en.wikipedia.org/wiki/Isbn
+ */
+class IsbnValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Isbn) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Isbn');
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+ $canonical = str_replace('-', '', $value);
+
+ if (null === $constraint->type) {
+ if ($constraint->isbn10 && !$constraint->isbn13) {
+ $constraint->type = 'isbn10';
+ } elseif ($constraint->isbn13 && !$constraint->isbn10) {
+ $constraint->type = 'isbn13';
+ }
+ }
+
+ // Explicitly validate against ISBN-10
+ if ('isbn10' === $constraint->type) {
+ if (true !== ($code = $this->validateIsbn10($canonical))) {
+ $this->buildViolation($this->getMessage($constraint, $constraint->type))
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode($code)
+ ->addViolation();
+ }
+
+ return;
+ }
+
+ // Explicitly validate against ISBN-13
+ if ('isbn13' === $constraint->type) {
+ if (true !== ($code = $this->validateIsbn13($canonical))) {
+ $this->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->buildViolation($this->getMessage($constraint))
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode($code)
+ ->addViolation();
+ }
+ }
+
+ protected function validateIsbn10($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;
+ }
+
+ protected function validateIsbn13($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;
+ }
+
+ protected function getMessage($constraint, $type = null)
+ {
+ if (null !== $constraint->message) {
+ return $constraint->message;
+ } elseif ('isbn10' === $type) {
+ return $constraint->isbn10Message;
+ } elseif ('isbn13' === $type) {
+ return $constraint->isbn13Message;
+ }
+
+ return $constraint->bothIsbnMessage;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Issn.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Issn.php
new file mode 100644
index 0000000..39716a2
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Issn.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Antonio J. García Lagar <aj@garcialagar.es>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class Issn extends Constraint
+{
+ const TOO_SHORT_ERROR = 1;
+ const TOO_LONG_ERROR = 2;
+ const MISSING_HYPHEN_ERROR = 3;
+ const INVALID_CHARACTERS_ERROR = 4;
+ const INVALID_CASE_ERROR = 5;
+ const CHECKSUM_FAILED_ERROR = 6;
+
+ protected static $errorNames = array(
+ 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',
+ );
+
+ public $message = 'This value is not a valid ISSN.';
+ public $caseSensitive = false;
+ public $requireHyphen = false;
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IssnValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IssnValidator.php
new file mode 100644
index 0000000..1f17c38
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IssnValidator.php
@@ -0,0 +1,132 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether the value is a valid ISSN.
+ *
+ * @author Antonio J. García Lagar <aj@garcialagar.es>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see https://en.wikipedia.org/wiki/Issn
+ */
+class IssnValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Issn) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Issn');
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($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->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Issn::MISSING_HYPHEN_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ $length = strlen($canonical);
+
+ if ($length < 8) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Issn::TOO_SHORT_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ if ($length > 8) {
+ $this->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->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->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->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) * $canonical{$i};
+ }
+
+ if (0 !== $checkSum % 11) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Issn::CHECKSUM_FAILED_ERROR)
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Language.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Language.php
new file mode 100644
index 0000000..e7c29dc
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Language.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Language extends Constraint
+{
+ public $message = 'This value is not a valid language.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LanguageValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LanguageValidator.php
new file mode 100644
index 0000000..be7ad28
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LanguageValidator.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Intl\Intl;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether a value is a valid language code.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class LanguageValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Language) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Language');
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+ $languages = Intl::getLanguageBundle()->getLanguageNames();
+
+ if (!isset($languages[$value])) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Length.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Length.php
new file mode 100644
index 0000000..8d00480
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Length.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\MissingOptionsException;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Length extends Constraint
+{
+ const TOO_SHORT_ERROR = 1;
+ const TOO_LONG_ERROR = 2;
+
+ protected static $errorNames = array(
+ self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR',
+ self::TOO_LONG_ERROR => 'TOO_LONG_ERROR',
+ );
+
+ 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';
+
+ public function __construct($options = null)
+ {
+ if (null !== $options && !is_array($options)) {
+ $options = array(
+ 'min' => $options,
+ 'max' => $options,
+ );
+ }
+
+ parent::__construct($options);
+
+ if (null === $this->min && null === $this->max) {
+ throw new MissingOptionsException(sprintf('Either option "min" or "max" must be given for constraint %s', __CLASS__), array('min', 'max'));
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LengthValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LengthValidator.php
new file mode 100644
index 0000000..f822047
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LengthValidator.php
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class LengthValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Length) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Length');
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $stringValue = (string) $value;
+ $invalidCharset = false;
+
+ if ('UTF8' === $charset = strtoupper($constraint->charset)) {
+ $charset = 'UTF-8';
+ }
+
+ if (function_exists('iconv_strlen')) {
+ $length = @iconv_strlen($stringValue, $constraint->charset);
+ $invalidCharset = false === $length;
+ } elseif (function_exists('mb_strlen')) {
+ if (mb_check_encoding($stringValue, $constraint->charset)) {
+ $length = mb_strlen($stringValue, $constraint->charset);
+ } else {
+ $invalidCharset = true;
+ }
+ } elseif ('UTF-8' !== $charset) {
+ $length = strlen($stringValue);
+ } elseif (!preg_match('//u', $stringValue)) {
+ $invalidCharset = true;
+ } elseif (function_exists('utf8_decode')) {
+ $length = strlen(utf8_decode($stringValue));
+ } else {
+ preg_replace('/./u', '', $stringValue, -1, $length);
+ }
+
+ if ($invalidCharset) {
+ $this->buildViolation($constraint->charsetMessage)
+ ->setParameter('{{ value }}', $this->formatValue($stringValue))
+ ->setParameter('{{ charset }}', $constraint->charset)
+ ->setInvalidValue($value)
+ ->addViolation();
+
+ return;
+ }
+
+ if (null !== $constraint->max && $length > $constraint->max) {
+ $this->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->maxMessage)
+ ->setParameter('{{ value }}', $this->formatValue($stringValue))
+ ->setParameter('{{ limit }}', $constraint->max)
+ ->setInvalidValue($value)
+ ->setPlural((int) $constraint->max)
+ ->setCode(Length::TOO_LONG_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ if (null !== $constraint->min && $length < $constraint->min) {
+ $this->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->minMessage)
+ ->setParameter('{{ value }}', $this->formatValue($stringValue))
+ ->setParameter('{{ limit }}', $constraint->min)
+ ->setInvalidValue($value)
+ ->setPlural((int) $constraint->min)
+ ->setCode(Length::TOO_SHORT_ERROR)
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThan.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThan.php
new file mode 100644
index 0000000..b116320
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThan.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class LessThan extends AbstractComparison
+{
+ public $message = 'This value should be less than {{ compared_value }}.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanOrEqual.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanOrEqual.php
new file mode 100644
index 0000000..7faca84
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanOrEqual.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class LessThanOrEqual extends AbstractComparison
+{
+ public $message = 'This value should be less than or equal to {{ compared_value }}.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanOrEqualValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanOrEqualValidator.php
new file mode 100644
index 0000000..dcc93b2
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanOrEqualValidator.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * Validates values are less than or equal to the previous (<=).
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class LessThanOrEqualValidator extends AbstractComparisonValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function compareValues($value1, $value2)
+ {
+ return $value1 <= $value2;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanValidator.php
new file mode 100644
index 0000000..081316a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LessThanValidator.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * Validates values are less than the previous (<).
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class LessThanValidator extends AbstractComparisonValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function compareValues($value1, $value2)
+ {
+ return $value1 < $value2;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Locale.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Locale.php
new file mode 100644
index 0000000..12a5546
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Locale.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Locale extends Constraint
+{
+ public $message = 'This value is not a valid locale.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LocaleValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LocaleValidator.php
new file mode 100644
index 0000000..748e5cf
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LocaleValidator.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Intl\Intl;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether a value is a valid locale code.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class LocaleValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Locale) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Locale');
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+ $locales = Intl::getLocaleBundle()->getLocaleNames();
+
+ if (!isset($locales[$value])) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Luhn.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Luhn.php
new file mode 100644
index 0000000..24f5bc7
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Luhn.php
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Metadata for the LuhnValidator.
+ *
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Tim Nagel <t.nagel@infinite.net.au>
+ * @author Greg Knapp http://gregk.me/2011/php-implementation-of-bank-card-luhn-algorithm/
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class Luhn extends Constraint
+{
+ const INVALID_CHARACTERS_ERROR = 1;
+ const CHECKSUM_FAILED_ERROR = 2;
+
+ protected static $errorNames = array(
+ self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR',
+ self::CHECKSUM_FAILED_ERROR => 'CHECKSUM_FAILED_ERROR',
+ );
+
+ public $message = 'Invalid card number.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LuhnValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LuhnValidator.php
new file mode 100644
index 0000000..d58bfbf
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LuhnValidator.php
@@ -0,0 +1,96 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * 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 <t.nagel@infinite.net.au>
+ * @author Greg Knapp http://gregk.me/2011/php-implementation-of-bank-card-luhn-algorithm/
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class LuhnValidator extends ConstraintValidator
+{
+ /**
+ * Validates a credit card number with the Luhn algorithm.
+ *
+ * @param mixed $value
+ * @param Constraint $constraint
+ *
+ * @throws UnexpectedTypeException when the given credit card number is no string
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Luhn) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Luhn');
+ }
+
+ 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) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+
+ if (!ctype_digit($value)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Luhn::INVALID_CHARACTERS_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ $checkSum = 0;
+ $length = strlen($value);
+
+ // 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
+ for ($i = $length - 1; $i >= 0; $i -= 2) {
+ $checkSum += $value{$i};
+ }
+
+ // 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
+ for ($i = $length - 2; $i >= 0; $i -= 2) {
+ $checkSum += array_sum(str_split($value{$i} * 2));
+ }
+
+ if (0 === $checkSum || 0 !== $checkSum % 10) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Luhn::CHECKSUM_FAILED_ERROR)
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlank.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlank.php
new file mode 100644
index 0000000..c578c6d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlank.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class NotBlank extends Constraint
+{
+ public $message = 'This value should not be blank.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlankValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlankValidator.php
new file mode 100644
index 0000000..9deab15
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlankValidator.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class NotBlankValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof NotBlank) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\NotBlank');
+ }
+
+ if (false === $value || (empty($value) && '0' != $value)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotEqualTo.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotEqualTo.php
new file mode 100644
index 0000000..abd8092
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotEqualTo.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class NotEqualTo extends AbstractComparison
+{
+ public $message = 'This value should not be equal to {{ compared_value }}.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotEqualToValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotEqualToValidator.php
new file mode 100644
index 0000000..5710a85
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotEqualToValidator.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * Validates values are all unequal (!=).
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class NotEqualToValidator extends AbstractComparisonValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function compareValues($value1, $value2)
+ {
+ return $value1 != $value2;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotIdenticalTo.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotIdenticalTo.php
new file mode 100644
index 0000000..fb4ef3f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotIdenticalTo.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class NotIdenticalTo extends AbstractComparison
+{
+ public $message = 'This value should not be identical to {{ compared_value_type }} {{ compared_value }}.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotIdenticalToValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotIdenticalToValidator.php
new file mode 100644
index 0000000..ed8dc1c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotIdenticalToValidator.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * Validates values aren't identical (!==).
+ *
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class NotIdenticalToValidator extends AbstractComparisonValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function compareValues($value1, $value2)
+ {
+ return $value1 !== $value2;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNull.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNull.php
new file mode 100644
index 0000000..60416c7
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNull.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class NotNull extends Constraint
+{
+ public $message = 'This value should not be null.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNullValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNullValidator.php
new file mode 100644
index 0000000..a7a905a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNullValidator.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class NotNullValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof NotNull) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\NotNull');
+ }
+
+ if (null === $value) {
+ $this->context->addViolation($constraint->message);
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Null.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Null.php
new file mode 100644
index 0000000..3104550
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Null.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Null extends Constraint
+{
+ public $message = 'This value should be null.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NullValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NullValidator.php
new file mode 100644
index 0000000..1e6c3a5
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NullValidator.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class NullValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Null) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Null');
+ }
+
+ if (null !== $value) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Optional.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Optional.php
new file mode 100644
index 0000000..dab8b43
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Optional.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * @Annotation
+ * @Target({"ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class Optional extends Existence
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Range.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Range.php
new file mode 100644
index 0000000..a12afff
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Range.php
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\MissingOptionsException;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Range extends Constraint
+{
+ const INVALID_VALUE_ERROR = 1;
+ const BEYOND_RANGE_ERROR = 2;
+ const BELOW_RANGE_ERROR = 3;
+
+ protected static $errorNames = array(
+ self::INVALID_VALUE_ERROR => 'INVALID_VALUE_ERROR',
+ self::BEYOND_RANGE_ERROR => 'BEYOND_RANGE_ERROR',
+ self::BELOW_RANGE_ERROR => 'BELOW_RANGE_ERROR',
+ );
+
+ 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 $min;
+ public $max;
+
+ public function __construct($options = null)
+ {
+ parent::__construct($options);
+
+ if (null === $this->min && null === $this->max) {
+ throw new MissingOptionsException(sprintf('Either option "min" or "max" must be given for constraint %s', __CLASS__), array('min', 'max'));
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/RangeValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/RangeValidator.php
new file mode 100644
index 0000000..ebae112
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/RangeValidator.php
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class RangeValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Range) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Range');
+ }
+
+ if (null === $value) {
+ return;
+ }
+
+ if (!is_numeric($value) && !$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
+ $this->buildViolation($constraint->invalidMessage)
+ ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE))
+ ->setCode(Range::INVALID_VALUE_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ $min = $constraint->min;
+ $max = $constraint->max;
+
+ // Convert strings to DateTimes if comparing another DateTime
+ // This allows to compare with any date/time value supported by
+ // the DateTime constructor:
+ // http://php.net/manual/en/datetime.formats.php
+ if ($value instanceof \DateTime || $value instanceof \DateTimeInterface) {
+ if (is_string($min)) {
+ $min = new \DateTime($min);
+ }
+
+ if (is_string($max)) {
+ $max = new \DateTime($max);
+ }
+ }
+
+ if (null !== $constraint->max && $value > $max) {
+ $this->buildViolation($constraint->maxMessage)
+ ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE))
+ ->setParameter('{{ limit }}', $this->formatValue($max, self::PRETTY_DATE))
+ ->setCode(Range::BEYOND_RANGE_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ if (null !== $constraint->min && $value < $min) {
+ $this->buildViolation($constraint->minMessage)
+ ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE))
+ ->setParameter('{{ limit }}', $this->formatValue($min, self::PRETTY_DATE))
+ ->setCode(Range::BELOW_RANGE_ERROR)
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Regex.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Regex.php
new file mode 100644
index 0000000..3cdf514
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Regex.php
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Regex extends Constraint
+{
+ public $message = 'This value is not valid.';
+ public $pattern;
+ public $htmlPattern;
+ public $match = true;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultOption()
+ {
+ return 'pattern';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRequiredOptions()
+ {
+ return array('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.
+ *
+ * Pattern is also ignored if match=false since the pattern should
+ * then be reversed before application.
+ *
+ * @link http://dev.w3.org/html5/spec/single-page.html#the-pattern-attribute
+ *
+ * @return string|null
+ */
+ public function getHtmlPattern()
+ {
+ // 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;
+ }
+
+ $delimiter = $this->pattern[0];
+
+ // Unescape the delimiter
+ $pattern = str_replace('\\'.$delimiter, $delimiter, substr($this->pattern, 1, -1));
+
+ // If the pattern is inverted, we can simply 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 (false !== strpos($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/vendor/symfony/validator/Symfony/Component/Validator/Constraints/RegexValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/RegexValidator.php
new file mode 100644
index 0000000..5916e85
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/RegexValidator.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether a value match or not given regexp pattern.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @author Joseph Bielawski <stloyd@gmail.com>
+ *
+ * @api
+ */
+class RegexValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Regex) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Regex');
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+
+ if ($constraint->match xor preg_match($constraint->pattern, $value)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Required.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Required.php
new file mode 100644
index 0000000..bd77a90
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Required.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+/**
+ * @Annotation
+ * @Target({"ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class Required extends Existence
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Time.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Time.php
new file mode 100644
index 0000000..7998c6f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Time.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Time extends Constraint
+{
+ const INVALID_FORMAT_ERROR = 1;
+ const INVALID_TIME_ERROR = 2;
+
+ protected static $errorNames = array(
+ self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR',
+ self::INVALID_TIME_ERROR => 'INVALID_TIME_ERROR',
+ );
+
+ public $message = 'This value is not a valid time.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TimeValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TimeValidator.php
new file mode 100644
index 0000000..bfecf95
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TimeValidator.php
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class TimeValidator extends ConstraintValidator
+{
+ const PATTERN = '/^(\d{2}):(\d{2}):(\d{2})$/';
+
+ /**
+ * Checks whether a time is valid.
+ *
+ * @param int $hour The hour
+ * @param int $minute The minute
+ * @param int $second The second
+ *
+ * @return bool Whether the time is valid
+ *
+ * @internal
+ */
+ public static function checkTime($hour, $minute, $second)
+ {
+ return $hour >= 0 && $hour < 24 && $minute >= 0 && $minute < 60 && $second >= 0 && $second < 60;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Time) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Time');
+ }
+
+ if (null === $value || '' === $value || $value instanceof \DateTime) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+
+ if (!preg_match(static::PATTERN, $value, $matches)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Time::INVALID_FORMAT_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ if (!self::checkTime($matches[1], $matches[2], $matches[3])) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Time::INVALID_TIME_ERROR)
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Traverse.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Traverse.php
new file mode 100644
index 0000000..4abae6c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Traverse.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+/**
+ * @Annotation
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class Traverse extends Constraint
+{
+ public $traverse = true;
+
+ public function __construct($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);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultOption()
+ {
+ return 'traverse';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getTargets()
+ {
+ return self::CLASS_CONSTRAINT;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/True.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/True.php
new file mode 100644
index 0000000..788e36a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/True.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class True extends Constraint
+{
+ public $message = 'This value should be true.';
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TrueValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TrueValidator.php
new file mode 100644
index 0000000..a01f5bb
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TrueValidator.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class TrueValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof True) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\True');
+ }
+
+ if (null === $value) {
+ return;
+ }
+
+ if (true !== $value && 1 !== $value && '1' !== $value) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Type.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Type.php
new file mode 100644
index 0000000..fc4cc72
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Type.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Type extends Constraint
+{
+ public $message = 'This value should be of type {{ type }}.';
+ public $type;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultOption()
+ {
+ return 'type';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRequiredOptions()
+ {
+ return array('type');
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TypeValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TypeValidator.php
new file mode 100644
index 0000000..66217d0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TypeValidator.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class TypeValidator extends ConstraintValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Type) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Type');
+ }
+
+ if (null === $value) {
+ return;
+ }
+
+ $type = strtolower($constraint->type);
+ $type = $type == 'boolean' ? 'bool' : $constraint->type;
+ $isFunction = 'is_'.$type;
+ $ctypeFunction = 'ctype_'.$type;
+
+ if (function_exists($isFunction) && $isFunction($value)) {
+ return;
+ } elseif (function_exists($ctypeFunction) && $ctypeFunction($value)) {
+ return;
+ } elseif ($value instanceof $constraint->type) {
+ return;
+ }
+
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setParameter('{{ type }}', $constraint->type)
+ ->addViolation();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Url.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Url.php
new file mode 100644
index 0000000..e867ee1
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Url.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Url extends Constraint
+{
+ public $message = 'This value is not a valid URL.';
+ public $protocols = array('http', 'https');
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/UrlValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/UrlValidator.php
new file mode 100644
index 0000000..3d18477
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/UrlValidator.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class UrlValidator extends ConstraintValidator
+{
+ const PATTERN = '~^
+ (%s):// # protocol
+ (([\pL\pN-]+:)?([\pL\pN-]+)@)? # basic auth
+ (
+ ([\pL\pN\pS-\.])+(\.?([\pL]|xn\-\-[\pL\pN-]+)+\.?) # a domain name
+ | # or
+ \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # a 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})))?::))))
+ \] # a IPv6 address
+ )
+ (:[0-9]+)? # a port (optional)
+ (/?|/\S+) # a /, nothing or a / with something
+ $~ixu';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (!$constraint instanceof Url) {
+ throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Url');
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+ $pattern = sprintf(static::PATTERN, implode('|', $constraint->protocols));
+
+ if (!preg_match($pattern, $value)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Uuid.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Uuid.php
new file mode 100644
index 0000000..3c67a3a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Uuid.php
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @author Colin O'Dell <colinodell@gmail.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class Uuid extends Constraint
+{
+ const TOO_SHORT_ERROR = 1;
+ const TOO_LONG_ERROR = 2;
+ const INVALID_CHARACTERS_ERROR = 3;
+ const INVALID_HYPHEN_PLACEMENT_ERROR = 4;
+ const INVALID_VERSION_ERROR = 5;
+ const INVALID_VARIANT_ERROR = 6;
+
+ protected static $errorNames = array(
+ 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',
+ );
+
+ // Possible versions defined by RFC 4122
+ const V1_MAC = 1;
+ const V2_DCE = 2;
+ const V3_MD5 = 3;
+ const V4_RANDOM = 4;
+ const V5_SHA1 = 5;
+
+ /**
+ * 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 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 = array(
+ self::V1_MAC,
+ self::V2_DCE,
+ self::V3_MD5,
+ self::V4_RANDOM,
+ self::V5_SHA1,
+ );
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/UuidValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/UuidValidator.php
new file mode 100644
index 0000000..0ae04e2
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/UuidValidator.php
@@ -0,0 +1,264 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether the value is a valid UUID per RFC 4122.
+ *
+ * @author Colin O'Dell <colinodell@gmail.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see http://tools.ietf.org/html/rfc4122
+ * @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..5}
+ // N = any allowed variant {8, 9, a, b}
+
+ const STRICT_LENGTH = 36;
+ const STRICT_FIRST_HYPHEN_POSITION = 8;
+ const STRICT_LAST_HYPHEN_POSITION = 23;
+ const STRICT_VERSION_POSITION = 14;
+ 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.
+
+ const LOOSE_MAX_LENGTH = 39;
+ const LOOSE_FIRST_HYPHEN_POSITION = 4;
+
+ /**
+ * @deprecated Deprecated since Symfony 2.6, to be removed in 3.0
+ */
+ const STRICT_PATTERN = '/^[a-f0-9]{8}-[a-f0-9]{4}-[%s][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/i';
+
+ /**
+ * @deprecated Deprecated since Symfony 2.6, to be removed in 3.0
+ */
+ const LOOSE_PATTERN = '/^[a-f0-9]{4}(?:-?[a-f0-9]{4}){7}$/i';
+
+ /**
+ * @deprecated Deprecated since Symfony 2.6, to be removed in 3.0
+ */
+ const STRICT_UUID_LENGTH = self::STRICT_LENGTH;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, Constraint $constraint)
+ {
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+ throw new UnexpectedTypeException($value, 'string');
+ }
+
+ $value = (string) $value;
+
+ if ($constraint->strict) {
+ $this->validateStrict($value, $constraint);
+
+ return;
+ }
+
+ $this->validateLoose($value, $constraint);
+ }
+
+ private function validateLoose($value, Uuid $constraint)
+ {
+ // 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->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->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->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Uuid::INVALID_CHARACTERS_ERROR)
+ ->addViolation();
+
+ return;
+ }
+ }
+
+ // Check length again
+ if (isset($trimmed{$i})) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Uuid::TOO_LONG_ERROR)
+ ->addViolation();
+ }
+ }
+
+ private function validateStrict($value, Uuid $constraint)
+ {
+ // 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->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->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->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Uuid::INVALID_CHARACTERS_ERROR)
+ ->addViolation();
+
+ return;
+ }
+
+ // Missing hyphen
+ if ($i === $h) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Uuid::INVALID_HYPHEN_PLACEMENT_ERROR)
+ ->addViolation();
+
+ return;
+ }
+ }
+
+ // Check length again
+ if (isset($value{$i})) {
+ $this->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)) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Uuid::INVALID_VERSION_ERROR)
+ ->addViolation();
+ }
+
+ // Check variant - first two bits must equal "10"
+ // 0b10xx
+ // & 0b1100 (12)
+ // = 0b1000 (8)
+ if ((hexdec($value{self::STRICT_VARIANT_POSITION}) & 12) !== 8) {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Uuid::INVALID_VARIANT_ERROR)
+ ->addViolation();
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Valid.php b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Valid.php
new file mode 100644
index 0000000..b0f518b
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Valid.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+/**
+ * @Annotation
+ * @Target({"PROPERTY", "METHOD", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class Valid extends Constraint
+{
+ public $traverse = true;
+
+ /**
+ * @deprecated Deprecated as of version 2.5, to be removed in Symfony 3.0.
+ */
+ public $deep = true;
+
+ public function __construct($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);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContext.php b/vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContext.php
new file mode 100644
index 0000000..f329615
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContext.php
@@ -0,0 +1,404 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Context;
+
+use Symfony\Component\Translation\TranslatorInterface;
+use Symfony\Component\Validator\ClassBasedInterface;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\ConstraintViolationList;
+use Symfony\Component\Validator\Exception\BadMethodCallException;
+use Symfony\Component\Validator\Mapping\MetadataInterface;
+use Symfony\Component\Validator\Mapping\PropertyMetadataInterface;
+use Symfony\Component\Validator\Util\PropertyPath;
+use Symfony\Component\Validator\Validator\ValidatorInterface;
+use Symfony\Component\Validator\Violation\ConstraintViolationBuilder;
+
+/**
+ * The context used and created by {@link ExecutionContextFactory}.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see ExecutionContextInterface
+ *
+ * @internal You should not instantiate or use this class. Code against
+ * {@link ExecutionContextInterface} instead.
+ */
+class ExecutionContext implements ExecutionContextInterface
+{
+ /**
+ * @var ValidatorInterface
+ */
+ private $validator;
+
+ /**
+ * The root value of the validated object graph.
+ *
+ * @var mixed
+ */
+ private $root;
+
+ /**
+ * @var TranslatorInterface
+ */
+ private $translator;
+
+ /**
+ * @var string
+ */
+ private $translationDomain;
+
+ /**
+ * The violations generated in the current context.
+ *
+ * @var ConstraintViolationList
+ */
+ private $violations;
+
+ /**
+ * The currently validated value.
+ *
+ * @var mixed
+ */
+ private $value;
+
+ /**
+ * The currently validated object.
+ *
+ * @var object|null
+ */
+ private $object;
+
+ /**
+ * The property path leading to the current value.
+ *
+ * @var string
+ */
+ private $propertyPath = '';
+
+ /**
+ * The current validation metadata.
+ *
+ * @var MetadataInterface|null
+ */
+ private $metadata;
+
+ /**
+ * The currently validated group.
+ *
+ * @var string|null
+ */
+ private $group;
+
+ /**
+ * The currently validated constraint.
+ *
+ * @var Constraint|null
+ */
+ private $constraint;
+
+ /**
+ * Stores which objects have been validated in which group.
+ *
+ * @var array
+ */
+ private $validatedObjects = array();
+
+ /**
+ * Stores which class constraint has been validated for which object.
+ *
+ * @var array
+ */
+ private $validatedConstraints = array();
+
+ /**
+ * Stores which objects have been initialized.
+ *
+ * @var array
+ */
+ private $initializedObjects;
+
+ /**
+ * Creates a new execution context.
+ *
+ * @param ValidatorInterface $validator The validator
+ * @param mixed $root The root value of the
+ * validated object graph
+ * @param TranslatorInterface $translator The translator
+ * @param string|null $translationDomain The translation domain to
+ * use for translating
+ * violation messages
+ *
+ * @internal Called by {@link ExecutionContextFactory}. Should not be used
+ * in user code.
+ */
+ public function __construct(ValidatorInterface $validator, $root, TranslatorInterface $translator, $translationDomain = null)
+ {
+ $this->validator = $validator;
+ $this->root = $root;
+ $this->translator = $translator;
+ $this->translationDomain = $translationDomain;
+ $this->violations = new ConstraintViolationList();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setNode($value, $object, MetadataInterface $metadata = null, $propertyPath)
+ {
+ $this->value = $value;
+ $this->object = $object;
+ $this->metadata = $metadata;
+ $this->propertyPath = (string) $propertyPath;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setGroup($group)
+ {
+ $this->group = $group;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setConstraint(Constraint $constraint)
+ {
+ $this->constraint = $constraint;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addViolation($message, array $parameters = array(), $invalidValue = null, $plural = null, $code = null)
+ {
+ // The parameters $invalidValue and following are ignored by the new
+ // API, as they are not present in the new interface anymore.
+ // You should use buildViolation() instead.
+ if (func_num_args() > 2) {
+ throw new BadMethodCallException(
+ 'The parameters $invalidValue, $pluralization and $code are '.
+ 'not supported anymore as of Symfony 2.5. Please use '.
+ 'buildViolation() instead or enable the legacy mode.'
+ );
+ }
+
+ $this->violations->add(new ConstraintViolation(
+ $this->translator->trans($message, $parameters, $this->translationDomain),
+ $message,
+ $parameters,
+ $this->root,
+ $this->propertyPath,
+ $this->value,
+ null,
+ null,
+ $this->constraint
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildViolation($message, array $parameters = array())
+ {
+ return new ConstraintViolationBuilder(
+ $this->violations,
+ $this->constraint,
+ $message,
+ $parameters,
+ $this->root,
+ $this->propertyPath,
+ $this->value,
+ $this->translator,
+ $this->translationDomain
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getViolations()
+ {
+ return $this->violations;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getValidator()
+ {
+ return $this->validator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRoot()
+ {
+ return $this->root;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getObject()
+ {
+ return $this->object;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadata()
+ {
+ return $this->metadata;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getGroup()
+ {
+ return $this->group;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getClassName()
+ {
+ return $this->metadata instanceof ClassBasedInterface ? $this->metadata->getClassName() : null;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPropertyName()
+ {
+ return $this->metadata instanceof PropertyMetadataInterface ? $this->metadata->getPropertyName() : null;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPropertyPath($subPath = '')
+ {
+ return PropertyPath::append($this->propertyPath, $subPath);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addViolationAt($subPath, $message, array $parameters = array(), $invalidValue = null, $plural = null, $code = null)
+ {
+ throw new BadMethodCallException(
+ 'addViolationAt() is not supported anymore as of Symfony 2.5. '.
+ 'Please use buildViolation() instead or enable the legacy mode.'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, $subPath = '', $groups = null, $traverse = false, $deep = false)
+ {
+ throw new BadMethodCallException(
+ 'validate() is not supported anymore as of Symfony 2.5. '.
+ 'Please use getValidator() instead or enable the legacy mode.'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateValue($value, $constraints, $subPath = '', $groups = null)
+ {
+ throw new BadMethodCallException(
+ 'validateValue() is not supported anymore as of Symfony 2.5. '.
+ 'Please use getValidator() instead or enable the legacy mode.'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadataFactory()
+ {
+ throw new BadMethodCallException(
+ 'getMetadataFactory() is not supported anymore as of Symfony 2.5. '.
+ 'Please use getValidator() in combination with getMetadataFor() '.
+ 'or hasMetadataFor() instead or enable the legacy mode.'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function markGroupAsValidated($cacheKey, $groupHash)
+ {
+ if (!isset($this->validatedObjects[$cacheKey])) {
+ $this->validatedObjects[$cacheKey] = array();
+ }
+
+ $this->validatedObjects[$cacheKey][$groupHash] = true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isGroupValidated($cacheKey, $groupHash)
+ {
+ return isset($this->validatedObjects[$cacheKey][$groupHash]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function markConstraintAsValidated($cacheKey, $constraintHash)
+ {
+ $this->validatedConstraints[$cacheKey.':'.$constraintHash] = true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isConstraintValidated($cacheKey, $constraintHash)
+ {
+ return isset($this->validatedConstraints[$cacheKey.':'.$constraintHash]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function markObjectAsInitialized($cacheKey)
+ {
+ $this->initializedObjects[$cacheKey] = true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isObjectInitialized($cacheKey)
+ {
+ return isset($this->initializedObjects[$cacheKey]);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextFactory.php b/vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextFactory.php
new file mode 100644
index 0000000..d94a806
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextFactory.php
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Context;
+
+use Symfony\Component\Translation\TranslatorInterface;
+use Symfony\Component\Validator\Validator\ValidatorInterface;
+
+/**
+ * Creates new {@link ExecutionContext} instances.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @internal You should not instantiate or use this class. Code against
+ * {@link ExecutionContextFactoryInterface} instead.
+ */
+class ExecutionContextFactory implements ExecutionContextFactoryInterface
+{
+ /**
+ * @var TranslatorInterface
+ */
+ private $translator;
+
+ /**
+ * @var string|null
+ */
+ private $translationDomain;
+
+ /**
+ * Creates a new context factory.
+ *
+ * @param TranslatorInterface $translator The translator
+ * @param string|null $translationDomain The translation domain to
+ * use for translating
+ * violation messages
+ */
+ public function __construct(TranslatorInterface $translator, $translationDomain = null)
+ {
+ $this->translator = $translator;
+ $this->translationDomain = $translationDomain;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createContext(ValidatorInterface $validator, $root)
+ {
+ return new ExecutionContext(
+ $validator,
+ $root,
+ $this->translator,
+ $this->translationDomain
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextFactoryInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextFactoryInterface.php
new file mode 100644
index 0000000..f0ee001
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextFactoryInterface.php
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface ExecutionContextFactoryInterface
+{
+ /**
+ * Creates a new execution context.
+ *
+ * @param ValidatorInterface $validator The validator
+ * @param mixed $root The root value of the validated
+ * object graph
+ *
+ * @return ExecutionContextInterface The new execution context
+ */
+ public function createContext(ValidatorInterface $validator, $root);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextInterface.php
new file mode 100644
index 0000000..4865204
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Context/ExecutionContextInterface.php
@@ -0,0 +1,226 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Context;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ExecutionContextInterface as LegacyExecutionContextInterface;
+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($value, Constraint $constraint)
+ * {
+ * $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($value, Constraint $constraint)
+ * {
+ * $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.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface ExecutionContextInterface extends LegacyExecutionContextInterface
+{
+ /**
+ * 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 $message The error message
+ * @param array $parameters The parameters substituted in the error message
+ *
+ * @return ConstraintViolationBuilderInterface The violation builder
+ */
+ public function buildViolation($message, array $parameters = array());
+
+ /**
+ * Returns the validator.
+ *
+ * Useful if you want to validate additional constraints:
+ *
+ * public function validate($value, Constraint $constraint)
+ * {
+ * $validator = $this->context->getValidator();
+ *
+ * $violations = $validator->validateValue($value, new Length(array('min' => 3)));
+ *
+ * if (count($violations) > 0) {
+ * // ...
+ * }
+ * }
+ *
+ * @return ValidatorInterface
+ */
+ public function getValidator();
+
+ /**
+ * Returns the currently validated object.
+ *
+ * If the validator is currently validating a class constraint, the
+ * object of that class is returned. If it is a validating a property or
+ * getter constraint, the object that the property/getter belongs to is
+ * returned.
+ *
+ * In other cases, null is returned.
+ *
+ * @return object|null The currently validated object or null.
+ */
+ public function getObject();
+
+ /**
+ * Sets the currently validated value.
+ *
+ * @param mixed $value The validated value
+ * @param object|null $object The currently validated object
+ * @param MetadataInterface|null $metadata The validation metadata
+ * @param string $propertyPath The property path to the current value
+ *
+ * @internal Used by the validator engine. Should not be called by user
+ * code.
+ */
+ public function setNode($value, $object, MetadataInterface $metadata = null, $propertyPath);
+
+ /**
+ * Sets the currently validated group.
+ *
+ * @param string|null $group The validated group
+ *
+ * @internal Used by the validator engine. Should not be called by user
+ * code.
+ */
+ public function setGroup($group);
+
+ /**
+ * Sets the currently validated constraint.
+ *
+ * @param Constraint $constraint The validated constraint
+ *
+ * @internal Used by the validator engine. Should not be called by user
+ * code.
+ */
+ public function setConstraint(Constraint $constraint);
+
+ /**
+ * Marks an object as validated in a specific validation group.
+ *
+ * @param string $cacheKey The hash of the object
+ * @param string $groupHash The group's name or hash, if it is group
+ * sequence
+ *
+ * @internal Used by the validator engine. Should not be called by user
+ * code.
+ */
+ public function markGroupAsValidated($cacheKey, $groupHash);
+
+ /**
+ * Returns whether an object was validated in a specific validation group.
+ *
+ * @param string $cacheKey The hash of the object
+ * @param string $groupHash The group's name or hash, if it is group
+ * sequence
+ *
+ * @return bool Whether the object was already validated for that
+ * group
+ *
+ * @internal Used by the validator engine. Should not be called by user
+ * code.
+ */
+ public function isGroupValidated($cacheKey, $groupHash);
+
+ /**
+ * Marks a constraint as validated for an object.
+ *
+ * @param string $cacheKey The hash of the object
+ * @param string $constraintHash The hash of the constraint
+ *
+ * @internal Used by the validator engine. Should not be called by user
+ * code.
+ */
+ public function markConstraintAsValidated($cacheKey, $constraintHash);
+
+ /**
+ * Returns whether a constraint was validated for an object.
+ *
+ * @param string $cacheKey The hash of the object
+ * @param string $constraintHash The hash of the constraint
+ *
+ * @return bool Whether the constraint was already validated
+ *
+ * @internal Used by the validator engine. Should not be called by user
+ * code.
+ */
+ public function isConstraintValidated($cacheKey, $constraintHash);
+
+ /**
+ * Marks that an object was initialized.
+ *
+ * @param string $cacheKey The hash of the object
+ *
+ * @internal Used by the validator engine. Should not be called by user
+ * code.
+ *
+ * @see ObjectInitializerInterface
+ */
+ public function markObjectAsInitialized($cacheKey);
+
+ /**
+ * Returns whether an object was initialized.
+ *
+ * @param string $cacheKey The hash of the object
+ *
+ * @return bool Whether the object was already initialized
+ *
+ * @internal Used by the validator engine. Should not be called by user
+ * code.
+ *
+ * @see ObjectInitializerInterface
+ */
+ public function isObjectInitialized($cacheKey);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Context/LegacyExecutionContext.php b/vendor/symfony/validator/Symfony/Component/Validator/Context/LegacyExecutionContext.php
new file mode 100644
index 0000000..de34b1f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Context/LegacyExecutionContext.php
@@ -0,0 +1,156 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Context;
+
+use Symfony\Component\Translation\TranslatorInterface;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\Validator\ValidatorInterface;
+
+/**
+ * An execution context that is compatible with the legacy API (< 2.5).
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Implemented for backwards compatibility with Symfony < 2.5.
+ * To be removed in Symfony 3.0.
+ */
+class LegacyExecutionContext extends ExecutionContext
+{
+ /**
+ * @var MetadataFactoryInterface
+ */
+ private $metadataFactory;
+
+ /**
+ * Creates a new context.
+ *
+ * @see ExecutionContext::__construct()
+ *
+ * @internal Called by {@link LegacyExecutionContextFactory}. Should not be used
+ * in user code.
+ */
+ public function __construct(ValidatorInterface $validator, $root, MetadataFactoryInterface $metadataFactory, TranslatorInterface $translator, $translationDomain = null)
+ {
+ parent::__construct(
+ $validator,
+ $root,
+ $translator,
+ $translationDomain
+ );
+
+ $this->metadataFactory = $metadataFactory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addViolation($message, array $parameters = array(), $invalidValue = null, $plural = null, $code = null)
+ {
+ if (func_num_args() > 2) {
+ $this
+ ->buildViolation($message, $parameters)
+ ->setInvalidValue($invalidValue)
+ ->setPlural($plural)
+ ->setCode($code)
+ ->addViolation()
+ ;
+
+ return;
+ }
+
+ parent::addViolation($message, $parameters);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addViolationAt($subPath, $message, array $parameters = array(), $invalidValue = null, $plural = null, $code = null)
+ {
+ if (func_num_args() > 2) {
+ $this
+ ->buildViolation($message, $parameters)
+ ->atPath($subPath)
+ ->setInvalidValue($invalidValue)
+ ->setPlural($plural)
+ ->setCode($code)
+ ->addViolation()
+ ;
+
+ return;
+ }
+
+ $this
+ ->buildViolation($message, $parameters)
+ ->atPath($subPath)
+ ->addViolation()
+ ;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, $subPath = '', $groups = null, $traverse = false, $deep = false)
+ {
+ if (is_array($value)) {
+ // The $traverse flag is ignored for arrays
+ $constraint = new Valid(array('traverse' => true, 'deep' => $deep));
+
+ return $this
+ ->getValidator()
+ ->inContext($this)
+ ->atPath($subPath)
+ ->validate($value, $constraint, $groups)
+ ;
+ }
+
+ if ($traverse && $value instanceof \Traversable) {
+ $constraint = new Valid(array('traverse' => true, 'deep' => $deep));
+
+ return $this
+ ->getValidator()
+ ->inContext($this)
+ ->atPath($subPath)
+ ->validate($value, $constraint, $groups)
+ ;
+ }
+
+ return $this
+ ->getValidator()
+ ->inContext($this)
+ ->atPath($subPath)
+ ->validate($value, null, $groups)
+ ;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateValue($value, $constraints, $subPath = '', $groups = null)
+ {
+ return $this
+ ->getValidator()
+ ->inContext($this)
+ ->atPath($subPath)
+ ->validate($value, $constraints, $groups)
+ ;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadataFactory()
+ {
+ return $this->metadataFactory;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Context/LegacyExecutionContextFactory.php b/vendor/symfony/validator/Symfony/Component/Validator/Context/LegacyExecutionContextFactory.php
new file mode 100644
index 0000000..cf5cd07
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Context/LegacyExecutionContextFactory.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Context;
+
+use Symfony\Component\Translation\TranslatorInterface;
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\Validator\ValidatorInterface;
+
+/**
+ * Creates new {@link LegacyExecutionContext} instances.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Implemented for backwards compatibility with Symfony < 2.5.
+ * To be removed in Symfony 3.0.
+ */
+class LegacyExecutionContextFactory implements ExecutionContextFactoryInterface
+{
+ /**
+ * @var MetadataFactoryInterface
+ */
+ private $metadataFactory;
+
+ /**
+ * @var TranslatorInterface
+ */
+ private $translator;
+
+ /**
+ * @var string|null
+ */
+ private $translationDomain;
+
+ /**
+ * Creates a new context factory.
+ *
+ * @param MetadataFactoryInterface $metadataFactory The metadata factory
+ * @param TranslatorInterface $translator The translator
+ * @param string|null $translationDomain The translation domain
+ * to use for translating
+ * violation messages
+ */
+ public function __construct(MetadataFactoryInterface $metadataFactory, TranslatorInterface $translator, $translationDomain = null)
+ {
+ $this->metadataFactory = $metadataFactory;
+ $this->translator = $translator;
+ $this->translationDomain = $translationDomain;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createContext(ValidatorInterface $validator, $root)
+ {
+ return new LegacyExecutionContext(
+ $validator,
+ $root,
+ $this->metadataFactory,
+ $this->translator,
+ $this->translationDomain
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/DefaultTranslator.php b/vendor/symfony/validator/Symfony/Component/Validator/DefaultTranslator.php
new file mode 100644
index 0000000..06967de
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/DefaultTranslator.php
@@ -0,0 +1,167 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+use Symfony\Component\Translation\TranslatorInterface;
+use Symfony\Component\Validator\Exception\BadMethodCallException;
+use Symfony\Component\Validator\Exception\InvalidArgumentException;
+
+/**
+ * Simple translator implementation that simply replaces the parameters in
+ * the message IDs.
+ *
+ * Example usage:
+ *
+ * $translator = new DefaultTranslator();
+ *
+ * echo $translator->trans(
+ * 'This is a {{ var }}.',
+ * array('{{ var }}' => 'donkey')
+ * );
+ *
+ * // -> This is a donkey.
+ *
+ * echo $translator->transChoice(
+ * 'This is {{ count }} donkey.|These are {{ count }} donkeys.',
+ * 3,
+ * array('{{ count }}' => 'three')
+ * );
+ *
+ * // -> These are three donkeys.
+ *
+ * This translator does not support message catalogs, translation domains or
+ * locales. Instead, it implements a subset of the capabilities of
+ * {@link \Symfony\Component\Translation\Translator} and can be used in places
+ * where translation is not required by default but should be optional.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class DefaultTranslator implements TranslatorInterface
+{
+ /**
+ * Interpolates the given message.
+ *
+ * Parameters are replaced in the message in the same manner that
+ * {@link strtr()} uses.
+ *
+ * Example usage:
+ *
+ * $translator = new DefaultTranslator();
+ *
+ * echo $translator->trans(
+ * 'This is a {{ var }}.',
+ * array('{{ var }}' => 'donkey')
+ * );
+ *
+ * // -> This is a donkey.
+ *
+ * @param string $id The message id
+ * @param array $parameters An array of parameters for the message
+ * @param string $domain Ignored
+ * @param string $locale Ignored
+ *
+ * @return string The interpolated string
+ */
+ public function trans($id, array $parameters = array(), $domain = null, $locale = null)
+ {
+ return strtr($id, $parameters);
+ }
+
+ /**
+ * Interpolates the given choice message by choosing a variant according to a number.
+ *
+ * The variants are passed in the message ID using the format
+ * "<singular>|<plural>". "<singular>" is chosen if the passed $number is
+ * exactly 1. "<plural>" is chosen otherwise.
+ *
+ * This format is consistent with the format supported by
+ * {@link \Symfony\Component\Translation\Translator}, but it does not
+ * have the same expressiveness. While Translator supports intervals in
+ * message translations, which are needed for languages other than English,
+ * this translator does not. You should use Translator or a custom
+ * implementation of {@link TranslatorInterface} if you need this or similar
+ * functionality.
+ *
+ * Example usage:
+ *
+ * echo $translator->transChoice(
+ * 'This is {{ count }} donkey.|These are {{ count }} donkeys.',
+ * 0,
+ * array('{{ count }}' => 0)
+ * );
+ *
+ * // -> These are 0 donkeys.
+ *
+ * echo $translator->transChoice(
+ * 'This is {{ count }} donkey.|These are {{ count }} donkeys.',
+ * 1,
+ * array('{{ count }}' => 1)
+ * );
+ *
+ * // -> This is 1 donkey.
+ *
+ * echo $translator->transChoice(
+ * 'This is {{ count }} donkey.|These are {{ count }} donkeys.',
+ * 3,
+ * array('{{ count }}' => 3)
+ * );
+ *
+ * // -> These are 3 donkeys.
+ *
+ * @param string $id The message id
+ * @param int $number The number to use to find the index of the message
+ * @param array $parameters An array of parameters for the message
+ * @param string $domain Ignored
+ * @param string $locale Ignored
+ *
+ * @return string The translated string
+ *
+ * @throws InvalidArgumentException If the message id does not have the format
+ * "singular|plural".
+ */
+ public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
+ {
+ $ids = explode('|', $id);
+
+ if (1 == $number) {
+ return strtr($ids[0], $parameters);
+ }
+
+ if (!isset($ids[1])) {
+ throw new InvalidArgumentException(sprintf('The message "%s" cannot be pluralized, because it is missing a plural (e.g. "There is one apple|There are %%count%% apples").', $id));
+ }
+
+ return strtr($ids[1], $parameters);
+ }
+
+ /**
+ * Not supported.
+ *
+ * @param string $locale The locale
+ *
+ * @throws BadMethodCallException
+ */
+ public function setLocale($locale)
+ {
+ throw new BadMethodCallException('Unsupported method.');
+ }
+
+ /**
+ * Returns the locale of the translator.
+ *
+ * @return string Always returns 'en'
+ */
+ public function getLocale()
+ {
+ return 'en';
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/BadMethodCallException.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/BadMethodCallException.php
new file mode 100644
index 0000000..939161b
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/BadMethodCallException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+/**
+ * Base BadMethodCallException for the Validator component.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/ConstraintDefinitionException.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/ConstraintDefinitionException.php
new file mode 100644
index 0000000..b24fdd6
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/ConstraintDefinitionException.php
@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+class ConstraintDefinitionException extends ValidatorException
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/ExceptionInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..77d09b9
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/ExceptionInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+/**
+ * Base ExceptionInterface for the Validator component.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface ExceptionInterface
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/GroupDefinitionException.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/GroupDefinitionException.php
new file mode 100644
index 0000000..ab7e91d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/GroupDefinitionException.php
@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+class GroupDefinitionException extends ValidatorException
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/InvalidArgumentException.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..22da39b
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/InvalidArgumentException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+/**
+ * Base InvalidArgumentException for the Validator component.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/InvalidOptionsException.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/InvalidOptionsException.php
new file mode 100644
index 0000000..ce87c42
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/InvalidOptionsException.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+class InvalidOptionsException extends ValidatorException
+{
+ private $options;
+
+ public function __construct($message, array $options)
+ {
+ parent::__construct($message);
+
+ $this->options = $options;
+ }
+
+ public function getOptions()
+ {
+ return $this->options;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/MappingException.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/MappingException.php
new file mode 100644
index 0000000..4c8c057
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/MappingException.php
@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+class MappingException extends ValidatorException
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/MissingOptionsException.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/MissingOptionsException.php
new file mode 100644
index 0000000..07c5d9e
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/MissingOptionsException.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+class MissingOptionsException extends ValidatorException
+{
+ private $options;
+
+ public function __construct($message, array $options)
+ {
+ parent::__construct($message);
+
+ $this->options = $options;
+ }
+
+ public function getOptions()
+ {
+ return $this->options;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/NoSuchMetadataException.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/NoSuchMetadataException.php
new file mode 100644
index 0000000..4cac74c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/NoSuchMetadataException.php
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class NoSuchMetadataException extends ValidatorException
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/OutOfBoundsException.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/OutOfBoundsException.php
new file mode 100644
index 0000000..30906e8
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/OutOfBoundsException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+/**
+ * Base OutOfBoundsException for the Validator component.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/RuntimeException.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/RuntimeException.php
new file mode 100644
index 0000000..df4a50c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/RuntimeException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+/**
+ * Base RuntimeException for the Validator component.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class RuntimeException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/UnexpectedTypeException.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/UnexpectedTypeException.php
new file mode 100644
index 0000000..49d8cc2
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/UnexpectedTypeException.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+class UnexpectedTypeException extends ValidatorException
+{
+ public function __construct($value, $expectedType)
+ {
+ parent::__construct(sprintf('Expected argument of type "%s", "%s" given', $expectedType, is_object($value) ? get_class($value) : gettype($value)));
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/UnsupportedMetadataException.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/UnsupportedMetadataException.php
new file mode 100644
index 0000000..c6ece50
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/UnsupportedMetadataException.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+/**
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class UnsupportedMetadataException extends InvalidArgumentException
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Exception/ValidatorException.php b/vendor/symfony/validator/Symfony/Component/Validator/Exception/ValidatorException.php
new file mode 100644
index 0000000..28bd470
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Exception/ValidatorException.php
@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Exception;
+
+class ValidatorException extends RuntimeException
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ExecutionContext.php b/vendor/symfony/validator/Symfony/Component/Validator/ExecutionContext.php
new file mode 100644
index 0000000..31911b8
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ExecutionContext.php
@@ -0,0 +1,293 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+use Symfony\Component\Translation\TranslatorInterface;
+
+/**
+ * Default implementation of {@link ExecutionContextInterface}.
+ *
+ * This class is immutable by design.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Context\ExecutionContext} instead.
+ */
+class ExecutionContext implements ExecutionContextInterface
+{
+ /**
+ * @var GlobalExecutionContextInterface
+ */
+ private $globalContext;
+
+ /**
+ * @var TranslatorInterface
+ */
+ private $translator;
+
+ /**
+ * @var null|string
+ */
+ private $translationDomain;
+
+ /**
+ * @var MetadataInterface
+ */
+ private $metadata;
+
+ /**
+ * @var mixed
+ */
+ private $value;
+
+ /**
+ * @var string
+ */
+ private $group;
+
+ /**
+ * @var string
+ */
+ private $propertyPath;
+
+ /**
+ * Creates a new execution context.
+ *
+ * @param GlobalExecutionContextInterface $globalContext The global context storing node-independent state.
+ * @param TranslatorInterface $translator The translator for translating violation messages.
+ * @param null|string $translationDomain The domain of the validation messages.
+ * @param MetadataInterface $metadata The metadata of the validated node.
+ * @param mixed $value The value of the validated node.
+ * @param string $group The current validation group.
+ * @param string $propertyPath The property path to the current node.
+ */
+ public function __construct(GlobalExecutionContextInterface $globalContext, TranslatorInterface $translator, $translationDomain = null, MetadataInterface $metadata = null, $value = null, $group = null, $propertyPath = '')
+ {
+ if (null === $group) {
+ $group = Constraint::DEFAULT_GROUP;
+ }
+
+ $this->globalContext = $globalContext;
+ $this->translator = $translator;
+ $this->translationDomain = $translationDomain;
+ $this->metadata = $metadata;
+ $this->value = $value;
+ $this->propertyPath = $propertyPath;
+ $this->group = $group;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addViolation($message, array $params = array(), $invalidValue = null, $plural = null, $code = null)
+ {
+ if (null === $plural) {
+ $translatedMessage = $this->translator->trans($message, $params, $this->translationDomain);
+ } else {
+ try {
+ $translatedMessage = $this->translator->transChoice($message, $plural, $params, $this->translationDomain);
+ } catch (\InvalidArgumentException $e) {
+ $translatedMessage = $this->translator->trans($message, $params, $this->translationDomain);
+ }
+ }
+
+ $this->globalContext->getViolations()->add(new ConstraintViolation(
+ $translatedMessage,
+ $message,
+ $params,
+ $this->globalContext->getRoot(),
+ $this->propertyPath,
+ // check using func_num_args() to allow passing null values
+ func_num_args() >= 3 ? $invalidValue : $this->value,
+ $plural,
+ $code
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addViolationAt($subPath, $message, array $parameters = array(), $invalidValue = null, $plural = null, $code = null)
+ {
+ $this->globalContext->getViolations()->add(new ConstraintViolation(
+ null === $plural
+ ? $this->translator->trans($message, $parameters, $this->translationDomain)
+ : $this->translator->transChoice($message, $plural, $parameters, $this->translationDomain),
+ $message,
+ $parameters,
+ $this->globalContext->getRoot(),
+ $this->getPropertyPath($subPath),
+ // check using func_num_args() to allow passing null values
+ func_num_args() >= 4 ? $invalidValue : $this->value,
+ $plural,
+ $code
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getViolations()
+ {
+ return $this->globalContext->getViolations();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRoot()
+ {
+ return $this->globalContext->getRoot();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPropertyPath($subPath = '')
+ {
+ if ('' != $subPath && '' !== $this->propertyPath && '[' !== $subPath[0]) {
+ return $this->propertyPath.'.'.$subPath;
+ }
+
+ return $this->propertyPath.$subPath;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getClassName()
+ {
+ if ($this->metadata instanceof ClassBasedInterface) {
+ return $this->metadata->getClassName();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPropertyName()
+ {
+ if ($this->metadata instanceof PropertyMetadataInterface) {
+ return $this->metadata->getPropertyName();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getGroup()
+ {
+ return $this->group;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadata()
+ {
+ return $this->metadata;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadataFor($value)
+ {
+ return $this->globalContext->getMetadataFactory()->getMetadataFor($value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, $subPath = '', $groups = null, $traverse = false, $deep = false)
+ {
+ $propertyPath = $this->getPropertyPath($subPath);
+
+ foreach ($this->resolveGroups($groups) as $group) {
+ $this->globalContext->getVisitor()->validate($value, $group, $propertyPath, $traverse, $deep);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateValue($value, $constraints, $subPath = '', $groups = null)
+ {
+ $constraints = is_array($constraints) ? $constraints : array($constraints);
+
+ if (null === $groups && '' === $subPath) {
+ $context = clone $this;
+ $context->value = $value;
+ $context->executeConstraintValidators($value, $constraints);
+
+ return;
+ }
+
+ $propertyPath = $this->getPropertyPath($subPath);
+
+ foreach ($this->resolveGroups($groups) as $group) {
+ $context = clone $this;
+ $context->value = $value;
+ $context->group = $group;
+ $context->propertyPath = $propertyPath;
+ $context->executeConstraintValidators($value, $constraints);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadataFactory()
+ {
+ return $this->globalContext->getMetadataFactory();
+ }
+
+ /**
+ * Executes the validators of the given constraints for the given value.
+ *
+ * @param mixed $value The value to validate.
+ * @param Constraint[] $constraints The constraints to match against.
+ */
+ private function executeConstraintValidators($value, array $constraints)
+ {
+ foreach ($constraints as $constraint) {
+ $validator = $this->globalContext->getValidatorFactory()->getInstance($constraint);
+ $validator->initialize($this);
+ $validator->validate($value, $constraint);
+ }
+ }
+
+ /**
+ * Returns an array of group names.
+ *
+ * @param null|string|string[] $groups The groups to resolve. If a single string is
+ * passed, it is converted to an array. If null
+ * is passed, an array containing the current
+ * group of the context is returned.
+ *
+ * @return array An array of validation groups.
+ */
+ private function resolveGroups($groups)
+ {
+ return $groups ? (array) $groups : (array) $this->group;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ExecutionContextInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/ExecutionContextInterface.php
new file mode 100644
index 0000000..ebef4bd
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ExecutionContextInterface.php
@@ -0,0 +1,329 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * Stores the validator's state during validation.
+ *
+ * For example, let's validate the following object graph:
+ *
+ * <pre>
+ * (Person)---($firstName: string)
+ * \
+ * ($address: Address)---($street: string)
+ * </pre>
+ *
+ * We validate the <tt>Person</tt> instance, which becomes the "root" of the
+ * validation run (see {@link getRoot}). The state of the context after the
+ * first step will be like this:
+ *
+ * <pre>
+ * (Person)---($firstName: string)
+ * ^ \
+ * ($address: Address)---($street: string)
+ * </pre>
+ *
+ * The validator is stopped at the <tt>Person</tt> node, both the root and the
+ * value (see {@link getValue}) of the context point to the <tt>Person</tt>
+ * instance. The property path is empty at this point (see {@link getPropertyPath}).
+ * The metadata of the context is the metadata of the <tt>Person</tt> node
+ * (see {@link getMetadata}).
+ *
+ * After advancing to the property <tt>$firstName</tt> of the <tt>Person</tt>
+ * instance, the state of the context looks like this:
+ *
+ * <pre>
+ * (Person)---($firstName: string)
+ * \ ^
+ * ($address: Address)---($street: string)
+ * </pre>
+ *
+ * The validator is stopped at the property <tt>$firstName</tt>. The root still
+ * points to the <tt>Person</tt> instance, because this is where the validation
+ * started. The property path is now "firstName" and the current value is the
+ * value of that property.
+ *
+ * After advancing to the <tt>$address</tt> property and then to the
+ * <tt>$street</tt> property of the <tt>Address</tt> instance, the context state
+ * looks like this:
+ *
+ * <pre>
+ * (Person)---($firstName: string)
+ * \
+ * ($address: Address)---($street: string)
+ * ^
+ * </pre>
+ *
+ * The validator is stopped at the property <tt>$street</tt>. The root still
+ * points to the <tt>Person</tt> instance, but the property path is now
+ * "address.street" and the validated value is the value of that property.
+ *
+ * Apart from the root, the property path and the currently validated value,
+ * the execution context also knows the metadata of the current node (see
+ * {@link getMetadata}) which for example returns a {@link Mapping\PropertyMetadata}
+ * or a {@link Mapping\ClassMetadata} object. he context also contains the
+ * validation group that is currently being validated (see {@link getGroup}) and
+ * the violations that happened up until now (see {@link getViolations}).
+ *
+ * Apart from reading the execution context, you can also use
+ * {@link addViolation} or {@link addViolationAt} to add new violations and
+ * {@link validate} or {@link validateValue} to validate values that the
+ * validator otherwise would not reach.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Context\ExecutionContextInterface} instead.
+ */
+interface ExecutionContextInterface
+{
+ /**
+ * Adds a violation at the current node of the validation graph.
+ *
+ * @param string $message The error message
+ * @param array $params The parameters substituted in the error message
+ * @param mixed $invalidValue The invalid, validated value
+ * @param int|null $plural The number to use to pluralize of the message
+ * @param int|null $code The violation code
+ *
+ * @api
+ *
+ * @deprecated The parameters $invalidValue, $pluralization and $code are
+ * deprecated since version 2.5 and will be removed in
+ * Symfony 3.0.
+ */
+ public function addViolation($message, array $params = array(), $invalidValue = null, $plural = null, $code = null);
+
+ /**
+ * Adds a violation at the validation graph node with the given property
+ * path relative to the current property path.
+ *
+ * @param string $subPath The relative property path for the violation
+ * @param string $message The error message
+ * @param array $parameters The parameters substituted in the error message
+ * @param mixed $invalidValue The invalid, validated value
+ * @param int|null $plural The number to use to pluralize of the message
+ * @param int|null $code The violation code
+ *
+ * @api
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Context\ExecutionContextInterface::buildViolation()}
+ * instead.
+ */
+ public function addViolationAt($subPath, $message, array $parameters = array(), $invalidValue = null, $plural = null, $code = null);
+
+ /**
+ * Validates the given value within the scope of the current validation.
+ *
+ * The value may be any value recognized by the used metadata factory
+ * (see {@link MetadataFactoryInterface::getMetadata}), or an array or a
+ * traversable object of such values.
+ *
+ * Usually you validate a value that is not the current node of the
+ * execution context. For this case, you can pass the {@link $subPath}
+ * argument which is appended to the current property path when a violation
+ * is created. For example, take the following object graph:
+ *
+ * <pre>
+ * (Person)---($address: Address)---($phoneNumber: PhoneNumber)
+ * ^
+ * </pre>
+ *
+ * When the execution context stops at the <tt>Person</tt> instance, the
+ * property path is "address". When you validate the <tt>PhoneNumber</tt>
+ * instance now, pass "phoneNumber" as sub path to correct the property path
+ * to "address.phoneNumber":
+ *
+ * <pre>
+ * $context->validate($address->phoneNumber, 'phoneNumber');
+ * </pre>
+ *
+ * Any violations generated during the validation will be added to the
+ * violation list that you can access with {@link getViolations}.
+ *
+ * @param mixed $value The value to validate.
+ * @param string $subPath The path to append to the context's property path.
+ * @param null|string|string[] $groups The groups to validate in. If you don't pass any
+ * groups here, the current group of the context
+ * will be used.
+ * @param bool $traverse Whether to traverse the value if it is an array
+ * or an instance of <tt>\Traversable</tt>.
+ * @param bool $deep Whether to traverse the value recursively if
+ * it is a collection of collections.
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Context\ExecutionContextInterface::getValidator()}
+ * instead.
+ */
+ public function validate($value, $subPath = '', $groups = null, $traverse = false, $deep = false);
+
+ /**
+ * Validates a value against a constraint.
+ *
+ * Use the parameter <tt>$subPath</tt> to adapt the property path for the
+ * validated value. For example, take the following object graph:
+ *
+ * <pre>
+ * (Person)---($address: Address)---($street: string)
+ * ^
+ * </pre>
+ *
+ * When the validator validates the <tt>Address</tt> instance, the
+ * property path stored in the execution context is "address". When you
+ * manually validate the property <tt>$street</tt> now, pass the sub path
+ * "street" to adapt the full property path to "address.street":
+ *
+ * <pre>
+ * $context->validate($address->street, new NotNull(), 'street');
+ * </pre>
+ *
+ * @param mixed $value The value to validate.
+ * @param Constraint|Constraint[] $constraints The constraint(s) to validate against.
+ * @param string $subPath The path to append to the context's property path.
+ * @param null|string|string[] $groups The groups to validate in. If you don't pass any
+ * groups here, the current group of the context
+ * will be used.
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Context\ExecutionContextInterface::getValidator()}
+ * instead.
+ */
+ public function validateValue($value, $constraints, $subPath = '', $groups = null);
+
+ /**
+ * Returns the violations generated by the validator so far.
+ *
+ * @return ConstraintViolationListInterface The constraint violation list.
+ *
+ * @api
+ */
+ public function getViolations();
+
+ /**
+ * 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}.
+ *
+ * @return mixed The root value of the validation.
+ */
+ public function getRoot();
+
+ /**
+ * 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}.
+ *
+ * @return mixed The currently validated value.
+ */
+ public function getValue();
+
+ /**
+ * Returns the metadata for the currently validated value.
+ *
+ * With the core implementation, this method returns a
+ * {@link Mapping\ClassMetadata} 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.
+ *
+ * @return MetadataInterface|null The metadata of the currently validated
+ * value.
+ */
+ public function getMetadata();
+
+ /**
+ * Returns the used metadata factory.
+ *
+ * @return MetadataFactoryInterface The metadata factory.
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Context\ExecutionContextInterface::getValidator()}
+ * instead and call
+ * {@link Validator\ValidatorInterface::getMetadataFor()} or
+ * {@link Validator\ValidatorInterface::hasMetadataFor()} there.
+ */
+ public function getMetadataFactory();
+
+ /**
+ * Returns the validation group that is currently being validated.
+ *
+ * @return string The current validation group.
+ */
+ public function getGroup();
+
+ /**
+ * Returns the class name of the current node.
+ *
+ * If the metadata of the current node does not implement
+ * {@link ClassBasedInterface} or if no metadata is available for the
+ * current node, this method returns null.
+ *
+ * @return string|null The class name or null, if no class name could be found.
+ */
+ public function getClassName();
+
+ /**
+ * 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.
+ *
+ * @return string|null The property name or null, if no property name could be found.
+ */
+ public function getPropertyName();
+
+ /**
+ * Returns the property path to the value that the validator is currently
+ * validating.
+ *
+ * For example, take the following object graph:
+ *
+ * <pre>
+ * (Person)---($address: Address)---($street: string)
+ * </pre>
+ *
+ * When the <tt>Person</tt> instance is passed to the validator, the
+ * property path is initially empty. When the <tt>$address</tt> property
+ * of that person is validated, the property path is "address". When
+ * the <tt>$street</tt> property of the related <tt>Address</tt> 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 <tt>$addresses</tt> and contains an array
+ * of <tt>Address</tt> instance, the property path generated for the
+ * <tt>$street</tt> 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($subPath = '');
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/GlobalExecutionContextInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/GlobalExecutionContextInterface.php
new file mode 100644
index 0000000..06dbf3e
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/GlobalExecutionContextInterface.php
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * Stores the node-independent state of a validation run.
+ *
+ * When the validator validates a graph of objects, it uses two classes to
+ * store the state during the validation:
+ *
+ * <ul>
+ * <li>For each node in the validation graph (objects, properties, getters) the
+ * validator creates an instance of {@link ExecutionContextInterface} that
+ * stores the information about that node.</li>
+ * <li>One single <tt>GlobalExecutionContextInterface</tt> stores the state
+ * that is independent of the current node.</li>
+ * </ul>
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Context\ExecutionContextInterface} instead.
+ */
+interface GlobalExecutionContextInterface
+{
+ /**
+ * Returns the violations generated by the validator so far.
+ *
+ * @return ConstraintViolationListInterface A list of constraint violations.
+ */
+ public function getViolations();
+
+ /**
+ * Returns the value at which validation was started in the object graph.
+ *
+ * @return mixed The root value.
+ *
+ * @see ExecutionContextInterface::getRoot()
+ */
+ public function getRoot();
+
+ /**
+ * Returns the visitor instance used to validate the object graph nodes.
+ *
+ * @return ValidationVisitorInterface The validation visitor.
+ */
+ public function getVisitor();
+
+ /**
+ * Returns the factory for constraint validators.
+ *
+ * @return ConstraintValidatorFactoryInterface The constraint validator factory.
+ */
+ public function getValidatorFactory();
+
+ /**
+ * Returns the factory for validation metadata objects.
+ *
+ * @return MetadataFactoryInterface The metadata factory.
+ */
+ public function getMetadataFactory();
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/GroupSequenceProviderInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/GroupSequenceProviderInterface.php
new file mode 100644
index 0000000..62e8a5e
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/GroupSequenceProviderInterface.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * 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 array An array of validation groups
+ */
+ public function getGroupSequence();
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/LICENSE b/vendor/symfony/validator/Symfony/Component/Validator/LICENSE
new file mode 100644
index 0000000..43028bc
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2015 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/vendor/symfony/validator/Symfony/Component/Validator/Mapping/BlackholeMetadataFactory.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/BlackholeMetadataFactory.php
new file mode 100644
index 0000000..7913e15
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/BlackholeMetadataFactory.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping;
+
+/**
+ * Alias of {@link Factory\BlackHoleMetadataFactory}.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Factory\BlackHoleMetadataFactory} instead.
+ */
+class BlackholeMetadataFactory extends \Symfony\Component\Validator\Mapping\Factory\BlackHoleMetadataFactory
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/ApcCache.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/ApcCache.php
new file mode 100644
index 0000000..64929b0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/ApcCache.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Cache;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+/**
+ * @deprecated Deprecated since version 2.5, to be removed in 3.0.
+ * Use DoctrineCache with Doctrine\Common\Cache\ApcCache instead.
+ */
+class ApcCache implements CacheInterface
+{
+ private $prefix;
+
+ public function __construct($prefix)
+ {
+ if (!extension_loaded('apc')) {
+ throw new \RuntimeException('Unable to use ApcCache to cache validator mappings as APC is not enabled.');
+ }
+
+ $this->prefix = $prefix;
+ }
+
+ public function has($class)
+ {
+ if (!function_exists('apc_exists')) {
+ $exists = false;
+
+ apc_fetch($this->prefix.$class, $exists);
+
+ return $exists;
+ }
+
+ return apc_exists($this->prefix.$class);
+ }
+
+ public function read($class)
+ {
+ return apc_fetch($this->prefix.$class);
+ }
+
+ public function write(ClassMetadata $metadata)
+ {
+ apc_store($this->prefix.$metadata->getClassName(), $metadata);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/CacheInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/CacheInterface.php
new file mode 100644
index 0000000..e8047c6
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/CacheInterface.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Cache;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+/**
+ * Persists ClassMetadata instances in a cache.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface CacheInterface
+{
+ /**
+ * Returns whether metadata for the given class exists in the cache.
+ *
+ * @param string $class
+ */
+ public function has($class);
+
+ /**
+ * Returns the metadata for the given class from the cache.
+ *
+ * @param string $class Class Name
+ *
+ * @return ClassMetadata|false A ClassMetadata instance or false on miss
+ */
+ public function read($class);
+
+ /**
+ * Stores a class metadata in the cache.
+ *
+ * @param ClassMetadata $metadata A Class Metadata
+ */
+ public function write(ClassMetadata $metadata);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/DoctrineCache.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/DoctrineCache.php
new file mode 100644
index 0000000..6dd5447
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/DoctrineCache.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Cache;
+
+use Doctrine\Common\Cache\Cache;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+/**
+ * Adapts a Doctrine cache to a CacheInterface.
+ *
+ * @author Florian Voutzinos <florian@voutzinos.com>
+ */
+final class DoctrineCache implements CacheInterface
+{
+ private $cache;
+
+ /**
+ * Creates a new Doctrine cache.
+ *
+ * @param Cache $cache The cache to adapt
+ */
+ public function __construct(Cache $cache)
+ {
+ $this->cache = $cache;
+ }
+
+ /**
+ * Sets the cache to adapt.
+ *
+ * @param Cache $cache The cache to adapt
+ */
+ public function setCache(Cache $cache)
+ {
+ $this->cache = $cache;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($class)
+ {
+ return $this->cache->contains($class);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($class)
+ {
+ return $this->cache->fetch($class);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write(ClassMetadata $metadata)
+ {
+ $this->cache->save($metadata->getClassName(), $metadata);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/CascadingStrategy.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/CascadingStrategy.php
new file mode 100644
index 0000000..ff2853f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/CascadingStrategy.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see TraversalStrategy
+ */
+class CascadingStrategy
+{
+ /**
+ * Specifies that a node should not be cascaded.
+ */
+ const NONE = 1;
+
+ /**
+ * Specifies that a node should be cascaded.
+ */
+ const CASCADE = 2;
+
+ /**
+ * Not instantiable.
+ */
+ private function __construct()
+ {
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadata.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadata.php
new file mode 100644
index 0000000..a234939
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadata.php
@@ -0,0 +1,548 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping;
+
+use Symfony\Component\Validator\Constraint;
+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\ValidationVisitorInterface;
+
+/**
+ * Default implementation of {@link ClassMetadataInterface}.
+ *
+ * This class supports serialization and cloning.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ClassMetadata extends ElementMetadata implements ClassMetadataInterface
+{
+ /**
+ * @var string
+ *
+ * @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 $name;
+
+ /**
+ * @var string
+ *
+ * @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 $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 $members = array();
+
+ /**
+ * @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 $properties = array();
+
+ /**
+ * @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 $getters = array();
+
+ /**
+ * @var array
+ *
+ * @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 = array();
+
+ /**
+ * @var bool
+ *
+ * @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 $groupSequenceProvider = false;
+
+ /**
+ * The strategy for traversing traversable objects.
+ *
+ * By default, only instances of {@link \Traversable} are traversed.
+ *
+ * @var int
+ *
+ * @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 $traversalStrategy = TraversalStrategy::IMPLICIT;
+
+ /**
+ * @var \ReflectionClass
+ */
+ private $reflClass;
+
+ /**
+ * Constructs a metadata for the given class.
+ *
+ * @param string $class
+ */
+ public function __construct($class)
+ {
+ $this->name = $class;
+ // class name without namespace
+ if (false !== $nsSep = strrpos($class, '\\')) {
+ $this->defaultGroup = substr($class, $nsSep + 1);
+ } else {
+ $this->defaultGroup = $class;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ */
+ public function accept(ValidationVisitorInterface $visitor, $value, $group, $propertyPath, $propagatedGroup = null)
+ {
+ if (null === $propagatedGroup && Constraint::DEFAULT_GROUP === $group
+ && ($this->hasGroupSequence() || $this->isGroupSequenceProvider())) {
+ if ($this->hasGroupSequence()) {
+ $groups = $this->getGroupSequence();
+ } else {
+ $groups = $value->getGroupSequence();
+ }
+
+ foreach ($groups as $group) {
+ $this->accept($visitor, $value, $group, $propertyPath, Constraint::DEFAULT_GROUP);
+
+ if (count($visitor->getViolations()) > 0) {
+ break;
+ }
+ }
+
+ return;
+ }
+
+ $visitor->visit($this, $value, $group, $propertyPath);
+
+ if (null !== $value) {
+ $pathPrefix = empty($propertyPath) ? '' : $propertyPath.'.';
+
+ foreach ($this->getConstrainedProperties() as $property) {
+ foreach ($this->getPropertyMetadata($property) as $member) {
+ $member->accept($visitor, $member->getPropertyValue($value), $group, $pathPrefix.$property, $propagatedGroup);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __sleep()
+ {
+ $parentProperties = parent::__sleep();
+
+ // Don't store the cascading strategy. Classes never cascade.
+ unset($parentProperties[array_search('cascadingStrategy', $parentProperties)]);
+
+ return array_merge($parentProperties, array(
+ 'getters',
+ 'groupSequence',
+ 'groupSequenceProvider',
+ 'members',
+ 'name',
+ 'properties',
+ 'defaultGroup',
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getClassName()
+ {
+ 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
+ * "<ClassName>", where <ClassName> 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 "<ClassName>".
+ *
+ * @return string The name of the default group
+ */
+ public function getDefaultGroup()
+ {
+ return $this->defaultGroup;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addConstraint(Constraint $constraint)
+ {
+ if (!in_array(Constraint::CLASS_CONSTRAINT, (array) $constraint->getTargets())) {
+ throw new ConstraintDefinitionException(sprintf(
+ 'The constraint "%s" cannot be put on classes.',
+ get_class($constraint)
+ ));
+ }
+
+ if ($constraint instanceof Valid) {
+ throw new ConstraintDefinitionException(sprintf(
+ 'The constraint "%s" cannot be put on classes.',
+ get_class($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;
+ }
+
+ $constraint->addImplicitGroupName($this->getDefaultGroup());
+
+ parent::addConstraint($constraint);
+
+ return $this;
+ }
+
+ /**
+ * Adds a constraint to the given property.
+ *
+ * @param string $property The name of the property
+ * @param Constraint $constraint The constraint
+ *
+ * @return ClassMetadata This object
+ */
+ public function addPropertyConstraint($property, Constraint $constraint)
+ {
+ 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 string $property
+ * @param Constraint[] $constraints
+ *
+ * @return ClassMetadata
+ */
+ public function addPropertyConstraints($property, array $constraints)
+ {
+ 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 either the prefix "get" or "is".
+ *
+ * @param string $property The name of the property
+ * @param Constraint $constraint The constraint
+ *
+ * @return ClassMetadata This object
+ */
+ public function addGetterConstraint($property, Constraint $constraint)
+ {
+ 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;
+ }
+
+ /**
+ * @param string $property
+ * @param Constraint[] $constraints
+ *
+ * @return ClassMetadata
+ */
+ public function addGetterConstraints($property, array $constraints)
+ {
+ foreach ($constraints as $constraint) {
+ $this->addGetterConstraint($property, $constraint);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Merges the constraints of the given metadata into this object.
+ *
+ * @param ClassMetadata $source The source metadata
+ */
+ public function mergeConstraints(ClassMetadata $source)
+ {
+ 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) {
+ $constraint->addImplicitGroupName($this->getDefaultGroup());
+ }
+
+ $this->addPropertyMetadata($member);
+
+ if ($member instanceof MemberMetadata && !$member->isPrivate($this->name)) {
+ $property = $member->getPropertyName();
+
+ if ($member instanceof PropertyMetadata && !isset($this->properties[$property])) {
+ $this->properties[$property] = $member;
+ } elseif ($member instanceof GetterMetadata && !isset($this->getters[$property])) {
+ $this->getters[$property] = $member;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds a member metadata.
+ *
+ * @param MemberMetadata $metadata
+ *
+ * @deprecated Deprecated since version 2.6, to be removed in 3.0.
+ */
+ protected function addMemberMetadata(MemberMetadata $metadata)
+ {
+ $this->addPropertyMetadata($metadata);
+ }
+
+ /**
+ * Returns true if metadatas of members is present for the given property.
+ *
+ * @param string $property The name of the property
+ *
+ * @return bool
+ *
+ * @deprecated Deprecated since version 2.6, to be removed in 3.0. Use {@link hasPropertyMetadata} instead.
+ */
+ public function hasMemberMetadatas($property)
+ {
+ return $this->hasPropertyMetadata($property);
+ }
+
+ /**
+ * Returns all metadatas of members describing the given property.
+ *
+ * @param string $property The name of the property
+ *
+ * @return MemberMetadata[] An array of MemberMetadata
+ *
+ * @deprecated Deprecated since version 2.6, to be removed in 3.0. Use {@link getPropertyMetadata} instead.
+ */
+ public function getMemberMetadatas($property)
+ {
+ return $this->getPropertyMetadata($property);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasPropertyMetadata($property)
+ {
+ return array_key_exists($property, $this->members);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPropertyMetadata($property)
+ {
+ if (!isset($this->members[$property])) {
+ return array();
+ }
+
+ return $this->members[$property];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getConstrainedProperties()
+ {
+ return array_keys($this->members);
+ }
+
+ /**
+ * Sets the default group sequence for this class.
+ *
+ * @param array $groupSequence An array of group names
+ *
+ * @return ClassMetadata
+ *
+ * @throws GroupDefinitionException
+ */
+ public function setGroupSequence($groupSequence)
+ {
+ 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;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasGroupSequence()
+ {
+ return count($this->groupSequence) > 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getGroupSequence()
+ {
+ return $this->groupSequence;
+ }
+
+ /**
+ * Returns a ReflectionClass instance for this class.
+ *
+ * @return \ReflectionClass
+ */
+ public function getReflectionClass()
+ {
+ if (!$this->reflClass) {
+ $this->reflClass = new \ReflectionClass($this->getClassName());
+ }
+
+ return $this->reflClass;
+ }
+
+ /**
+ * Sets whether a group sequence provider should be used.
+ *
+ * @param bool $active
+ *
+ * @throws GroupDefinitionException
+ */
+ public function setGroupSequenceProvider($active)
+ {
+ if ($this->hasGroupSequence()) {
+ throw new GroupDefinitionException('Defining a group sequence provider is not allowed with a static group sequence');
+ }
+
+ if (!$this->getReflectionClass()->implementsInterface('Symfony\Component\Validator\GroupSequenceProviderInterface')) {
+ throw new GroupDefinitionException(sprintf('Class "%s" must implement GroupSequenceProviderInterface', $this->name));
+ }
+
+ $this->groupSequenceProvider = $active;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isGroupSequenceProvider()
+ {
+ return $this->groupSequenceProvider;
+ }
+
+ /**
+ * Class nodes are never cascaded.
+ *
+ * {@inheritdoc}
+ */
+ public function getCascadingStrategy()
+ {
+ return CascadingStrategy::NONE;
+ }
+
+ /**
+ * Adds a property metadata.
+ *
+ * @param PropertyMetadataInterface $metadata
+ */
+ private function addPropertyMetadata(PropertyMetadataInterface $metadata)
+ {
+ $property = $metadata->getPropertyName();
+
+ $this->members[$property][] = $metadata;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactory.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactory.php
new file mode 100644
index 0000000..9b05edd
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactory.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping;
+
+use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
+
+/**
+ * Alias of {@link LazyLoadingMetadataFactory}.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link LazyLoadingMetadataFactory} instead.
+ */
+class ClassMetadataFactory extends LazyLoadingMetadataFactory
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataInterface.php
new file mode 100644
index 0000000..bb76c2c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataInterface.php
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping;
+
+use Symfony\Component\Validator\ClassBasedInterface;
+use Symfony\Component\Validator\PropertyMetadataContainerInterface as LegacyPropertyMetadataContainerInterface;
+
+/**
+ * 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.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see MetadataInterface
+ * @see \Symfony\Component\Validator\Constraints\GroupSequence
+ * @see \Symfony\Component\Validator\GroupSequenceProviderInterface
+ * @see TraversalStrategy
+ */
+interface ClassMetadataInterface extends MetadataInterface, LegacyPropertyMetadataContainerInterface, ClassBasedInterface
+{
+ /**
+ * Returns the names of all constrained properties.
+ *
+ * @return string[] A list of property names
+ */
+ public function getConstrainedProperties();
+
+ /**
+ * Returns whether the "Default" group is overridden by a group sequence.
+ *
+ * If it is, you can access the group sequence with {@link getGroupSequence()}.
+ *
+ * @return bool Returns true if the "Default" group is overridden
+ *
+ * @see \Symfony\Component\Validator\Constraints\GroupSequence
+ */
+ public function hasGroupSequence();
+
+ /**
+ * Returns the group sequence that overrides the "Default" group for this
+ * class.
+ *
+ * @return \Symfony\Component\Validator\Constraints\GroupSequence|null The group sequence or null
+ *
+ * @see \Symfony\Component\Validator\Constraints\GroupSequence
+ */
+ public function getGroupSequence();
+
+ /**
+ * 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 \Symfony\Component\Validator\GroupSequenceProviderInterface}.
+ * This interface will be used to obtain the group sequence when an object
+ * of this class is validated.
+ *
+ * @return bool Returns true if the "Default" group is overridden by
+ * a dynamic group sequence
+ *
+ * @see \Symfony\Component\Validator\GroupSequenceProviderInterface
+ */
+ public function isGroupSequenceProvider();
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ElementMetadata.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ElementMetadata.php
new file mode 100644
index 0000000..1b971c9
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ElementMetadata.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping;
+
+/**
+ * Contains the metadata of a structural element.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Extend {@link GenericMetadata} instead.
+ */
+abstract class ElementMetadata extends GenericMetadata
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/BlackHoleMetadataFactory.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/BlackHoleMetadataFactory.php
new file mode 100644
index 0000000..5b38d0c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/BlackHoleMetadataFactory.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Factory;
+
+/**
+ * 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 <fabien@symfony.com>
+ */
+class BlackHoleMetadataFactory implements MetadataFactoryInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadataFor($value)
+ {
+ throw new \LogicException('This class does not support metadata.');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasMetadataFor($value)
+ {
+ return false;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php
new file mode 100644
index 0000000..b6ef076
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php
@@ -0,0 +1,153 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Factory;
+
+use Symfony\Component\Validator\Exception\NoSuchMetadataException;
+use Symfony\Component\Validator\Mapping\Cache\CacheInterface;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
+
+/**
+ * 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 Loader\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 <bschussek@gmail.com>
+ */
+class LazyLoadingMetadataFactory implements MetadataFactoryInterface
+{
+ /**
+ * The loader for loading the class metadata
+ *
+ * @var LoaderInterface|null
+ */
+ protected $loader;
+
+ /**
+ * The cache for caching class metadata
+ *
+ * @var CacheInterface|null
+ */
+ protected $cache;
+
+ /**
+ * The loaded metadata, indexed by class name
+ *
+ * @var ClassMetadata[]
+ */
+ protected $loadedClasses = array();
+
+ /**
+ * Creates a new metadata factory.
+ *
+ * @param LoaderInterface|null $loader The loader for configuring new metadata
+ * @param CacheInterface|null $cache The cache for persisting metadata
+ * between multiple PHP requests
+ */
+ public function __construct(LoaderInterface $loader = null, CacheInterface $cache = null)
+ {
+ $this->loader = $loader;
+ $this->cache = $cache;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * 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($value)
+ {
+ if (!is_object($value) && !is_string($value)) {
+ throw new NoSuchMetadataException(sprintf('Cannot create metadata for non-objects. Got: %s', gettype($value)));
+ }
+
+ $class = ltrim(is_object($value) ? get_class($value) : $value, '\\');
+
+ if (isset($this->loadedClasses[$class])) {
+ return $this->loadedClasses[$class];
+ }
+
+ if (null !== $this->cache && false !== ($this->loadedClasses[$class] = $this->cache->read($class))) {
+ return $this->loadedClasses[$class];
+ }
+
+ if (!class_exists($class) && !interface_exists($class)) {
+ throw new NoSuchMetadataException(sprintf('The class or interface "%s" does not exist.', $class));
+ }
+
+ $metadata = new ClassMetadata($class);
+
+ // Include constraints from the parent class
+ if ($parent = $metadata->getReflectionClass()->getParentClass()) {
+ $metadata->mergeConstraints($this->getMetadataFor($parent->name));
+ }
+
+ // Include constraints from all implemented interfaces
+ foreach ($metadata->getReflectionClass()->getInterfaces() as $interface) {
+ if ('Symfony\Component\Validator\GroupSequenceProviderInterface' === $interface->name) {
+ continue;
+ }
+ $metadata->mergeConstraints($this->getMetadataFor($interface->name));
+ }
+
+ if (null !== $this->loader) {
+ $this->loader->loadClassMetadata($metadata);
+ }
+
+ if (null !== $this->cache) {
+ $this->cache->write($metadata);
+ }
+
+ return $this->loadedClasses[$class] = $metadata;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasMetadataFor($value)
+ {
+ if (!is_object($value) && !is_string($value)) {
+ return false;
+ }
+
+ $class = ltrim(is_object($value) ? get_class($value) : $value, '\\');
+
+ if (class_exists($class) || interface_exists($class)) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/MetadataFactoryInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/MetadataFactoryInterface.php
new file mode 100644
index 0000000..ef25174
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Factory/MetadataFactoryInterface.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Factory;
+
+use Symfony\Component\Validator\MetadataFactoryInterface as LegacyMetadataFactoryInterface;
+
+/**
+ * Returns {@link MetadataInterface} instances for values.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface MetadataFactoryInterface extends LegacyMetadataFactoryInterface
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/GenericMetadata.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/GenericMetadata.php
new file mode 100644
index 0000000..904dcd7
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/GenericMetadata.php
@@ -0,0 +1,243 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Constraints\Traverse;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\Exception\BadMethodCallException;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+use Symfony\Component\Validator\ValidationVisitorInterface;
+
+/**
+ * A generic container of {@link Constraint} objects.
+ *
+ * This class supports serialization and cloning.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+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 $constraints = array();
+
+ /**
+ * @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 $constraintsByGroup = array();
+
+ /**
+ * The strategy for cascading objects.
+ *
+ * By default, objects are not cascaded.
+ *
+ * @var int
+ *
+ * @see 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 $cascadingStrategy = CascadingStrategy::NONE;
+
+ /**
+ * The strategy for traversing traversable objects.
+ *
+ * By default, traversable objects are not traversed.
+ *
+ * @var int
+ *
+ * @see 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 $traversalStrategy = TraversalStrategy::NONE;
+
+ /**
+ * Returns the names of the properties that should be serialized.
+ *
+ * @return string[]
+ */
+ public function __sleep()
+ {
+ return array(
+ 'constraints',
+ 'constraintsByGroup',
+ 'cascadingStrategy',
+ 'traversalStrategy',
+ );
+ }
+
+ /**
+ * Clones this object.
+ */
+ public function __clone()
+ {
+ $constraints = $this->constraints;
+
+ $this->constraints = array();
+ $this->constraintsByGroup = array();
+
+ 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
+ * properties $traverse and $deep of that constraint, the traversal strategy
+ * will be set to one of the following:
+ *
+ * - {@link TraversalStrategy::IMPLICIT} if $traverse is enabled and $deep
+ * is enabled
+ * - {@link TraversalStrategy::IMPLICIT} | {@link TraversalStrategy::STOP_RECURSION}
+ * if $traverse is enabled, but $deep is disabled
+ * - {@link TraversalStrategy::NONE} if $traverse is disabled
+ *
+ * @param Constraint $constraint The constraint to add
+ *
+ * @return GenericMetadata This object
+ *
+ * @throws ConstraintDefinitionException When trying to add the
+ * {@link Traverse} constraint
+ */
+ public function addConstraint(Constraint $constraint)
+ {
+ if ($constraint instanceof Traverse) {
+ throw new ConstraintDefinitionException(sprintf(
+ 'The constraint "%s" can only be put on classes. Please use '.
+ '"Symfony\Component\Validator\Constraints\Valid" instead.',
+ get_class($constraint)
+ ));
+ }
+
+ if ($constraint instanceof Valid) {
+ $this->cascadingStrategy = CascadingStrategy::CASCADE;
+
+ if ($constraint->traverse) {
+ // Traverse unless the value is not traversable
+ $this->traversalStrategy = TraversalStrategy::IMPLICIT;
+
+ if (!$constraint->deep) {
+ $this->traversalStrategy |= TraversalStrategy::STOP_RECURSION;
+ }
+ } else {
+ $this->traversalStrategy = TraversalStrategy::NONE;
+ }
+
+ 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 GenericMetadata This object
+ */
+ public function addConstraints(array $constraints)
+ {
+ foreach ($constraints as $constraint) {
+ $this->addConstraint($constraint);
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getConstraints()
+ {
+ return $this->constraints;
+ }
+
+ /**
+ * Returns whether this element has any constraints.
+ *
+ * @return bool
+ */
+ public function hasConstraints()
+ {
+ return count($this->constraints) > 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * Aware of the global group (* group).
+ */
+ public function findConstraints($group)
+ {
+ return isset($this->constraintsByGroup[$group])
+ ? $this->constraintsByGroup[$group]
+ : array();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCascadingStrategy()
+ {
+ return $this->cascadingStrategy;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getTraversalStrategy()
+ {
+ return $this->traversalStrategy;
+ }
+
+ /**
+ * Exists for compatibility with the deprecated
+ * {@link Symfony\Component\Validator\MetadataInterface}.
+ *
+ * Should not be used.
+ *
+ * @throws BadMethodCallException
+ *
+ * @deprecated Implemented for backwards compatibility with Symfony < 2.5.
+ * Will be removed in Symfony 3.0.
+ */
+ public function accept(ValidationVisitorInterface $visitor, $value, $group, $propertyPath)
+ {
+ throw new BadMethodCallException('Not supported.');
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/GetterMetadata.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/GetterMetadata.php
new file mode 100644
index 0000000..0cf9992
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/GetterMetadata.php
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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 either "get" or "is". 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 <bschussek@gmail.com>
+ *
+ * @see PropertyMetadataInterface
+ */
+class GetterMetadata extends MemberMetadata
+{
+ /**
+ * Constructor.
+ *
+ * @param string $class The class the getter is defined on
+ * @param string $property The property which the getter returns
+ *
+ * @throws ValidatorException
+ */
+ public function __construct($class, $property)
+ {
+ $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));
+ }
+
+ parent::__construct($class, $method, $property);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPropertyValue($object)
+ {
+ return $this->newReflectionMember($object)->invoke($object);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function newReflectionMember($objectOrClassName)
+ {
+ return new \ReflectionMethod($objectOrClassName, $this->getName());
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php
new file mode 100644
index 0000000..2ae8988
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Loader;
+
+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 <bschussek@gmail.com>
+ */
+abstract class AbstractLoader implements LoaderInterface
+{
+ /**
+ * The namespace to load constraints from by default.
+ */
+ const DEFAULT_NAMESPACE = '\\Symfony\\Component\\Validator\\Constraints\\';
+
+ /**
+ * @var array
+ */
+ protected $namespaces = array();
+
+ /**
+ * 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');
+ *
+ * @param string $alias The alias
+ * @param string $namespace The PHP namespace
+ */
+ protected function addNamespaceAlias($alias, $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
+ *
+ * @return Constraint
+ *
+ * @throws MappingException If the namespace prefix is undefined
+ */
+ protected function newConstraint($name, $options = null)
+ {
+ if (strpos($name, '\\') !== false && class_exists($name)) {
+ $className = (string) $name;
+ } elseif (strpos($name, ':') !== false) {
+ list($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;
+ }
+
+ return new $className($options);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php
new file mode 100644
index 0000000..af0bf52
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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}.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class AnnotationLoader implements LoaderInterface
+{
+ /**
+ * @var Reader
+ */
+ protected $reader;
+
+ public function __construct(Reader $reader)
+ {
+ $this->reader = $reader;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function loadClassMetadata(ClassMetadata $metadata)
+ {
+ $reflClass = $metadata->getReflectionClass();
+ $className = $reflClass->name;
+ $success = false;
+
+ foreach ($this->reader->getClassAnnotations($reflClass) as $constraint) {
+ if ($constraint instanceof GroupSequence) {
+ $metadata->setGroupSequence($constraint->groups);
+ } elseif ($constraint instanceof GroupSequenceProvider) {
+ $metadata->setGroupSequenceProvider(true);
+ } elseif ($constraint instanceof Constraint) {
+ $metadata->addConstraint($constraint);
+ }
+
+ $success = true;
+ }
+
+ foreach ($reflClass->getProperties() as $property) {
+ if ($property->getDeclaringClass()->name == $className) {
+ foreach ($this->reader->getPropertyAnnotations($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->reader->getMethodAnnotations($method) as $constraint) {
+ if ($constraint instanceof Callback) {
+ $constraint->callback = $method->getName();
+ $constraint->methods = null;
+
+ $metadata->addConstraint($constraint);
+ } elseif ($constraint instanceof Constraint) {
+ if (preg_match('/^(get|is|has)(.+)$/i', $method->name, $matches)) {
+ $metadata->addGetterConstraint(lcfirst($matches[2]), $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;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FileLoader.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FileLoader.php
new file mode 100644
index 0000000..326bbdf
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FileLoader.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Loader;
+
+use Symfony\Component\Validator\Exception\MappingException;
+
+/**
+ * Base loader for loading validation metadata from a file.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see YamlFileLoader
+ * @see XmlFileLoader
+ */
+abstract class FileLoader extends AbstractLoader
+{
+ /**
+ * The file to load.
+ *
+ * @var string
+ */
+ 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($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/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php
new file mode 100644
index 0000000..571c7e7
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Loader;
+
+/**
+ * Base loader for loading validation metadata from a list of files.
+ *
+ * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @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.
+ *
+ * @param array $paths An array of file paths
+ *
+ * @return LoaderInterface[] The metadata loaders
+ */
+ protected function getFileLoaders($paths)
+ {
+ $loaders = array();
+
+ foreach ($paths as $path) {
+ $loaders[] = $this->getFileLoaderInstance($path);
+ }
+
+ return $loaders;
+ }
+
+ /**
+ * Creates a loader for the given file path.
+ *
+ * @param string $path The file path
+ *
+ * @return LoaderInterface The created loader
+ */
+ abstract protected function getFileLoaderInstance($path);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php
new file mode 100644
index 0000000..970d906
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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 <bschussek@gmail.com>
+ */
+class LoaderChain implements LoaderInterface
+{
+ /**
+ * @var 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_class($loader)));
+ }
+ }
+
+ $this->loaders = $loaders;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function loadClassMetadata(ClassMetadata $metadata)
+ {
+ $success = false;
+
+ foreach ($this->loaders as $loader) {
+ $success = $loader->loadClassMetadata($metadata) || $success;
+ }
+
+ return $success;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.php
new file mode 100644
index 0000000..5dadc82
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Loader;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+/**
+ * Loads validation metadata into {@link ClassMetadata} instances.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface LoaderInterface
+{
+ /**
+ * Loads validation metadata into a {@link ClassMetadata} instance.
+ *
+ * @param ClassMetadata $metadata The metadata to load
+ *
+ * @return bool Whether the loader succeeded
+ */
+ public function loadClassMetadata(ClassMetadata $metadata);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php
new file mode 100644
index 0000000..4ff2257
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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 <bschussek@gmail.com>
+ */
+class StaticMethodLoader implements LoaderInterface
+{
+ /**
+ * The name of the method to call.
+ *
+ * @var string
+ */
+ protected $methodName;
+
+ /**
+ * Creates a new loader.
+ *
+ * @param string $methodName The name of the static method to call
+ */
+ public function __construct($methodName = 'loadValidatorMetadata')
+ {
+ $this->methodName = $methodName;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function loadClassMetadata(ClassMetadata $metadata)
+ {
+ /** @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/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php
new file mode 100644
index 0000000..2961b00
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php
@@ -0,0 +1,219 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Loader;
+
+use Symfony\Component\Config\Util\XmlUtils;
+use Symfony\Component\Validator\Exception\MappingException;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+/**
+ * Loads validation metadata from an XML file.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class XmlFileLoader extends FileLoader
+{
+ /**
+ * The XML nodes of the mapping file.
+ *
+ * @var \SimpleXMLElement[]|null
+ */
+ protected $classes;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function loadClassMetadata(ClassMetadata $metadata)
+ {
+ if (null === $this->classes) {
+ // This method may throw an exception. Do not modify the class'
+ // state before it completes
+ $xml = $this->parseFile($this->file);
+
+ $this->classes = array();
+
+ foreach ($xml->namespace as $namespace) {
+ $this->addNamespaceAlias((string) $namespace['prefix'], trim((string) $namespace));
+ }
+
+ foreach ($xml->class as $class) {
+ $this->classes[(string) $class['name']] = $class;
+ }
+ }
+
+ if (isset($this->classes[$metadata->getClassName()])) {
+ $classDescription = $this->classes[$metadata->getClassName()];
+
+ $this->loadClassMetadataFromXml($metadata, $classDescription);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Parses a collection of "constraint" XML nodes.
+ *
+ * @param \SimpleXMLElement $nodes The XML nodes
+ *
+ * @return array The Constraint instances
+ */
+ protected function parseConstraints(\SimpleXMLElement $nodes)
+ {
+ $constraints = array();
+
+ foreach ($nodes as $node) {
+ if (count($node) > 0) {
+ if (count($node->value) > 0) {
+ $options = $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 = array();
+ }
+ } elseif (strlen((string) $node) > 0) {
+ $options = trim($node);
+ } else {
+ $options = null;
+ }
+
+ $constraints[] = $this->newConstraint((string) $node['name'], $options);
+ }
+
+ return $constraints;
+ }
+
+ /**
+ * Parses a collection of "value" XML nodes.
+ *
+ * @param \SimpleXMLElement $nodes The XML nodes
+ *
+ * @return array The values
+ */
+ protected function parseValues(\SimpleXMLElement $nodes)
+ {
+ $values = array();
+
+ 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 = array();
+ }
+ } 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
+ *
+ * @return array The options
+ */
+ protected function parseOptions(\SimpleXMLElement $nodes)
+ {
+ $options = array();
+
+ 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 = array();
+ }
+ } 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.
+ *
+ * @param string $path The path of the XML file
+ *
+ * @return \SimpleXMLElement The class descriptions
+ *
+ * @throws MappingException If the file could not be loaded
+ */
+ protected function parseFile($path)
+ {
+ 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);
+ }
+
+ /**
+ * Loads the validation metadata from the given XML class description.
+ *
+ * @param ClassMetadata $metadata The metadata to load
+ * @param array $classDescription The XML class description
+ */
+ private function loadClassMetadataFromXml(ClassMetadata $metadata, $classDescription)
+ {
+ foreach ($classDescription->{'group-sequence-provider'} as $_) {
+ $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/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFilesLoader.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFilesLoader.php
new file mode 100644
index 0000000..6017c3f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFilesLoader.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Loader;
+
+/**
+ * Loads validation metadata from a list of XML files.
+ *
+ * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see FilesLoader
+ */
+class XmlFilesLoader extends FilesLoader
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getFileLoaderInstance($file)
+ {
+ return new XmlFileLoader($file);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php
new file mode 100644
index 0000000..e293a6e
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php
@@ -0,0 +1,179 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Loader;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Yaml\Parser as YamlParser;
+
+/**
+ * Loads validation metadata from a YAML file.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class YamlFileLoader extends FileLoader
+{
+ /**
+ * An array of YAML class descriptions.
+ *
+ * @var array
+ */
+ protected $classes = null;
+
+ /**
+ * Caches the used YAML parser.
+ *
+ * @var YamlParser
+ */
+ private $yamlParser;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function loadClassMetadata(ClassMetadata $metadata)
+ {
+ if (null === $this->classes) {
+ if (null === $this->yamlParser) {
+ $this->yamlParser = new YamlParser();
+ }
+
+ // This method may throw an exception. Do not modify the class'
+ // state before it completes
+ if (false === ($classes = $this->parseFile($this->file))) {
+ return false;
+ }
+
+ $this->classes = $classes;
+
+ if (isset($this->classes['namespaces'])) {
+ foreach ($this->classes['namespaces'] as $alias => $namespace) {
+ $this->addNamespaceAlias($alias, $namespace);
+ }
+
+ unset($this->classes['namespaces']);
+ }
+ }
+
+ if (isset($this->classes[$metadata->getClassName()])) {
+ $classDescription = $this->classes[$metadata->getClassName()];
+
+ $this->loadClassMetadataFromYaml($metadata, $classDescription);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Parses a collection of YAML nodes.
+ *
+ * @param array $nodes The YAML nodes
+ *
+ * @return array An array of values or Constraint instances
+ */
+ protected function parseNodes(array $nodes)
+ {
+ $values = array();
+
+ foreach ($nodes as $name => $childNodes) {
+ if (is_numeric($name) && is_array($childNodes) && count($childNodes) == 1) {
+ $options = current($childNodes);
+
+ if (is_array($options)) {
+ $options = $this->parseNodes($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.
+ *
+ * @param string $path The path of the YAML file
+ *
+ * @return array|null The class descriptions or null, if the file was empty
+ *
+ * @throws \InvalidArgumentException If the file could not be loaded or did
+ * not contain a YAML array
+ */
+ private function parseFile($path)
+ {
+ $classes = $this->yamlParser->parse(file_get_contents($path));
+
+ // 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;
+ }
+
+ /**
+ * Loads the validation metadata from the given YAML class description.
+ *
+ * @param ClassMetadata $metadata The metadata to load
+ * @param array $classDescription The YAML class description
+ */
+ private function loadClassMetadataFromYaml(ClassMetadata $metadata, array $classDescription)
+ {
+ if (isset($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/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFilesLoader.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFilesLoader.php
new file mode 100644
index 0000000..235856f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFilesLoader.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Loader;
+
+/**
+ * Loads validation metadata from a list of YAML files.
+ *
+ * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see FilesLoader
+ */
+class YamlFilesLoader extends FilesLoader
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getFileLoaderInstance($file)
+ {
+ return new YamlFileLoader($file);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd
new file mode 100644
index 0000000..1ca840b
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd
@@ -0,0 +1,160 @@
+<?xml version="1.0" ?>
+
+<xsd:schema xmlns="http://symfony.com/schema/dic/constraint-mapping"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://symfony.com/schema/dic/constraint-mapping"
+ elementFormDefault="qualified">
+
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Symfony Validator Constraint Mapping Schema, version 1.0
+ Authors: Bernhard Schussek
+
+ A constraint mapping connects classes, properties and getters with
+ validation constraints.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:element name="constraint-mapping" type="constraint-mapping" />
+
+ <xsd:complexType name="constraint-mapping">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The root element of the constraint mapping definition.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="namespace" type="namespace" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="class" type="class" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="namespace">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Contains the abbreviation for a namespace.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="prefix" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="class">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Contains constraints for a single class.
+
+ Nested elements may be class constraints, property and/or getter
+ definitions.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="group-sequence-provider" type="group-sequence-provider" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="group-sequence" type="group-sequence" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="constraint" type="constraint" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="getter" type="getter" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:choice>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+
+ <xsd:complexType name="group-sequence">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Contains the group sequence of a class. Each group should be written
+ into a "value" tag.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="value" type="value" minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="group-sequence-provider">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Defines the name of the group sequence provider for a class.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:complexType>
+
+ <xsd:complexType name="property">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Contains constraints for a single property. The name of the property
+ should be given in the "name" option.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="constraint" type="constraint" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+
+ <xsd:complexType name="getter">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Contains constraints for a getter method. The name of the corresponding
+ property should be given in the "property" option.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="constraint" type="constraint" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="property" type="xsd:string" use="required" />
+ </xsd:complexType>
+
+ <xsd:complexType name="constraint" mixed="true">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Contains a constraint definition. The name of the constraint should be
+ given in the "name" option.
+
+ May contain a single value, multiple "constraint" elements,
+ multiple "value" elements or multiple "option" elements.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:choice minOccurs="0">
+ <xsd:element name="constraint" type="constraint" minOccurs="1" maxOccurs="unbounded" />
+ <xsd:element name="option" type="option" minOccurs="1" maxOccurs="unbounded" />
+ <xsd:element name="value" type="value" minOccurs="1" maxOccurs="unbounded" />
+ </xsd:choice>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+
+ <xsd:complexType name="option" mixed="true">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Contains a constraint option definition. The name of the option
+ should be given in the "name" option.
+
+ May contain a single value, multiple "value" elements or multiple
+ "constraint" elements.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:choice minOccurs="0">
+ <xsd:element name="constraint" type="constraint" minOccurs="1" maxOccurs="unbounded" />
+ <xsd:element name="value" type="value" minOccurs="1" maxOccurs="unbounded" />
+ </xsd:choice>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+
+ <xsd:complexType name="value" mixed="true">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A value of an element.
+
+ May contain a single value, multiple "value" elements or multiple
+ "constraint" elements.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:choice minOccurs="0">
+ <xsd:element name="constraint" type="constraint" minOccurs="1" maxOccurs="unbounded" />
+ <xsd:element name="value" type="value" minOccurs="1" maxOccurs="unbounded" />
+ </xsd:choice>
+ <xsd:attribute name="key" type="xsd:string" use="optional" />
+ </xsd:complexType>
+</xsd:schema>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/MemberMetadata.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/MemberMetadata.php
new file mode 100644
index 0000000..a0bbe0d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/MemberMetadata.php
@@ -0,0 +1,251 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+use Symfony\Component\Validator\ValidationVisitorInterface;
+
+/**
+ * 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 <bschussek@gmail.com>
+ *
+ * @see PropertyMetadataInterface
+ */
+abstract class MemberMetadata extends ElementMetadata implements PropertyMetadataInterface
+{
+ /**
+ * @var string
+ *
+ * @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 $class;
+
+ /**
+ * @var string
+ *
+ * @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 $name;
+
+ /**
+ * @var string
+ *
+ * @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 $property;
+
+ /**
+ * @var \ReflectionMethod[]|\ReflectionProperty[]
+ */
+ private $reflMember = array();
+
+ /**
+ * Constructor.
+ *
+ * @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($class, $name, $property)
+ {
+ $this->class = $class;
+ $this->name = $name;
+ $this->property = $property;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ */
+ public function accept(ValidationVisitorInterface $visitor, $value, $group, $propertyPath, $propagatedGroup = null)
+ {
+ $visitor->visit($this, $value, $group, $propertyPath);
+
+ if ($this->isCascaded()) {
+ $visitor->validate($value, $propagatedGroup ?: $group, $propertyPath, $this->isCollectionCascaded(), $this->isCollectionCascadedDeeply());
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addConstraint(Constraint $constraint)
+ {
+ if (!in_array(Constraint::PROPERTY_CONSTRAINT, (array) $constraint->getTargets())) {
+ throw new ConstraintDefinitionException(sprintf(
+ 'The constraint %s cannot be put on properties or getters',
+ get_class($constraint)
+ ));
+ }
+
+ parent::addConstraint($constraint);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __sleep()
+ {
+ return array_merge(parent::__sleep(), array(
+ 'class',
+ 'name',
+ 'property',
+ ));
+ }
+
+ /**
+ * Returns the name of the member.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getClassName()
+ {
+ return $this->class;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPropertyName()
+ {
+ return $this->property;
+ }
+
+ /**
+ * Returns whether this member is public.
+ *
+ * @param object|string $objectOrClassName The object or the class name
+ *
+ * @return bool
+ */
+ public function isPublic($objectOrClassName)
+ {
+ return $this->getReflectionMember($objectOrClassName)->isPublic();
+ }
+
+ /**
+ * Returns whether this member is protected.
+ *
+ * @param object|string $objectOrClassName The object or the class name
+ *
+ * @return bool
+ */
+ public function isProtected($objectOrClassName)
+ {
+ return $this->getReflectionMember($objectOrClassName)->isProtected();
+ }
+
+ /**
+ * Returns whether this member is private.
+ *
+ * @param object|string $objectOrClassName The object or the class name
+ *
+ * @return bool
+ */
+ public function isPrivate($objectOrClassName)
+ {
+ return $this->getReflectionMember($objectOrClassName)->isPrivate();
+ }
+
+ /**
+ * Returns whether objects stored in this member should be validated.
+ *
+ * @return bool
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link getCascadingStrategy()} instead.
+ */
+ public function isCascaded()
+ {
+ return (bool) ($this->cascadingStrategy & CascadingStrategy::CASCADE);
+ }
+
+ /**
+ * Returns whether arrays or traversable objects stored in this member
+ * should be traversed and validated in each entry.
+ *
+ * @return bool
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link getTraversalStrategy()} instead.
+ */
+ public function isCollectionCascaded()
+ {
+ return (bool) ($this->traversalStrategy & (TraversalStrategy::IMPLICIT | TraversalStrategy::TRAVERSE));
+ }
+
+ /**
+ * Returns whether arrays or traversable objects stored in this member
+ * should be traversed recursively for inner arrays/traversable objects.
+ *
+ * @return bool
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link getTraversalStrategy()} instead.
+ */
+ public function isCollectionCascadedDeeply()
+ {
+ return !($this->traversalStrategy & TraversalStrategy::STOP_RECURSION);
+ }
+
+ /**
+ * Returns the reflection instance for accessing the member's value.
+ *
+ * @param object|string $objectOrClassName The object or the class name
+ *
+ * @return \ReflectionMethod|\ReflectionProperty The reflection instance
+ */
+ public function getReflectionMember($objectOrClassName)
+ {
+ $className = is_string($objectOrClassName) ? $objectOrClassName : get_class($objectOrClassName);
+ 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.
+ *
+ * Must be implemented by subclasses.
+ *
+ * @param object|string $objectOrClassName The object or the class name
+ *
+ * @return \ReflectionMethod|\ReflectionProperty The reflection instance
+ */
+ abstract protected function newReflectionMember($objectOrClassName);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/MetadataInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/MetadataInterface.php
new file mode 100644
index 0000000..fda1dbb
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/MetadataInterface.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping;
+
+use Symfony\Component\Validator\MetadataInterface as LegacyMetadataInterface;
+
+/**
+ * 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.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see CascadingStrategy
+ * @see TraversalStrategy
+ */
+interface MetadataInterface extends LegacyMetadataInterface
+{
+ /**
+ * Returns the strategy for cascading objects.
+ *
+ * @return int The cascading strategy
+ *
+ * @see CascadingStrategy
+ */
+ public function getCascadingStrategy();
+
+ /**
+ * Returns the strategy for traversing traversable objects.
+ *
+ * @return int The traversal strategy
+ *
+ * @see TraversalStrategy
+ */
+ public function getTraversalStrategy();
+
+ /**
+ * Returns all constraints of this element.
+ *
+ * @return Constraint[] A list of Constraint instances
+ */
+ public function getConstraints();
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/PropertyMetadata.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/PropertyMetadata.php
new file mode 100644
index 0000000..7319294
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/PropertyMetadata.php
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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 <bschussek@gmail.com>
+ *
+ * @see PropertyMetadataInterface
+ */
+class PropertyMetadata extends MemberMetadata
+{
+ /**
+ * Constructor.
+ *
+ * @param string $class The class this property is defined on
+ * @param string $name The name of this property
+ *
+ * @throws ValidatorException
+ */
+ public function __construct($class, $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);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPropertyValue($object)
+ {
+ return $this->getReflectionMember($object)->getValue($object);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function newReflectionMember($objectOrClassName)
+ {
+ $class = new \ReflectionClass($objectOrClassName);
+ while (!$class->hasProperty($this->getName())) {
+ $class = $class->getParentClass();
+ }
+
+ $member = new \ReflectionProperty($class->getName(), $this->getName());
+ $member->setAccessible(true);
+
+ return $member;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/PropertyMetadataInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/PropertyMetadataInterface.php
new file mode 100644
index 0000000..79e2c79
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/PropertyMetadataInterface.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping;
+
+use Symfony\Component\Validator\ClassBasedInterface;
+use Symfony\Component\Validator\PropertyMetadataInterface as LegacyPropertyMetadataInterface;
+
+/**
+ * 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.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see MetadataInterface
+ * @see CascadingStrategy
+ * @see TraversalStrategy
+ */
+interface PropertyMetadataInterface extends MetadataInterface, LegacyPropertyMetadataInterface, ClassBasedInterface
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Mapping/TraversalStrategy.php b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/TraversalStrategy.php
new file mode 100644
index 0000000..5122c47
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Mapping/TraversalStrategy.php
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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.
+ *
+ * @since 2.1
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see CascadingStrategy
+ */
+class TraversalStrategy
+{
+ /**
+ * Specifies that a node's value should be iterated only if it is an
+ * instance of {@link \Traversable}.
+ */
+ const IMPLICIT = 1;
+
+ /**
+ * Specifies that a node's value should never be iterated.
+ */
+ 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.
+ */
+ const TRAVERSE = 4;
+
+ /**
+ * Specifies that nested instances of {@link \Traversable} should never be
+ * iterated. Can be combined with {@link IMPLICIT} or {@link TRAVERSE}.
+ *
+ * @deprecated This constant was added for backwards compatibility only.
+ * It will be removed in Symfony 3.0.
+ * @internal
+ */
+ const STOP_RECURSION = 8;
+
+ /**
+ * Not instantiable.
+ */
+ private function __construct()
+ {
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/MetadataFactoryInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/MetadataFactoryInterface.php
new file mode 100644
index 0000000..4c0cbad
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/MetadataFactoryInterface.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * Returns {@link MetadataInterface} instances for values.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Mapping\Factory\MetadataFactoryInterface} instead.
+ */
+interface MetadataFactoryInterface
+{
+ /**
+ * Returns the metadata for the given value.
+ *
+ * @param mixed $value Some value
+ *
+ * @return MetadataInterface The metadata for the value
+ *
+ * @throws Exception\NoSuchMetadataException If no metadata exists for the given value
+ */
+ public function getMetadataFor($value);
+
+ /**
+ * Returns whether the class is able to return metadata for the given value.
+ *
+ * @param mixed $value Some value
+ *
+ * @return bool Whether metadata can be returned for that value
+ */
+ public function hasMetadataFor($value);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/MetadataInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/MetadataInterface.php
new file mode 100644
index 0000000..60abfeb
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/MetadataInterface.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * A container for validation metadata.
+ *
+ * The container contains constraints that may belong to different validation
+ * groups. Constraints for a specific group can be fetched by calling
+ * {@link findConstraints}.
+ *
+ * Implement this interface to add validation metadata to your own metadata
+ * layer. Each metadata may have named properties. Each property can be
+ * represented by one or more {@link PropertyMetadataInterface} instances that
+ * are returned by {@link getPropertyMetadata}. Since
+ * <tt>PropertyMetadataInterface</tt> inherits from <tt>MetadataInterface</tt>,
+ * each property may be divided into further properties.
+ *
+ * The {@link accept} method of each metadata implements the Visitor pattern.
+ * The method should forward the call to the visitor's
+ * {@link ValidationVisitorInterface::visit} method and additionally call
+ * <tt>accept()</tt> on all structurally related metadata instances.
+ *
+ * For example, to store constraints for PHP classes and their properties,
+ * create a class <tt>ClassMetadata</tt> (implementing <tt>MetadataInterface</tt>)
+ * and a class <tt>PropertyMetadata</tt> (implementing <tt>PropertyMetadataInterface</tt>).
+ * <tt>ClassMetadata::getPropertyMetadata($property)</tt> returns all
+ * <tt>PropertyMetadata</tt> instances for a property of that class. Its
+ * <tt>accept()</tt>-method simply forwards to <tt>ValidationVisitorInterface::visit()</tt>
+ * and calls <tt>accept()</tt> on all contained <tt>PropertyMetadata</tt>
+ * instances, which themselves call <tt>ValidationVisitorInterface::visit()</tt>
+ * again.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Mapping\MetadataInterface} instead.
+ */
+interface MetadataInterface
+{
+ /**
+ * Implementation of the Visitor design pattern.
+ *
+ * Calls {@link ValidationVisitorInterface::visit} and then forwards the
+ * <tt>accept()</tt>-call to all property metadata instances.
+ *
+ * @param ValidationVisitorInterface $visitor The visitor implementing the validation logic
+ * @param mixed $value The value to validate
+ * @param string|string[] $group The validation group to validate in
+ * @param string $propertyPath The current property path in the validation graph
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ */
+ public function accept(ValidationVisitorInterface $visitor, $value, $group, $propertyPath);
+
+ /**
+ * Returns all constraints for a given validation group.
+ *
+ * @param string $group The validation group
+ *
+ * @return Constraint[] A list of constraint instances
+ */
+ public function findConstraints($group);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ObjectInitializerInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/ObjectInitializerInterface.php
new file mode 100644
index 0000000..0426bc8
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ObjectInitializerInterface.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * Prepares an object for validation.
+ *
+ * Concrete implementations of this interface are used by {@link ValidationVisitorInterface}
+ * to initialize objects just before validating them.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+interface ObjectInitializerInterface
+{
+ /**
+ * Initializes an object just before validation.
+ *
+ * @param object $object The object to validate
+ *
+ * @api
+ */
+ public function initialize($object);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataContainerInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataContainerInterface.php
new file mode 100644
index 0000000..91b286a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataContainerInterface.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * A container for {@link PropertyMetadataInterface} instances.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Mapping\ClassMetadataInterface} instead.
+ */
+interface PropertyMetadataContainerInterface
+{
+ /**
+ * Check if there's any metadata attached to the given named property.
+ *
+ * @param string $property The property name.
+ *
+ * @return bool
+ */
+ public function hasPropertyMetadata($property);
+
+ /**
+ * Returns all metadata instances for the given named property.
+ *
+ * If your implementation does not support properties, simply throw an
+ * exception in this method (for example a <tt>BadMethodCallException</tt>).
+ *
+ * @param string $property The property name.
+ *
+ * @return PropertyMetadataInterface[] A list of metadata instances. Empty if
+ * no metadata exists for the property.
+ */
+ public function getPropertyMetadata($property);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataInterface.php
new file mode 100644
index 0000000..c18ae83
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataInterface.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * A container for validation metadata of a property.
+ *
+ * What exactly you define as "property" is up to you. The validator expects
+ * implementations of {@link MetadataInterface} that contain constraints and
+ * optionally a list of named properties that also have constraints (and may
+ * have further sub properties). Such properties are mapped by implementations
+ * of this interface.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see MetadataInterface
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Mapping\PropertyMetadataInterface} instead.
+ */
+interface PropertyMetadataInterface extends MetadataInterface
+{
+ /**
+ * Returns the name of the property.
+ *
+ * @return string The property name.
+ */
+ public function getPropertyName();
+
+ /**
+ * Extracts the value of the property from the given container.
+ *
+ * @param mixed $containingValue The container to extract the property value from.
+ *
+ * @return mixed The value of the property.
+ */
+ public function getPropertyValue($containingValue);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/README.md b/vendor/symfony/validator/Symfony/Component/Validator/README.md
new file mode 100644
index 0000000..f6891ff
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/README.md
@@ -0,0 +1,126 @@
+Validator Component
+===================
+
+This component is based on the JSR-303 Bean Validation specification and
+enables specifying validation rules for classes using XML, YAML, PHP or
+annotations, which can then be checked against instances of these classes.
+
+Usage
+-----
+
+The component provides "validation constraints", which are simple objects
+containing the rules for the validation. Let's validate a simple string
+as an example:
+
+```php
+use Symfony\Component\Validator\Validation;
+use Symfony\Component\Validator\Constraints\Length;
+
+$validator = Validation::createValidator();
+
+$violations = $validator->validateValue('Bernhard', new Length(array('min' => 10)));
+```
+
+This validation will fail because the given string is shorter than ten
+characters. The precise errors, here called "constraint violations", are
+returned by the validator. You can analyze these or return them to the user.
+If the violation list is empty, validation succeeded.
+
+Validation of arrays is possible using the `Collection` constraint:
+
+```php
+use Symfony\Component\Validator\Validation;
+use Symfony\Component\Validator\Constraints as Assert;
+
+$validator = Validation::createValidator();
+
+$constraint = new Assert\Collection(array(
+ 'name' => new Assert\Collection(array(
+ 'first_name' => new Assert\Length(array('min' => 101)),
+ 'last_name' => new Assert\Length(array('min' => 1)),
+ )),
+ 'email' => new Assert\Email(),
+ 'simple' => new Assert\Length(array('min' => 102)),
+ 'gender' => new Assert\Choice(array(3, 4)),
+ 'file' => new Assert\File(),
+ 'password' => new Assert\Length(array('min' => 60)),
+));
+
+$violations = $validator->validateValue($input, $constraint);
+```
+
+Again, the validator returns the list of violations.
+
+Validation of objects is possible using "constraint mapping". With such
+a mapping you can put constraints onto properties and objects of classes.
+Whenever an object of this class is validated, its properties and
+method results are matched against the constraints.
+
+```php
+use Symfony\Component\Validator\Validation;
+use Symfony\Component\Validator\Constraints as Assert;
+
+class User
+{
+ /**
+ * @Assert\Length(min = 3)
+ * @Assert\NotBlank
+ */
+ private $name;
+
+ /**
+ * @Assert\Email
+ * @Assert\NotBlank
+ */
+ private $email;
+
+ public function __construct($name, $email)
+ {
+ $this->name = $name;
+ $this->email = $email;
+ }
+
+ /**
+ * @Assert\True(message = "The user should have a Google Mail account")
+ */
+ public function isGmailUser()
+ {
+ return false !== strpos($this->email, '@gmail.com');
+ }
+}
+
+$validator = Validation::createValidatorBuilder()
+ ->enableAnnotationMapping()
+ ->getValidator();
+
+$user = new User('John Doe', 'john@example.com');
+
+$violations = $validator->validate($user);
+```
+
+This example uses the annotation support of Doctrine Common to
+map constraints to properties and methods. You can also map constraints
+using XML, YAML or plain PHP, if you dislike annotations or don't want
+to include Doctrine. Check the documentation for more information about
+these drivers.
+
+Resources
+---------
+
+Silex integration:
+
+https://github.com/fabpot/Silex/blob/master/src/Silex/Provider/ValidatorServiceProvider.php
+
+Documentation:
+
+http://symfony.com/doc/2.6/book/validation.html
+
+JSR-303 Specification:
+
+http://jcp.org/en/jsr/detail?id=303
+
+You can run the unit tests with the following command:
+
+ $ cd path/to/Symfony/Component/Validator/
+ $ composer install
+ $ phpunit
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.af.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.af.xlf
new file mode 100644
index 0000000..177bb00
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.af.xlf
@@ -0,0 +1,227 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Hierdie waarde moet vals wees.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Hierdie waarde moet waar wees.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Hierdie waarde moet van die soort {{type}} wees.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Hierdie waarde moet leeg wees.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Die waarde wat jy gekies het is nie 'n geldige keuse nie.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Jy moet ten minste {{ limit }} kies.|Jy moet ten minste {{ limit }} keuses kies.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Jy moet by die meeste {{ limit }} keuse kies.|Jy moet by die meeste {{ limit }} keuses kies.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Een of meer van die gegewe waardes is ongeldig.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Die veld is nie verwag nie.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Hierdie veld ontbreek.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Hierdie waarde is nie 'n geldige datum nie.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Hierdie waarde is nie 'n geldige datum en tyd nie.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Hierdie waarde is nie 'n geldige e-pos adres nie.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Die lêer kon nie gevind word nie.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Die lêer kan nie gelees word nie.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Die lêer is te groot ({{ size }} {{ suffix }}). Toegelaat maksimum grootte is {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Die MIME-tipe van die lêer is ongeldig ({{ type }}). Toegelaat MIME-tipes is {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Hierdie waarde moet {{ limit }} of minder wees.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Hierdie waarde is te lank. Dit moet {{ limit }} karakter of minder wees.|Hierdie waarde is te lank. Dit moet {{ limit }} karakters of minder wees.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Hierdie waarde moet {{ limit }} of meer wees.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Hierdie waarde is te kort. Dit moet {{ limit }} karakter of meer wees.|Hierdie waarde is te kort. Dit moet {{ limit }} karakters of meer wees.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Hierdie waarde moet nie leeg wees nie.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Hierdie waarde moet nie nul wees nie.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Hierdie waarde moet nul wees.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Hierdie waarde is nie geldig nie.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Hierdie waarde is nie 'n geldige tyd nie.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Hierdie waarde is nie 'n geldige URL nie.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Die twee waardes moet gelyk wees.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Die lêer is te groot. Toegelaat maksimum grootte is {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Die lêer is te groot.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Die lêer kan nie opgelaai word nie.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Hierdie waarde moet 'n geldige nommer wees.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Hierdie lêer is nie 'n geldige beeld nie.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Hierdie is nie 'n geldige IP-adres nie.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Hierdie waarde is nie 'n geldige taal nie.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Hierdie waarde is nie 'n geldige land instelling nie.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Hierdie waarde is nie 'n geldige land nie.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Hierdie waarde word reeds gebruik.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Die grootte van die beeld kon nie opgespoor word nie.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Die beeld breedte is te groot ({{ width }}px). Toegelaat maksimum breedte is {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Die beeld breedte is te klein ({{ width }}px). Minimum breedte verwag is {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Die beeld hoogte is te groot ({{ height }}px). Toegelaat maksimum hoogte is {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Die beeld hoogte is te klein ({{ height }}px). Minimum hoogte verwag is {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Hierdie waarde moet die huidige wagwoord van die gebruiker wees.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Hierdie waarde moet presies {{ limit }} karakter wees.|Hierdie waarde moet presies {{ limit }} karakters wees.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Die lêer is slegs gedeeltelik opgelaai.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Geen lêer is opgelaai nie.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Geen tydelike lêer is ingestel in php.ini nie.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Kan nie tydelike lêer skryf op skyf nie.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>'n PHP-uitbreiding veroorsaak die oplaai van die lêer om te misluk.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Hierdie versameling moet {{ limit }} element of meer bevat.|Hierdie versameling moet {{ limit }} elemente of meer bevat.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Hierdie versameling moet {{ limit }} element of minder bevat.|Hierdie versameling moet {{ limit }} elemente of meer bevat.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Hierdie versameling moet presies {{ limit }} element bevat.|Hierdie versameling moet presies {{ limit }} elemente bevat.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Ongeldige kredietkaart nommer.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Nie-ondersteunde tipe kaart of ongeldige kredietkaart nommer.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ar.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ar.xlf
new file mode 100644
index 0000000..b448c2e
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ar.xlf
@@ -0,0 +1,283 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>هذه القيمة يجب أن تكون خاطئة.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>هذه القيمة يجب أن تكون حقيقية.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>هذه القيمة يجب ان تكون من نوع {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>هذه القيمة يجب ان تكون فارغة.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>القيمة المختارة ليست خيارا صحيحا.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>يجب ان تختار {{ limit }} اختيار على الاقل.|يجب ان تختار {{ limit }} اختيار على الاقل.|يجب ان تختار {{ limit }} اختيارات على الاقل.|يجب ان تختار {{ limit }} اختيار على الاقل.|يجب ان تختار {{ limit }} اختيار على الاقل.|يجب ان تختار {{ limit }} اختيار على الاقل.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>يجب ان تختار {{ limit }} اختيار على الاكثر.|يجب ان تختار {{ limit }} اختيار على الاكثر.|يجب ان تختار {{ limit }} اختيارات على الاكثر.|يجب ان تختار {{ limit }} اختيار على الاكثر.|يجب ان تختار {{ limit }} اختيار على الاكثر.|يجب ان تختار {{ limit }} اختيار على الاكثر.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>واحد أو أكثر من القيم المعطاه خاطئ.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>لم يكن من المتوقع هذا المجال.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>هذا المجال مفقود.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>هذه القيمة ليست تاريخا صالحا.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>هذه القيمة ليست تاريخا و وقتا صالحا.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>هذه القيمة ليست عنوان بريد إلكتروني صحيح.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>لا يمكن العثور على الملف.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>الملف غير قابل للقراءة.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>الملف كبير جدا ({{ size }} {{ suffix }}).اقصى مساحه مسموح بها ({{ limit }} {{ suffix }}).</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>نوع الملف غير صحيح ({{ type }}). الانواع المسموح بها هى {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>هذه القيمة يجب ان تكون {{ limit }} او اقل.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حروف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل.|هذه القيمة طويلة جدا. يجب ان تكون {{ limit }} حرف او اقل.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>هذه القيمة يجب ان تكون {{ limit }} او اكثر.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حروف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر.|هذه القيمة قصيرة جدا. يجب ان تكون {{ limit }} حرف او اكثر.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>هذه القيمة يجب الا تكون فارغة.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>هذه القيمة يجب الا تكون فارغة.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>هذه القيمة يجب ان تكون فارغة.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>هذه القيمة غير صحيحة.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>هذه القيمة ليست وقت صحيح.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>هذه القيمة ليست رابط الكترونى صحيح.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>القيمتان يجب ان تكونا متساويتان.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>الملف كبير جدا. اقصى مساحه مسموح بها {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>الملف كبير جدا.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>لم استطع استقبال الملف.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>هذه القيمة يجب ان تكون رقم.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>هذا الملف ليس صورة صحيحة.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>هذه القيمة ليست عنوان رقمى صحيح.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>هذه القيمة ليست لغة صحيحة.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>هذه القيمة ليست موقع صحيح.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>هذه القيمة ليست بلدا صالحا.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>هذه القيمة مستخدمة بالفعل.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>لم استطع معرفة حجم الصورة.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>عرض الصورة كبير جدا ({{ width }}px). اقصى عرض مسموح به هو{{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>عرض الصورة صغير جدا ({{ width }}px). اقل عرض مسموح به هو{{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>طول الصورة كبير جدا ({{ height }}px). اقصى طول مسموح به هو{{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>طول الصورة صغير جدا ({{ height }}px). اقل طول مسموح به هو{{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>هذه القيمة يجب ان تكون كلمة سر المستخدم الحالية.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حروف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط.|هذه القيمة يجب ان تحتوى على {{ limit }} حرف فقط.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>تم استقبال جزء من الملف فقط.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>لم يتم ارسال اى ملف.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>لم يتم تهيئة حافظة مؤقتة فى ملف php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>لم استطع كتابة الملف المؤقت.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>احد اضافات PHP تسببت فى فشل استقبال الملف.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عناصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اكثر.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عناصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر او اقل.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عناصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط.|هذه المجموعة يجب ان تحتوى على {{ limit }} عنصر فقط.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>رقم البطاقه غير صحيح.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>نوع البطاقه غير مدعوم او الرقم غير صحيح.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>الرقم IBAN (رقم الحساب المصرفي الدولي) الذي تم إدخاله غير صالح.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>هذه القيمة ليست ISBN-10 صالحة.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>هذه القيمة ليست ISBN-13 صالحة.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>هذه القيمة ليست ISBN-10 صالحة ولا ISBN-13 صالحة.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>هذه القيمة ليست ISSN صالحة.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>العُملة غير صحيحة.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>القيمة يجب ان تساوي {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>القيمة يجب ان تكون اعلي من {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>القيمة يجب ان تكون مساوية او اعلي من {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>القيمة يجب ان تطابق {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>القيمة يجب ان تكون اقل من {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>القيمة يجب ان تساوي او تقل عن {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>القيمة يجب ان لا تساوي {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>القيمة يجب ان لا تطابق {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.az.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.az.xlf
new file mode 100644
index 0000000..add868c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.az.xlf
@@ -0,0 +1,227 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Bu dəyər false olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Bu dəyər true olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Bu dəyərin tipi {{ type }} olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Bu dəyər boş olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Seçdiyiniz dəyər düzgün bir seçim değil.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Ən az {{ limit }} seçim qeyd edilməlidir.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Ən çox {{ limit }} seçim qeyd edilməlidir.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Təqdim edilən dəyərlərdən bir və ya bir neçəsi yanlışdır.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Bu sahə gözlənilmirdi.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Bu sahə əksikdir.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Bu dəyər düzgün bir tarix deyil.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Bu dəyər düzgün bir tarixsaat deyil.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Bu dəyər düzgün bir e-poçt adresi deyil.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Fayl tapılmadı.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Fayl oxunabilən deyil.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Fayl çox böyükdür ({{ size }} {{ suffix }}). İcazə verilən maksimum fayl ölçüsü {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Faylın mime tipi yanlışdr ({{ type }}). İcazə verilən mime tipləri {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Bu dəyər {{ limit }} və ya altında olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Bu dəyər çox uzundur. {{ limit }} və ya daha az simvol olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Bu dəyər {{ limit }} veya daha fazla olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Bu dəyər çox qısadır. {{ limit }} və ya daha çox simvol olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Bu dəyər boş olmamalıdır.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Bu dəyər boş olmamalıdır.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Bu dəyər boş olmamalıdır.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Bu dəyər doğru deyil.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Bu dəyər doğru bir saat deyil.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Bu dəyər doğru bir URL değil.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>İki dəyər eyni olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Fayl çox böyükdür. İcazə verilən ən böyük fayl ölçüsü {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Fayl çox böyükdür.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Fayl yüklənəbilmir.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Bu dəyər rəqəm olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Bu fayl düzgün bir şəkil deyil.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Bu düzgün bir IP adresi deyil.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Bu dəyər düzgün bir dil deyil.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Bu dəyər düzgün bir dil deyil.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Bu dəyər düzgün bir ölkə deyil.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Bu dəyər hal-hazırda istifadədədir.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Şəklin ölçüsü hesablana bilmir.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Şəklin genişliyi çox böyükdür ({{ width }}px). İcazə verilən ən böyük genişlik {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Şəklin genişliyi çox kiçikdir ({{ width }}px). Ən az {{ min_width }}px olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Şəklin yüksəkliyi çox böyükdür ({{ height }}px). İcazə verilən ən böyük yüksəklik {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Şəklin yüksəkliyi çox kiçikdir ({{ height }}px). Ən az {{ min_height }}px olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Bu dəyər istifadəçinin hazırkı parolu olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Bu dəyər tam olaraq {{ limit }} simvol olmaldır.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Fayl qismən yükləndi.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Fayl yüklənmədi.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>php.ini'də müvəqqəti qovluq quraşdırılmayıb.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Müvəqqəti fayl diskə yazıla bilmir.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Bir PHP əlavəsi faylın yüklənməsinə mane oldu.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Bu kolleksiyada {{ limit }} və ya daha çox element olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Bu kolleksiyada {{ limit }} və ya daha az element olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Bu kolleksiyada tam olaraq {{ limit }} element olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Yanlış kart nömrəsi.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Dəstəklənməyən kart tipi və ya yanlış kart nömrəsi.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.bg.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.bg.xlf
new file mode 100644
index 0000000..7c5da55
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.bg.xlf
@@ -0,0 +1,283 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Стойността трябва да бъде лъжа (false).</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Стойността трябва да бъде истина (true).</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Стойността трябва да бъде от тип {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Стойността трябва да бъде празна.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Избраната стойност е невалидна.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Трябва да изберете поне {{ limit }} опция.|Трябва да изберете поне {{ limit }} опции.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Трябва да изберете най-много {{ limit }} опция.|Трябва да изберете най-много {{ limit }} опции.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Една или повече от зададените стойности е невалидна.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Това поле не се е очаквало.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Това поле липсва.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Стойността не е валидна дата (date).</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Стойността не е валидна дата (datetime).</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Стойността не е валиден email адрес.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Файлът не беше открит.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Файлът не може да бъде прочетен.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Файлът е твърде голям ({{ size }} {{ suffix }}). Максималният размер е {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Майм типа на файла е невалиден ({{ type }}). Разрешени майм типове са {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Стойността трябва да бъде {{ limit }} или по-малко.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Стойността е твърде дълга. Трябва да съдържа най-много {{ limit }} символ.|Стойността е твърде дълга. Трябва да съдържа най-много {{ limit }} символа.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Стойността трябва да бъде {{ limit }} или повече.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Стойността е твърде кратка. Трябва да съдържа поне {{ limit }} символ.|Стойността е твърде кратка. Трябва да съдържа поне {{ limit }} символа.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Стойността не трябва да бъде празна.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Стойността не трябва да бъде null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Стойността трябва да бъде null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Стойността не е валидна.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Стойността не е валидно време (time).</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Стойността не е валиден URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Двете стойности трябва да бъдат равни.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Файлът е твърде голям. Разрешеният максимален размер е {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Файлът е твърде голям.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Файлът не може да бъде качен.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Стойността трябва да бъде валиден номер.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Файлът не е валидно изображение.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Това не е валиден IP адрес.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Стойността не е валиден език.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Стойността не е валидна локализация.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Стойността не е валидна държава.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Стойността вече е в употреба.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Размера на изображението не може да бъде определен.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Изображението е твърде широко ({{ width }}px). Широчината трябва да бъде максимум {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Изображението е с твърде малка широчина ({{ width }}px). Широчината трябва да бъде минимум {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Изображението е с твърде голяма височина ({{ height }}px). Височината трябва да бъде максимум {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Изображението е с твърде малка височина ({{ height }}px). Височина трябва да бъде минимум {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Стойността трябва да бъде текущата потребителска парола.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Стойността трябва да бъде точно {{ limit }} символ.|Стойността трябва да бъде точно {{ limit }} символа.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Файлът е качен частично.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Файлът не беше качен.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Не е посочена директория за временни файлове в php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Не може да запише временен файл на диска.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>PHP разширение предизвика прекъсване на качването.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Колекцията трябва да съдържа поне {{ limit }} елемент.|Колекцията трябва да съдържа поне {{ limit }} елемента.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Колекцията трябва да съдържа най-много {{ limit }} елемент.|Колекцията трябва да съдържа най-много {{ limit }} елемента.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Колекцията трябва да съдържа точно {{ limit }} елемент.|Колекцията трябва да съдържа точно {{ limit }} елемента.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Невалиден номер на картата.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Неподдържан тип карта или невалиден номер на картата.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Невалиден Международен номер на банкова сметка (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Невалиден ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Невалиден ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Невалидна стойност както за ISBN-10, така и за ISBN-13 .</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Невалиден Международен стандартен сериен номер (ISSN).</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Невалидна валута.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Стойността трябва да бъде равна на {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Стойността трябва да бъде по-голяма от {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Стойността трябва да бъде по-голяма или равна на {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Стойността трябва да бъде идентична с {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Стойността трябва да бъде по-малка {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Стойността трябва да бъде по-малка или равна на {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Стойността не трябва да бъде равна на {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Стойността не трябва да бъде идентична с {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ca.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ca.xlf
new file mode 100644
index 0000000..85b6970
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ca.xlf
@@ -0,0 +1,307 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Aquest valor hauria de ser fals.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Aquest valor hauria de ser cert.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Aquest valor hauria de ser del tipus {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Aquest valor hauria d'estar buit.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>El valor seleccionat no és una opció vàlida.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Ha de seleccionar almenys {{ limit }} opció.|Ha de seleccionar almenys {{ limit }} opcions.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Ha de seleccionar com a màxim {{ limit }} opció.|Ha de seleccionar com a màxim {{ limit }} opcions.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Un o més dels valors facilitats són incorrectes.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Aquest camp no s'esperava.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Aquest camp està desaparegut.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Aquest valor no és una data vàlida.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Aquest valor no és una data i hora vàlida.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Aquest valor no és una adreça d'email vàlida.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>No s'ha pogut trobar l'arxiu.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>No es pot llegir l'arxiu.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>L'arxiu és massa gran ({{ size }} {{ suffix }}). La grandària màxima permesa és {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>El tipus mime de l'arxiu no és vàlid ({{ type }}). Els tipus mime vàlids són {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Aquest valor hauria de ser {{ limit }} o menys.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Aquest valor hauria de ser {{ limit }} o més.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Aquest valor és massa curt. Hauria de tenir {{ limit }} caràcters o més.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Aquest valor no hauria d'estar buit.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Aquest valor no hauria de ser null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Aquest valor hauria de ser null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Aquest valor no és vàlid.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Aquest valor no és una hora vàlida.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Aquest valor no és una URL vàlida.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Els dos valors haurien de ser iguals.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>L'arxiu és massa gran. El tamany màxim permés és {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>L'arxiu és massa gran.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>No es pot pujar l'arxiu.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Aquest valor hauria de ser un nombre vàlid.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>L'arxiu no és una imatge vàlida.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Això no és una adreça IP vàlida.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Aquest valor no és un idioma vàlid.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Aquest valor no és una localització vàlida.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Aquest valor no és un país vàlid.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Aquest valor ja s'ha utilitzat.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>No s'ha pogut determinar la grandària de la imatge.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>L'amplària de la imatge és massa gran ({{ width }}px). L'amplària màxima permesa són {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>L'amplària de la imatge és massa petita ({{ width }}px). L'amplària mínima requerida són {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>L'altura de la imatge és massa gran ({{ height }}px). L'altura màxima permesa són {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>L'altura de la imatge és massa petita ({{ height }}px). L'altura mínima requerida són {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Aquest valor hauria de ser la contrasenya actual de l'usuari.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Aquest valor hauria de tenir exactament {{ limit }} caràcter.|Aquest valor hauria de tenir exactament {{ limit }} caràcters.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>L'arxiu va ser només pujat parcialment.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Cap arxiu va ser pujat.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Cap carpeta temporal va ser configurada en php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>No es va poder escriure l'arxiu temporal en el disc.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Una extensió de PHP va fer que la pujada fallara.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Aquesta col·lecció ha de contenir {{ limit }} element o més.|Aquesta col·lecció ha de contenir {{ limit }} elements o més.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Aquesta col·lecció ha de contenir {{ limit }} element o menys.|Aquesta col·lecció ha de contenir {{ limit }} elements o menys.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Aquesta col·lecció ha de contenir exactament {{ limit }} element.|Aquesta col·lecció ha de contenir exactament {{ limit }} elements.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Número de targeta invàlid.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Tipus de targeta no suportada o número de targeta invàlid.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Això no és un nombre de compte bancari internacional (IBAN) vàlid.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Aquest valor no és un ISBN-10 vàlid.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Aquest valor no és un ISBN-13 vàlid.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Aquest valor no és ni un ISBN-10 vàlid ni un ISBN-13 vàlid.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Aquest valor no és un ISSN vàlid.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Aquest valor no és una divisa vàlida.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Aquest valor hauria de ser igual a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Aquest valor hauria de ser més gran a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Aquest valor hauria de ser major o igual a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Aquest valor hauria de ser idèntic a {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Aquest valor hauria de ser menor a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Aquest valor hauria de ser menor o igual a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Aquest valor no hauria de ser igual a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Aquest valor no hauria de idèntic a {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>La proporció de l'imatge és massa gran ({{ ratio }}). La màxima proporció permesa és {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>La proporció de l'imatge és massa petita ({{ ratio }}). La mínima proporció permesa és {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>L'imatge és quadrada({{ width }}x{{ height }}px). Les imatges quadrades no estan permeses.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>L'imatge està orientada horitzontalment ({{ width }}x{{ height }}px). Les imatges orientades horitzontalment no estan permeses.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>L'imatge està orientada verticalment ({{ width }}x{{ height }}px). Les imatges orientades verticalment no estan permeses.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>No està permès un fixter buit.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.cs.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.cs.xlf
new file mode 100644
index 0000000..2ae47b2
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.cs.xlf
@@ -0,0 +1,307 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Tato hodnota musí být nepravdivá (false).</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Tato hodnota musí být pravdivá (true).</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Tato hodnota musí být typu {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Tato hodnota musí být prázdná.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Vybraná hodnota není platnou možností.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>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í.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>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í.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Některé z uvedených hodnot jsou neplatné.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Toto pole nebyla očekávána.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Toto pole chybí.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Tato hodnota není platné datum.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Tato hodnota není platné datum s časovým údajem.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Tato hodnota není platná e-mailová adresa.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Soubor nebyl nalezen.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Soubor je nečitelný.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Soubor je příliš velký ({{ size }} {{ suffix }}). Maximální povolená velikost souboru je {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Neplatný mime typ souboru ({{ type }}). Povolené mime typy souborů jsou {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Tato hodnota musí být {{ limit }} nebo méně.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>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ů.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Tato hodnota musí být {{ limit }} nebo více.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>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ů.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Tato hodnota nesmí být prázdná.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Tato hodnota nesmí být null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Tato hodnota musí být null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Tato hodnota není platná.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Tato hodnota není platný časový údaj.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Tato hodnota není platná URL adresa.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Tyto dvě hodnoty musí být stejné.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Soubor je příliš velký. Maximální povolená velikost souboru je {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Soubor je příliš velký.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Soubor se nepodařilo nahrát.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Tato hodnota musí být číslo.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Tento soubor není obrázek.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Toto není platná IP adresa.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Tento jazyk neexistuje.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Tato lokalizace neexistuje.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Tato země neexistuje.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Tato hodnota je již používána.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Nepodařily se zjistit rozměry obrázku.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Obrázek je příliš široký ({{ width }}px). Maximální povolená šířka obrázku je {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Obrázek je příliš úzký ({{ width }}px). Minimální šířka musí být {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Obrázek je příliš vysoký ({{ height }}px). Maximální povolená výška obrázku je {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Obrázek je příliš nízký ({{ height }}px). Minimální výška obrázku musí být {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Tato hodnota musí být aktuální heslo uživatele.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>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ů.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Byla nahrána jen část souboru.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Žádný soubor nebyl nahrán.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>V php.ini není nastavena cesta k adresáři pro dočasné soubory.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Dočasný soubor se nepodařilo zapsat na disk.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Rozšíření PHP zabránilo nahrání souboru.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Tato kolekce musí obsahovat minimálně {{ limit }} prvek.|Tato kolekce musí obsahovat minimálně {{ limit }} prvky.|Tato kolekce musí obsahovat minimálně {{ limit }} prvků.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Tato kolekce musí obsahovat maximálně {{ limit }} prvek.|Tato kolekce musí obsahovat maximálně {{ limit }} prvky.|Tato kolekce musí obsahovat maximálně {{ limit }} prvků.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Tato kolekce musí obsahovat přesně {{ limit }} prvek.|Tato kolekce musí obsahovat přesně {{ limit }} prvky.|Tato kolekce musí obsahovat přesně {{ limit }} prvků.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Neplatné číslo karty.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Nepodporovaný typ karty nebo neplatné číslo karty.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Toto je neplatný IBAN.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Tato hodnota není platné ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Tato hodnota není platné ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Tato hodnota není platné ISBN-10 ani ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Tato hodnota není platné ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Tato měna neexistuje.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Tato hodnota musí být rovna {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Tato hodnota musí být větší než {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Tato hodnota musí být větší nebo rovna {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Tato hodnota musí být typu {{ compared_value_type }} a zároveň musí být rovna {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Tato hodnota musí být menší než {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Tato hodnota musí být menší nebo rovna {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Tato hodnota nesmí být rovna {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Tato hodnota nesmí být typu {{ compared_value_type }} a zároveň nesmí být rovna {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>Poměr stran obrázku je příliš velký ({{ ratio }}). Maximální povolený poměr stran obrázku je {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>Poměr stran obrázku je příliš malý ({{ ratio }}). Minimální povolený poměr stran obrázku je {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>Strany obrázku jsou čtvercové ({{ width }}x{{ height }}px). Čtvercové obrázky nejsou povolené.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>Obrázek je orientovaný na šířku ({{ width }}x{{ height }}px). Obrázky orientované na šířku nejsou povolené.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>Obrázek je orientovaný na výšku ({{ width }}x{{ height }}px). Obrázky orientované na výšku nejsou povolené.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Soubor nesmí být prázdný.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.cy.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.cy.xlf
new file mode 100644
index 0000000..da7cb9a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.cy.xlf
@@ -0,0 +1,227 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Dylid bod y gwerth hwn yn ffug.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Dylid bod y gwerth hwn yn wir.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Dylid bod y gwerth hwn bod o fath {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Dylid bod y gwerth hwn yn wag.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Nid yw'r gwerth â ddewiswyd yn ddilys.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Rhaid dewis o leiaf {{ limit }} opsiwn.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Rhaid dewis dim mwy na {{ limit }} opsiwn.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Mae un neu fwy o'r gwerthoedd a roddwyd yn annilys.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Nid oedd disgwyl y maes hwn.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Mae'r maes hwn ar goll.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Nid yw'r gwerth yn ddyddiad dilys.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Nid yw'r gwerth yn datetime dilys.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Nid yw'r gwerth yn gyfeiriad ebost dilys.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Ni ddarganfyddwyd y ffeil.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Ni ellir darllen y ffeil.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Mae'r ffeil yn rhy fawr ({{ size }} {{ suffix }}). Yr uchafswm â ganiateir yw {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Nid yw math mime y ffeil yn ddilys ({{ type }}). Dyma'r mathau â ganiateir {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Dylai'r gwerth hwn fod yn {{ limit }} neu lai.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Mae'r gwerth hwn rhy hir. Dylai gynnwys {{ limit }} nodyn cyfrifiadurol neu lai.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Dylai'r gwerth hwn fod yn {{ limit }} neu fwy.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Mae'r gwerth hwn yn rhy fyr. Dylai gynnwys {{ limit }} nodyn cyfrifiadurol neu fwy.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Ni ddylai'r gwerth hwn fod yn wag.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Ni ddylai'r gwerth hwn fod yn null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Dylai'r gwerth fod yn null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Nid yw'r gwerth hwn yn ddilys.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Nid yw'r gwerth hwn yn amser dilys.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Nid yw'r gwerth hwn yn URL dilys.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Rhaid i'r ddau werth fod yn gyfystyr a'u gilydd.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Mae'r ffeil yn rhy fawr. Yr uchafswm â ganiateir yw {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Mae'r ffeil yn rhy fawr.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Methwyd ag uwchlwytho'r ffeil.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Dylai'r gwerth hwn fod yn rif dilys.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Nid yw'r ffeil hon yn ddelwedd dilys.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Nid yw hwn yn gyfeiriad IP dilys.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Nid yw'r gwerth hwn yn iaith ddilys.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Nid yw'r gwerth hwn yn locale dilys.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Nid yw'r gwerth hwn yn wlad dilys.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Mae'r gwerth hwn eisoes yn cael ei ddefnyddio.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Methwyd â darganfod maint y ddelwedd.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Mae lled y ddelwedd yn rhy fawr ({{ width }}px). Y lled mwyaf â ganiateir yw {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Mae lled y ddelwedd yn rhy fach ({{ width }}px). Y lled lleiaf â ganiateir yw {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Mae uchder y ddelwedd yn rhy fawr ({{ width }}px). Yr uchder mwyaf â ganiateir yw {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Mae uchder y ddelwedd yn rhy fach ({{ width }}px). Yr uchder lleiaf â ganiateir yw {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Dylaid bod y gwerth hwn yn gyfrinair presenol y defnyddiwr.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Dylai'r gwerth hwn fod yn union {{ limit }} nodyn cyfrifiadurol o hyd.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Dim ond rhan o'r ffeil ag uwchlwythwyd.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Ni uwchlwythwyd unrhyw ffeil.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Nid oes ffolder dros-dro wedi'i gosod yn php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Methwyd ag ysgrifennu'r ffeil dros-dro ar ddisg.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Methwyd ag uwchlwytho oherwydd ategyn PHP.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Dylai'r casgliad hwn gynnwys {{ limit }} elfen neu fwy.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Dylai'r casgliad hwn gynnwys {{ limit }} elfen neu lai.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Dylai'r casgliad hwn gynnwys union {{ limit }} elfen.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Nid oedd rhif y cerdyn yn ddilys.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Unai ni dderbynir y math yna o gerdyn, neu nid yw rhif y cerdyn yn ddilys.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.da.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.da.xlf
new file mode 100644
index 0000000..14e479a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.da.xlf
@@ -0,0 +1,247 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Værdien skal være falsk.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Værdien skal være sand.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Værdien skal være af typen {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Værdien skal være blank.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Værdien skal være en af de givne muligheder.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Du skal vælge mindst {{ limit }} muligheder.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Du kan højest vælge {{ limit }} muligheder.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>En eller flere af de oplyste værdier er ugyldige.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Feltet blev ikke forventet.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Dette felt er mangler.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Værdien er ikke en gyldig dato.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Værdien er ikke en gyldig dato og tid.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Værdien er ikke en gyldig e-mail adresse.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Filen kunne ikke findes.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Filen kan ikke læses.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Filen er for stor ({{ size }} {{ suffix }}). Tilladte maksimale størrelse {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Mimetypen af filen er ugyldig ({{ type }}). Tilladte mimetyper er {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Værdien skal være {{ limit }} eller mindre.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Værdien er for lang. Den skal have {{ limit }} bogstaver eller mindre.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Værdien skal være {{ limit }} eller mere.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Værdien er for kort. Den skal have {{ limit }} tegn eller flere.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Værdien må ikke være blank.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Værdien må ikke være tom (null).</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Værdien skal være tom (null).</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Værdien er ikke gyldig.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Værdien er ikke en gyldig tid.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Værdien er ikke en gyldig URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>De to værdier skal være ens.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Filen er for stor. Den maksimale størrelse er {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Filen er for stor.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Filen kunne ikke blive uploadet.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Værdien skal være et gyldigt tal.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Filen er ikke gyldigt billede.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Dette er ikke en gyldig IP adresse.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Værdien er ikke et gyldigt sprog.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Værdien er ikke en gyldig lokalitet.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Værdien er ikke et gyldigt land.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Værdien er allerede i brug.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Størrelsen på billedet kunne ikke detekteres.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Billedbredden er for stor ({{ width }}px). Tilladt maksimumsbredde er {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Billedebredden er for lille ({{ width }}px). Forventet minimumshøjde er {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Billedhøjden er for stor ({{ height }}px). Tilladt maksimumshøjde er {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Billedhøjden er for lille ({{ height }}px). Forventet minimumshøjde er {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Værdien skal være brugerens nuværende password.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Værdien skal have præcis {{ limit }} tegn.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Filen var kun delvis uploadet.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Ingen fil blev uploadet.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Ingen midlertidig mappe er konfigureret i php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Kan ikke skrive midlertidig fil til disk.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>En PHP udvidelse forårsagede fejl i upload.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Denne samling skal indeholde {{ limit }} element eller flere.|Denne samling skal indeholde {{ limit }} elementer eller flere.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Denne samling skal indeholde {{ limit }} element eller mindre.|Denne samling skal indeholde {{ limit }} elementer eller mindre.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Denne samling skal indeholde præcis {{ limit }} element.|Denne samling skal indeholde præcis {{ limit }} elementer.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Ugyldigt kortnummer.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Ikke-understøttet korttype eller ugyldigt kortnummer.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Det er ikke en gyldig International Bank Account Number (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Værdien er ikke en gyldig ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Værdien er ikke en gyldig ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Værdien er hverken en gyldig ISBN-10 eller en gyldig ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Værdien er ikke en gyldig ISSN.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.de.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.de.xlf
new file mode 100644
index 0000000..d2e13c6
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.de.xlf
@@ -0,0 +1,311 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Dieser Wert sollte false sein.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Dieser Wert sollte true sein.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Dieser Wert sollte vom Typ {{ type }} sein.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Dieser Wert sollte leer sein.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Sie haben einen ungültigen Wert ausgewählt.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Sie müssen mindestens {{ limit }} Möglichkeit wählen.|Sie müssen mindestens {{ limit }} Möglichkeiten wählen.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Sie dürfen höchstens {{ limit }} Möglichkeit wählen.|Sie dürfen höchstens {{ limit }} Möglichkeiten wählen.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Einer oder mehrere der angegebenen Werte sind ungültig.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Dieses Feld wurde nicht erwartet.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Dieses Feld fehlt.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Dieser Wert entspricht keiner gültigen Datumsangabe.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Dieser Wert entspricht keiner gültigen Datums- und Zeitangabe.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Dieser Wert ist keine gültige E-Mail-Adresse.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Die Datei wurde nicht gefunden.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Die Datei ist nicht lesbar.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Die Datei ist zu groß ({{ size }} {{ suffix }}). Die maximal zulässige Größe beträgt {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Der Dateityp ist ungültig ({{ type }}). Erlaubte Dateitypen sind {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Dieser Wert sollte kleiner oder gleich {{ limit }} sein.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Diese Zeichenkette ist zu lang. Sie sollte höchstens {{ limit }} Zeichen haben.|Diese Zeichenkette ist zu lang. Sie sollte höchstens {{ limit }} Zeichen haben.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Dieser Wert sollte größer oder gleich {{ limit }} sein.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Diese Zeichenkette ist zu kurz. Sie sollte mindestens {{ limit }} Zeichen haben.|Diese Zeichenkette ist zu kurz. Sie sollte mindestens {{ limit }} Zeichen haben.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Dieser Wert sollte nicht leer sein.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Dieser Wert sollte nicht null sein.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Dieser Wert sollte null sein.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Dieser Wert ist nicht gültig.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Dieser Wert entspricht keiner gültigen Zeitangabe.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Dieser Wert ist keine gültige URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Die beiden Werte sollten identisch sein.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Die Datei ist zu groß. Die maximal zulässige Größe beträgt {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Die Datei ist zu groß.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Die Datei konnte nicht hochgeladen werden.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Dieser Wert sollte eine gültige Zahl sein.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Diese Datei ist kein gültiges Bild.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Dies ist keine gültige IP-Adresse.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Dieser Wert entspricht keiner gültigen Sprache.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Dieser Wert entspricht keinem gültigen Gebietsschema.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Dieser Wert entspricht keinem gültigen Land.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Dieser Wert wird bereits verwendet.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Die Größe des Bildes konnte nicht ermittelt werden.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Die Bildbreite ist zu groß ({{ width }}px). Die maximal zulässige Breite beträgt {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Die Bildbreite ist zu gering ({{ width }}px). Die erwartete Mindestbreite beträgt {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Die Bildhöhe ist zu groß ({{ height }}px). Die maximal zulässige Höhe beträgt {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Die Bildhöhe ist zu gering ({{ height }}px). Die erwartete Mindesthöhe beträgt {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Dieser Wert sollte dem aktuellen Benutzerpasswort entsprechen.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Dieser Wert sollte genau {{ limit }} Zeichen lang sein.|Dieser Wert sollte genau {{ limit }} Zeichen lang sein.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Die Datei wurde nur teilweise hochgeladen.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Es wurde keine Datei hochgeladen.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Es wurde kein temporärer Ordner in der php.ini konfiguriert.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Kann die temporäre Datei nicht speichern.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Eine PHP-Erweiterung verhinderte den Upload.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Diese Sammlung sollte {{ limit }} oder mehr Elemente beinhalten.|Diese Sammlung sollte {{ limit }} oder mehr Elemente beinhalten.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Diese Sammlung sollte {{ limit }} oder weniger Elemente beinhalten.|Diese Sammlung sollte {{ limit }} oder weniger Elemente beinhalten.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Diese Sammlung sollte genau {{ limit }} Element beinhalten.|Diese Sammlung sollte genau {{ limit }} Elemente beinhalten.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Ungültige Kartennummer.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Nicht unterstützer Kartentyp oder ungültige Kartennummer.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Dieser Wert ist keine gültige IBAN-Kontonummer.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Dieser Wert entspricht keiner gültigen ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Dieser Wert entspricht keiner gültigen ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Dieser Wert ist weder eine gültige ISBN-10 noch eine gültige ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Dieser Wert ist keine gültige ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Dieser Wert ist keine gültige Währung.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Dieser Wert sollte gleich {{ compared_value }} sein.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Dieser Wert sollte größer als {{ compared_value }} sein.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Dieser Wert sollte größer oder gleich {{ compared_value }} sein.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Dieser Wert sollte identisch sein mit {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Dieser Wert sollte kleiner als {{ compared_value }} sein.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Dieser Wert sollte kleiner oder gleich {{ compared_value }} sein.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Dieser Wert sollte nicht {{ compared_value }} sein.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Dieser Wert sollte nicht identisch sein mit {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>Das Seitenverhältnis des Bildes ist zu groß ({{ ratio }}). Der erlaubte Maximalwert ist {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>Das Seitenverhältnis des Bildes ist zu klein ({{ ratio }}). Der erwartete Minimalwert ist {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>Das Bild ist quadratisch ({{ width }}x{{ height }}px). Quadratische Bilder sind nicht erlaubt.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>Das Bild ist im Querformat ({{ width }}x{{ height }}px). Bilder im Querformat sind nicht erlaubt.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>Das Bild ist im Hochformat ({{ width }}x{{ height }}px). Bilder im Hochformat sind nicht erlaubt.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Eine leere Datei ist nicht erlaubt.</target>
+ </trans-unit>
+ <trans-unit id="80">
+ <source>This value does not match the expected {{ charset }} charset.</source>
+ <target>Dieser Wert entspricht nicht dem erwarteten Zeichensatz {{ charset }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.el.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.el.xlf
new file mode 100644
index 0000000..4fa0d42
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.el.xlf
@@ -0,0 +1,283 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Αυτή η τιμή πρέπει να είναι ψευδής.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Αυτή η τιμή πρέπει να είναι αληθής.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Αυτή η τιμή πρέπει να είναι τύπου {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Αυτή η τιμή πρέπει να είναι κενή.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Η τιμή που επιλέχθηκε δεν αντιστοιχεί σε έγκυρη επιλογή.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Πρέπει να επιλέξετε τουλάχιστον {{ limit }} επιλογή.|Πρέπει να επιλέξετε τουλάχιστον {{ limit }} επιλογές.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Πρέπει να επιλέξετε το πολύ {{ limit }} επιλογή.|Πρέπει να επιλέξετε το πολύ {{ limit }} επιλογές.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Μια ή περισσότερες τιμές δεν είναι έγκυρες.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Αυτό το πεδίο δεν ήταν αναμενόμενο.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Λείπει αυτό το πεδίο.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Η τιμή δεν αντιστοιχεί σε έγκυρη ημερομηνία.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Η τιμή δεν αντιστοιχεί σε έγκυρη ημερομηνία και ώρα.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Η τιμή δεν αντιστοιχεί σε έγκυρο email.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Το αρχείο δε μπορεί να βρεθεί.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Το αρχείο δεν είναι αναγνώσιμο.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Το αρχείο είναι πολύ μεγάλο ({{ size }} {{ suffix }}). Το μέγιστο επιτρεπτό μέγεθος είναι {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Ο τύπος mime του αρχείου δεν είναι έγκυρος ({{ type }}). Οι έγκρυοι τύποι mime είναι {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Αυτή η τιμή θα έπρεπε να είναι {{ limit }} ή λιγότερο.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Αυτή η τιμή είναι πολύ μεγάλη. Θα έπρεπε να έχει {{ limit }} χαρακτήρα ή λιγότερο.|Αυτή η τιμή είναι πολύ μεγάλη. Θα έπρεπε να έχει {{ limit }} χαρακτήρες ή λιγότερο.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Αυτή η τιμή θα έπρεπε να είναι {{ limit }} ή περισσότερο.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Αυτή η τιμή είναι πολύ μικρή. Θα έπρεπε να έχει {{ limit }} χαρακτήρα ή περισσότερο.|Αυτή η τιμή είναι πολύ μικρή. Θα έπρεπε να έχει {{ limit }} χαρακτήρες ή περισσότερο.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Αυτή η τιμή δεν πρέπει να είναι κενή.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Αυτή η τιμή δεν πρέπει να είναι μηδενική.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Αυτή η τιμή πρέπει να είναι μηδενική.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Αυτή η τιμή δεν είναι έκγυρη.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Αυτή η τιμή δεν αντιστοιχεί σε έγκυρη ώρα.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Αυτή η τιμή δεν αντιστοιχεί σε έγκυρο URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Οι δύο τιμές θα πρέπει να είναι ίδιες.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Το αρχείο είναι πολύ μεγάλο. Το μέγιστο επιτρεπτό μέγεθος είναι {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Το αρχείο είναι πολύ μεγάλο.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Το αρχείο δε μπορεί να ανέβει.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Αυτή η τιμή θα πρέπει να είναι ένας έγκυρος αριθμός.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Το αρχείο δεν αποτελεί έγκυρη εικόνα.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Αυτό δεν είναι μια έκγυρη διεύθυνση IP.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Αυτή η τιμή δεν αντιστοιχεί σε μια έκγυρη γλώσσα.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Αυτή η τιμή δεν αντιστοιχεί σε έκγυρο κωδικό τοποθεσίας.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Αυτή η τιμή δεν αντιστοιχεί σε μια έκγυρη χώρα.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Αυτή η τιμή χρησιμοποιείται ήδη.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Το μέγεθος της εικόνας δεν ήταν δυνατό να ανιχνευθεί.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Το πλάτος της εικόνας είναι πολύ μεγάλο ({{ width }}px). Το μέγιστο επιτρεπτό πλάτος είναι {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Το πλάτος της εικόνας είναι πολύ μικρό ({{ width }}px). Το ελάχιστο επιτρεπτό πλάτος είναι {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Το ύψος της εικόνας είναι πολύ μεγάλο ({{ height }}px). Το μέγιστο επιτρεπτό ύψος είναι {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Το ύψος της εικόνας είναι πολύ μικρό ({{ height }}px). Το ελάχιστο επιτρεπτό ύψος είναι {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Αυτή η τιμή θα έπρεπε να είναι ο τρέχων κωδικός.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Αυτή η τιμή θα έπρεπε να έχει ακριβώς {{ limit }} χαρακτήρα.|Αυτή η τιμή θα έπρεπε να έχει ακριβώς {{ limit }} χαρακτήρες.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Το αρχείο δεν ανέβηκε ολόκληρο.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Δεν ανέβηκε κανένα αρχείο.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Κανένας προσωρινός φάκελος δεν έχει ρυθμιστεί στο php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Αδυναμία εγγραφής προσωρινού αρχείου στο δίσκο.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Μια επέκταση PHP προκάλεσε αδυναμία ανεβάσματος.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Αυτή η συλλογή θα πρέπει να περιέχει {{ limit }} στοιχείο ή περισσότερα.|Αυτή η συλλογή θα πρέπει να περιέχει {{ limit }} στοιχεία ή περισσότερα.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Αυτή η συλλογή θα πρέπει να περιέχει {{ limit }} στοιχείo ή λιγότερα.|Αυτή η συλλογή θα πρέπει να περιέχει {{ limit }} στοιχεία ή λιγότερα.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Αυτή η συλλογή θα πρέπει να περιέχει ακριβώς {{ limit }} στοιχείo.|Αυτή η συλλογή θα πρέπει να περιέχει ακριβώς {{ limit }} στοιχεία.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Μη έγκυρος αριθμός κάρτας.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Μη υποστηριζόμενος τύπος κάρτας ή μη έγκυρος αριθμός κάρτας.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Αυτό δεν αντιστοιχεί σε έκγυρο διεθνή αριθμό τραπεζικού λογαριασμού (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Αυτό δεν είναι έγκυρος κωδικός ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Αυτό δεν είναι έγκυρος κωδικός ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Αυτό δεν είναι ούτε έγκυρος κωδικός ISBN-10 ούτε έγκυρος κωδικός ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Αυτό δεν είναι έγκυρος κωδικός ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Αυτό δεν αντιστοιχεί σε έγκυρο νόμισμα.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Αυτή η τιμή θα πρέπει να είναι ίση με {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Αυτή η τιμή θα πρέπει να είναι μεγαλύτερη από {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Αυτή η τιμή θα πρέπει να είναι μεγαλύτερη ή ίση με {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Αυτή η τιμή θα πρέπει να είναι πανομοιότυπη με {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Αυτή η τιμή θα πρέπει να είναι μικρότερη από {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Αυτή η τιμή θα πρέπει να είναι μικρότερη ή ίση με {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Αυτή η τιμή δεν θα πρέπει να είναι ίση με {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Αυτή η τιμή δεν πρέπει να είναι πανομοιότυπη με {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.en.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.en.xlf
new file mode 100644
index 0000000..6509ab1
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.en.xlf
@@ -0,0 +1,311 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>This value should be false.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>This value should be true.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>This value should be of type {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>This value should be blank.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>The value you selected is not a valid choice.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>One or more of the given values is invalid.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>This field was not expected.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>This field is missing.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>This value is not a valid date.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>This value is not a valid datetime.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>This value is not a valid email address.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>The file could not be found.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>The file is not readable.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>This value should be {{ limit }} or less.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>This value should be {{ limit }} or more.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>This value should not be blank.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>This value should not be null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>This value should be null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>This value is not valid.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>This value is not a valid time.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>This value is not a valid URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>The two values should be equal.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>The file is too large.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>The file could not be uploaded.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>This value should be a valid number.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>This file is not a valid image.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>This is not a valid IP address.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>This value is not a valid language.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>This value is not a valid locale.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>This value is not a valid country.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>This value is already used.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>The size of the image could not be detected.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>This value should be the user's current password.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>The file was only partially uploaded.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>No file was uploaded.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>No temporary folder was configured in php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Cannot write temporary file to disk.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>A PHP extension caused the upload to fail.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Invalid card number.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Unsupported card type or invalid card number.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>This is not a valid International Bank Account Number (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>This value is not a valid ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>This value is not a valid ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>This value is neither a valid ISBN-10 nor a valid ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>This value is not a valid ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>This value is not a valid currency.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>This value should be equal to {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>This value should be greater than {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>This value should be greater than or equal to {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>This value should be less than {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>This value should be less than or equal to {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>This value should not be equal to {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>An empty file is not allowed.</target>
+ </trans-unit>
+ <trans-unit id="80">
+ <source>This value does not match the expected {{ charset }} charset.</source>
+ <target>This value does not match the expected {{ charset }} charset.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.es.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.es.xlf
new file mode 100644
index 0000000..ee8ffe6
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.es.xlf
@@ -0,0 +1,311 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Este valor debería ser falso.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Este valor debería ser verdadero.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Este valor debería ser de tipo {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Este valor debería estar vacío.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>El valor seleccionado no es una opción válida.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Debe seleccionar al menos {{ limit }} opción.|Debe seleccionar al menos {{ limit }} opciones.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Debe seleccionar como máximo {{ limit }} opción.|Debe seleccionar como máximo {{ limit }} opciones.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Uno o más de los valores indicados no son válidos.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Este campo no se esperaba.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Este campo está desaparecido.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Este valor no es una fecha válida.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Este valor no es una fecha y hora válidas.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Este valor no es una dirección de email válida.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>No se pudo encontrar el archivo.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>No se puede leer el archivo.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>El archivo es demasiado grande ({{ size }} {{ suffix }}). El tamaño máximo permitido es {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>El tipo mime del archivo no es válido ({{ type }}). Los tipos mime válidos son {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Este valor debería ser {{ limit }} o menos.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Este valor debería ser {{ limit }} o más.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Este valor no debería estar vacío.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Este valor no debería ser nulo.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Este valor debería ser nulo.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Este valor no es válido.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Este valor no es una hora válida.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Este valor no es una URL válida.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Los dos valores deberían ser iguales.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>El archivo es demasiado grande. El tamaño máximo permitido es {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>El archivo es demasiado grande.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>No se pudo subir el archivo.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Este valor debería ser un número válido.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>El archivo no es una imagen válida.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Esto no es una dirección IP válida.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Este valor no es un idioma válido.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Este valor no es una localización válida.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Este valor no es un país válido.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Este valor ya se ha utilizado.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>No se pudo determinar el tamaño de la imagen.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>El ancho de la imagen es demasiado grande ({{ width }}px). El ancho máximo permitido es de {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>El ancho de la imagen es demasiado pequeño ({{ width }}px). El ancho mínimo requerido es {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>La altura de la imagen es demasiado grande ({{ height }}px). La altura máxima permitida es de {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>La altura de la imagen es demasiado pequeña ({{ height }}px). La altura mínima requerida es de {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Este valor debería ser la contraseña actual del usuario.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Este valor debería tener exactamente {{ limit }} carácter.|Este valor debería tener exactamente {{ limit }} caracteres.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>El archivo fue sólo subido parcialmente.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Ningún archivo fue subido.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Ninguna carpeta temporal fue configurada en php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>No se pudo escribir el archivo temporal en el disco.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Una extensión de PHP hizo que la subida fallara.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Esta colección debe contener {{ limit }} elemento o más.|Esta colección debe contener {{ limit }} elementos o más.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Esta colección debe contener {{ limit }} elemento o menos.|Esta colección debe contener {{ limit }} elementos o menos.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Esta colección debe contener exactamente {{ limit }} elemento.|Esta colección debe contener exactamente {{ limit }} elementos.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Número de tarjeta inválido.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Tipo de tarjeta no soportado o número de tarjeta inválido.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Esto no es un International Bank Account Number (IBAN) válido.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Este valor no es un ISBN-10 válido.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Este valor no es un ISBN-13 válido.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Este valor no es ni un ISBN-10 válido ni un ISBN-13 válido.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Este valor no es un ISSN válido.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Este valor no es una divisa válida.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Este valor debería ser igual que {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Este valor debería ser mayor que {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Este valor debería ser mayor o igual que {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Este valor debería ser idéntico a {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Este valor debería ser menor que {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Este valor debería ser menor o igual que {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Este valor debería ser distinto de {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Este valor no debería ser idéntico a {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>La proporción de la imagen es demasiado grande ({{ ratio }}). La máxima proporción permitida es {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>La proporción de la imagen es demasiado pequeña ({{ ratio }}). La mínima proporción permitida es {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>La imagen es cuadrada ({{ width }}x{{ height }}px). Las imágenes cuadradas no están permitidas.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>La imagen está orientada horizontalmente ({{ width }}x{{ height }}px). Las imágenes orientadas horizontalmente no están permitidas.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>La imagen está orientada verticalmente ({{ width }}x{{ height }}px). Las imágenes orientadas verticalmente no están permitidas.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>No está permitido un archivo vacío.</target>
+ </trans-unit>
+ <trans-unit id="80">
+ <source>This value does not match the expected {{ charset }} charset.</source>
+ <target>La codificación de caracteres para este valor debería ser {{ charset }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.et.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.et.xlf
new file mode 100644
index 0000000..d047c8b
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.et.xlf
@@ -0,0 +1,283 @@
+<?xml version='1.0'?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Väärtus peaks olema väär.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Väärtus peaks oleme tõene.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Väärtus peaks olema {{ type }}-tüüpi.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Väärtus peaks olema tühi.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Väärtus peaks olema üks etteantud valikutest.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Valima peaks vähemalt {{ limit }} valikut.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Valima peaks mitte rohkem kui {{ limit }} valikut.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>One or more of the given values is invalid.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>See väli ei oodatud.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>See väli on puudu.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Väärtus pole korrektne kuupäev.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Väärtus pole korrektne kuupäev ja kellaeg.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Väärtus pole korrektne e-maili aadress.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Faili ei leita.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Fail ei ole loetav.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Fail on liiga suur ({{ size }} {{ suffix }}). Suurim lubatud suurus on {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Faili sisutüüp on vigane ({{ type }}). Lubatud sisutüübid on {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Väärtus peaks olema {{ limit }} või vähem.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Väärtus on liiga pikk. Pikkus peaks olema {{ limit }} tähemärki või vähem.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Väärtus peaks olema {{ limit }} või rohkem.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Väärtus on liiga lühike. Pikkus peaks olema {{ limit }} tähemärki või rohkem.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Väärtus ei tohiks olla tühi.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Väärtus ei tohiks olla 'null'.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Väärtus peaks olema 'null'.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Väärtus on vigane.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Väärtus pole korrektne aeg.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Väärtus pole korrektne URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Väärtused peaksid olema võrdsed.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Fail on liiga suur. Maksimaalne lubatud suurus on {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Fail on liiga suur.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Faili ei saa üles laadida.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Väärtus peaks olema korrektne number.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Fail ei ole korrektne pilt.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>IP aadress pole korrektne.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Väärtus pole korrektne keel.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Väärtus pole korrektne asukohakeel.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Väärtus pole olemasolev riik.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Väärtust on juba kasutatud.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Pildi suurust polnud võimalik tuvastada.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Pilt on liiga lai ({{ width }}px). Suurim lubatud laius on {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Pilt on liiga kitsas ({{ width }}px). Vähim lubatud laius on {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Pilt on liiga pikk ({{ height }}px). Lubatud suurim pikkus on {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Pilt pole piisavalt pikk ({{ height }}px). Lubatud vähim pikkus on {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Väärtus peaks olema kasutaja kehtiv salasõna.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} characters.</source>
+ <target>Väärtus peaks olema täpselt {{ limit }} tähemärk pikk.|Väärtus peaks olema täpselt {{ limit }} tähemärki pikk.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Fail ei laetud täielikult üles.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Ühtegi faili ei laetud üles.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Ühtegi ajutist kausta polnud php.ini-s seadistatud.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Ajutist faili ei saa kettale kirjutada.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>PHP laiendi tõttu ebaõnnestus faili üleslaadimine.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} elements or more.</source>
+ <target>Kogumikus peaks olema vähemalt {{ limit }} element.|Kogumikus peaks olema vähemalt {{ limit }} elementi.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} elements or less.</source>
+ <target>Kogumikus peaks olema ülimalt {{ limit }} element.|Kogumikus peaks olema ülimalt {{ limit }} elementi.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} elements.</source>
+ <target>Kogumikus peaks olema täpselt {{ limit }} element.|Kogumikus peaks olema täpselt {{ limit }}|elementi.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Vigane kaardi number.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Kaardi tüüpi ei toetata või kaardi number on vigane.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Väärtus pole korrektne IBAN-number.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Väärtus pole korrektne ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Väärtus pole korrektne ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Väärtus pole korrektne ISBN-10 ega ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Väärtus pole korrektne ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Väärtus pole korrektne valuuta.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Väärtus peaks olema võrdne {{ compared_value }}-ga.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Väärtus peaks olema suurem kui {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Väärtus peaks olema suurem kui või võrduma {{ compared_value }}-ga.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Väärtus peaks olema identne väärtusega {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Väärtus peaks olema väiksem kui {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Väärtus peaks olema väiksem kui või võrduma {{ compared_value }}-ga.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Väärtus ei tohiks võrduda {{ compared_value }}-ga.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Väärtus ei tohiks olla identne väärtusega {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.eu.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.eu.xlf
new file mode 100644
index 0000000..b2edefd
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.eu.xlf
@@ -0,0 +1,283 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Balio hau faltsua izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Balio hau egia izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Balio hau {{ type }} motakoa izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Balio hau hutsik egon beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Hautatu duzun balioa ez da aukera egoki bat.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Gutxienez aukera {{ limit }} hautatu behar duzu.|Gutxienez {{ limit }} aukera hautatu behar dituzu.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Gehienez aukera {{ limit }} hautatu behar duzu.|Gehienez {{ limit }} aukera hautatu behar dituzu.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Emandako balioetatik gutxienez bat ez da egokia.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Eremu hau ez zen espero.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Eremu hau falta da.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Balio hau ez da data egoki bat.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Balio hau ez da data-ordu egoki bat.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Balio hau ez da posta elektroniko egoki bat.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Ezin izan da fitxategia aurkitu.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Fitxategia ez da irakurgarria.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Fitxategia handiegia da ({{ size }} {{ suffix }}). Baimendutako tamaina handiena {{ limit }} {{ suffix }} da.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Fitxategiaren mime mota ez da egokia ({{ type }}). Hauek dira baimendutako mime motak: {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Balio hau gehienez {{ limit }} izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Balio hau luzeegia da. Gehienez karaktere {{ limit }} eduki beharko luke.|Balio hau luzeegia da. Gehienez {{ limit }} karaktere eduki beharko lituzke.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Balio hau gutxienez {{ limit }} izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Balio hau motzegia da. Karaktere {{ limit }} gutxienez eduki beharko luke.|Balio hau motzegia da. Gutxienez {{ limit }} karaktere eduki beharko lituzke.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Balio hau ez litzateke hutsik egon behar.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Balio hau ez litzateke nulua izan behar.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Balio hau nulua izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Balio hau ez da egokia.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Balio hau ez da ordu egoki bat.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Balio hau ez da baliabideen kokatzaile uniforme (URL) egoki bat.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Bi balioak berdinak izan beharko lirateke.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Fitxategia handiegia da. Baimendutako tamaina handiena {{ limit }} {{ suffix }} da.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Fitxategia handiegia da.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Ezin izan da fitxategia igo.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Balio hau zenbaki egoki bat izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Fitxategi hau ez da irudi egoki bat.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Honako hau ez da IP helbide egoki bat.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Balio hau ez da hizkuntza egoki bat.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Balio hau ez da kokapen egoki bat.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Balio hau ez da herrialde egoki bat.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Balio hau jadanik erabilia izan da.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Ezin izan da irudiaren tamaina detektatu.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Irudiaren zabalera handiegia da ({{ width }}px). Onartutako gehienezko zabalera {{ max_width }}px dira.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Irudiaren zabalera txikiegia da ({{ width }}px). Onartutako gutxieneko zabalera {{ min_width }}px dira.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Irudiaren altuera handiegia da ({{ height }}px). Onartutako gehienezko altuera {{ max_height }}px dira.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Irudiaren altuera txikiegia da ({{ height }}px). Onartutako gutxieneko altuera {{ min_height }}px dira.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Balio hau uneko erabiltzailearen pasahitza izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Balio honek zehazki karaktere {{ limit }} izan beharko luke.|Balio honek zehazki {{ limit }} karaktere izan beharko lituzke.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Fitxategiaren zati bat bakarrik igo da.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Ez da fitxategirik igo.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Ez da aldi baterako karpetarik konfiguratu php.ini fitxategian.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Ezin izan da aldi baterako fitxategia diskoan idatzi.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>PHP luzapen batek igoeraren hutsa eragin du.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Bilduma honek gutxienez elementu {{ limit }} eduki beharko luke.|Bilduma honek gutxienez {{ limit }} elementu eduki beharko lituzke.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Bilduma honek gehienez elementu {{ limit }} eduki beharko luke.|Bilduma honek gehienez {{ limit }} elementu eduki beharko lituzke.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Bilduma honek zehazki elementu {{ limit }} eduki beharko luke.|Bilduma honek zehazki {{ limit }} elementu eduki beharko lituzke.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Txartel zenbaki baliogabea.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Txartel mota onartezina edo txartel zenbaki baliogabea.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Hau ez da baliozko banku internazionaleko kontu zenbaki (IBAN) bat.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Balio hau ez da onartutako ISBN-10 bat.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Balio hau ez da onartutako ISBN-13 bat.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Balio hau ez da onartutako ISBN-10 edo ISBN-13 bat.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Balio hau ez da onartutako ISSN bat.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Balio hau ez da baliozko moneta bat.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Balio hau {{ compared_value }}-(r)en berbera izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Balio hau {{ compared_value }} baino handiagoa izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Balio hau {{ compared_value }}-(r)en berdina edota handiagoa izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Balio hau {{ compared_value_type }} {{ compared_value }}-(r)en berbera izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Balio hau {{ compared_value }} baino txikiagoa izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Balio hau {{ compared_value }}-(r)en berdina edota txikiagoa izan beharko litzateke.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Balio hau ez litzateke {{ compared_value }}-(r)en berdina izan behar.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Balio hau ez litzateke {{ compared_value_type }} {{ compared_value }}-(r)en berbera izan behar.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fa.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fa.xlf
new file mode 100644
index 0000000..98b4bd6
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fa.xlf
@@ -0,0 +1,283 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target state="needs-review-translation">این مقدار باید نادرست(False) باشد.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>این مقدار باید درست(True) باشد.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>این مقدار باید از نوع {{ type }} باشد.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>این فیلد باید خالی باشد.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>گزینه انتخابی معتبر نیست.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>باید حداقل {{ limit }} گزینه انتخاب کنید.|باید حداقل {{ limit }} گزینه انتخاب کنید.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>حداکثر {{ limit }} گزینه می توانید انتخاب کنید.|حداکثر {{ limit }} گزینه می توانید انتخاب کنید.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>یک یا چند مقدار نامعتبر وجود دارد.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>The fields {{ fields }} were not expected.</source>
+ <target>فیلدهای {{ fields }} اضافی هستند.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>The fields {{ fields }} are missing.</source>
+ <target>فیلدهای {{ fields }} کم هستند.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>این مقدار یک تاریخ معتبر نیست.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>این مقدار یک تاریخ و زمان معتبر نیست.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>این یک رایانامه معتبر نیست.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>فایل پیدا نشد.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>فایل قابلیت خواندن ندارد.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>فایل بیش از اندازه بزرگ است({{ size }} {{ suffix }}). حداکثر اندازه مجاز برابر {{ limit }} {{ suffix }} است.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>این نوع فایل مجاز نیست({{ type }}). نوع های مجاز {{ types }} هستند.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>این مقدار باید کوچکتر یا مساوی {{ limit }} باشد.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>بسیار طولانی است.حداکثر تعداد حروف مجاز برابر {{ limit }} است.|بسیار طولانی است.حداکثر تعداد حروف مجاز برابر {{ limit }} است.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>این مقدار باید برابر و یا بیشتر از {{ limit }} باشد.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>بسیار کوتاه است.تعداد حروف باید حداقل {{ limit }} باشد.|بسیار کوتاه است.تعداد حروف باید حداقل {{ limit }} باشد.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>این مقدار نباید تهی باشد.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>باید مقداری داشته باشد..</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>نباید مقداری داشته باشد.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>این مقدار معتبر نیست.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>این مقدار یک زمان صحیح نیست.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>این یک URL معتبر نیست.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>دو مقدار باید برابر باشند.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>فایل بیش از اندازه بزرگ است. حداکثر اندازه مجاز برابر {{ limit }} {{ suffix }} است.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>فایل بیش از اندازه بزرگ است.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>بارگذاری فایل با شکست مواجه شد.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>این مقدار باید یک عدد معتبر باشد.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>این فایل یک تصویر نیست.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>این مقدار یک IP معتبر نیست.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>این مقدار یک زبان صحیح نیست.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>این مقدار یک محل صحیح نیست.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>این مقدار یک کشور صحیح نیست.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>این مقدار قبلا مورد استفاده قرار گرفته است.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>اندازه تصویر قابل شناسایی نیست.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>طول تصویر بسیار بزرگ است ({{ width }}px). بشینه طول مجاز {{ max_width }}px است.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>طول تصویر بسیار کوچک است ({{ width }}px). کمینه طول موردنظر {{ min_width }}px است.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>ارتفاع تصویر بسیار بزرگ است ({{ height }}px). بشینه ارتفاع مجاز {{ max_height }}px است.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>ارتفاع تصویر بسیار کوچک است ({{ height }}px). کمینه ارتفاع موردنظر {{ min_height }}px است.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>این مقدار می بایست کلمه عبور کنونی کاربر باشد.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target> این مقدار می بایست دقیقا {{ limit }} کاراکتر داشته باشد.| این مقدار می بایست دقیقا {{ limit }} کاراکتر داشته باشد.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>فایل به صورت جزیی بارگذاری شده است.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>هیچ فایلی بارگذاری نشد.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>فولدر موقت در php.ini پیکربندی نشده است.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>فایل موقت را نمی توان در دیسک نوشت.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>اکستنشن PHP موجب شد که بارگذاری فایل با شکست مواجه شود.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>این مجموعه می بایست دارای {{ limit }} عنصر یا بیشتر باشد.|این مجموعه می بایست دارای {{ limit }} عنصر یا بیشتر باشد.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>این مجموعه می بایست دارای حداقل {{ limit }} عنصر یا کمتر باشد.|این مجموعه می بایست دارای {{ limit }} عنصر یا کمتر باشد.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>این مجموعه می بایست به طور دقیق دارا {{ limit }} عنصر باشد.|این مجموعه می بایست به طور دقیق دارای {{ limit }} قلم باشد.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>شماره کارت نامعتبر است.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>نوع کارت پشتیبانی نمی شود یا شماره کارت نامعتبر است.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>این یک شماره حساب بین المللی بانک (IBAN) درست نیست.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>این مقدار یک ISBN-10 درست نیست.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>این مقدار یک ISBN-13 درست نیست.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>این مقدار یک ISBN-10 درست یا ISBN-13 درست نیست.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>این مقدار یک ISSN درست نیست.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>این مقدار یک یکای پول درست نیست.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>این مقدار باید برابر با {{ compared_value }} باشد.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>این مقدار باید از {{ compared_value }} بیشتر باشد.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>این مقدار باید بزرگتر یا مساوی با {{ compared_value }} باشد.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>این مقدار باید با {{ compared_value_type }} {{ compared_value }} یکی باشد.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>این مقدار باید کمتر از {{ compared_value }} باشد.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>این مقدار باید کمتر یا مساوی با {{ compared_value }} باشد.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>این مقدار نباید با {{ compared_value }} برابر باشد.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>این مقدار نباید {{ compared_value_type }} {{ compared_value }} یکی باشد.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fi.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fi.xlf
new file mode 100644
index 0000000..3f5a07e
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fi.xlf
@@ -0,0 +1,227 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Arvon tulee olla epätosi.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Arvon tulee olla tosi.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Arvon tulee olla tyyppiä {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Arvon tulee olla tyhjä.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Arvon tulee olla yksi annetuista vaihtoehdoista.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Sinun tulee valita vähintään {{ limit }} vaihtoehtoa.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Sinun tulee valitan enintään {{ limit }} vaihtoehtoa.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Yksi tai useampi annetuista arvoista on virheellinen.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Tässä kentässä ei odotettu.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Tämä kenttä puuttuu.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Annettu arvo ei ole kelvollinen päivämäärä.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Annettu arvo ei ole kelvollinen päivämäärä ja kellonaika.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Annettu arvo ei ole kelvollinen sähköpostiosoite.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Tiedostoa ei löydy.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Tiedostoa ei voida lukea.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Tiedostonkoko ({{ size }} {{ suffix }}) on liian iso. Suurin sallittu tiedostonkoko on {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Tiedostotyyppi ({{ type }}) on virheellinen. Sallittuja tiedostotyyppejä ovat {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Arvon tulee olla {{ limit }} tai vähemmän.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Liian pitkä syöte. Syöte saa olla enintään {{ limit }} merkkiä.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Arvon tulee olla {{ limit }} tai enemmän.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Liian lyhyt syöte. Syötteen tulee olla vähintään {{ limit }} merkkiä.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Kenttä ei voi olla tyhjä.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Syöte ei voi olla null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Syötteen tulee olla null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Virheellinen arvo.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Annettu arvo ei ole kelvollinen kellonaika.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Annettu arvo ei ole kelvollinen URL-osoite.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Kahden annetun arvon tulee olla samat.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Annettu tiedosto on liian iso. Suurin sallittu tiedostokoko on {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Tiedosto on liian iso.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Tiedoston siirto epäonnistui.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Tämän arvon tulee olla numero.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Tämä tiedosto ei ole kelvollinen kuva.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Tämä ei ole kelvollinen IP-osoite.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Tämä arvo ei ole kelvollinen kieli.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Tämä arvo ei ole kelvollinen kieli- ja alueasetus (locale).</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Tämä arvo ei ole kelvollinen maa.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Tämä arvo on jo käytetty.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Kuvan kokoa ei voitu tunnistaa.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Kuva on liian leveä ({{ width }}px). Sallittu maksimileveys on {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Kuva on liian kapea ({{ width }}px). Leveyden tulisi olla vähintään {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Kuva on liian korkea ({{ width }}px). Sallittu maksimikorkeus on {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Kuva on liian matala ({{ height }}px). Korkeuden tulisi olla vähintään {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Tämän arvon tulisi olla käyttäjän tämänhetkinen salasana.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Tämän arvon tulisi olla tasan yhden merkin pituinen.|Tämän arvon tulisi olla tasan {{ limit }} merkkiä pitkä.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Tiedosto ladattiin vain osittain.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Tiedostoa ei ladattu.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Väliaikaishakemistoa ei ole asetettu php.ini -tiedostoon.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Väliaikaistiedostoa ei voitu kirjoittaa levylle.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>PHP-laajennoksen vuoksi tiedoston lataus epäonnistui.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Tässä ryhmässä tulisi olla yksi tai useampi elementti.|Tässä ryhmässä tulisi olla vähintään {{ limit }} elementtiä.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Tässä ryhmässä tulisi olla enintään yksi elementti.|Tässä ryhmässä tulisi olla enintään {{ limit }} elementtiä.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Tässä ryhmässä tulisi olla tasan yksi elementti.|Tässä ryhmässä tulisi olla enintään {{ limit }} elementtiä.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Virheellinen korttinumero.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Tätä korttityyppiä ei tueta tai korttinumero on virheellinen.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fr.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fr.xlf
new file mode 100644
index 0000000..237a3b4
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.fr.xlf
@@ -0,0 +1,311 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Cette valeur doit être fausse.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Cette valeur doit être vraie.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Cette valeur doit être de type {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Cette valeur doit être vide.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Cette valeur doit être l'un des choix proposés.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Vous devez sélectionner au moins {{ limit }} choix.|Vous devez sélectionner au moins {{ limit }} choix.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Vous devez sélectionner au maximum {{ limit }} choix.|Vous devez sélectionner au maximum {{ limit }} choix.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Une ou plusieurs des valeurs soumises sont invalides.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Ce champ n'a pas été prévu.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Ce champ est manquant.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Cette valeur n'est pas une date valide.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Cette valeur n'est pas une date valide.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Cette valeur n'est pas une adresse email valide.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Le fichier n'a pas été trouvé.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Le fichier n'est pas lisible.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Le fichier est trop volumineux ({{ size }} {{ suffix }}). Sa taille ne doit pas dépasser {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Le type du fichier est invalide ({{ type }}). Les types autorisés sont {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Cette valeur doit être inférieure ou égale à {{ limit }}.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Cette chaine est trop longue. Elle doit avoir au maximum {{ limit }} caractère.|Cette chaine est trop longue. Elle doit avoir au maximum {{ limit }} caractères.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Cette valeur doit être supérieure ou égale à {{ limit }}.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Cette chaine est trop courte. Elle doit avoir au minimum {{ limit }} caractère.|Cette chaine est trop courte. Elle doit avoir au minimum {{ limit }} caractères.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Cette valeur ne doit pas être vide.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Cette valeur ne doit pas être nulle.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Cette valeur doit être nulle.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Cette valeur n'est pas valide.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Cette valeur n'est pas une heure valide.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Cette valeur n'est pas une URL valide.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Les deux valeurs doivent être identiques.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Le fichier est trop volumineux. Sa taille ne doit pas dépasser {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Le fichier est trop volumineux.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Le téléchargement de ce fichier est impossible.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Cette valeur doit être un nombre.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Ce fichier n'est pas une image valide.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Cette adresse IP n'est pas valide.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Cette langue n'est pas valide.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Ce paramètre régional n'est pas valide.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Ce pays n'est pas valide.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Cette valeur est déjà utilisée.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>La taille de l'image n'a pas pu être détectée.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>La largeur de l'image est trop grande ({{ width }}px). La largeur maximale autorisée est de {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>La largeur de l'image est trop petite ({{ width }}px). La largeur minimale attendue est de {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>La hauteur de l'image est trop grande ({{ height }}px). La hauteur maximale autorisée est de {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>La hauteur de l'image est trop petite ({{ height }}px). La hauteur minimale attendue est de {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Cette valeur doit être le mot de passe actuel de l'utilisateur.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Cette chaine doit avoir exactement {{ limit }} caractère.|Cette chaine doit avoir exactement {{ limit }} caractères.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Le fichier a été partiellement transféré.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Aucun fichier n'a été transféré.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Aucun répertoire temporaire n'a été configuré dans le php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Impossible d'écrire le fichier temporaire sur le disque.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Une extension PHP a empêché le transfert du fichier.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Cette collection doit contenir {{ limit }} élément ou plus.|Cette collection doit contenir {{ limit }} éléments ou plus.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Cette collection doit contenir {{ limit }} élément ou moins.|Cette collection doit contenir {{ limit }} éléments ou moins.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Cette collection doit contenir exactement {{ limit }} élément.|Cette collection doit contenir exactement {{ limit }} éléments.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Numéro de carte invalide.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Type de carte non supporté ou numéro invalide.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Le numéro IBAN (International Bank Account Number) saisi n'est pas valide.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Cette valeur n'est pas un code ISBN-10 valide.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Cette valeur n'est pas un code ISBN-13 valide.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Cette valeur n'est ni un code ISBN-10, ni un code ISBN-13 valide.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Cette valeur n'est pas un code ISSN valide.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Cette valeur n'est pas une devise valide.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Cette valeur doit être égale à {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Cette valeur doit être supérieure à {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Cette valeur doit être supérieure ou égale à {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Cette valeur doit être identique à {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Cette valeur doit être inférieure à {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Cette valeur doit être inférieure ou égale à {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Cette valeur ne doit pas être égale à {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Cette valeur ne doit pas être identique à {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>Le rapport largeur/hauteur de l'image est trop grand ({{ ratio }}). Le rapport maximal autorisé est {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>Le rapport largeur/hauteur de l'image est trop petit ({{ ratio }}). Le rapport minimal attendu est {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>L'image est carrée ({{ width }}x{{ height }}px). Les images carrées ne sont pas autorisées.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>L'image est au format paysage ({{ width }}x{{ height }}px). Les images au format paysage ne sont pas autorisées.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>L'image est au format portrait ({{ width }}x{{ height }}px). Les images au format portrait ne sont pas autorisées.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Un fichier vide n'est pas autorisé.</target>
+ </trans-unit>
+ <trans-unit id="80">
+ <source>This value does not match the expected {{ charset }} charset.</source>
+ <target>Cette valeur ne correspond pas au jeu de caractères {{ charset }} attendu.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.gl.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.gl.xlf
new file mode 100644
index 0000000..1d0cc13
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.gl.xlf
@@ -0,0 +1,315 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Este valor debería ser falso.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Este valor debería ser verdadeiro.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Este valor debería ser de tipo {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Este valor debería estar baleiro.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>O valor seleccionado non é unha opción válida.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Debe seleccionar polo menos {{ limit }} opción.|Debe seleccionar polo menos {{ limit }} opcions.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Debe seleccionar como máximo {{ limit }} opción.|Debe seleccionar como máximo {{ limit }} opcions.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Un ou máis dos valores indicados non son válidos.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Este campo non era esperado.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Este campo falta.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Este valor non é unha data válida.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Este valor non é unha data e hora válidas.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Este valor non é unha dirección de correo electrónico válida.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Non se puido atopar o arquivo.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>O arquivo non se pode ler.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>O arquivo é demasiado grande ({{ size }} {{ suffix }}). O tamaño máximo permitido é {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>O tipo mime do arquivo non é válido ({{ type }}). Os tipos mime válidos son {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Este valor debería ser {{ limit }} ou menos.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Este valor é demasiado longo. Debería ter {{ limit }} carácter ou menos.|Este valor é demasiado longo. Debería ter {{ limit }} caracteres ou menos.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Este valor debería ser {{ limit }} ou máis.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Este valor non debería estar baleiro.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Este valor non debería ser null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Este valor debería ser null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Este valor non é válido.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Este valor non é unha hora válida.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Este valor non é unha URL válida.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Os dous valores deberían ser iguais.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>O arquivo é demasiado grande. O tamaño máximo permitido é {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>O arquivo é demasiado grande.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>No se puido cargar o arquivo.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Este valor debería ser un número válido.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>O arquivo non é unha imaxe válida.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Isto non é unha dirección IP válida.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Este valor non é un idioma válido.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Este valor non é unha localización válida.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Este valor non é un país válido.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Este valor xa está a ser empregado.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Non se puido determinar o tamaño da imaxe.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>A largura da imaxe é demasiado grande ({{ width }}px). A largura máxima permitida son {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>A largura da imaxe é demasiado pequena ({{ width }}px). A largura mínima requerida son {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>A altura da imaxe é demasiado grande ({{ height }}px). A altura máxima permitida son {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>A altura da imaxe é demasiado pequena ({{ height }}px). A altura mínima requerida son {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Este valor debería ser a contrasinal actual do usuario.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Este valor debería ter exactamente {{ limit }} carácter.|Este valor debería ter exactamente {{ limit }} caracteres.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>O arquivo foi só subido parcialmente.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Non se subiu ningún arquivo.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Ningunha carpeta temporal foi configurada en php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Non se puido escribir o arquivo temporal no disco.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Unha extensión de PHP provocou que a subida fallara.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Esta colección debe conter {{ limit }} elemento ou máis.|Esta colección debe conter {{ limit }} elementos ou máis.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Esta colección debe conter {{ limit }} elemento ou menos.|Esta colección debe conter {{ limit }} elementos ou menos.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Esta colección debe conter exactamente {{ limit }} elemento.|Esta colección debe conter exactamente {{ limit }} elementos.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Número de tarxeta non válido.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Tipo de tarxeta non soportado ou número de tarxeta non válido.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Este valor non é un International Bank Account Number (IBAN) válido.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Este valor non é un ISBN-10 válido.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Este valor non é un ISBN-13 válido.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Este valor non é nin un ISBN-10 válido nin un ISBN-13 válido.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Este valor non é un ISSN válido.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Este valor non é unha moeda válida.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Este valor debería ser igual a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Este valor debería ser maior que {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Este valor debería ser maior ou igual que {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Este valor debería ser identico a {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Este valor debería ser menor que {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Este valor debería ser menor ou igual que {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Este valor non debería ser igual a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Este valor non debería ser identico a {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>A proporción da imaxe é demasiado grande ({{ ratio }}). A proporción máxima permitida é {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>A proporción da é demasiado pequena ({{ ratio }}). A proporción mínima permitida é {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>A imaxe é cadrada ({{ width }}x{{ height }}px). As imáxenes cadradas non están permitidas.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>A imaxe está orientada horizontalmente ({{ width }}x{{ height }}px). As imáxenes orientadas horizontalmente non están permitidas.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>A imaxe está orientada verticalmente ({{ width }}x{{ height }}px). As imáxenes orientadas verticalmente non están permitidas.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Non está permitido un arquivo baleiro.</target>
+ </trans-unit>
+ <trans-unit id="79">
+ <source>The host could not be resolved.</source>
+ <target>Non se puido resolver o host.</target>
+ </trans-unit>
+ <trans-unit id="80">
+ <source>This value does not match the expected {{ charset }} charset.</source>
+ <target>A codificación de caracteres para este valor debería ser {{ charset }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.he.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.he.xlf
new file mode 100644
index 0000000..6510514
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.he.xlf
@@ -0,0 +1,307 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>הערך צריך להיות שקר.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>הערך צריך להיות אמת.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>הערך צריך להיות מסוג {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>הערך צריך להיות ריק.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>הערך שבחרת אינו חוקי.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>אתה צריך לבחור לפחות {{ limit }} אפשרויות.|אתה צריך לבחור לפחות {{ limit }} אפשרויות.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>אתה צריך לבחור לכל היותר {{ limit }} אפשרויות.|אתה צריך לבחור לכל היותר {{ limit }} אפשרויות.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>אחד או יותר מהערכים אינו חוקי.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>שדה זה לא היה צפוי</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>שדה זה חסר.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>הערך אינו תאריך חוקי.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>הערך אינו תאריך ושעה חוקיים.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>כתובת המייל אינה תקינה.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>הקובץ לא נמצא.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>לא ניתן לקרוא את הקובץ.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>הקובץ גדול מדי ({{ size }} {{ suffix }}). הגודל המרבי המותר הוא {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>סוג MIME של הקובץ אינו חוקי ({{ type }}). מותרים סוגי MIME {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>הערך צריל להכיל {{ limit }} תווים לכל היותר.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>הערך ארוך מידי. הוא צריך להכיל {{ limit }} תווים לכל היותר.|הערך ארוך מידי. הוא צריך להכיל {{ limit }} תווים לכל היותר.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>הערך צריך להכיל {{ limit }} תווים לפחות.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>הערך קצר מידיץ הוא צריך להכיל {{ limit }} תווים לפחות.|הערך קצר מידיץ הוא צריך להכיל {{ limit }} תווים לפחות.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>הערך לא אמור להיות ריק.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>הערך לא אמור להיות ריק.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>הערך צריך להיות ריק.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>הערך אינו חוקי.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>הערך אינו זמן תקין.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>זאת אינה כתובת אתר תקינה.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>שני הערכים צריכים להיות שווים.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>הקובץ גדול מדי. הגודל המרבי המותר הוא {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>הקובץ גדול מדי.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>לא ניתן לעלות את הקובץ.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>הערך צריך להיות מספר חוקי.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>הקובץ הזה אינו תמונה תקינה.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>זו אינה כתובת IP חוקית.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>הערך אינו שפה חוקית.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>הערך אינו אזור תקף.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>הערך אינו ארץ חוקית.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>הערך כבר בשימוש.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>לא ניתן לקבוע את גודל התמונה.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>רוחב התמונה גדול מדי ({{ width }}px). הרוחב המקסימלי הוא {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>רוחב התמונה קטן מדי ({{ width }}px). הרוחב המינימלי הוא {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>גובה התמונה גדול מדי ({{ height }}px). הגובה המקסימלי הוא {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>גובה התמונה קטן מדי ({{ height }}px). הגובה המינימלי הוא {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>הערך צריך להיות סיסמת המשתמש הנוכחי.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>הערך צריך להיות בדיוק {{ limit }} תווים.|הערך צריך להיות בדיוק {{ limit }} תווים.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>הקובץ הועלה באופן חלקי.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>הקובץ לא הועלה.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>לא הוגדרה תיקייה זמנית ב php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>לא ניתן לכתוב קובץ זמני לדיסק.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>סיומת PHP גרם להעלאה להיכשל.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>האוסף אמור להכיל {{ limit }} אלמנטים או יותר.|האוסף אמור להכיל {{ limit }} אלמנטים או יותר.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>האוסף אמור להכיל {{ limit }} אלמנטים או פחות.|האוסף אמור להכיל {{ limit }} אלמנטים או פחות.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>האוסף צריך להכיל בדיוק {{ limit }} אלמנטים.|האוסף צריך להכיל בדיוק {{ limit }} אלמנטים.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>מספר הכרטיס אינו חוקי.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>סוג הכרטיס אינו נתמך או לא חוקי.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>This is not a valid International Bank Account Number (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>This value is not a valid ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>This value is not a valid ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>This value is neither a valid ISBN-10 nor a valid ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>This value is not a valid ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>This value is not a valid currency.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>This value should be equal to {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>This value should be greater than {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>This value should be greater than or equal to {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>This value should be less than {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>This value should be less than or equal to {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>This value should not be equal to {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>An empty file is not allowed.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hr.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hr.xlf
new file mode 100644
index 0000000..a11e825
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hr.xlf
@@ -0,0 +1,283 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Ova vrijednost treba biti netočna (false).</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Ova vrijednost treba biti točna (true).</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Ova vrijednost treba biti tipa {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Ova vrijednost treba biti prazna.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Ova vrijednost treba biti jedna od ponuđenih.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Izaberite barem {{ limit }} mogućnosti.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Izaberite najviše {{ limit }} mogućnosti.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Jedna ili više danih vrijednosti nije ispravna.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Ovo polje nije očekivalo.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Ovo polje nedostaje.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Ova vrijednost nije ispravan datum.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Ova vrijednost nije ispravan datum-vrijeme.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Ova vrijednost nije ispravna e-mail adresa.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Datoteka ne može biti pronađena.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Datoteka nije čitljiva.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Datoteka je prevelika ({{ size }} {{ suffix }}). Najveća dozvoljena veličina je {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Mime tip datoteke nije ispravan ({{ type }}). Dozvoljeni mime tipovi su {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Ova vrijednost treba biti {{ limit }} ili manje.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Ova vrijednost je predugačka. Treba imati {{ limit }} znakova ili manje.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Ova vrijednost treba biti {{ limit }} ili više.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Ova vrijednost je prekratka. Treba imati {{ limit }} znakova ili više.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Ova vrijednost ne smije biti prazna.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Ova vrijednost ne smije biti null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Ova vrijednost treba biti null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Ova vrijednost nije ispravna.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Ova vrijednost nije ispravno vrijeme.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Ova vrijednost nije ispravan URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Obje vrijednosti trebaju biti jednake.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Ova datoteka je prevelika. Najveća dozvoljena veličina je {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Ova datoteka je prevelika.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Ova datoteka ne može biti prenesena.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Ova vrijednost treba biti ispravan broj.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Ova datoteka nije ispravna slika.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Ovo nije ispravna IP adresa.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Ova vrijednost nije ispravan jezik.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Ova vrijednost nije ispravana regionalna oznaka.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Ova vrijednost nije ispravna zemlja.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Ova vrijednost je već iskorištena.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Veličina slike se ne može odrediti.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Širina slike je prevelika ({{ width }}px). Najveća dozvoljena širina je {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Širina slike je premala ({{ width }}px). Najmanja dozvoljena širina je {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Visina slike je prevelika ({{ height }}px). Najveća dozvoljena visina je {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Visina slike je premala ({{ height }}px). Najmanja dozvoljena visina je {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Ova vrijednost treba biti trenutna korisnička lozinka.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Ova vrijednost treba imati točno {{ limit }} znakova.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Datoteka je samo djelomično prenesena.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Niti jedna datoteka nije prenesena.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>U php.ini datoteci nije konfiguriran privremeni folder.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Ne mogu zapisati privremenu datoteku na disk.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Prijenos datoteke nije uspio zbog PHP ekstenzije.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Neispravan broj kartice.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Neispravan broj kartice ili tip kartice nije podržan.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Ova vrijednost nije ispravan međunarodni broj bankovnog računa (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Ova vrijednost nije ispravan ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Ova vrijednost nije ispravan ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Ova vrijednost nije ispravan ISBN-10 niti ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Ova vrijednost nije ispravan ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Ova vrijednost nije ispravna valuta.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Ova vrijednost bi trebala biti jednaka {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Ova vrijednost bi trebala biti veća od {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Ova vrijednost bi trebala biti veća ili jednaka od {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ova vrijednost bi trebala biti {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Ova vrijednost bi trebala biti manja od {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Ova vrijednost bi trebala biti manja ili jednaka {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Ova vrijednost ne bi trebala biti {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ova vrijednost ne bi trebala biti {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hu.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hu.xlf
new file mode 100644
index 0000000..f5cbd0d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hu.xlf
@@ -0,0 +1,311 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Ennek az értéknek hamisnak kell lennie.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Ennek az értéknek igaznak kell lennie.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Ennek az értéknek {{ type }} típusúnak kell lennie.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Ennek az értéknek üresnek kell lennie.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>A választott érték érvénytelen.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Legalább {{ limit }} értéket kell kiválasztani.|Legalább {{ limit }} értéket kell kiválasztani.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Legfeljebb {{ limit }} értéket lehet kiválasztani.|Legfeljebb {{ limit }} értéket lehet kiválasztani.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>A megadott értékek közül legalább egy érvénytelen.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Nem várt mező.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Ez a mező hiányzik.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Ez az érték nem egy érvényes dátum.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Ez az érték nem egy érvényes időpont.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Ez az érték nem egy érvényes e-mail cím.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>A fájl nem található.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>A fájl nem olvasható.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>A fájl túl nagy ({{ size }} {{ suffix }}). A legnagyobb megengedett méret {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>A fájl MIME típusa érvénytelen ({{ type }}). Az engedélyezett MIME típusok: {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Ez az érték legfeljebb {{ limit }} lehet.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Ez az érték túl hosszú. Legfeljebb {{ limit }} karaktert tartalmazhat.|Ez az érték túl hosszú. Legfeljebb {{ limit }} karaktert tartalmazhat.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Ez az érték legalább {{ limit }} kell, hogy legyen.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Ez az érték nem lehet üres.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Ez az érték nem lehet null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Ennek az értéknek nullnak kell lennie.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Ez az érték nem érvényes.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Ez az érték nem egy érvényes időpont.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Ez az érték nem egy érvényes URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>A két értéknek azonosnak kell lennie.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>A fájl túl nagy. A megengedett maximális méret: {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>A fájl túl nagy.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>A fájl nem tölthető fel.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Ennek az értéknek érvényes számnak kell lennie.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Ez a fájl nem egy érvényes kép.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Ez az érték nem egy érvényes IP cím.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Ez az érték nem egy érvényes nyelv.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Ez az érték nem egy érvényes területi beállítás.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Ez az érték nem egy érvényes ország.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Ez az érték már használatban van.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>A kép méretét nem lehet megállapítani.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>A kép szélessége túl nagy ({{ width }}px). A megengedett legnagyobb szélesség {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>A kép szélessége túl kicsi ({{ width }}px). Az elvárt legkisebb szélesség {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>A kép magassága túl nagy ({{ height }}px). A megengedett legnagyobb magasság {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>A kép magassága túl kicsi ({{ height }}px). Az elvárt legkisebb magasság {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Ez az érték a felhasználó jelenlegi jelszavával kell megegyezzen.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Ennek az értéknek pontosan {{ limit }} karaktert kell tartalmaznia.|Ennek az értéknek pontosan {{ limit }} karaktert kell tartalmaznia.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>A fájl csak részben lett feltöltve.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Nem lett fájl feltöltve.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Nincs ideiglenes könyvtár beállítva a php.ini-ben.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Az ideiglenes fájl nem írható a lemezre.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Egy PHP bővítmény miatt a feltöltés nem sikerült.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Ennek a gyűjteménynek legalább {{ limit }} elemet kell tartalmaznia.|Ennek a gyűjteménynek legalább {{ limit }} elemet kell tartalmaznia.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Ez a gyűjtemény legfeljebb {{ limit }} elemet tartalmazhat.|Ez a gyűjtemény legfeljebb {{ limit }} elemet tartalmazhat.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Ennek a gyűjteménynek pontosan {{ limit }} elemet kell tartalmaznia.|Ennek a gyűjteménynek pontosan {{ limit }} elemet kell tartalmaznia.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Érvénytelen kártyaszám.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Nem támogatott kártyatípus vagy érvénytelen kártyaszám.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Érvénytelen nemzetközi bankszámlaszám (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Ez az érték nem egy érvényes ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Ez az érték nem egy érvényes ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Ez az érték nem egy érvényes ISBN-10 vagy ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Ez az érték nem egy érvényes ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Ez az érték nem egy érvényes pénznem.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Ez az érték legyen {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Ez az érték nagyobb legyen, mint {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Ez az érték nagyobb vagy egyenlő legyen, mint {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ez az érték ugyanolyan legyen, mint {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Ez az érték kisebb legyen, mint {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Ez az érték kisebb vagy egyenlő legyen, mint {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Ez az érték ne legyen {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ez az érték ne legyen ugyanolyan, mint {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>A képarány túl nagy ({{ ratio }}). A megengedett legnagyobb képarány {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>A képarány túl kicsi ({{ ratio }}). A megengedett legkisebb képarány {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>A kép négyzet alakú ({{ width }}x{{ height }}px). A négyzet alakú képek nem engedélyezettek.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>A kép fekvő tájolású ({{ width }}x{{ height }}px). A fekvő tájolású képek nem engedélyezettek.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>A kép álló tájolású ({{ width }}x{{ height }}px). Az álló tájolású képek nem engedélyezettek.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Üres fájl nem megengedett.</target>
+ </trans-unit>
+ <trans-unit id="80">
+ <source>This value does not match the expected {{ charset }} charset.</source>
+ <target>Ez az érték nem az elvárt {{ charset }} karakterkódolást használja.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hy.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hy.xlf
new file mode 100644
index 0000000..664c085
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.hy.xlf
@@ -0,0 +1,187 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Արժեքը պետք է լինի կեղծ.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Արժեքը պետք է լինի ճշմարիտ.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Արժեքը պետք է լինի {{ type }} տեսակի.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Արժեքը պետք է լինի դատարկ.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Ձեր ընտրած արժեքը անթույլատրելի է.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Դուք պետք է ընտրեք ամենաքիչը {{ limit }} տարբերակներ.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Դուք պետք է ընտրեք ոչ ավելի քան {{ limit }} տարբերակներ.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Մեկ կամ ավելի տրված արժեքները անթույլատրելի են.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Այս դաշտը չի սպասվում.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Այս դաշտը բացակայում է.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Արժեքը սխալ ամսաթիվ է.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Ամսաթվի և ժամանակի արժեքը անթույլատրելի է.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Էլ-փոստի արժեքը անթույլատրելի է.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Ֆայլը չի գտնվել.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Ֆայլը անընթեռնելի է.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Ֆայլը չափազանց մեծ է ({{ size }} {{ suffix }}): Մաքսիմալ թույլատրելի չափսը՝ {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>MIME-տեսակը անթույլատրելի է({{ type }}): Ֆայլերի թույլատրելի MIME-տեսակներն են: {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Արժեքը պետք է լինի {{ limit }} կամ փոքր.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Արժեքը չափազանց երկար է: Պետք է լինի {{ limit }} կամ ավել սիմվոլներ.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Արժեքը պետ է լինի {{ limit }} կամ շատ.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Արժեքը չափազանց կարճ է: Պետք է լինի {{ limit }} կամ ավելի սիմվոլներ.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Արժեքը չպետք է դատարկ լինի.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Արժեքը չպետք է լինի null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Արժեքը պետք է լինի null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Անթույլատրելի արժեք.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Ժամանակի արժեքը անթույլատրելի է.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Արժեքը URL չէ.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Երկու արժեքները պետք է նույնը լինեն.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Ֆայլը չափազանց մեծ է: Մաքսիմալ թույլատրելի չափսը {{ limit }} {{ suffix }} է.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Ֆայլը չափազանց մեծ է.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Ֆայլը չի կարող բեռնվել.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Արժեքը պետք է լինի թիվ.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This value is not a valid country.</source>
+ <target>Արժեքը պետք է լինի երկիր.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This file is not a valid image.</source>
+ <target>Ֆայլը նկարի թույլատրելի ֆորմատ չէ.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This is not a valid IP address.</source>
+ <target>Արժեքը թույլատրելի IP հասցե չէ.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid language.</source>
+ <target>Արժեքը թույլատրելի լեզու չէ.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid locale.</source>
+ <target>Արժեքը չի հանդիսանում թույլատրելի տեղայնացում.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Այդ արժեքը արդեն օգտագործվում է.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Նկարի չափսերը չստացվեց որոշել.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Նկարի լայնությունը չափազանց մեծ է({{ width }}px). Մաքսիմալ չափն է {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Նկարի լայնությունը չափազանց փոքր է ({{ width }}px). Մինիմալ չափն է {{ min_ width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Նկարի բարձրությունը չափազանց մեծ է ({{ height }}px). Մաքսիմալ չափն է {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Նկարի բարձրությունը չափազանց փոքր է ({{ height }}px). Մինիմալ չափն է {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Այս արժեքը պետք է լինի օգտագործողի ներկա ծածկագիրը.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Այս արժեքը պետք է ունենա ճիշտ {{ limit }} սիմվոլներ.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.id.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.id.xlf
new file mode 100644
index 0000000..742f4a1
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.id.xlf
@@ -0,0 +1,283 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Nilai ini harus bernilai salah.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Nilai ini harus bernilai benar.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Nilai ini harus bertipe {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Nilai ini harus kosong.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Nilai yang dipilih tidak tepat.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Anda harus memilih paling tidak {{ limit }} pilihan.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Anda harus memilih paling banyak {{ limit }} pilihan.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Satu atau lebih nilai yang diberikan tidak sah.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Bidang ini tidak diharapkan.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Bidang ini hilang.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Nilai ini bukan merupakan tanggal yang sah.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Nilai ini bukan merupakan tanggal dan waktu yang sah.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Nilai ini bukan alamat email yang sah.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Berkas tidak ditemukan.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Berkas tidak bisa dibaca.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Ukuran berkas terlalu besar ({{ size }} {{ suffix }}). Ukuran maksimum yang diizinkan adalah {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Jenis berkas ({{ type }}) tidak sah. Jenis berkas yang diijinkan adalah {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Nilai ini harus {{ limit }} atau kurang.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Nilai ini terlalu panjang. Seharusnya {{ limit }} karakter atau kurang.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Nilai ini harus {{ limit }} atau lebih.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Nilai ini terlalu pendek. Seharusnya {{ limit }} karakter atau lebih.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Nilai ini tidak boleh kosong.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Nilai ini tidak boleh 'null'.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Nilai ini harus 'null'.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Nilai ini tidak sah.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Nilai ini bukan merupakan waktu yang sah.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Nilai ini bukan URL yang sah.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Isi keduanya harus sama.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Ukuran berkas terlalu besar. Ukuran maksimum yang diijinkan adalah {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Ukuran berkas terlalu besar.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Berkas tidak dapat diunggah.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Nilai ini harus angka yang sah.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Berkas ini tidak termasuk gambar.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Ini bukan alamat IP yang sah.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Nilai ini bukan bahasa yang sah.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Nilai ini bukan lokal yang sah.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Nilai ini bukan negara yang sah.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Nilai ini sudah digunakan.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Ukuran dari gambar tidak bisa dideteksi.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Lebar gambar terlalu besar ({{ width }}px). Ukuran lebar maksimum adalah {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Lebar gambar terlalu kecil ({{ width }}px). Ukuran lebar minimum yang diharapkan adalah {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Tinggi gambar terlalu besar ({{ height }}px). Ukuran tinggi maksimum adalah {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Tinggi gambar terlalu kecil ({{ height }}px). Ukuran tinggi minimum yang diharapkan adalah {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Nilai ini harus kata sandi pengguna saat ini.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Nilai ini harus memiliki tepat {{ limit }} karakter.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Berkas hanya terunggah sebagian.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Tidak ada berkas terunggah.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Direktori sementara tidak dikonfiguasi pada php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Tidak dapat menuliskan berkas sementara ke dalam media penyimpanan.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Sebuah ekstensi PHP menyebabkan kegagalan unggah.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Kumpulan ini harus memiliki {{ limit }} elemen atau lebih.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Kumpulan ini harus memiliki kurang dari {{ limit }} elemen.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Kumpulan ini harus memiliki tepat {{ limit }} elemen.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Nomor kartu tidak sah.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Jenis kartu tidak didukung atau nomor kartu tidak sah.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Ini bukan Nomor Rekening Bank Internasional (IBAN) yang sah.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Nilai ini bukan ISBN-10 yang sah.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Nilai ini bukan ISBN-13 yang sah.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Nilai ini bukan ISBN-10 maupun ISBN-13 yang sah.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Nilai ini bukan ISSN yang sah.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Nilai ini bukan mata uang yang sah.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Nilai ini seharusnya sama dengan {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Nilai ini seharusnya lebih dari {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Nilai ini seharusnya lebih dari atau sama dengan {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Nilai ini seharusnya identik dengan {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Nilai ini seharusnya kurang dari {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Nilai ini seharusnya kurang dari atau sama dengan {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Nilai ini seharusnya tidak sama dengan {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Nilai ini seharusnya tidak identik dengan {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.it.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.it.xlf
new file mode 100644
index 0000000..5a411ea
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.it.xlf
@@ -0,0 +1,307 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Questo valore dovrebbe essere falso.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Questo valore dovrebbe essere vero.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Questo valore dovrebbe essere di tipo {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Questo valore dovrebbe essere vuoto.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Questo valore dovrebbe essere una delle opzioni disponibili.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Si dovrebbe selezionare almeno {{ limit }} opzione.|Si dovrebbero selezionare almeno {{ limit }} opzioni.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Si dovrebbe selezionare al massimo {{ limit }} opzione.|Si dovrebbero selezionare al massimo {{ limit }} opzioni.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Uno o più valori inseriti non sono validi.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Questo campo non è stato previsto.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Questo campo è manca.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Questo valore non è una data valida.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Questo valore non è una data e ora valida.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Questo valore non è un indirizzo email valido.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Non è stato possibile trovare il file.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Il file non è leggibile.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Il file è troppo grande ({{ size }} {{ suffix }}). La dimensione massima consentita è {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Il mime type del file non è valido ({{ type }}). I tipi permessi sono {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Questo valore dovrebbe essere {{ limit }} o inferiore.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Questo valore è troppo lungo. Dovrebbe essere al massimo di {{ limit }} carattere.|Questo valore è troppo lungo. Dovrebbe essere al massimo di {{ limit }} caratteri.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Questo valore dovrebbe essere {{ limit }} o superiore.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Questo valore è troppo corto. Dovrebbe essere almeno di {{ limit }} carattere.|Questo valore è troppo corto. Dovrebbe essere almeno di {{ limit }} caratteri.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Questo valore non dovrebbe essere vuoto.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Questo valore non dovrebbe essere nullo.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Questo valore dovrebbe essere nullo.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Questo valore non è valido.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Questo valore non è un'ora valida.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Questo valore non è un URL valido.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>I due valori dovrebbero essere uguali.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Il file è troppo grande. La dimensione massima è {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Il file è troppo grande.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Il file non può essere caricato.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Questo valore dovrebbe essere un numero.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Questo file non è una immagine valida.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Questo valore non è un indirizzo IP valido.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Questo valore non è una lingua valida.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Questo valore non è una impostazione regionale valida.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Questo valore non è una nazione valida.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Questo valore è già stato utilizzato.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>La dimensione dell'immagine non può essere determinata.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>La larghezza dell'immagine è troppo grande ({{ width }}px). La larghezza massima è di {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>La larghezza dell'immagine è troppo piccola ({{ width }}px). La larghezza minima è di {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>L'altezza dell'immagine è troppo grande ({{ height }}px). L'altezza massima è di {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>L'altezza dell'immagine è troppo piccola ({{ height }}px). L'altezza minima è di {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Questo valore dovrebbe essere la password attuale dell'utente.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Questo valore dovrebbe contenere esattamente {{ limit }} carattere.|Questo valore dovrebbe contenere esattamente {{ limit }} caratteri.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Il file è stato caricato solo parzialmente.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Nessun file è stato caricato.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Nessuna cartella temporanea è stata configurata nel php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Impossibile scrivere il file temporaneo sul disco.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Un'estensione PHP ha causato il fallimento del caricamento.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Questa collezione dovrebbe contenere almeno {{ limit }} elemento.|Questa collezione dovrebbe contenere almeno {{ limit }} elementi.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Questa collezione dovrebbe contenere massimo {{ limit }} elemento.|Questa collezione dovrebbe contenere massimo {{ limit }} elementi.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Questa collezione dovrebbe contenere esattamente {{ limit }} elemento.|Questa collezione dovrebbe contenere esattamente {{ limit }} elementi.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Numero di carta non valido.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Tipo di carta non supportato o numero non valido.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Questo valore non è un IBAN (International Bank Account Number) valido.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Questo valore non è un codice ISBN-10 valido.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Questo valore non è un codice ISBN-13 valido.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Questo valore non è un codice ISBN-10 o ISBN-13 valido.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Questo valore non è un codice ISSN valido.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Questo valore non è una valuta valida.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Questo valore dovrebbe essere uguale a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Questo valore dovrebbe essere maggiore di {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Questo valore dovrebbe essere maggiore o uguale a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Questo valore dovrebbe essere identico a {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Questo valore dovrebbe essere minore di {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Questo valore dovrebbe essere minore o uguale a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Questo valore dovrebbe essere diverso da {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Questo valore dovrebbe essere diverso da {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>Il rapporto di aspetto dell'immagine è troppo grande ({{ ratio }}). Il rapporto massimo consentito è {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>Il rapporto di aspetto dell'immagine è troppo piccolo ({{ ratio }}). Il rapporto minimo consentito è {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>L'immagine è quadrata ({{ width }}x{{ height }}px). Le immagini quadrate non sono consentite.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>L'immagine è orizzontale ({{ width }}x{{ height }}px). Le immagini orizzontali non sono consentite.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>L'immagine è verticale ({{ width }}x{{ height }}px). Le immagini verticali non sono consentite.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Un file vuoto non è consentito.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ja.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ja.xlf
new file mode 100644
index 0000000..63eecc0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ja.xlf
@@ -0,0 +1,315 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>falseでなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>trueでなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>型は{{ type }}でなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>空でなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>有効な選択肢ではありません。</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>{{ limit }}個以上選択してください。</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>{{ limit }}個以内で選択してください。</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>無効な選択肢が含まれています。</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>このフィールドは予期されていませんでした。</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>このフィールドは、欠落しています。</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>有効な日付ではありません。</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>有効な日時ではありません。</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>有効なメールアドレスではありません。</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>ファイルが見つかりません。</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>ファイルを読み込めません。</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>ファイルのサイズが大きすぎます({{ size }} {{ suffix }})。有効な最大サイズは{{ limit }} {{ suffix }}です。</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>ファイルのMIMEタイプが無効です({{ type }})。有効なMIMEタイプは{{ types }}です。</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>{{ limit }}以下でなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>値が長すぎます。{{ limit }}文字以内でなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>{{ limit }}以上でなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>値が短すぎます。{{ limit }}文字以上でなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>空であってはなりません。</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>nullであってはなりません。</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>nullでなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>有効な値ではありません。</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>有効な時刻ではありません。</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>有効なURLではありません。</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>2つの値が同じでなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>ファイルのサイズが大きすぎます。有効な最大サイズは{{ limit }} {{ suffix }}です。</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>ファイルのサイズが大きすぎます。</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>ファイルをアップロードできませんでした。</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>有効な数字ではありません。</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>ファイルが画像ではありません。</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>有効なIPアドレスではありません。</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>有効な言語名ではありません。</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>有効なロケールではありません。</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>有効な国名ではありません。</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>既に使用されています。</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>画像のサイズが検出できません。</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>画像の幅が大きすぎます({{ width }}ピクセル)。{{ max_width }}ピクセルまでにしてください。</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>画像の幅が小さすぎます({{ width }}ピクセル)。{{ min_width }}ピクセル以上にしてください。</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>画像の高さが大きすぎます({{ height }}ピクセル)。{{ max_height }}ピクセルまでにしてください。</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>画像の高さが小さすぎます({{ height }}ピクセル)。{{ min_height }}ピクセル以上にしてください。</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user current password.</source>
+ <target>ユーザーの現在のパスワードでなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>ちょうど{{ limit }}文字でなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>ファイルのアップロードは完全ではありません。</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>ファイルがアップロードされていません。</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>php.iniで一時フォルダが設定されていません。</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>一時ファイルをディスクに書き込むことができません。</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>PHP拡張によってアップロードに失敗しました。</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>{{ limit }}個以上の要素を含んでなければいけません。</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>要素は{{ limit }}個までです。</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>要素はちょうど{{ limit }}個でなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>無効なカード番号です。</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>未対応のカード種類又は無効なカード番号です。</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>有効なIBANコードではありません。</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>有効なISBN-10コードではありません。</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>有効なISBN-13コードではありません。</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>有効なISBN-10コード又はISBN-13コードではありません。</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>有効なISSNコードではありません。</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>有効な貨幣ではありません。</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>{{ compared_value }}と等しくなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>{{ compared_value }}より大きくなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>{{ compared_value }}以上でなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>{{ compared_value_type }}としての{{ compared_value }}と等しくなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>{{ compared_value }}未満でなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>{{ compared_value }}以下でなければなりません。</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>{{ compared_value }}と等しくてはいけません。</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>{{ compared_value_type }}としての{{ compared_value }}と等しくてはいけません。</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>画像のアスペクト比が大きすぎます({{ ratio }})。{{ max_ratio }}までにしてください。</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>画像のアスペクト比が小さすぎます({{ ratio }})。{{ min_ratio }}以上にしてください。</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>画像が正方形になっています({{ width }}x{{ height }}ピクセル)。正方形の画像は許可されていません。</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>画像が横向きになっています({{ width }}x{{ height }}ピクセル)。横向きの画像は許可されていません。</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>画像が縦向きになっています({{ width }}x{{ height }}ピクセル)。縦向きの画像は許可されていません。</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>空のファイルは許可されていません。</target>
+ </trans-unit>
+ <trans-unit id="79">
+ <source>The host could not be resolved.</source>
+ <target>ホストを解決できませんでした。</target>
+ </trans-unit>
+ <trans-unit id="80">
+ <source>This value does not match the expected {{ charset }} charset.</source>
+ <target>この値は予期される文字コード({{ charset }})と異なります。</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.lb.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.lb.xlf
new file mode 100644
index 0000000..8281c7c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.lb.xlf
@@ -0,0 +1,303 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Dëse Wäert sollt falsch sinn.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Dëse Wäert sollt wouer sinn.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Dëse Wäert sollt vum Typ {{ type }} sinn.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Dëse Wäert sollt eidel sinn.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Dëse Wäert sollt enger vun de Wielméiglechkeeten entspriechen.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Dir sollt mindestens {{ limit }} Méiglechkeete wielen.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Dir sollt héchstens {{ limit }} Méiglechkeete wielen.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Een oder méi vun de Wäerter ass ongëlteg.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>The fields {{ fields }} were not expected.</source>
+ <target>D'Felder {{ fields }} goufen net erwaart.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>The fields {{ fields }} are missing.</source>
+ <target>D'Felder {{ fields }} feelen.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Dëse Wäert entsprécht kenger gëlteger Datumsangab.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Dëse Wäert entsprécht kenger gëlteger Datums- an Zäitangab.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Dëse Wäert ass keng gëlteg Email-Adress.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>De Fichier gouf net fonnt.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>De Fichier ass net liesbar.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>De Fichier ass ze grouss ({{ size }} {{ suffix }}). Déi zougeloosse Maximalgréisst bedréit {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Den Typ vum Fichier ass ongëlteg ({{ type }}). Erlaabten Type sinn {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Dëse Wäert soll méi kleng oder gläich {{ limit }} sinn.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Dës Zeecheketten ass ze laang. Se sollt héchstens {{ limit }} Zeechen hunn.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Dëse Wäert sollt méi grouss oder gläich {{ limit }} sinn.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Dës Zeecheketten ass ze kuerz. Se sollt mindestens {{ limit }} Zeechen hunn.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Dëse Wäert sollt net eidel sinn.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Dëst sollt keen Null-Wäert sinn.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Dëst sollt keen Null-Wäert sinn.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Dëse Wäert ass net gëlteg.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Dëse Wäert entsprécht kenger gëlteger Zäitangab.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Dëse Wäert ass keng gëlteg URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Béid Wäerter sollten identesch sinn.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>De fichier ass ze grouss. Déi maximal Gréisst dierf {{ limit }} {{ suffix }} net depasséieren.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>De Fichier ass ze grouss.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>De Fichier konnt net eropgeluede ginn.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Dëse Wäert sollt eng gëlteg Zuel sinn.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Dëse Fichier ass kee gëltegt Bild.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Dëst ass keng gëlteg IP-Adress.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Dëse Wäert aentsprécht kenger gëlteger Sprooch.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Dëse Wäert entsprécht kengem gëltege Gebittsschema.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Dëse Wäert entsprécht kengem gëltege Land.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Dëse Wäert gëtt scho benotzt.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>D'Gréisst vum Bild konnt net detektéiert ginn.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>D'Breet vum Bild ass ze grouss ({{ width }}px). Déi erlaabte maximal Breet ass {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>D'Breet vum Bild ass ze kleng ({{ width }}px). Déi minimal Breet ass {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>D'Héicht vum Bild ass ze grouss ({{ height }}px). Déi erlaabte maximal Héicht ass {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>D'Héicht vum Bild ass ze kleng ({{ height }}px). Déi minimal Héicht ass {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Dëse Wäert sollt dem aktuelle Benotzerpasswuert entspriechen.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Dëse Wäert sollt exactly {{ limit }} Buschtaf hunn.|Dëse Wäert sollt exakt {{ limit }} Buschtawen hunn.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>De Fichier gouf just deelweis eropgelueden.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Et gouf kee Fichier eropgelueden.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Et gouf keen temporären Dossier an der php.ini konfiguréiert.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Den temporäre Fichier kann net gespäichert ginn.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Eng PHP-Erweiderung huet den Upload verhënnert.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Dës Sammlung sollt {{ limit }} oder méi Elementer hunn.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Dës Sammlung sollt {{ limit }} oder manner Elementer hunn.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Dës Sammlung sollt exakt {{ limit }} Element hunn.|Dës Sammlung sollt exakt {{ limit }} Elementer hunn.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Ongëlteg Kaartennummer.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Net ënnerstëtzte Kaartentyp oder ongëlteg Kaartennummer.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Dëst ass keng gëlteg IBAN-Kontonummer.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Dëse Wäert ass keng gëlteg ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Dëse Wäert ass keng gëlteg ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Dëse Wäert ass weder eng gëlteg ISBN-10 nach eng gëlteg ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Dëse Wäert ass keng gëlteg ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Dëse Wäert ass keng gëlteg Währung.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Dëse Wäert sollt {{ compared_value }} sinn.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Dëse Wäert sollt méi grouss wéi {{ compared_value }} sinn.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Dëse Wäert sollt méi grouss wéi oder gläich {{ compared_value }} sinn.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Dëse Wäert sollt identesch si mat {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Dëse Wäert sollt méi kleng wéi {{ compared_value }} sinn.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Dëse Wäert sollt méi kleng wéi oder gläich {{ compared_value }} sinn.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Dëse Wäert sollt net {{ compared_value }} sinn.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Dëse Wäert sollt net identesch si mat {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>D'Säiteverhältnis vum Bild ass ze grouss ({{ ratio }}). Den erlaabte Maximalwäert ass {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>D'Säiteverhältnis vum Bild ass ze kleng ({{ ratio }}). Den erwaarte Minimalwäert ass {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>D'Bild ass quadratesch ({{ width }}x{{ height }}px). Quadratesch Biller sinn net erlaabt.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>D'Bild ass am Queeschformat ({{ width }}x{{ height }}px). Biller am Queeschformat sinn net erlaabt.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>D'Bild ass am Héichformat ({{ width }}x{{ height }}px). Biller am Héichformat sinn net erlaabt.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.lt.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.lt.xlf
new file mode 100644
index 0000000..a556c45
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.lt.xlf
@@ -0,0 +1,307 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Reikšmė turi būti neigiama.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Reikšmė turi būti teigiama.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Šios reikšmės tipas turi būti {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Ši reikšmė turi būti tuščia.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Neteisingas pasirinkimas.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Turite pasirinkti bent {{ limit }} variantą.|Turite pasirinkti bent {{ limit }} variantus.|Turite pasirinkti bent {{ limit }} variantų.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Turite pasirinkti ne daugiau kaip {{ limit }} variantą.|Turite pasirinkti ne daugiau kaip {{ limit }} variantus.|Turite pasirinkti ne daugiau kaip {{ limit }} variantų.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Viena ar daugiau įvestų reikšmių yra netinkamos.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Nebuvo tikimasi Šis laukas.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Šiame lauke yra dingęs.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Ši reikšmė nėra data.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Ši reikšmė nera data ir laikas.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Ši reikšmė nėra tinkamas el. pašto adresas.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Byla nerasta.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Negalima nuskaityti bylos.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Byla yra per didelė ({{ size }} {{ suffix }}). Maksimalus dydis {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Netinkamas bylos tipas (mime type) ({{ type }}). Galimi bylų tipai {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Reikšmė turi būti {{ limit }} arba mažiau.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>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ų.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Reikšmė turi būti {{ limit }} arba daugiau.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>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ų.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Ši reikšmė negali būti tuščia.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Ši reikšmė negali būti null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Ši reikšmė turi būti null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Netinkama reikšmė.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Ši reikšmė nėra laikas.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Ši reikšmė nėra tinkamas interneto adresas.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Abi reikšmės turi būti identiškos.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Byla yra per didelė. Maksimalus dydis yra {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Byla per didelė.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Byla negali būti įkelta.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Ši reikšmė turi būti skaičius.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This value is not a valid country.</source>
+ <target>Ši reikšmė nėra tinkama šalis.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This file is not a valid image.</source>
+ <target>Byla nėra paveikslėlis.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This is not a valid IP address.</source>
+ <target>Ši reikšmė nėra tinkamas IP adresas.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid language.</source>
+ <target>Ši reikšmė nėra tinkama kalba.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid locale.</source>
+ <target>Ši reikšmė nėra tinkama lokalė.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Ši reikšmė jau yra naudojama.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Nepavyko nustatyti nuotraukos dydžio.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Nuotraukos plotis per didelis ({{ width }}px). Maksimalus leidžiamas plotis yra {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Nuotraukos plotis per mažas ({{ width }}px). Minimalus leidžiamas plotis yra {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Nuotraukos aukštis per didelis ({{ height }}px). Maksimalus leidžiamas aukštis yra {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Nuotraukos aukštis per mažas ({{ height }}px). Minimalus leidžiamas aukštis yra {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Ši reikšmė turi sutapti su dabartiniu naudotojo slaptažodžiu.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Š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ų.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Failas buvo tik dalinai įkeltas.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Nebuvo įkelta jokių failų.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Nėra sukonfiguruoto jokio laikino katalogo php.ini faile.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Nepavyko išsaugoti laikino failo.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>PHP plėtinys sutrukdė failo įkėlimą ir jis nepavyko.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>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šų.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>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šų.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>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šų.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Klaidingas kortelės numeris.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Kortelės tipas nepalaikomas arba klaidingas kortelės numeris.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Ši reišmė neatitinka tarptautinio banko sąskaitos numerio formato (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Ši reikšmė neatitinka ISBN-10 formato.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Ši reikšmė neatitinka ISBN-13 formato.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Ši reikšmė neatitinka nei ISBN-10, nei ISBN-13 formato.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Ši reišmė neatitinka ISSN formato.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Netinkamas valiutos formatas.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Ši reikšmė turi būti lygi {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Ši reikšmė turi būti didesnė už {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Ši reikšmė turi būti didesnė už arba lygi {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ši reikšmė turi būti identiška {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Ši reikšmė turi būti mažesnė už {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Ši reikšmė turi būti mažesnė už arba lygi {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Ši reikšmė neturi būti lygi {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ši reikšmė neturi būti identiška {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>Nuotraukos santykis yra per didelis ({{ ratio }}). Didžiausias leistinas santykis yra {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>Nuotraukos santykis yra per mažas ({{ ratio }}). Mažiausias leistinas santykis yra {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>Nuotrauka yra kvadratinė ({{ width }}x{{ height }}px). Kvadratinės nuotraukos nėra leistinos.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>Nuotrauka orientuota į plotį ({{ width }}x{{ height }}px). Nuotraukos orientuotos į plotį nėra leistinos.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>Nuotrauka orientuota į aukštį ({{ width }}x{{ height }}px). Nuotraukos orientuotos į aukštį nėra leistinos.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Failas negali būti tuščias.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.mn.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.mn.xlf
new file mode 100644
index 0000000..dfe7eeb
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.mn.xlf
@@ -0,0 +1,151 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Энэ утга буруу байх ёстой.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Энэ утга үнэн байх ёстой.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Энэ утга {{ type }} -н төрөл байх ёстой.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Энэ утга хоосон байх ёстой.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Сонгосон утга буруу байна.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Хамгийн багадаа {{ limit }} утга сонгогдсон байх ёстой.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Хамгийн ихдээ {{ limit }} утга сонгогдох боломжтой.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Өгөгдсөн нэг эсвэл нэгээс олон утга буруу байна.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Энэ талбар нь хүлээгдэж байсан юм.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Энэ талбар нь алга болсон байна.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Энэ утга буруу date төрөл байна .</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Энэ утга буруу цаг төрөл байна.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>И-майл хаяг буруу байна.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Файл олдсонгүй.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Файл уншигдахуйц биш байна.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Файл хэтэрхий том байна ({{ size }} {{ suffix }}). Зөвшөөрөгдөх дээд хэмжээ {{ limit }} {{ suffix }} байна.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Файлын MIME-төрөл нь буруу байна ({{ type }}). Зөвшөөрөгдөх MIME-төрлүүд {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Энэ утга {{ limit }} юмуу эсвэл бага байна.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Энэ утга хэтэрхий урт байна. {{ limit }} тэмдэгтийн урттай юмуу эсвэл бага байна.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Энэ утга {{ limit }} юмуу эсвэл их байна.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Энэ утга хэтэрхий богино байна. {{ limit }} тэмдэгт эсвэл их байна.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Энэ утга хоосон байж болохгүй.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Энэ утга null байж болохгүй.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Энэ утга null байна.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Энэ утга буруу байна.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Энэ утга буруу цаг төрөл байна.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Энэ утга буруу URL байна .</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Хоёр утгууд ижил байх ёстой.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Файл хэтэрхий том байна. Зөвшөөрөгдөх дээд хэмжээ нь {{ limit }} {{ suffix }} байна.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Файл хэтэрхий том байна.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Файл upload хийгдсэнгүй.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Энэ утга зөвхөн тоо байна.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This value is not a valid country.</source>
+ <target>Энэ утга үнэн бодит улс биш байна.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This file is not a valid image.</source>
+ <target>Файл зураг биш байна.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This is not a valid IP address.</source>
+ <target>IP хаяг зөв биш байна.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid language.</source>
+ <target>Энэ утга үнэн зөв хэл биш байна .</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.nb.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.nb.xlf
new file mode 100644
index 0000000..a8b790c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.nb.xlf
@@ -0,0 +1,155 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Verdien skal være falsk.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Verdien skal være sann.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Verdien skal være av typen {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Verdien skal være blank.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Verdien skal være en av de gitte valg.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Du skal velge minst {{ limit }} valg.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Du kan maks velge {{ limit }} valg.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>En eller flere av de oppgitte verdier er ugyldige.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Dette feltet ikke var forventet.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Dette feltet mangler.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Verdien er ikke en gyldig dato.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Verdien er ikke en gyldig dato og tid.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Verdien er ikke en gyldig e-mail adresse.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Filen kunne ikke finnes.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Filen kan ikke leses.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Filen er for stor ({{ size }} {{ suffix }}). Tilatte maksimale størrelse {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Mimetypen av filen er ugyldig ({{ type }}). Tilatte mimetyper er {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Verdien skal være {{ limit }} eller mindre.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Verdien er for lang. Den skal ha {{ limit }} bokstaver eller mindre.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Verdien skal være {{ limit }} eller mer.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Verdien er for kort. Den skal ha {{ limit }} tegn eller flere.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Verdien må ikke være blank.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Verdien må ikke være tom (null).</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Verdien skal være tom (null).</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Verdien er ikke gyldig.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Verdien er ikke en gyldig tid.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Verdien er ikke en gyldig URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>De to verdier skal være ens.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Filen er for stor. Den maksimale størrelse er {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Filen er for stor.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Filen kunne ikke lastes opp.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Denne verdi skal være et gyldig tall.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Denne filen er ikke et gyldig bilde.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Dette er ikke en gyldig IP adresse.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Denne verdi er ikke et gyldig språk.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Denne verdi er ikke en gyldig lokalitet.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Denne verdi er ikke et gyldig land.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.nl.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.nl.xlf
new file mode 100644
index 0000000..c2372c9
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.nl.xlf
@@ -0,0 +1,311 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Deze waarde mag niet waar zijn.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Deze waarde moet waar zijn.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Deze waarde moet van het type {{ type }} zijn.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Deze waarde moet leeg zijn.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>De geselecteerde waarde is geen geldige optie.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Selecteer ten minste {{ limit }} optie.|Selecteer ten minste {{ limit }} opties.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Selecteer maximaal {{ limit }} optie.|Selecteer maximaal {{ limit }} opties.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Eén of meer van de ingegeven waarden zijn ongeldig.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Dit veld was niet verwacht.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Dit veld ontbreekt.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Deze waarde is geen geldige datum.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Deze waarde is geen geldige datum en tijd.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Deze waarde is geen geldig e-mailadres.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Het bestand is niet gevonden.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Het bestand is niet leesbaar.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Het bestand is te groot ({{ size }} {{ suffix }}). Toegestane maximum grootte is {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Het mime type van het bestand is ongeldig ({{ type }}). Toegestane mime types zijn {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Deze waarde moet {{ limit }} of minder zijn.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Deze waarde is te lang. Hij mag maximaal {{ limit }} teken bevatten.|Deze waarde is te lang. Hij mag maximaal {{ limit }} tekens bevatten.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Deze waarde moet {{ limit }} of meer zijn.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Deze waarde is te kort. Hij moet tenminste {{ limit }} teken bevatten.|Deze waarde is te kort. Hij moet tenminste {{ limit }} tekens bevatten.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Deze waarde mag niet leeg zijn.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Deze waarde mag niet null zijn.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Deze waarde moet null zijn.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Deze waarde is ongeldig.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Deze waarde is geen geldige tijd.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Deze waarde is geen geldige URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>De twee waarden moeten gelijk zijn.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Het bestand is te groot. Toegestane maximum grootte is {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Het bestand is te groot.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Het bestand kon niet geüpload worden.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Deze waarde moet een geldig getal zijn.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Dit bestand is geen geldige afbeelding.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Dit is geen geldig IP-adres.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Deze waarde representeert geen geldige taal.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Deze waarde representeert geen geldige lokalisering.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Deze waarde representeert geen geldig land.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Deze waarde wordt al gebruikt.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>De grootte van de afbeelding kon niet bepaald worden.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>De afbeelding is te breed ({{ width }}px). De maximaal toegestane breedte is {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>De afbeelding is niet breed genoeg ({{ width }}px). De minimaal verwachte breedte is {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>De afbeelding is te hoog ({{ height }}px). De maximaal toegestane hoogte is {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>De afbeelding is niet hoog genoeg ({{ height }}px). De minimaal verwachte hoogte is {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Deze waarde moet het huidige wachtwoord van de gebruiker zijn.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Deze waarde moet exact {{ limit }} teken lang zijn.|Deze waarde moet exact {{ limit }} tekens lang zijn.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Het bestand is niet geheel geüpload.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Er is geen bestand geüpload.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Er is geen tijdelijke map geconfigureerd in php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Kan het tijdelijke bestand niet wegschrijven op disk.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>De upload is mislukt vanwege een PHP-extensie.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Deze collectie moet {{ limit }} element of meer bevatten.|Deze collectie moet {{ limit }} elementen of meer bevatten.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Deze collectie moet {{ limit }} element of minder bevatten.|Deze collectie moet {{ limit }} elementen of minder bevatten.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Deze collectie moet exact {{ limit }} element bevatten.|Deze collectie moet exact {{ limit }} elementen bevatten.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Ongeldig creditcardnummer.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Niet-ondersteund type creditcard of ongeldig nummer.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Dit is geen geldig internationaal bankrekeningnummer (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Deze waarde is geen geldige ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Deze waarde is geen geldige ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Deze waarde is geen geldige ISBN-10 of ISBN-13 waarde.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Deze waarde is geen geldige ISSN waarde.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Deze waarde is geen geldige valuta.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Deze waarde moet gelijk zijn aan {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Deze waarde moet groter zijn dan {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Deze waarde moet groter dan of gelijk aan {{ compared_value }} zijn.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Deze waarde moet identiek zijn aan {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Deze waarde moet minder zijn dan {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Deze waarde moet minder dan of gelijk aan {{ compared_value }} zijn.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Deze waarde mag niet gelijk zijn aan {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value }}.</source>
+ <target>Deze waarde mag niet identiek zijn aan {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>De afbeeldingsverhouding is te groot ({{ ratio }}). Maximale verhouding is {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>De afbeeldingsverhouding is te klein ({{ ratio }}). Minimale verhouding is {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>De afbeelding is vierkant ({{ width }}x{{ height }}px). Vierkante afbeeldingen zijn niet toegestaan.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>De afbeelding is liggend ({{ width }}x{{ height }}px). Liggende afbeeldingen zijn niet toegestaan.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>De afbeelding is staand ({{ width }}x{{ height }}px). Staande afbeeldingen zijn niet toegestaan.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Lege bestanden zijn niet toegestaan.</target>
+ </trans-unit>
+ <trans-unit id="80">
+ <source>This value does not match the expected {{ charset }} charset.</source>
+ <target>Deze waarde is niet in de verwachte tekencodering {{ charset }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.no.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.no.xlf
new file mode 100644
index 0000000..ea01c63
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.no.xlf
@@ -0,0 +1,227 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Verdien skulle ha vore tom/nei.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Verdien skulla ha vore satt/ja.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Verdien må vere av typen {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Verdien skal vere blank.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Verdien du valgte er ikkje gyldig.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Du må velge minst {{ limit }} valg.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Du kan maksimalt gjere {{ limit }} valg.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Ein eller fleire av dei opplyste verdiane er ugyldige.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Dette feltet var ikke forventet.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Dette feltet mangler.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Verdien er ikkje ein gyldig dato.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Verdien er ikkje ein gyldig dato og tid.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Verdien er ikkje ei gyldig e-postadresse.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Fila kunne ikkje finnes.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Fila kan ikkje lesast.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Fila er for stor ({{ size }} {{ suffix }}). Tillatt maksimal størrelse er {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Mime-typen av fila er ugyldig ({{ type }}). Tillatte mime-typar er {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Verdien må vere {{ limit }} eller mindre.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Verdien er for lang. Den må vere {{ limit }} bokstavar eller mindre.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Verdien må vere {{ limit }} eller meir.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Verdien er for kort. Den må ha {{ limit }} teikn eller fleire.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Verdien må ikkje vere blank.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Verdien må ikkje vere tom (null).</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Verdien må vere tom (null).</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Verdien er ikkje gyldig.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Verdien er ikkje gyldig tidseining.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Verdien er ikkje ein gyldig URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Dei to verdiane må vere like.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Fila er for stor. Den maksimale storleik er {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Fila er for stor.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Fila kunne ikkje bli lasta opp.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Verdien må vere eit gyldig tal.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Fila er ikkje eit gyldig bilete.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Dette er ikkje ei gyldig IP-adresse.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Verdien er ikkje eit gyldig språk.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Verdien er ikkje ein gyldig lokalitet (språk/region).</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Verdien er ikkje eit gyldig land.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Verdien er allereie i bruk.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Storleiken på biletet kunne ikkje oppdagast.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Biletbreidda er for stor, ({{ width }} pikslar). Tillatt maksimumsbreidde er {{ max_width }} pikslar.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Biletbreidda er for liten, ({{ width }} pikslar). Forventa minimumsbreidde er {{ min_width }} pikslar.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Bilethøgda er for stor, ({{ height }} pikslar). Tillatt maksimumshøgde er {{ max_height }} pikslar.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Billethøgda er for låg, ({{ height }} pikslar). Forventa minimumshøgde er {{ min_height }} pikslar.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Verdien må vere brukaren sitt noverande passord.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Verdien må vere nøyaktig {{ limit }} teikn.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Fila vart kun delvis opplasta.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Inga fil vart lasta opp.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Førebels mappe (tmp) er ikkje konfigurert i php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Kan ikkje skrive førebels fil til disk.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Ei PHP-udviding forårsaka feil under opplasting.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Denne samlinga må innehalde {{ limit }} element eller meir.|Denne samlinga må innehalde {{ limit }} element eller meir.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Denne samlinga må innehalde {{ limit }} element eller færre.|Denne samlinga må innehalde {{ limit }} element eller færre.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Denne samlinga må innehalde nøyaktig {{ limit }} element.|Denne samlinga må innehalde nøyaktig {{ limit }} element.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Ugyldig kortnummer.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Korttypen er ikkje støtta eller ugyldig kortnummer.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pl.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pl.xlf
new file mode 100644
index 0000000..ac7406c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pl.xlf
@@ -0,0 +1,311 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Ta wartość powinna być fałszem.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Ta wartość powinna być prawdą.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Ta wartość powinna być typu {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Ta wartość powinna być pusta.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Ta wartość powinna być jedną z podanych opcji.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Powinieneś wybrać co najmniej {{ limit }} opcję.|Powinieneś wybrać co najmniej {{ limit }} opcje.|Powinieneś wybrać co najmniej {{ limit }} opcji.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Powinieneś wybrać maksymalnie {{ limit }} opcję.|Powinieneś wybrać maksymalnie {{ limit }} opcje.|Powinieneś wybrać maksymalnie {{ limit }} opcji.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Jedna lub więcej z podanych wartości jest nieprawidłowa.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>To pole nie spodziewano.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>To pole jest chybianie.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Ta wartość nie jest prawidłową datą.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Ta wartość nie jest prawidłową datą i czasem.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Ta wartość nie jest prawidłowym adresem email.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Plik nie mógł zostać odnaleziony.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Nie można odczytać pliku.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Plik jest za duży ({{ size }} {{ suffix }}). Maksymalny dozwolony rozmiar to {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Nieprawidłowy typ mime pliku ({{ type }}). Dozwolone typy mime to {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Ta wartość powinna wynosić {{ limit }} lub mniej.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Ta wartość powinna wynosić {{ limit }} lub więcej.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Ta wartość nie powinna być pusta.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Ta wartość nie powinna być nullem.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Ta wartość powinna być nullem.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Ta wartość jest nieprawidłowa.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Ta wartość nie jest prawidłowym czasem.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Ta wartość nie jest prawidłowym adresem URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Obie wartości powinny być równe.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Plik jest za duży. Maksymalny dozwolony rozmiar to {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Plik jest za duży.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Plik nie mógł być wgrany.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Ta wartość powinna być prawidłową liczbą.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Ten plik nie jest obrazem.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>To nie jest prawidłowy adres IP.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Ta wartość nie jest prawidłowym językiem.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Ta wartość nie jest prawidłową lokalizacją.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Ta wartość nie jest prawidłową nazwą kraju.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Ta wartość jest już wykorzystywana.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Nie można wykryć rozmiaru obrazka.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Szerokość obrazka jest zbyt duża ({{ width }}px). Maksymalna dopuszczalna szerokość to {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Szerokość obrazka jest zbyt mała ({{ width }}px). Oczekiwana minimalna szerokość to {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Wysokość obrazka jest zbyt duża ({{ height }}px). Maksymalna dopuszczalna wysokość to {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Wysokość obrazka jest zbyt mała ({{ height }}px). Oczekiwana minimalna wysokość to {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Ta wartość powinna być aktualnym hasłem użytkownika.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Plik został wgrany tylko częściowo.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Żaden plik nie został wgrany.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Nie skonfigurowano folderu tymczasowego w php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Nie można zapisać pliku tymczasowego na dysku.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Rozszerzenie PHP spowodowało błąd podczas wgrywania.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Ten zbiór powinien zawierać {{ limit }} lub więcej elementów.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Ten zbiór powinien zawierać {{ limit }} lub mniej elementów.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Nieprawidłowy numer karty.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Nieobsługiwany rodzaj karty lub nieprawidłowy numer karty.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Nieprawidłowy międzynarodowy numer rachunku bankowego (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Ta wartość nie jest prawidłowym numerem ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Ta wartość nie jest prawidłowym numerem ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Ta wartość nie jest prawidłowym numerem ISBN-10 ani ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Ta wartość nie jest prawidłowym numerem ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Ta wartość nie jest prawidłową walutą.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Ta wartość powinna być równa {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Ta wartość powinna być większa niż {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Ta wartość powinna być większa bądź równa {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ta wartość powinna być identycznego typu {{ compared_value_type }} oraz wartości {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Ta wartość powinna być mniejsza niż {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Ta wartość powinna być mniejsza bądź równa {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Ta wartość nie powinna być równa {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ta wartość nie powinna być identycznego typu {{ compared_value_type }} oraz wartości {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>Proporcje obrazu są zbyt duże ({{ ratio }}). Maksymalne proporcje to {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>Proporcje obrazu są zbyt małe ({{ ratio }}). Minimalne proporcje to {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>Obraz jest kwadratem ({{ width }}x{{ height }}px). Kwadratowe obrazy nie są akceptowane.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>Obraz jest panoramiczny ({{ width }}x{{ height }}px). Panoramiczne zdjęcia nie są akceptowane.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>Obraz jest portretowy ({{ width }}x{{ height }}px). Portretowe zdjęcia nie są akceptowane.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Plik nie może być pusty.</target>
+ </trans-unit>
+ <trans-unit id="80">
+ <source>This value does not match the expected {{ charset }} charset.</source>
+ <target>Ta wartość nie pasuje do oczekiwanego zestawu znaków {{ charset }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pt.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pt.xlf
new file mode 100644
index 0000000..d563c92
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pt.xlf
@@ -0,0 +1,307 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Este valor deveria ser falso.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Este valor deveria ser verdadeiro.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Este valor deveria ser do tipo {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Este valor deveria ser vazio.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>O valor selecionado não é uma opção válida.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Você deveria selecionar {{ limit }} opção no mínimo.|Você deveria selecionar {{ limit }} opções no mínimo.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Você deve selecionar, no máximo {{ limit }} opção.|Você deve selecionar, no máximo {{ limit }} opções.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Um ou mais dos valores introduzidos não são válidos.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Este campo não era esperado.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Este campo está faltando.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Este valor não é uma data válida.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Este valor não é uma data-hora válida.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Este valor não é um endereço de e-mail válido.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>O arquivo não pôde ser encontrado.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>O arquivo não pôde ser lido.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>O arquivo é muito grande ({{ size }} {{ suffix }}). O tamanho máximo permitido é de {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>O tipo mime do arquivo é inválido ({{ type }}). Os tipos mime permitidos são {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Este valor deveria ser {{ limit }} ou menor.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>O valor é muito longo. Deveria ter {{ limit }} caracteres ou menos.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Este valor deveria ser {{ limit }} ou mais.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>O valor é muito curto. Deveria de ter {{ limit }} caractere ou mais.|O valor é muito curto. Deveria de ter {{ limit }} caracteres ou mais.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Este valor não deveria ser branco/vazio.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Este valor não deveria ser nulo.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Este valor deveria ser nulo.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Este valor não é válido.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Este valor não é uma hora válida.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Este valor não é um URL válido.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Os dois valores deveriam ser iguais.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>O arquivo é muito grande. O tamanho máximo permitido é de {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>O ficheiro é muito grande.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Não foi possível carregar o ficheiro.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Este valor deveria de ser um número válido.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Este ficheiro não é uma imagem.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Este endereço de IP não é válido.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Este valor não é uma linguagem válida.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Este valor não é um 'locale' válido.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Este valor não é um País válido.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Este valor já está a ser usado.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>O tamanho da imagem não foi detetado.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>A largura da imagem ({{ width }}px) é muito grande. A largura máxima da imagem é: {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>A largura da imagem ({{ width }}px) é muito pequena. A largura miníma da imagem é de: {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>A altura da imagem ({{ height }}px) é muito grande. A altura máxima da imagem é de: {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>A altura da imagem ({{ height }}px) é muito pequena. A altura miníma da imagem é de: {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Este valor deveria de ser a password atual do utilizador.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Este valor tem de ter exatamente {{ limit }} carateres.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Só foi enviado parte do ficheiro.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Nenhum ficheiro foi enviado.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Não existe nenhum directório temporária configurado no ficheiro php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Não foi possível escrever ficheiros temporários no disco.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Uma extensão PHP causou a falha no envio.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Esta coleção deve conter {{ limit }} elemento ou mais.|Esta coleção deve conter {{ limit }} elementos ou mais.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Esta coleção deve conter {{ limit }} elemento ou menos.|Esta coleção deve conter {{ limit }} elementos ou menos.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Esta coleção deve conter exatamente {{ limit }} elemento.|Esta coleção deve conter exatamente {{ limit }} elementos.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Número de cartão inválido.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Tipo de cartão não suportado ou número de cartão inválido.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Este não é um Número Internacional de Conta Bancária (IBAN) válido.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Este valor não é um ISBN-10 válido.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Este valor não é um ISBN-13 válido.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Este valor não é um ISBN-10 ou ISBN-13 válido.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Este valor não é um ISSN válido.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Este não é um valor monetário válido.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Este valor deve ser igual a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Este valor deve ser superior a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Este valor deve ser igual ou superior a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Este valor deve ser idêntico a {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Este valor deve ser inferior a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Este valor deve ser igual ou inferior a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Este valor não deve ser igual a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Este valor não deve ser idêntico a {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>O formato da imagem é muito grande ({{ ratio }}). O formato máximo é {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>O formato da imagem é muito pequeno ({{ ratio }}). O formato mínimo esperado é {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>A imagem é um quadrado ({{ width }}x{{ height }}px). Imagens quadradas não são permitidas.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>A imagem está orientada à paisagem ({{ width }}x{{ height }}px). Imagens orientadas à paisagem não são permitidas.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>A imagem está orientada ao retrato ({{ width }}x{{ height }}px). Imagens orientadas ao retrato não são permitidas.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Ficheiro vazio não é permitido.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pt_BR.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pt_BR.xlf
new file mode 100644
index 0000000..bff91e3
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.pt_BR.xlf
@@ -0,0 +1,315 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Este valor deve ser falso.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Este valor deve ser verdadeiro.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Este valor deve ser do tipo {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Este valor deve ser vazio.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>O valor selecionado não é uma opção válida.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Você deve selecionar, no mínimo, {{ limit }} opção.|Você deve selecionar, no mínimo, {{ limit }} opções.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Você deve selecionar, no máximo, {{ limit }} opção.|Você deve selecionar, no máximo, {{ limit }} opções.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Um ou mais valores informados são inválidos.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Este campo não era esperado.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Este campo está ausente.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Este valor não é uma data válida.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Este valor não é uma data e hora válida.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Este valor não é um endereço de e-mail válido.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>O arquivo não foi encontrado.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>O arquivo não pode ser lido.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>O arquivo é muito grande ({{ size }} {{ suffix }}). O tamanho máximo permitido é {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>O tipo mime do arquivo é inválido ({{ type }}). Os tipos mime permitidos são {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Este valor deve ser {{ limit }} ou menos.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Este valor é muito longo. Deve ter {{ limit }} caractere ou menos.|Este valor é muito longo. Deve ter {{ limit }} caracteres ou menos.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Este valor deve ser {{ limit }} ou mais.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Este valor é muito curto. Deve ter {{ limit }} caractere ou mais.|Este valor é muito curto. Deve ter {{ limit }} caracteres ou mais.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Este valor não deve ser vazio.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Este valor não deve ser nulo.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Este valor deve ser nulo.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Este valor não é válido.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Este valor não é uma hora válida.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Este valor não é uma URL válida.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Os dois valores devem ser iguais.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>O arquivo é muito grande. O tamanho máximo permitido é de {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>O arquivo é muito grande.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>O arquivo não pode ser enviado.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Este valor deve ser um número válido.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Este arquivo não é uma imagem válida.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Este não é um endereço de IP válido.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Este valor não é um idioma válido.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Este valor não é uma localidade válida.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Este valor não é um país válido.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Este valor já está sendo usado.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>O tamanho da imagem não pode ser detectado.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>A largura da imagem é muito grande ({{ width }}px). A largura máxima permitida é de {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>A largura da imagem é muito pequena ({{ width }}px). A largura mínima esperada é de {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>A altura da imagem é muito grande ({{ height }}px). A altura máxima permitida é de {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>A altura da imagem é muito pequena ({{ height }}px). A altura mínima esperada é de {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Este valor deve ser a senha atual do usuário.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Este valor deve ter exatamente {{ limit }} caractere.|Este valor deve ter exatamente {{ limit }} caracteres.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>O arquivo foi enviado apenas parcialmente.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Nenhum arquivo foi enviado.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Nenhum diretório temporário foi configurado no php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Não foi possível escrever o arquivo temporário no disco.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Uma extensão PHP fez com que o envio falhasse.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Esta coleção deve conter {{ limit }} elemento ou mais.|Esta coleção deve conter {{ limit }} elementos ou mais.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Esta coleção deve conter {{ limit }} elemento ou menos.|Esta coleção deve conter {{ limit }} elementos ou menos.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Esta coleção deve conter exatamente {{ limit }} elemento.|Esta coleção deve conter exatamente {{ limit }} elementos.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Número de cartão inválido.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Tipo de cartão não suportado ou número de cartão inválido.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Este não é um Número Internacional de Conta Bancária (IBAN) válido.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Este valor não é um ISBN-10 válido.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Este valor não é um ISBN-13 válido.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Este valor não é um ISBN-10 e nem um ISBN-13 válido.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Este valor não é um ISSN válido.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Este não é um valor monetário válido.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Este valor deve ser igual a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Este valor deve ser maior que {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Este valor deve ser maior ou igual a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Este valor deve ser idêntico a {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Este valor deve ser menor que {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Este valor deve ser menor ou igual a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Este valor não deve ser igual a {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Este valor não deve ser idêntico a {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>A proporção da imagem é muito grande ({{ ratio }}). A proporção máxima permitida é {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>A proporção da imagem é muito pequena ({{ ratio }}). A proporção mínima esperada é {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>A imagem está num formato quadrado ({{ width }}x{{ height }}px). Imagens com formato quadrado não são permitidas.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>A imagem está orientada à paisagem ({{ width }}x{{ height }}px). Imagens orientadas à paisagem não são permitidas.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>A imagem está orientada ao retrato ({{ width }}x{{ height }}px). Imagens orientadas ao retrato não são permitidas.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Arquivo vazio não é permitido.</target>
+ </trans-unit>
+ <trans-unit id="79">
+ <source>The host could not be resolved.</source>
+ <target>O host não pôde ser resolvido.</target>
+ </trans-unit>
+ <trans-unit id="80">
+ <source>This value does not match the expected {{ charset }} charset.</source>
+ <target>Este valor não corresponde ao charset {{ charset }} esperado.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ro.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ro.xlf
new file mode 100644
index 0000000..27346a9
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ro.xlf
@@ -0,0 +1,283 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Această valoare ar trebui să fie falsă (false).</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Această valoare ar trebui să fie adevărată (true).</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Această valoare ar trebui să fie de tipul {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Această valoare ar trebui sa fie goală.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Valoarea selectată nu este o opțiune validă.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Trebuie să selectați cel puțin {{ limit }} opțiune.|Trebuie să selectați cel puțin {{ limit }} opțiuni.|Trebuie să selectați cel puțin {{ limit }} de opțiuni</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Trebuie să selectați cel mult {{ limit }} opțiune.|Trebuie să selectați cel mult {{ limit }} opțiuni.|Trebuie să selectați cel mult {{ limit }} de opțiuni.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Una sau mai multe dintre valorile furnizate sunt invalide.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Acest câmp nu era de aşteptat.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Acest câmp este lipsă.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Această valoare nu reprezintă o dată validă.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Această valoare nu reprezintă o dată și oră validă.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Această valoare nu reprezintă o adresă de e-mail validă.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Fișierul nu a putut fi găsit.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Fișierul nu poate fi citit.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Fișierul este prea mare ({{ size }} {{ suffix }}). Dimensiunea maximă permisă este {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Tipul fișierului este invalid ({{ type }}). Tipurile permise de fișiere sunt ({{ types }}).</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Această valoare ar trebui să fie cel mult {{ limit }}.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Această valoare este prea lungă. Ar trebui să aibă maxim {{ limit }} caracter.|Această valoare este prea lungă. Ar trebui să aibă maxim {{ limit }} caractere.|Această valoare este prea lungă. Ar trebui să aibă maxim {{ limit }} de caractere.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Această valoare ar trebui să fie cel puțin {{ limit }}.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Această valoare este prea scurtă. Ar trebui să aibă minim {{ limit }} caracter.|Această valoare este prea scurtă. Ar trebui să aibă minim {{ limit }} caractere.|Această valoare este prea scurtă. Ar trebui să aibă minim {{ limit }} de caractere.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Această valoare nu ar trebui să fie goală.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Această valoare nu ar trebui să fie nulă (null).</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Această valoare ar trebui să fie nulă (null).</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Această valoare nu este validă.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Această valoare nu reprezintă o oră validă.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Această valoare nu reprezintă un URL (link) valid.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Cele două valori ar trebui să fie egale.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Fișierul este prea mare. Mărimea maximă permisă este {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Fișierul este prea mare.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Fișierul nu a putut fi încărcat.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Această valoare nu reprezintă un număr valid.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Acest fișier nu este o imagine validă.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Această valoare nu este o adresă IP validă.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Această valoare nu reprezintă o limbă corectă.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Această valoare nu reprezintă un dialect (o limbă) corect.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Această valoare nu este o țară validă.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Această valoare este folosită deja.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Mărimea imaginii nu a putut fi detectată.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Lățimea imaginii este prea mare ({{ width }}px). Lățimea maximă permisă este de {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Lățimea imaginii este prea mică ({{ width }}px). Lățimea minimă permisă este de {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Înălțimea imaginii este prea mare ({{ height }}px). Înălțimea maximă permisă este de {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Înălțimea imaginii este prea mică ({{ height }}px). Înălțimea minimă permisă este de {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Această valoare trebuie să fie parola curentă a utilizatorului.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Această valoare trebuie să conțină exact {{ limit }} caracter.|Această valoare trebuie să conțină exact {{ limit }} caractere.|Această valoare trebuie să conțină exact {{ limit }} de caractere.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Fișierul a fost încărcat parțial.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Nu a fost încărcat nici un fișier.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Nu este configurat nici un director temporar in php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Nu a fost posibilă scrierea fișierului temporar pe disk.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>O extensie PHP a prevenit încărcarea cu succes a fișierului.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Această colecție trebuie să conțină cel puțin {{ limit }} element.|Această colecție trebuie să conțină cel puțin {{ limit }} elemente.|Această colecție trebuie să conțină cel puțin {{ limit }} de elemente.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Această colecție trebuie să conțină cel mult {{ limit }} element.|Această colecție trebuie să conțină cel mult {{ limit }} elemente.|Această colecție trebuie să conțină cel mult {{ limit }} de elemente.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Această colecție trebuie să conțină {{ limit }} element.|Această colecție trebuie să conțină {{ limit }} elemente.|Această colecție trebuie să conțină {{ limit }} de elemente.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Numărul card invalid.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Tipul sau numărul cardului nu sunt valide.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Acesta nu este un cod IBAN (International Bank Account Number) valid.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Această valoare nu este un cod ISBN-10 valid.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Această valoare nu este un cod ISBN-13 valid.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Această valoare nu este un cod ISBN-10 sau ISBN-13 valid.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Această valoare nu este un cod ISSN valid.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Această valoare nu este o monedă validă.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Această valoare trebuie să fie egală cu {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Această valoare trebuie să fie mai mare de {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Această valoare trebuie să fie mai mare sau egală cu {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Această valoare trebuie identică cu {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Această valoare trebuie să fie mai mică de {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Această valoare trebuie să fie mai mică sau egală cu {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Această valoare nu trebuie să fie egală cu {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Această valoare nu trebuie să fie identică cu {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ru.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ru.xlf
new file mode 100644
index 0000000..8e6e7c2
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.ru.xlf
@@ -0,0 +1,311 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Значение должно быть ложным.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Значение должно быть истинным.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Тип значения должен быть {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Значение должно быть пустым.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Выбранное Вами значение недопустимо.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Вы должны выбрать хотя бы {{ limit }} вариант.|Вы должны выбрать хотя бы {{ limit }} варианта.|Вы должны выбрать хотя бы {{ limit }} вариантов.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Вы должны выбрать не более чем {{ limit }} вариант.|Вы должны выбрать не более чем {{ limit }} варианта.|Вы должны выбрать не более чем {{ limit }} вариантов.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Одно или несколько заданных значений недопустимо.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Это поле не ожидалось.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Это поле отсутствует.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Значение не является правильной датой.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Значение даты и времени недопустимо.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Значение адреса электронной почты недопустимо.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Файл не может быть найден.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Файл не может быть прочитан.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Файл слишком большой ({{ size }} {{ suffix }}). Максимально допустимый размер {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>MIME-тип файла недопустим ({{ type }}). Допустимы MIME-типы файлов {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Значение должно быть {{ limit }} или меньше.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Значение слишком длинное. Должно быть равно {{ limit }} символу или меньше.|Значение слишком длинное. Должно быть равно {{ limit }} символам или меньше.|Значение слишком длинное. Должно быть равно {{ limit }} символам или меньше.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Значение должно быть {{ limit }} или больше.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Значение слишком короткое. Должно быть равно {{ limit }} символу или больше.|Значение слишком короткое. Должно быть равно {{ limit }} символам или больше.|Значение слишком короткое. Должно быть равно {{ limit }} символам или больше.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Значение не должно быть пустым.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Значение не должно быть null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Значение должно быть null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Значение недопустимо.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Значение времени недопустимо.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Значение не является допустимым URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Оба значения должны быть одинаковыми.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Файл слишком большой. Максимально допустимый размер {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Файл слишком большой.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Файл не может быть загружен.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Значение должно быть числом.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This value is not a valid country.</source>
+ <target>Значение не является допустимой страной.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This file is not a valid image.</source>
+ <target>Файл не является допустимым форматом изображения.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This is not a valid IP address.</source>
+ <target>Значение не является допустимым IP адресом.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid language.</source>
+ <target>Значение не является допустимым языком.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid locale.</source>
+ <target>Значение не является допустимой локалью.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Это значение уже используется.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Не удалось определить размер изображения.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Ширина изображения слишком велика ({{ width }}px). Максимально допустимая ширина {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Ширина изображения слишком мала ({{ width }}px). Минимально допустимая ширина {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Высота изображения слишком велика ({{ height }}px). Максимально допустимая высота {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Высота изображения слишком мала ({{ height }}px). Минимально допустимая высота {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Значение должно быть текущим паролем пользователя.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Значение должно быть равно {{ limit }} символу.|Значение должно быть равно {{ limit }} символам.|Значение должно быть равно {{ limit }} символам.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Файл был загружен только частично.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Файл не был загружен.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Не настроена временная директория в php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Невозможно записать временный файл на диск.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Расширение PHP вызвало ошибку при загрузке.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Эта коллекция должна содержать {{ limit }} элемент или больше.|Эта коллекция должна содержать {{ limit }} элемента или больше.|Эта коллекция должна содержать {{ limit }} элементов или больше.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Эта коллекция должна содержать {{ limit }} элемент или меньше.|Эта коллекция должна содержать {{ limit }} элемента или меньше.|Эта коллекция должна содержать {{ limit }} элементов или меньше.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Эта коллекция должна содержать ровно {{ limit }} элемент.|Эта коллекция должна содержать ровно {{ limit }} элемента.|Эта коллекция должна содержать ровно {{ limit }} элементов.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Неверный номер карты.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Неподдерживаемый тип или неверный номер карты.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Значение не является допустимым международным номером банковского счета (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Значение имеет неверный формат ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Значение имеет неверный формат ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Значение не соответствует форматам ISBN-10 и ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Значение не соответствует формату ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Некорректный формат валюты.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Значение должно быть равно {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Значение должно быть больше чем {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Значение должно быть больше или равно {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Значение должно быть идентичным {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Значение должно быть меньше чем {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Значение должно быть меньше или равно {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Значение не должно быть равно {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Значение не должно быть идентичным {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>Соотношение сторон изображения слишком велико ({{ ratio }}). Максимальное соотношение сторон {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>Соотношение сторон изображения слишком мало ({{ ratio }}). Минимальное соотношение сторон {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>Изображение квадратное ({{ width }}x{{ height }}px). Квадратные изображения не разрешены.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>Изображение в альбомной ориентации ({{ width }}x{{ height }}px). Изображения в альбомной ориентации не разрешены.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>Изображение в портретной ориентации ({{ width }}x{{ height }}px). Изображения в портретной ориентации не разрешены.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Пустые файлы не разрешены.</target>
+ </trans-unit>
+ <trans-unit id="80">
+ <source>This value does not match the expected {{ charset }} charset.</source>
+ <target>Значение не совпадает с ожидаемой {{ charset }} кодировкой.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sk.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sk.xlf
new file mode 100644
index 0000000..46f3ec3
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sk.xlf
@@ -0,0 +1,307 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Táto hodnota by mala byť nastavená na false.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Táto hodnota by mala byť nastavená na true.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Táto hodnota by mala byť typu {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Táto hodnota by mala byť prázdna.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Táto hodnota by mala byť jednou z poskytnutých možností.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>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í.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Mali by ste vybrať najviac {{ limit }} možnosť.|Mali by ste vybrať najviac {{ limit }} možnosti.|Mali by ste vybrať najviac {{ limit }} možností.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Niektoré z uvedených hodnôt sú neplatné.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Toto pole sa neočakáva.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Toto pole chýba.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Tato hodnota nemá platný formát dátumu.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Táto hodnota nemá platný formát dátumu a času.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Táto hodnota nie je platná emailová adresa.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Súbor sa nenašiel.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Súbor nie je čitateľný.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Súbor je príliš veľký ({{ size }} {{ suffix }}). Maximálna povolená veľkosť je {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Súbor typu ({{ type }}) nie je podporovaný. Podporované typy sú {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Táto hodnota by mala byť {{ limit }} alebo menej.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Táto hodnota by mala byť viac ako {{ limit }}.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>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 }}.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Táto hodnota by mala byť vyplnená.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Táto hodnota by nemala byť null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Táto hodnota by mala byť null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Táto hodnota nie je platná.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Tato hodnota nemá správny formát času.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Táto hodnota nie je platnou URL adresou.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Tieto dve hodnoty by mali byť rovnaké.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Súbor je príliš veľký. Maximálna povolená veľkosť je {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Súbor je príliš veľký.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Súbor sa nepodarilo nahrať.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Táto hodnota by mala byť číslo.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Tento súbor nie je obrázok.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Toto nie je platná IP adresa.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Tento jazyk neexistuje.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Táto lokalizácia neexistuje.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Táto krajina neexistuje.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Táto hodnota sa už používa.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Nepodarilo sa zistiť rozmery obrázku.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Obrázok je príliš široký ({{ width }}px). Maximálna povolená šírka obrázku je {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Obrázok je príliš úzky ({{ width }}px). Minimálna šírka obrázku by mala byť {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>>Obrázok je príliš vysoký ({{ height }}px). Maximálna povolená výška obrázku je {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Obrázok je príliš nízky ({{ height }}px). Minimálna výška obrázku by mala byť {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Táto hodnota by mala byť aktuálne heslo používateľa.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Bola nahraná len časť súboru.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Žiadny súbor nebol nahraný.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>V php.ini nie je nastavená cesta k adresáru pre dočasné súbory.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Dočasný súbor sa nepodarilo zapísať na disk.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Rozšírenie PHP zabránilo nahraniu súboru.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Neplatné číslo karty.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Nepodporovaný typ karty alebo neplatné číslo karty.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Toto je neplatný IBAN.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Táto hodnota je neplatné ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Táto hodnota je neplatné ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Táto hodnota nie je platné ISBN-10 ani ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Táto hodnota nie je platné ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Táto hodnota nie je platná mena.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Táto hodnota by mala byť rovná {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Táto hodnota by mala byť väčšia ako {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Táto hodnota by mala byť väčšia alebo rovná {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Táto hodnota by mala byť typu {{ compared_value_type }} a zároveň by mala byť rovná {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Táto hodnota by mala byť menšia ako {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Táto hodnota by mala byť menšia alebo rovná {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Táto hodnota by nemala byť rovná {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Táto hodnota by nemala byť typu {{ compared_value_type }} a zároveň by nemala byť rovná {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>Pomer strán obrázku je príliš veľký ({{ ratio }}). Maximálny povolený pomer strán obrázku je {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>Pomer strán obrázku je príliš malý ({{ ratio }}). Minimálny povolený pomer strán obrázku je {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>Strany obrázku sú štvorcové ({{ width }}x{{ height }}px). Štvorcové obrázky nie sú povolené.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>Obrázok je orientovaný na šírku ({{ width }}x{{ height }}px). Obrázky orientované na šírku nie sú povolené.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>Obrázok je orientovaný na výšku ({{ width }}x{{ height }}px). Obrázky orientované na výšku nie sú povolené.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Súbor nesmie byť prázdny.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sl.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sl.xlf
new file mode 100644
index 0000000..b41d1ae
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sl.xlf
@@ -0,0 +1,311 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Vrednost bi morala biti nepravilna (false).</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Vrednost bi morala biti pravilna (true).</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Vrednost mora biti naslednjega tipa {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Vrednost mora biti prazna.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Vrednost, ki ste jo izbrali, ni veljavna možnost.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Izbrati morate vsaj {{ limit }} možnost.|Izbrati morate vsaj {{ limit }} možnosti.|Izbrati morate vsaj {{ limit }} možnosti.|Izbrati morate vsaj {{ limit }} možnosti.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Izberete lahko največ {{ limit }} možnost.|Izberete lahko največ {{ limit }} možnosti.|Izberete lahko največ {{ limit }} možnosti.|Izberete lahko največ {{ limit }} možnosti.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Ena ali več podanih vrednosti ni veljavnih.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>To polje ni bilo pričakovati.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>To polje manjka.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Ta vrednost ni veljaven datum.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Ta vrednost ni veljaven datum in čas.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Ta vrednost ni veljaven e-poštni naslov.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Datoteke ni mogoče najti.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Datoteke ni mogoče prebrati.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Datoteka je prevelika ({{ size }} {{ suffix }}). Največja dovoljena velikost je {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Mime tip datoteke je neveljaven ({{ type }}). Dovoljeni mime tipi so {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Ta vrednost bi morala biti {{ limit }} ali manj.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Ta vrednost bi morala biti {{ limit }} ali več.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>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č.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Ta vrednost ne bi smela biti prazna.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Ta vrednost ne bi smela biti nedefinirana (null).</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Ta vrednost bi morala biti nedefinirana (null).</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Ta vrednost ni veljavna.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Ta vrednost ni veljaven čas.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Ta vrednost ni veljaven URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Ti dve vrednosti bi morali biti enaki.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Datoteka je prevelika. Največja dovoljena velikost je {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Datoteka je prevelika.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Datoteke ni bilo mogoče naložiti.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Ta vrednost bi morala biti veljavna številka.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Ta datoteka ni veljavna slika.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>To ni veljaven IP naslov.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Ta vrednost ni veljaven jezik.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Ta vrednost ni veljavna lokalnost.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Ta vrednost ni veljavna država.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Ta vrednost je že uporabljena.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Velikosti slike ni bilo mogoče zaznati.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Širina slike je preširoka ({{ width }}px). Največja dovoljena širina je {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Širina slike je premajhna ({{ width }}px). Najmanjša predvidena širina je {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Višina slike je prevelika ({{ height }}px). Največja dovoljena višina je {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Višina slike je premajhna ({{ height }}px). Najmanjša predvidena višina je {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Ta vrednost bi morala biti trenutno uporabnikovo geslo.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Datoteka je bila le delno naložena.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Nobena datoteka ni bila naložena.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Začasna mapa ni nastavljena v php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Začasne datoteke ni bilo mogoče zapisati na disk.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>PHP razširitev je vzrok, da nalaganje ni uspelo.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>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č.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Neveljavna številka kartice.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Nepodprti tip kartice ali neveljavna številka kartice.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>To ni veljavna mednarodna številka bančnega računa (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Neveljavna vrednost po ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Neveljavna vrednost po ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Neveljavna vrednost po ISBN-10 ali po ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Neveljavna vrednost ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Ta vrednost ni veljavna valuta.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Ta vrednost bi morala biti enaka {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Ta vrednost bi morala biti večja od {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Ta vrednost bi morala biti večja ali enaka {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ta vrednost bi morala biti identična {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Ta vrednost bi morala biti manjša od {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Ta vrednost bi morala biti manjša ali enaka {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Ta vrednost ne bi smela biti enaka {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ta vrednost ne bi smela biti identična {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>Razmerje slike je preveliko ({{ ratio }}). Največje dovoljeno razmerje je {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>Razmerje slike je premajhno ({{ ratio }}). Najmanjše pričakovano razmerje je {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>Slika je kvadrat ({{ width }}x{{ height }}px). Kvadratne slike niso dovoljene.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>Slika je ležeče usmerjena ({{ width }}x{{ height }}px). Ležeče usmerjene slike niso dovoljene.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>Slika je pokončno usmerjena ({{ width }}x{{ height }}px). Pokončno usmerjene slike niso dovoljene.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>Prazna datoteka ni dovoljena.</target>
+ </trans-unit>
+ <trans-unit id="80">
+ <source>This value does not match the expected {{ charset }} charset.</source>
+ <target>Ta vrednost se ne ujema s pričakovanim naborom znakov {{ charset }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sq.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sq.xlf
new file mode 100644
index 0000000..ffc8ccf
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sq.xlf
@@ -0,0 +1,227 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Kjo vlerë duhet të jetë e pavërtetë (false).</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Kjo vlerë duhet të jetë e vërtetë (true).</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Kjo vlerë duhet të jetë e llojit {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Kjo vlerë duhet të jetë e zbrazët.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Vlera që keni zgjedhur nuk është alternativë e vlefshme.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Duhet të zgjedhni së paku {{ limit }} alternativa.|Duhet të zgjedhni së paku {{ limit }} alternativa.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Duhet të zgjedhni më së shumti {{ limit }} alternativa.|Duhet të zgjedhni më së shumti {{ limit }} alternativa.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Një apo më shumë nga vlerat e dhëna nuk janë të sakta.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Kjo fushë nuk pritej.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Kjo fushë është zhdukur.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Kjo vlerë nuk është datë e vlefshme.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Kjo vlerë nuk është datë-kohë e vlefshme.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Kjo vlerë nuk është e-mail adresë e vlefshme.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>File nuk mund të gjindej.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>File nuk është i lexueshëm.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>File është shumë i madh ({{ size }} {{ suffix }}). Madhësia më e madhe e lejuar është {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Lloji mime i files nuk është i vlefshëm ({{ type }}). Llojet mime të lejuara janë {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Kjo vlerë duhet të jetë {{ limit }} ose më pak.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Kjo vlerë është shumë e gjatë. Duhet t'i ketë {{ limit }} ose më pak karaktere.|Kjo vlerë është shumë e gjatë. Duhet t'i ketë {{ limit }} ose më pak karaktere.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Kjo vlerë duhet të jetë {{ limit }} ose më shumë.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Kjo vlerë është shumë e shkurtër. Duhet t'i ketë {{ limit }} ose më shumë karaktere.|Kjo vlerë është shumë e shkurtër. Duhet t'i ketë {{ limit }} ose më shumë karaktere.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Kjo vlerë nuk duhet të jetë e zbrazët.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Kjo vlerë nuk duhet të jetë null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Kjo vlerë duhet të jetë null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Kjo vlerë nuk është e vlefshme.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Kjo vlerë nuk është kohë e vlefshme.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Kjo vlerë nuk është URL e vlefshme.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Këto dy vlera duhet të jenë të barabarta.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Ky file është shumë i madh. Madhësia maksimale e lejuar është {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Ky file është shumë i madh.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Ky file nuk mund të ngarkohet.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Kjo vlerë duhet të jetë numër i vlefshëm.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Ky file nuk është imazh i vlefshëm.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Kjo vlerë nuk është IP adresë e vlefshme.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Kjo vlerë nuk është gjuhë e vlefshme.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Kjo vlerë nuk është përcaktim rajonal i vlefshëm.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Kjo vlerë nuk është shtet i vlefshëm.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Kjo vlerë është tashmë në përdorim.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Madhësia e këtij imazhi nuk mund të zbulohet.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Gjerësia e imazhit është shumë e madhe ({{ width }}px). Gjerësia maksimale e lejuar është {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Gjerësia e imazhit është shumë e vogël ({{ width }}px). Gjerësia minimale e pritur është {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Gjatësia e imazhit është shumë e madhe ({{ height }}px). Gjatësia maksimale e lejuar është {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Gjatësia e imazhit është shumë e vogël ({{ height }}px). Gjatësia minimale e pritur është {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Kjo vlerë duhet të jetë fjalëkalimi aktual i përdoruesit.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Kjo vlerë duhet të ketë saktësisht {{ limit }} karaktere.|Kjo vlerë duhet të ketë saktësisht {{ limit }} karaktere.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Ky file është ngarkuar pjesërisht.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Nuk është ngarkuar ndonjë file.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Asnjë folder i përkohshëm nuk është konfiguruar në php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Nuk mund të shkruhet file i përkohshëm në disk.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Një ekstenzion i PHP-së bëri të dështojë ngarkimi i files.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Ky kolekcion duhet të përmbajë {{ limit }} ose më shumë elemente.|Ky kolekcion duhet të përmbajë {{ limit }} ose më shumë elemente.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Ky kolekcion duhet të përmbajë {{ limit }} ose më shumë elemente.|Ky kolekcion duhet të përmbajë {{ limit }} ose më shumë elemente.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Ky kolekcion duhet të përmbajë saktësisht {{ limit }} elemente.|Ky kolekcion duhet të përmbajë saktësisht {{ limit }} elemente.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Numër kartele i pavlefshëm.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Lloj kartele i pambështetur ose numër kartele i pavlefshëm.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sr_Cyrl.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sr_Cyrl.xlf
new file mode 100644
index 0000000..81f5210
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sr_Cyrl.xlf
@@ -0,0 +1,303 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Вредност треба да буде нетачна.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Вредност треба да буде тачна.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Вредност треба да буде типа {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Вредност треба да буде празна.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Вредност треба да буде једна од понуђених.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Изаберите бар {{ limit }} могућност.|Изаберите бар {{ limit }} могућности.|Изаберите бар {{ limit }} могућности.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Изаберите највише {{ limit }} могућност.|Изаберите највише {{ limit }} могућности.|Изаберите највише {{ limit }} могућности.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Једна или више вредности је невалидна.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Ово поље не очекује.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Ово поље недостаје.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Вредност није валидан датум.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Вредност није валидан датум-време.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Вредност није валидна адреса електронске поште.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Датотека не може бити пронађена.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Датотека није читљива.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Датотека је превелика ({{ size }} {{ suffix }}). Највећа дозвољена величина је {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Миме тип датотеке није валидан ({{ type }}). Дозвољени миме типови су {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Вредност треба да буде {{ limit }} или мање.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Вредност је предугачка. Треба да има {{ limit }} карактер или мање.|Вредност је предугачка. Треба да има {{ limit }} карактера или мање.|Вредност је предугачка. Треба да има {{ limit }} карактера или мање.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Вредност треба да буде {{ limit }} или више.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Вредност је прекратка. Треба да има {{ limit }} карактер или више.|Вредност је прекратка. Треба да има {{ limit }} карактера или више.|Вредност је прекратка. Треба да има {{ limit }} карактера или више.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Вредност не треба да буде празна.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Вредност не треба да буде null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Вредност треба да буде null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Вредност је невалидна.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Вредност није валидно време.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Вредност није валидан URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Обе вредности треба да буду једнаке.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Датотека је превелика. Највећа дозвољена величина је {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Датотека је превелика.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Датотека не може бити отпремљена.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Вредност треба да буде валидан број.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Ова датотека није валидна слика.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Ово није валидна ИП адреса.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Вредност није валидан језик.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Вредност није валидан локал.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Вредност није валидна земља.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Вредност је већ искоришћена.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Величина слике не може бити одређена.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Ширина слике је превелика ({{ width }}px). Најећа дозвољена ширина је {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Ширина слике је премала ({{ width }}px). Најмања дозвољена ширина је {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Висина слике је превелика ({{ height }}px). Најећа дозвољена висина је {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Висина слике је премала ({{ height }}px). Најмања дозвољена висина је {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Вредност треба да буде тренутна корисничка лозинка.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Вредност треба да има тачно {{ limit }} карактер.|Вредност треба да има тачно {{ limit }} карактера.|Вредност треба да има тачно {{ limit }} карактера.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Датотека је само парцијално отпремљена.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Датотека није отпремљена.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Привремени директоријум није конфигурисан у php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Немогуће писање привремене датотеке на диск.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>PHP екстензија је проузроковала неуспех отпремања датотеке.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Ова колекција треба да садржи {{ limit }} или више елемената.|Ова колекција треба да садржи {{ limit }} или више елемената.|Ова колекција треба да садржи {{ limit }} или више елемената.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Ова колекција треба да садржи {{ limit }} или мање елемената.|Ова колекција треба да садржи {{ limit }} или мање елемената.|Ова колекција треба да садржи {{ limit }} или мање елемената.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Ова колекција треба да садржи тачно {{ limit }} елемент.|Ова колекција треба да садржи тачно {{ limit }} елемента.|Ова колекција треба да садржи тачно {{ limit }} елемената.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Невалидан број картице.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Невалидан број картице или тип картице није подржан.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Ово није валидан међународни број банковног рачуна (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Ово није валидан ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Ово није валидан ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Ово није валидан ISBN-10 или ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Ово није валидан ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Ово није валидна валута.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Ова вредност треба да буде {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Ова вредност треба да буде већа од {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Ова вредност треба да буде већа или једнака {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ова вредност треба да буде идентична са {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Ова вредност треба да буде мања од {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Ова вредност треба да буде мања или једнака {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Ова вредност не треба да буде једнака {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ова вредност не треба да буде идентична са {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>Размера ове слике је превелика ({{ ratio }}). Максимална дозвољена размера је {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>Размера ове слике је премала ({{ ratio }}). Минимална очекивана размера је {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>Слика је квадратна ({{ width }}x{{ height }}px). Квадратне слике нису дозвољене.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>Слика је оријентације пејзажа ({{ width }}x{{ height }}px). Пејзажна оријентација слика није дозвољена.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>Слика је оријантације портрета ({{ width }}x{{ height }}px). Портретна оријентација слика није дозвољена.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sr_Latn.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sr_Latn.xlf
new file mode 100644
index 0000000..60c093a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sr_Latn.xlf
@@ -0,0 +1,303 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Vrednost treba da bude netačna.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Vrednost treba da bude tačna.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Vrednost treba da bude tipa {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Vrednost treba da bude prazna.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Vrednost treba da bude jedna od ponuđenih.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Izaberite bar {{ limit }} mogućnost.|Izaberite bar {{ limit }} mogućnosti.|Izaberite bar {{ limit }} mogućnosti.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Izaberite najviše {{ limit }} mogućnost.|Izaberite najviše {{ limit }} mogućnosti.|Izaberite najviše {{ limit }} mogućnosti.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Jedna ili više vrednosti je nevalidna.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Ovo polje ne očekuje.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Ovo polje nedostaje.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Vrednost nije validan datum.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Vrednost nije validan datum-vreme.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Vrednost nije validna adresa elektronske pošte.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Datoteka ne može biti pronađena.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Datoteka nije čitljiva.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Datoteka je prevelika ({{ size }} {{ suffix }}). Najveća dozvoljena veličina je {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Mime tip datoteke nije validan ({{ type }}). Dozvoljeni mime tipovi su {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Vrednost treba da bude {{ limit }} ili manje.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Vrednost treba da bude {{ limit }} ili više.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Vrednost ne treba da bude prazna.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Vrednost ne treba da bude null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Vrednost treba da bude null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Vrednost je nevalidna.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Vrednost nije validno vreme.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Vrednost nije validan URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Obe vrednosti treba da budu jednake.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Datoteka je prevelika. Najveća dozvoljena veličina je {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Datoteka je prevelika.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Datoteka ne može biti otpremljena.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Vrednost treba da bude validan broj.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Ova datoteka nije validna slika.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Ovo nije validna IP adresa.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Vrednost nije validan jezik.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Vrednost nije validan lokal.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Vrednost nije validna zemlja.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Vrednost je već iskorišćena.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Veličina slike ne može biti određena.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Širina slike je prevelika ({{ width }}px). Najeća dozvoljena širina je {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Širina slike je premala ({{ width }}px). Najmanja dozvoljena širina je {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Visina slike je prevelika ({{ height }}px). Najeća dozvoljena visina je {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Visina slike je premala ({{ height }}px). Najmanja dozvoljena visina je {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Vrednost treba da bude trenutna korisnička lozinka.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Vrednost treba da ima tačno {{ limit }} karakter.|Vrednost treba da ima tačno {{ limit }} karaktera.|Vrednost treba da ima tačno {{ limit }} karaktera.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Datoteka je samo parcijalno otpremljena.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Datoteka nije otpremljena.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Privremeni direktorijum nije konfigurisan u php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Nemoguće pisanje privremene datoteke na disk.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>PHP ekstenzija je prouzrokovala neuspeh otpremanja datoteke.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Nevalidan broj kartice.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Nevalidan broj kartice ili tip kartice nije podržan.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Ovo nije validan međunarodni broj bankovnog računa (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Ovo nije validan ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Ovo nije validan ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Ovo nije validan ISBN-10 ili ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Ovo nije validan ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Ovo nije validna valuta.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Ova vrednost treba da bude {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Ova vrednost treba da bude veća od {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Ova vrednost treba da bude veća ili jednaka {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ova vrednost treba da bude identična sa {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Ova vrednost treba da bude manja od {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Ova vrednost treba da bude manja ili jednaka {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Ova vrednost ne treba da bude jednaka {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Ova vrednost ne treba da bude identična sa {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>Razmera ove slike je prevelika ({{ ratio }}). Maksimalna dozvoljena razmera je {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>Razmera ove slike je premala ({{ ratio }}). Minimalna očekivana razmera je {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>Slika je kvadratna ({{ width }}x{{ height }}px). Kvadratne slike nisu dozvoljene.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>Slika je orijentacije pejzaža ({{ width }}x{{ height }}px). Pejzažna orijentacija slika nije dozvoljena.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>Slika je orijantacije portreta ({{ width }}x{{ height }}px). Portretna orijentacija slika nije dozvoljena.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sv.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sv.xlf
new file mode 100644
index 0000000..fbcb5f2
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.sv.xlf
@@ -0,0 +1,307 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Värdet ska vara falskt.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Värdet ska vara sant.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Värdet ska vara av typen {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Värdet ska vara tomt.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Värdet ska vara ett av de givna valen.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Du måste välja minst {{ limit }} val.|Du måste välja minst {{ limit }} val.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Du kan som mest välja {{ limit }} val.|Du kan som mest välja {{ limit }} val.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Ett eller fler av de angivna värdena är ogiltigt.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Det här fältet förväntades inte.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Det här fältet saknas.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Värdet är inte ett giltigt datum.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Värdet är inte ett giltigt datum med tid.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Värdet är inte en giltig epost-adress.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Filen kunde inte hittas.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Filen är inte läsbar.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Filen är för stor ({{ size }} {{ suffix }}). Största tillåtna storlek är {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Filens MIME-typ ({{ type }}) är ogiltig. De tillåtna typerna är {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Värdet ska vara {{ limit }} eller mindre.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Värdet ska vara {{ limit }} eller mer.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Värdet kan inte vara tomt.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Värdet kan inte vara null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Värdet ska vara null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Värdet är inte giltigt.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Värdet är inte en giltig tid.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Värdet är inte en giltig URL.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>De två värdena måste vara lika.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Filen är för stor. Tillåten maximal storlek är {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Filen är för stor.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Filen kunde inte laddas upp.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Värdet ska vara ett giltigt nummer.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Filen är ingen giltig bild.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Det här är inte en giltig IP-adress.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Värdet är inte ett giltigt språk.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Värdet är inte en giltig plats.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Värdet är inte ett giltigt land.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Värdet används redan.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Det gick inte att fastställa storleken på bilden.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Bildens bredd är för stor ({{ width }}px). Tillåten maximal bredd är {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Bildens bredd är för liten ({{ width }}px). Minsta förväntade bredd är {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Bildens höjd är för stor ({{ height }}px). Tillåten maximal bredd är {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Bildens höjd är för liten ({{ height }}px). Minsta förväntade höjd är {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Värdet ska vara användarens nuvarande lösenord.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Värdet ska ha exakt {{ limit }} tecken.|Värdet ska ha exakt {{ limit }} tecken.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Filen laddades bara upp delvis.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Ingen fil laddades upp.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Det finns ingen temporär mapp konfigurerad i php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Kan inte skriva temporär fil till disken.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>En PHP extension gjorde att uppladdningen misslyckades.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Den här samlingen ska innehålla {{ limit }} element eller mer.|Den här samlingen ska innehålla {{ limit }} element eller mer.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Den här samlingen ska innehålla {{ limit }} element eller mindre.|Den här samlingen ska innehålla {{ limit }} element eller mindre.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Den här samlingen ska innehålla exakt {{ limit }} element.|Den här samlingen ska innehålla exakt {{ limit }} element.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Ogiltigt kortnummer.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Okänd korttyp eller ogiltigt kortnummer.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Det här är inte en giltig International Bank Account Number (IBANK).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Värdet är inte en giltig ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Värdet är inte en giltig ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Värdet är varken en giltig ISBN-10 eller en giltig ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Värdet är inte en giltig ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Värdet är inte en giltig valuta.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Värdet ska vara detsamma som {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Värdet ska vara större än {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Värdet ska bara större än eller detsamma som {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Värdet ska vara identiskt till {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Värdet ska vara mindre än {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Värdet ska vara mindre än eller detsamma som {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Värdet ska inte vara detsamma som {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Värdet ska inte vara identiskt med {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>Förhållandet mellan bildens bredd och höjd är för stort ({{ ratio }}). Högsta tillåtna förhållande är {{ max_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>Förhållandet mellan bildens bredd och höjd är för litet ({{ ratio }}). Minsta tillåtna förhållande är {{ min_ratio }}.</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>Bilden är kvadratisk ({{ width }}x{{ height }}px). Kvadratiska bilder tillåts inte.</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>Bilden är landskapsorienterad ({{ width }}x{{ height }}px). Landskapsorienterade bilder tillåts inte.</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>Bilden är porträttsorienterad ({{ width }}x{{ height }}px). Porträttsorienterade bilder tillåts inte.</target>
+ </trans-unit>
+ <trans-unit id="78">
+ <source>An empty file is not allowed.</source>
+ <target>En tom fil är inte tillåten.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.th.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.th.xlf
new file mode 100644
index 0000000..0237a30
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.th.xlf
@@ -0,0 +1,303 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>ค่านี้ควรจะเป็น false</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>ค่านี้ควรจะเป็น true</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>ค่านี้ควรจะเป็นชนิด {{ type }}</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>ควรจะเป็นค่าว่าง</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>คุณเลือกค่าที่ไม่ตรงกับตัวเลือก</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>คุณต้องเลือกอย่างน้อย {{ limit }} ตัวเลือก</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>คุณเลือกได้มากที่สุด {{ limit }} ตัวเลือก</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>มีบางค่าที่ส่งมาไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>ฟิลด์นี้ที่ไม่ได้คาดหวัง</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>ฟิลด์นี้จะหายไป</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>ค่าของวันที่ไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>ค่าของวันที่และเวลาไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>ค่าของอีเมล์ไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>ไม่พบไฟล์</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>ไฟล์ไม่อยู่ในสถานะที่สามารถอ่านได้</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>ไฟล์ใหญ่เกิน ({{ size }} {{ suffix }}) อนุญาตให้ใหญ่ที่สุดได้ไม่เกิน {{ limit }} {{ suffix }}</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Mime type ของไฟล์ไม่ถูกต้อง ({{ type }}) Mime types ที่อนุญาตคือ {{ types }}</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>ค่านี้ควรจะเป็น {{ limit }} หรือน้อยกว่านั้น</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>ค่านี้ยาวเกินไป ควรจะมีแค่ {{ limit }} ตัวอักษรหรือน้อยกว่านั้น</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>ค่านี้ควรจะมี {{ limit }} หรือมากกว่านั้น</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>ค่านี้สั้นเกินไป ควรจะมี {{ limit }} ตัวอักษรหรือมากกว่านั้น</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>ค่านี้ไม่ควรเป็นค่าว่าง</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>ค่านี้ไม่ควรเป็นค่า null</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>ค่านี้ควรเป็นค่า null</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>ค่านี้ไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>ค่าของเวลาไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>ค่าของ URL ไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>ค่าทั้งสองค่าควรจะเหมือนกัน</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>ขนาดไฟล์ใหญ่เกินไป อนุญาตให้ไฟล์ขนาดใหญ่ได้ไม่เกิน {{ limit }} {{ suffix }}</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>ขนาดไฟล์ใหญ่เกินไป</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>ไม่สามารถอัปโหลดไฟล์ได้</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>ค่าของตัวเลขไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>ไฟล์นี้ไม่ใช่ไฟล์รูปภาพ</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>ค่าของ IP ไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>ค่าของภาษาไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>ค่าของภูมิภาค (Locale) ไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>ค่าของประเทศไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Tค่านี้ถูกใช้งานไปแล้ว</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>ไม่สามารถตรวจสอบขนาดไฟล์ของภาพได้</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>ความกว้างของภาพเกินขนาด ({{ width }}px) อนุญาตให้กว้างได้มากที่สุด {{ max_width }}px</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>ความกว้างของภาพไม่ได้ขนาด ({{ width }}px) อนุญาตให้สั้นที่สุด {{ min_width }}px</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>ความสูงของภาพเกินขนาด ({{ height }}px) อนุญาตให้สูงได้มากที่สุด {{ max_height }}px</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>ความสูงของภาพไม่ได้ขนาด ({{ height }}px) อนุญาตให้สูงอย่างน้อยที่สุด {{ min_height }}px</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user current password.</source>
+ <target>ค่านี้ควรจะเป็นรหัสผ่านปัจจุบันของผู้ใช้</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>ค่านี้ควรจะมีความยาว {{ limit }} ตัวอักษร</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>อัปโหลดไฟล์ได้เพียงบางส่วนเท่านั้น</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>ไม่มีไฟล์ใดถูกอัปโหลด</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>ไม่พบไฟล์ temp ควรจะกำหนดใน php.ini</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>ไม่สามารถเขียน temp ไฟล์ลงดิสก์ได้</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>PHP extension เกี่ยวกับการอัปโหลดมีปัญหา</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>คอเล็กชั่นนี้ควรจะประกอบไปด้วยอ่างน้อย {{ limit }} สมาชิก</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>คอเล็กชั่นนี้ไม่ควรมีสมาชิกเกิน {{ limit }}</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>คอเล็กชั่นนี้ควรจะมีสมาชิก {{ limit }} เท่านั้น</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>หมายเลขบัตรไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>ไม่รู้จักประเภทของบัตร หรือหมายเลขบัตรไม่ถูกต้อง</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>นี่ไม่ถูกต้องตาม International Bank Account Number (IBAN)</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>ค่านี้ไม่ถูกต้องตาม ISBN-10</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>ค่านี้ไม่ถูกต้องตาม ISBN-13</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>ค่านี้ไม่ถูกต้องตามทั้ง ISBN-10 และ ISBN-13</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>ค่านี้ไม่ถุกต้องตาม ISSN</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>ค่านี้ไม่ถูกต้องตามสกุลเงิน</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>ค่านี้ไม่ตรงกับ {{ compared_value }}</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>ค่านี้ควรจะมากกว่า {{ compared_value }}</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>ค่านี้ควรจะมากกว่าหรือตรงกับ {{ compared_value }}</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>ค่านี้ควรจะเหมือนกันกับ {{ compared_value_type }} {{ compared_value }}</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>ค่านี้ควรจะน้อยกว่า {{ compared_value }}</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>ค่านี้ควรจะน้อยกว่าหรือเท่ากับ {{ compared_value }}</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>ค่านี้ไม่ควรเท่ากันกับ {{ compared_value }}</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>ค่านี้ไม่ควรเหมือนกันกับ {{ compared_value_type }} {{ compared_value }}</target>
+ </trans-unit>
+ <trans-unit id="73">
+ <source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
+ <target>สัดส่วนของภาพใหญ่เกิน ({{ ratio }}) สามารถมีขนาดใหญ่ที่สุดได้ {{ max_ratio }}</target>
+ </trans-unit>
+ <trans-unit id="74">
+ <source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
+ <target>สัดส่วนของภาพเล็กเกิน ({{ ratio }}) สามารถมีขนาดเล็กที่สุดได้ {{ min_ratio }}</target>
+ </trans-unit>
+ <trans-unit id="75">
+ <source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
+ <target>รูปภาพเป็นจุตรัส ({{ width }}x{{ height }}px) ไม่อนุญาตภาพที่เป็นสี่เหลี่ยมจตุรัส</target>
+ </trans-unit>
+ <trans-unit id="76">
+ <source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
+ <target>ภาพนี้เป็นแนวนอน ({{ width }}x{{ height }}px) ไม่อนุญาตภาพที่เป็นแนวนอน</target>
+ </trans-unit>
+ <trans-unit id="77">
+ <source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
+ <target>ภาพนี้เป็นแนวตั้ง ({{ width }}x{{ height }}px) ไม่อนุญาตภาพที่เป็นแนวตั้ง</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.tr.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.tr.xlf
new file mode 100644
index 0000000..a7906ea
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.tr.xlf
@@ -0,0 +1,227 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Bu değer olumsuz olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Bu değer olumlu olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Bu değerin tipi {{ type }} olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Bu değer boş olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Seçtiğiniz değer geçerli bir seçenek değil.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>En az {{ limit }} seçenek belirtmelisiniz.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>En çok {{ limit }} seçenek belirtmelisiniz.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Verilen değerlerden bir veya daha fazlası geçersiz.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Bu alan beklenen olmadı.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Bu alan, eksik</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Bu değer doğru bir tarih biçimi değildir.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Bu değer doğru bir tarihsaat biçimi değildir.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Bu değer doğru bir e-mail adresi değildir.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Dosya bulunamadı.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Dosya okunabilir değil.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Dosya çok büyük ({{ size }} {{ suffix }}). İzin verilen en büyük dosya boyutu {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Dosyanın mime tipi geçersiz ({{ type }}). İzin verilen mime tipleri {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Bu değer {{ limit }} ve altında olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Bu değer çok uzun. {{ limit }} karakter veya daha az olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Bu değer {{ limit }} veya daha fazla olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Bu değer çok kısa. {{ limit }} karakter veya daha fazla olmaldır.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Bu değer boş bırakılmamalıdır.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Bu değer boş bırakılmamalıdır.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Bu değer boş bırakılmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Bu değer geçerli değil.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Bu değer doğru bir saat değil.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Bu değer doğru bir URL değil.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>İki değer eşit olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Dosya çok büyük. İzin verilen en büyük dosya boyutu {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Dosya çok büyük.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Dosya yüklenemiyor.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Bu değer geçerli bir rakam olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Bu dosya geçerli bir resim değildir.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Bu geçerli bir IP adresi değildir.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Bu değer geçerli bir lisan değil.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Bu değer geçerli bir yer değildir.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Bu değer geçerli bir ülke değildir.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Bu değer şu anda kullanımda.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Resmin boyutu saptanamıyor.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Resmin genişliği çok büyük ({{ width }}px). İzin verilen en büyük genişlik {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Resmin genişliği çok küçük ({{ width }}px). En az {{ min_width }}px olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Resmin yüksekliği çok büyük ({{ height }}px). İzin verilen en büyük yükseklik {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Resmin yüksekliği çok küçük ({{ height }}px). En az {{ min_height }}px olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Bu değer kullanıcının şu anki şifresi olmalıdır.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Bu değer tam olarak {{ limit }} karakter olmaldır.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Dosya sadece kısmen yüklendi.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Hiçbir dosya yüklenmedi.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>php.ini içerisinde geçici dizin tanımlanmadı.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Geçici dosya diske yazılamıyor.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Bir PHP eklentisi dosyanın yüklemesini başarısız kıldı.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Bu derlem {{ limit }} veya daha çok eleman içermelidir.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Bu derlem {{ limit }} veya daha az eleman içermelidir.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Bu derlem {{ limit }} eleman içermelidir.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Geçersiz kart numarası.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Desteklenmeyen kart tipi veya geçersiz kart numarası.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.uk.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.uk.xlf
new file mode 100644
index 0000000..02ecd5a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.uk.xlf
@@ -0,0 +1,283 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Значення повинно бути Ні.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Значення повинно бути Так.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Тип значення повинен бути {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Значення повинно бути пустим.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Обране вами значення недопустиме.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>Ви повинні обрати хоча б {{ limit }} варіант.|Ви повинні обрати хоча б {{ limit }} варіанти.|Ви повинні обрати хоча б {{ limit }} варіантів.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>Ви повинні обрати не більше ніж {{ limit }} варіантів.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Одне або кілька заданих значень є недопустимі.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Це поле не очікується.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Це поле не вистачає.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Дане значення не є вірною датою.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Дане значення дати та часу недопустиме.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Значення адреси электронної пошти недопустиме.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Файл не знайдено.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Файл не читається.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Файл занадто великий ({{ size }} {{ suffix }}). Дозволений максимальний розмір {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>MIME-тип файлу недопустимий ({{ type }}). Допустимі MIME-типи файлів {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Значення повинно бути {{ limit }} або менше.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>Значення занадто довге. Повинно бути рівне {{ limit }} символу або менше.|Значення занадто довге. Повинно бути рівне {{ limit }} символам або менше.|Значення занадто довге. Повинно бути рівне {{ limit }} символам або менше.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Значення повинно бути {{ limit }} або більше.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>Значення занадто коротке. Повинно бути рівне {{ limit }} символу або більше.|Значення занадто коротке. Повинно бути рівне {{ limit }} символам або більше.|Значення занадто коротке. Повинно бути рівне {{ limit }} символам або більше.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Значення не повинно бути пустим.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Значення не повинно бути null.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Значення повинно бути null.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Значення недопустиме.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Значення часу недопустиме.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Значення URL недопустиме.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Обидва занчення повинні бути одинаковими.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Файл занадто великий. Максимальний допустимий розмір {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Файл занадто великий.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Файл не можливо завантажити.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Значення має бути допустимим числом.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Цей файл не є допустимим форматом зображення.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Це некоректна IP адреса.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Це некоректна мова.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Це некоректна локалізація.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Це некоректна країна.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Це значення вже використовується.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Не вдалося визначити розмір зображення.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>Ширина зображення занадто велика ({{ width }}px). Максимально допустима ширина {{ max_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>Ширина зображення занадто мала ({{ width }}px). Мінімально допустима ширина {{ min_width }}px.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Висота зображення занадто велика ({{ height }}px). Максимально допустима висота {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>Висота зображення занадто мала ({{ height }}px). Мінімально допустима висота {{ min_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Значення має бути поточним паролем користувача.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Значення повиино бути рівним {{ limit }} символу.|Значення повиино бути рівним {{ limit }} символам.|Значення повиино бути рівним {{ limit }} символам.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Файл був завантажений лише частково.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Файл не був завантажений.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Не налаштована тимчасова директорія в php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Неможливо записати тимчасовий файл на диск.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Розширення PHP викликало помилку при завантаженні.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Ця колекція повинна містити {{ limit }} елемент чи більше.|Ця колекція повинна містити {{ limit }} елемента чи більше.|Ця колекція повинна містити {{ limit }} елементів чи більше.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Ця колекція повинна містити {{ limit }} елемент чи менше.|Ця колекція повинна містити {{ limit }} елемента чи менше.|Ця колекція повинна містити {{ limit }} елементов чи менше.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>Ця колекція повинна містити рівно {{ limit }} елемент.|Ця колекція повинна містити рівно {{ limit }} елемента.|Ця колекція повинна містити рівно {{ limit }} елементів.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Невірний номер карти.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Непідтримуваний тип карти або невірний номер карти.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Це не дійсний міжнародний номер банківського рахунку (IBAN).</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Значення не у форматі ISBN-10.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Значення не у форматі ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Значення не відповідає форматам ISBN-10 та ISBN-13.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Значення має невірний формат ISSN.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Значення має невірний формат валюти.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Значення повинно дорівнювати {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Значення має бути більше ніж {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Значення має бути більше або дорівнювати {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Значення має бути ідентичним {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Значення повинно бути менше ніж {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Значення повинно бути менше або дорівнювати {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Значення не повинно дорівнювати {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Значення не повинно бути ідентичним {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.vi.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.vi.xlf
new file mode 100644
index 0000000..e1833c7
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.vi.xlf
@@ -0,0 +1,283 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>Giá trị này phải là sai.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>Giá trị này phải là đúng.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>Giá trị này phải là kiểu {{ type }}.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>Giá trị này phải rỗng.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>Giá trị bạn vừa chọn không hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>Một hoặc nhiều giá trị được chọn không hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>Lĩnh vực này không được dự kiến.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>Lĩnh vực này là mất tích.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>Giá trị không phải là ngày hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>Giá trị không phải là ngày tháng hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>Giá trị này không phải là email hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>Tập tin không tìm thấy.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>Tập tin không thể đọc được.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Tập tin quá lớn ({{ size }} {{ suffix }}). Kích thước tối đa cho phép {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>Kiểu mime của tập tin không hợp lệ ({{ type }}). Kiểu hợp lệ là {{ types }}.</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>Giá trị phải bằng hoặc nhỏ hơn {{ limit }}.</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>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ự.</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>Giá trị phải lớn hơn hoặc bằng {{ limit }}.</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>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ự.</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>Giá trị không được phép để trống.</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>Giá trị không được phép rỗng.</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>Giá trị phải rỗng.</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>Giá trị không hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>Giá trị không phải là thời gian hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>Giá trị không phải là địa chỉ URL hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>Hai giá trị phải bằng nhau.</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>Tập tin quá lớn. Kích thước tối đa cho phép là {{ limit }} {{ suffix }}.</target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>Tập tin quá lớn.</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>Tập tin không thể tải lên.</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>Giá trị phải là con số.</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This file is not a valid image.</source>
+ <target>Tập tin không phải là hình ảnh.</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This is not a valid IP address.</source>
+ <target>Địa chỉ IP không hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This value is not a valid language.</source>
+ <target>Giá trị không phải là ngôn ngữ hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid locale.</source>
+ <target>Giá trị không phải là một bản địa địa phương hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid country.</source>
+ <target>Giá trị không phải là nước hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>Giá trị đã được sử dụng.</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>Kích thước của hình ảnh không thể xác định.</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>Chiều cao của hình quá cao ({{ height }}px). Chiều cao tối đa phải là {{ max_height }}px.</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>Giá trị này phải là mật khẩu hiện tại của người dùng.</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>Giá trị phải có chính xác {{ limit }} kí tự.|Giá trị phải có chính xác {{ limit }} kí tự.</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>Tập tin chỉ được tải lên một phần.</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>Tập tin không được tải lên.</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>Thư mục tạm không được định nghĩa trong php.ini.</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>Không thể ghi tập tin tạm ra đĩa.</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>Một PHP extension đã phá hỏng quá trình tải lên của tập tin.</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>Danh sách phải chứa {{ limit }} hoặc nhiều hơn thành phần.|Danh sách phải chứa {{ limit }} hoặc nhiều hơn thành phần.</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>Danh sách phải chứa {{ limit }} hoặc ít hơn thành phần.|Danh sách phải chứa {{ limit }} hoặc ít hơn thành phần.</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>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.</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>Số thẻ không hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>Thẻ không được hỗ trợ hoặc số thẻ không hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>Giá trị không phải là International Bank Account Number (IBAN) hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>Giá trị không phải là ISBN-10 hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>Giá trị không phải là ISBN-13 hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>Giá trị không phải là ISBN-10 hoặc ISBN-13 hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>Giá trị không là ISSN hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>Giá trị không phải là đơn vi tiền tệ hợp lệ.</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>Giá trị phải bằng {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>Giá trị phải lớn hơn {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>Giá trị phải lớn hơn hoặc bằng {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Giá trị phải giống {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>Giá trị phải bé hơn {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>Giá trị không được phép nhỏ hơn hoặc bằng {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>Giá trị không được phép bằng {{ compared_value }}.</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>Giá trị không được phép giống như {{ compared_value_type }} {{ compared_value }}.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf
new file mode 100644
index 0000000..5ffc643
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf
@@ -0,0 +1,283 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>该变量的值应为 false 。</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>该变量的值应为 true 。</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>该变量的类型应为 {{ type }} 。</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>该变量值应为空。</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>选定变量的值不是有效的选项。</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>您至少要选择 {{ limit }} 个选项。</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>您最多能选择 {{ limit }} 个选项。</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>一个或者多个给定的值无效。</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>此字段是多余的。</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>此字段缺失。</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>该值不是一个有效的日期(date)。</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>该值不是一个有效的日期时间(datetime)。</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>该值不是一个有效的邮件地址。</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>文件未找到。</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>文件不可读。</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>文件太大 ({{ size }} {{ suffix }})。文件大小不可以超过 {{ limit }} {{ suffix }} 。</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>无效的文件类型 ({{ type }}) 。允许的文件类型有 {{ types }} 。</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>这个变量的值应该小于或等于 {{ limit }}。</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>字符串太长,长度不可超过 {{ limit }} 个字符。</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>该变量的值应该大于或等于 {{ limit }}。</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>字符串太短,长度不可少于 {{ limit }} 个字符。</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>该变量不应为空。</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>该变量不应为 null 。</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>该变量应为空 null 。</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>该变量值无效 。</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>该值不是一个有效的时间。</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>该值不是一个有效的 URL 。</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>这两个变量的值应该相等。</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>文件太大,文件大小不可以超过 {{ limit }} {{ suffix }}。 </target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>文件太大。</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>无法上传此文件。</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>该值应该为有效的数字。</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This value is not a valid country.</source>
+ <target>该值不是有效的国家名。</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This file is not a valid image.</source>
+ <target>该文件不是有效的图片。</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This is not a valid IP address.</source>
+ <target>该值不是有效的IP地址。</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid language.</source>
+ <target>该值不是有效的语言名。</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid locale.</source>
+ <target>该值不是有效的区域值(locale)。</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>该值已经被使用。</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>不能解析图片大小。</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>图片太宽 ({{ width }}px),最大宽度为 {{ max_width }}px 。</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>图片宽度不够 ({{ width }}px),最小宽度为 {{ min_width }}px 。</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>图片太高 ({{ height }}px),最大高度为 {{ max_height }}px 。</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>图片高度不够 ({{ height }}px),最小高度为 {{ min_height }}px 。</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>该变量的值应为用户当前的密码。</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>该变量应为 {{ limit }} 个字符。</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>该文件的上传不完整。</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>没有上传任何文件。</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>php.ini 里没有配置临时文件目录。</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>临时文件写入磁盘失败。</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>某个 PHP 扩展造成上传失败。</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>该集合最少应包含 {{ limit }} 个元素。</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>该集合最多包含 {{ limit }} 个元素。</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>该集合应包含 {{ limit }} 个元素 element 。</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>无效的信用卡号。</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>不支持的信用卡类型或无效的信用卡号。</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>该值不是有效的国际银行帐号(IBAN)。</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>该值不是有效的10位国际标准书号(ISBN-10)。</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>该值不是有效的13位国际标准书号(ISBN-13)。</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>该值不是有效的国际标准书号(ISBN-10 或 ISBN-13)。</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>该值不是有效的国际标准期刊号(ISSN)。</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>该值不是有效的货币名(currency)。</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>该值应等于 {{ compared_value }} 。</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>该值应大于 {{ compared_value }} 。</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>该值应大于或等于 {{ compared_value }} 。</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>该值应与 {{ compared_value_type }} {{ compared_value }} 相同。</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>该值应小于 {{ compared_value }} 。</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>该值应小于或等于 {{ compared_value }} 。</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>该值不应先等于 {{ compared_value }} 。</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>该值不应与 {{ compared_value_type }} {{ compared_value }} 相同。</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.zh_TW.xlf b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.zh_TW.xlf
new file mode 100644
index 0000000..d9d5f2f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.zh_TW.xlf
@@ -0,0 +1,283 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>This value should be false.</source>
+ <target>該變數的值應為 false 。</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>This value should be true.</source>
+ <target>該變數的值應為 true 。</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>This value should be of type {{ type }}.</source>
+ <target>該變數的類型應為 {{ type }} 。</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>This value should be blank.</source>
+ <target>該變數應為空。</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>The value you selected is not a valid choice.</source>
+ <target>選定變數的值不是有效的選項。</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
+ <target>您至少要選擇 {{ limit }} 個選項。</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices.</source>
+ <target>您最多能選擇 {{ limit }} 個選項。</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>One or more of the given values is invalid.</source>
+ <target>一個或者多個給定的值無效。</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>This field was not expected.</source>
+ <target>此字段是沒有預料到。</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>This field is missing.</source>
+ <target>此字段缺失。</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>This value is not a valid date.</source>
+ <target>該值不是一個有效的日期(date)。</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>This value is not a valid datetime.</source>
+ <target>該值不是一個有效的日期時間(datetime)。</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>This value is not a valid email address.</source>
+ <target>該值不是一個有效的郵件地址。</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>The file could not be found.</source>
+ <target>找不到檔案。</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>The file is not readable.</source>
+ <target>無法讀取檔案。</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>檔案太大 ({{ size }} {{ suffix }})。檔案大小不可以超過 {{ limit }} {{ suffix }} 。</target>
+ </trans-unit>
+ <trans-unit id="17">
+ <source>The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.</source>
+ <target>無效的檔案類型 ({{ type }}) 。允許的檔案類型有 {{ types }} 。</target>
+ </trans-unit>
+ <trans-unit id="18">
+ <source>This value should be {{ limit }} or less.</source>
+ <target>這個變數的值應該小於或等於 {{ limit }}。</target>
+ </trans-unit>
+ <trans-unit id="19">
+ <source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
+ <target>字串太長,長度不可超過 {{ limit }} 個字元。</target>
+ </trans-unit>
+ <trans-unit id="20">
+ <source>This value should be {{ limit }} or more.</source>
+ <target>該變數的值應該大於或等於 {{ limit }}。</target>
+ </trans-unit>
+ <trans-unit id="21">
+ <source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
+ <target>字串太短,長度不可少於 {{ limit }} 個字元。</target>
+ </trans-unit>
+ <trans-unit id="22">
+ <source>This value should not be blank.</source>
+ <target>該變數不應為空白。</target>
+ </trans-unit>
+ <trans-unit id="23">
+ <source>This value should not be null.</source>
+ <target>該值不應為 null 。</target>
+ </trans-unit>
+ <trans-unit id="24">
+ <source>This value should be null.</source>
+ <target>該值應為 null 。</target>
+ </trans-unit>
+ <trans-unit id="25">
+ <source>This value is not valid.</source>
+ <target>無效的數值 。</target>
+ </trans-unit>
+ <trans-unit id="26">
+ <source>This value is not a valid time.</source>
+ <target>該值不是一個有效的時間。</target>
+ </trans-unit>
+ <trans-unit id="27">
+ <source>This value is not a valid URL.</source>
+ <target>該值不是一個有效的 URL 。</target>
+ </trans-unit>
+ <trans-unit id="31">
+ <source>The two values should be equal.</source>
+ <target>這兩個變數的值應該相等。</target>
+ </trans-unit>
+ <trans-unit id="32">
+ <source>The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.</source>
+ <target>檔案太大,檔案大小不可以超過 {{ limit }} {{ suffix }}。 </target>
+ </trans-unit>
+ <trans-unit id="33">
+ <source>The file is too large.</source>
+ <target>檔案太大。</target>
+ </trans-unit>
+ <trans-unit id="34">
+ <source>The file could not be uploaded.</source>
+ <target>無法上傳此檔案。</target>
+ </trans-unit>
+ <trans-unit id="35">
+ <source>This value should be a valid number.</source>
+ <target>該值應該為有效的數字。</target>
+ </trans-unit>
+ <trans-unit id="36">
+ <source>This value is not a valid country.</source>
+ <target>該值不是有效的國家名。</target>
+ </trans-unit>
+ <trans-unit id="37">
+ <source>This file is not a valid image.</source>
+ <target>該檔案不是有效的圖片。</target>
+ </trans-unit>
+ <trans-unit id="38">
+ <source>This is not a valid IP address.</source>
+ <target>該值不是有效的IP地址。</target>
+ </trans-unit>
+ <trans-unit id="39">
+ <source>This value is not a valid language.</source>
+ <target>該值不是有效的語言名。</target>
+ </trans-unit>
+ <trans-unit id="40">
+ <source>This value is not a valid locale.</source>
+ <target>該值不是有效的區域值(locale)。</target>
+ </trans-unit>
+ <trans-unit id="41">
+ <source>This value is already used.</source>
+ <target>該值已經被使用。</target>
+ </trans-unit>
+ <trans-unit id="42">
+ <source>The size of the image could not be detected.</source>
+ <target>不能解析圖片大小。</target>
+ </trans-unit>
+ <trans-unit id="43">
+ <source>The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.</source>
+ <target>圖片太寬 ({{ width }}px),最大寬度為 {{ max_width }}px 。</target>
+ </trans-unit>
+ <trans-unit id="44">
+ <source>The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.</source>
+ <target>圖片寬度不夠 ({{ width }}px),最小寬度為 {{ min_width }}px 。</target>
+ </trans-unit>
+ <trans-unit id="45">
+ <source>The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.</source>
+ <target>圖片太高 ({{ height }}px),最大高度為 {{ max_height }}px 。</target>
+ </trans-unit>
+ <trans-unit id="46">
+ <source>The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.</source>
+ <target>圖片高度不夠 ({{ height }}px),最小高度為 {{ min_height }}px 。</target>
+ </trans-unit>
+ <trans-unit id="47">
+ <source>This value should be the user's current password.</source>
+ <target>該變數的值應為用戶目前的密碼。</target>
+ </trans-unit>
+ <trans-unit id="48">
+ <source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
+ <target>該變數應為 {{ limit }} 個字元。</target>
+ </trans-unit>
+ <trans-unit id="49">
+ <source>The file was only partially uploaded.</source>
+ <target>該檔案的上傳不完整。</target>
+ </trans-unit>
+ <trans-unit id="50">
+ <source>No file was uploaded.</source>
+ <target>沒有上傳任何檔案。</target>
+ </trans-unit>
+ <trans-unit id="51">
+ <source>No temporary folder was configured in php.ini.</source>
+ <target>php.ini 裡沒有配置臨時目錄。</target>
+ </trans-unit>
+ <trans-unit id="52">
+ <source>Cannot write temporary file to disk.</source>
+ <target>暫存檔寫入磁碟失敗。</target>
+ </trans-unit>
+ <trans-unit id="53">
+ <source>A PHP extension caused the upload to fail.</source>
+ <target>某個 PHP 擴展造成上傳失敗。</target>
+ </trans-unit>
+ <trans-unit id="54">
+ <source>This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.</source>
+ <target>該集合最少應包含 {{ limit }} 個元素。</target>
+ </trans-unit>
+ <trans-unit id="55">
+ <source>This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.</source>
+ <target>該集合最多包含 {{ limit }} 個元素。</target>
+ </trans-unit>
+ <trans-unit id="56">
+ <source>This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.</source>
+ <target>該集合應包含 {{ limit }} 個元素 element 。</target>
+ </trans-unit>
+ <trans-unit id="57">
+ <source>Invalid card number.</source>
+ <target>無效的信用卡號。</target>
+ </trans-unit>
+ <trans-unit id="58">
+ <source>Unsupported card type or invalid card number.</source>
+ <target>不支援的信用卡類型或無效的信用卡號。</target>
+ </trans-unit>
+ <trans-unit id="59">
+ <source>This is not a valid International Bank Account Number (IBAN).</source>
+ <target>該值不是有效的國際銀行帳號(IBAN)。</target>
+ </trans-unit>
+ <trans-unit id="60">
+ <source>This value is not a valid ISBN-10.</source>
+ <target>該值不是有效的10位國際標準書號(ISBN-10)。</target>
+ </trans-unit>
+ <trans-unit id="61">
+ <source>This value is not a valid ISBN-13.</source>
+ <target>該值不是有效的13位國際標準書號(ISBN-13)。</target>
+ </trans-unit>
+ <trans-unit id="62">
+ <source>This value is neither a valid ISBN-10 nor a valid ISBN-13.</source>
+ <target>該值不是有效的國際標準書號(ISBN-10 或 ISBN-13)。</target>
+ </trans-unit>
+ <trans-unit id="63">
+ <source>This value is not a valid ISSN.</source>
+ <target>該值不是有效的國際標準期刊號(ISSN)。</target>
+ </trans-unit>
+ <trans-unit id="64">
+ <source>This value is not a valid currency.</source>
+ <target>該值不是有效的貨幣名(currency)。</target>
+ </trans-unit>
+ <trans-unit id="65">
+ <source>This value should be equal to {{ compared_value }}.</source>
+ <target>該值應等於 {{ compared_value }} 。</target>
+ </trans-unit>
+ <trans-unit id="66">
+ <source>This value should be greater than {{ compared_value }}.</source>
+ <target>該值應大於 {{ compared_value }} 。</target>
+ </trans-unit>
+ <trans-unit id="67">
+ <source>This value should be greater than or equal to {{ compared_value }}.</source>
+ <target>該值應大於或等於 {{ compared_value }} 。</target>
+ </trans-unit>
+ <trans-unit id="68">
+ <source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>該值應與 {{ compared_value_type }} {{ compared_value }} 相同。</target>
+ </trans-unit>
+ <trans-unit id="69">
+ <source>This value should be less than {{ compared_value }}.</source>
+ <target>該值應小於 {{ compared_value }} 。</target>
+ </trans-unit>
+ <trans-unit id="70">
+ <source>This value should be less than or equal to {{ compared_value }}.</source>
+ <target>該值應小於或等於 {{ compared_value }} 。</target>
+ </trans-unit>
+ <trans-unit id="71">
+ <source>This value should not be equal to {{ compared_value }}.</source>
+ <target>該值應不等於 {{ compared_value }} 。</target>
+ </trans-unit>
+ <trans-unit id="72">
+ <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
+ <target>該值不應與 {{ compared_value_type }} {{ compared_value }} 相同。</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintTest.php
new file mode 100644
index 0000000..f63570c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintTest.php
@@ -0,0 +1,209 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Tests\Fixtures\ClassConstraint;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintC;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintWithValue;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintWithValueAsDefault;
+
+class ConstraintTest extends \PHPUnit_Framework_TestCase
+{
+ public function testSetProperties()
+ {
+ $constraint = new ConstraintA(array(
+ 'property1' => 'foo',
+ 'property2' => 'bar',
+ ));
+
+ $this->assertEquals('foo', $constraint->property1);
+ $this->assertEquals('bar', $constraint->property2);
+ }
+
+ public function testSetNotExistingPropertyThrowsException()
+ {
+ $this->setExpectedException('Symfony\Component\Validator\Exception\InvalidOptionsException');
+
+ new ConstraintA(array(
+ 'foo' => 'bar',
+ ));
+ }
+
+ public function testMagicPropertiesAreNotAllowed()
+ {
+ $constraint = new ConstraintA();
+
+ $this->setExpectedException('Symfony\Component\Validator\Exception\InvalidOptionsException');
+
+ $constraint->foo = 'bar';
+ }
+
+ public function testInvalidAndRequiredOptionsPassed()
+ {
+ $this->setExpectedException('Symfony\Component\Validator\Exception\InvalidOptionsException');
+
+ new ConstraintC(array(
+ 'option1' => 'default',
+ 'foo' => 'bar',
+ ));
+ }
+
+ public function testSetDefaultProperty()
+ {
+ $constraint = new ConstraintA('foo');
+
+ $this->assertEquals('foo', $constraint->property2);
+ }
+
+ public function testSetDefaultPropertyDoctrineStyle()
+ {
+ $constraint = new ConstraintA(array('value' => 'foo'));
+
+ $this->assertEquals('foo', $constraint->property2);
+ }
+
+ public function testSetDefaultPropertyDoctrineStylePlusOtherProperty()
+ {
+ $constraint = new ConstraintA(array('value' => 'foo', 'property1' => 'bar'));
+
+ $this->assertEquals('foo', $constraint->property2);
+ $this->assertEquals('bar', $constraint->property1);
+ }
+
+ public function testSetDefaultPropertyDoctrineStyleWhenDefaultPropertyIsNamedValue()
+ {
+ $constraint = new ConstraintWithValueAsDefault(array('value' => 'foo'));
+
+ $this->assertEquals('foo', $constraint->value);
+ $this->assertNull($constraint->property);
+ }
+
+ public function testDontSetDefaultPropertyIfValuePropertyExists()
+ {
+ $constraint = new ConstraintWithValue(array('value' => 'foo'));
+
+ $this->assertEquals('foo', $constraint->value);
+ $this->assertNull($constraint->property);
+ }
+
+ public function testSetUndefinedDefaultProperty()
+ {
+ $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
+
+ new ConstraintB('foo');
+ }
+
+ public function testRequiredOptionsMustBeDefined()
+ {
+ $this->setExpectedException('Symfony\Component\Validator\Exception\MissingOptionsException');
+
+ new ConstraintC();
+ }
+
+ public function testRequiredOptionsPassed()
+ {
+ new ConstraintC(array('option1' => 'default'));
+ }
+
+ public function testGroupsAreConvertedToArray()
+ {
+ $constraint = new ConstraintA(array('groups' => 'Foo'));
+
+ $this->assertEquals(array('Foo'), $constraint->groups);
+ }
+
+ public function testAddDefaultGroupAddsGroup()
+ {
+ $constraint = new ConstraintA(array('groups' => 'Default'));
+ $constraint->addImplicitGroupName('Foo');
+ $this->assertEquals(array('Default', 'Foo'), $constraint->groups);
+ }
+
+ public function testAllowsSettingZeroRequiredPropertyValue()
+ {
+ $constraint = new ConstraintA(0);
+ $this->assertEquals(0, $constraint->property2);
+ }
+
+ public function testCanCreateConstraintWithNoDefaultOptionAndEmptyArray()
+ {
+ new ConstraintB(array());
+ }
+
+ public function testGetTargetsCanBeString()
+ {
+ $constraint = new ClassConstraint();
+
+ $this->assertEquals('class', $constraint->getTargets());
+ }
+
+ public function testGetTargetsCanBeArray()
+ {
+ $constraint = new ConstraintA();
+
+ $this->assertEquals(array('property', 'class'), $constraint->getTargets());
+ }
+
+ public function testSerialize()
+ {
+ $constraint = new ConstraintA(array(
+ 'property1' => 'foo',
+ 'property2' => 'bar',
+ ));
+
+ $restoredConstraint = unserialize(serialize($constraint));
+
+ $this->assertEquals($constraint, $restoredConstraint);
+ }
+
+ public function testSerializeInitializesGroupsOptionToDefault()
+ {
+ $constraint = new ConstraintA(array(
+ 'property1' => 'foo',
+ 'property2' => 'bar',
+ ));
+
+ $constraint = unserialize(serialize($constraint));
+
+ $expected = new ConstraintA(array(
+ 'property1' => 'foo',
+ 'property2' => 'bar',
+ 'groups' => 'Default',
+ ));
+
+ $this->assertEquals($expected, $constraint);
+ }
+
+ public function testSerializeKeepsCustomGroups()
+ {
+ $constraint = new ConstraintA(array(
+ 'property1' => 'foo',
+ 'property2' => 'bar',
+ 'groups' => 'MyGroup',
+ ));
+
+ $constraint = unserialize(serialize($constraint));
+
+ $this->assertSame(array('MyGroup'), $constraint->groups);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
+ */
+ public function testGetErrorNameForUnknownCode()
+ {
+ Constraint::getErrorName(1);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationListTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationListTest.php
new file mode 100644
index 0000000..30d7ff0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationListTest.php
@@ -0,0 +1,134 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests;
+
+use Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\ConstraintViolationList;
+
+class ConstraintViolationListTest extends \PHPUnit_Framework_TestCase
+{
+ protected $list;
+
+ protected function setUp()
+ {
+ $this->list = new ConstraintViolationList();
+ }
+
+ protected function tearDown()
+ {
+ $this->list = null;
+ }
+
+ public function testInit()
+ {
+ $this->assertCount(0, $this->list);
+ }
+
+ public function testInitWithViolations()
+ {
+ $violation = $this->getViolation('Error');
+ $this->list = new ConstraintViolationList(array($violation));
+
+ $this->assertCount(1, $this->list);
+ $this->assertSame($violation, $this->list[0]);
+ }
+
+ public function testAdd()
+ {
+ $violation = $this->getViolation('Error');
+ $this->list->add($violation);
+
+ $this->assertCount(1, $this->list);
+ $this->assertSame($violation, $this->list[0]);
+ }
+
+ public function testAddAll()
+ {
+ $violations = array(
+ 10 => $this->getViolation('Error 1'),
+ 20 => $this->getViolation('Error 2'),
+ 30 => $this->getViolation('Error 3'),
+ );
+ $otherList = new ConstraintViolationList($violations);
+ $this->list->addAll($otherList);
+
+ $this->assertCount(3, $this->list);
+
+ $this->assertSame($violations[10], $this->list[0]);
+ $this->assertSame($violations[20], $this->list[1]);
+ $this->assertSame($violations[30], $this->list[2]);
+ }
+
+ public function testIterator()
+ {
+ $violations = array(
+ 10 => $this->getViolation('Error 1'),
+ 20 => $this->getViolation('Error 2'),
+ 30 => $this->getViolation('Error 3'),
+ );
+
+ $this->list = new ConstraintViolationList($violations);
+
+ // indices are reset upon adding -> array_values()
+ $this->assertSame(array_values($violations), iterator_to_array($this->list));
+ }
+
+ public function testArrayAccess()
+ {
+ $violation = $this->getViolation('Error');
+ $this->list[] = $violation;
+
+ $this->assertSame($violation, $this->list[0]);
+ $this->assertTrue(isset($this->list[0]));
+
+ unset($this->list[0]);
+
+ $this->assertFalse(isset($this->list[0]));
+
+ $this->list[10] = $violation;
+
+ $this->assertSame($violation, $this->list[10]);
+ $this->assertTrue(isset($this->list[10]));
+ }
+
+ public function testToString()
+ {
+ $this->list = new ConstraintViolationList(array(
+ $this->getViolation('Error 1', 'Root'),
+ $this->getViolation('Error 2', 'Root', 'foo.bar'),
+ $this->getViolation('Error 3', 'Root', '[baz]'),
+ $this->getViolation('Error 4', '', 'foo.bar'),
+ $this->getViolation('Error 5', '', '[baz]'),
+ ));
+
+ $expected = <<<EOF
+Root:
+ Error 1
+Root.foo.bar:
+ Error 2
+Root[baz]:
+ Error 3
+foo.bar:
+ Error 4
+[baz]:
+ Error 5
+
+EOF;
+
+ $this->assertEquals($expected, (string) $this->list);
+ }
+
+ protected function getViolation($message, $root = null, $propertyPath = null)
+ {
+ return new ConstraintViolation($message, $message, array(), $root, $propertyPath, null);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationTest.php
new file mode 100644
index 0000000..2ceb016
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationTest.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests;
+
+use Symfony\Component\Validator\ConstraintViolation;
+
+class ConstraintViolationTest extends \PHPUnit_Framework_TestCase
+{
+ public function testToStringHandlesArrays()
+ {
+ $violation = new ConstraintViolation(
+ 'Array',
+ '{{ value }}',
+ array('{{ value }}' => array(1, 2, 3)),
+ 'Root',
+ 'property.path',
+ null
+ );
+
+ $expected = <<<EOF
+Root.property.path:
+ Array
+EOF;
+
+ $this->assertSame($expected, (string) $violation);
+ }
+
+ public function testToStringHandlesArrayRoots()
+ {
+ $violation = new ConstraintViolation(
+ '42 cannot be used here',
+ 'this is the message template',
+ array(),
+ array('some_value' => 42),
+ 'some_value',
+ null
+ );
+
+ $expected = <<<EOF
+Array.some_value:
+ 42 cannot be used here
+EOF;
+
+ $this->assertSame($expected, (string) $violation);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php
new file mode 100644
index 0000000..4013fd4
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php
@@ -0,0 +1,173 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Intl\Util\IntlTestHelper;
+use Symfony\Component\Validator\Constraint;
+
+class ComparisonTest_Class
+{
+ protected $value;
+
+ public function __construct($value)
+ {
+ $this->value = $value;
+ }
+
+ public function __toString()
+ {
+ return (string) $this->value;
+ }
+}
+
+/**
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+abstract class AbstractComparisonValidatorTestCase extends AbstractConstraintValidatorTest
+{
+ protected static function addPhp5Dot5Comparisons(array $comparisons)
+ {
+ if (version_compare(PHP_VERSION, '5.5.0-dev', '<')) {
+ return $comparisons;
+ }
+
+ $result = $comparisons;
+
+ // Duplicate all tests involving DateTime objects to be tested with
+ // DateTimeImmutable objects as well
+ foreach ($comparisons as $comparison) {
+ $add = false;
+
+ foreach ($comparison as $i => $value) {
+ if ($value instanceof \DateTime) {
+ $comparison[$i] = new \DateTimeImmutable(
+ $value->format('Y-m-d H:i:s.u e'),
+ $value->getTimezone()
+ );
+ $add = true;
+ } elseif ('DateTime' === $value) {
+ $comparison[$i] = 'DateTimeImmutable';
+ $add = true;
+ }
+ }
+
+ if ($add) {
+ $result[] = $comparison;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testThrowsConstraintExceptionIfNoValueOrProperty()
+ {
+ $comparison = $this->createConstraint(array());
+
+ $this->validator->validate('some value', $comparison);
+ }
+
+ /**
+ * @dataProvider provideAllValidComparisons
+ *
+ * @param mixed $dirtyValue
+ * @param mixed $comparisonValue
+ */
+ public function testValidComparisonToValue($dirtyValue, $comparisonValue)
+ {
+ $constraint = $this->createConstraint(array('value' => $comparisonValue));
+
+ $this->validator->validate($dirtyValue, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @return array
+ */
+ public function provideAllValidComparisons()
+ {
+ // The provider runs before setUp(), so we need to manually fix
+ // the default timezone
+ $this->setDefaultTimezone('UTC');
+
+ $comparisons = self::addPhp5Dot5Comparisons($this->provideValidComparisons());
+
+ $this->restoreDefaultTimezone();
+
+ return $comparisons;
+ }
+
+ /**
+ * @return array
+ */
+ abstract public function provideValidComparisons();
+
+ /**
+ * @dataProvider provideAllInvalidComparisons
+ *
+ * @param mixed $dirtyValue
+ * @param mixed $dirtyValueAsString
+ * @param mixed $comparedValue
+ * @param mixed $comparedValueString
+ * @param string $comparedValueType
+ */
+ public function testInvalidComparisonToValue($dirtyValue, $dirtyValueAsString, $comparedValue, $comparedValueString, $comparedValueType)
+ {
+ // Conversion of dates to string differs between ICU versions
+ // Make sure we have the correct version loaded
+ if ($dirtyValue instanceof \DateTime || $dirtyValue instanceof \DateTimeInterface) {
+ IntlTestHelper::requireIntl($this);
+ }
+
+ $constraint = $this->createConstraint(array('value' => $comparedValue));
+ $constraint->message = 'Constraint Message';
+
+ $this->validator->validate($dirtyValue, $constraint);
+
+ $this->buildViolation('Constraint Message')
+ ->setParameter('{{ value }}', $dirtyValueAsString)
+ ->setParameter('{{ compared_value }}', $comparedValueString)
+ ->setParameter('{{ compared_value_type }}', $comparedValueType)
+ ->assertRaised();
+ }
+
+ /**
+ * @return array
+ */
+ public function provideAllInvalidComparisons()
+ {
+ // The provider runs before setUp(), so we need to manually fix
+ // the default timezone
+ $this->setDefaultTimezone('UTC');
+
+ $comparisons = self::addPhp5Dot5Comparisons($this->provideInvalidComparisons());
+
+ $this->restoreDefaultTimezone();
+
+ return $comparisons;
+ }
+
+ /**
+ * @return array
+ */
+ abstract public function provideInvalidComparisons();
+
+ /**
+ * @param array $options Options for the constraint
+ *
+ * @return Constraint
+ */
+ abstract protected function createConstraint(array $options);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AbstractConstraintValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AbstractConstraintValidatorTest.php
new file mode 100644
index 0000000..d55e464
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AbstractConstraintValidatorTest.php
@@ -0,0 +1,545 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\ConstraintValidatorInterface;
+use Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\Context\ExecutionContext;
+use Symfony\Component\Validator\Context\ExecutionContextInterface;
+use Symfony\Component\Validator\Context\LegacyExecutionContext;
+use Symfony\Component\Validator\ExecutionContextInterface as LegacyExecutionContextInterface;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\PropertyMetadata;
+use Symfony\Component\Validator\Tests\Fixtures\StubGlobalExecutionContext;
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+abstract class AbstractConstraintValidatorTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var ExecutionContextInterface
+ */
+ protected $context;
+
+ /**
+ * @var ConstraintValidatorInterface
+ */
+ protected $validator;
+
+ protected $group;
+
+ protected $metadata;
+
+ protected $object;
+
+ protected $value;
+
+ protected $root;
+
+ protected $propertyPath;
+
+ protected $constraint;
+
+ protected $defaultTimezone;
+
+ protected function setUp()
+ {
+ if (Validation::API_VERSION_2_5 !== $this->getApiVersion()) {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+ }
+
+ $this->group = 'MyGroup';
+ $this->metadata = null;
+ $this->object = null;
+ $this->value = 'InvalidValue';
+ $this->root = 'root';
+ $this->propertyPath = 'property.path';
+
+ // Initialize the context with some constraint so that we can
+ // successfully build a violation.
+ // The 2.4 API does not keep a reference to the current
+ // constraint yet. There the violation stores null.
+ $this->constraint = Validation::API_VERSION_2_4 === $this->getApiVersion()
+ ? null
+ : new NotNull();
+
+ $this->context = $this->createContext();
+ $this->validator = $this->createValidator();
+ $this->validator->initialize($this->context);
+
+ \Locale::setDefault('en');
+
+ $this->setDefaultTimezone('UTC');
+ }
+
+ protected function tearDown()
+ {
+ $this->restoreDefaultTimezone();
+ }
+
+ protected function setDefaultTimezone($defaultTimezone)
+ {
+ // Make sure this method can not be called twice before calling
+ // also restoreDefaultTimezone()
+ if (null === $this->defaultTimezone) {
+ $this->defaultTimezone = date_default_timezone_get();
+ date_default_timezone_set($defaultTimezone);
+ }
+ }
+
+ protected function restoreDefaultTimezone()
+ {
+ if (null !== $this->defaultTimezone) {
+ date_default_timezone_set($this->defaultTimezone);
+ $this->defaultTimezone = null;
+ }
+ }
+
+ protected function createContext()
+ {
+ $translator = $this->getMock('Symfony\Component\Translation\TranslatorInterface');
+
+ if (Validation::API_VERSION_2_4 === $this->getApiVersion()) {
+ return $this->getMockBuilder('Symfony\Component\Validator\ExecutionContext')
+ ->setConstructorArgs(array(
+ new StubGlobalExecutionContext($this->root),
+ $translator,
+ null,
+ $this->metadata,
+ $this->value,
+ $this->group,
+ $this->propertyPath,
+ ))
+ ->setMethods(array('validate', 'validateValue'))
+ ->getMock();
+ }
+
+ $validator = $this->getMock('Symfony\Component\Validator\Validator\ValidatorInterface');
+ $contextualValidator = $this->getMock('Symfony\Component\Validator\Validator\ContextualValidatorInterface');
+
+ switch ($this->getApiVersion()) {
+ case Validation::API_VERSION_2_5:
+ $context = new ExecutionContext(
+ $validator,
+ $this->root,
+ $translator
+ );
+ break;
+ case Validation::API_VERSION_2_5_BC:
+ $context = new LegacyExecutionContext(
+ $validator,
+ $this->root,
+ $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface'),
+ $translator
+ );
+ break;
+ default:
+ throw new \RuntimeException('Invalid API version');
+ }
+
+ $context->setGroup($this->group);
+ $context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath);
+ $context->setConstraint($this->constraint);
+
+ $validator->expects($this->any())
+ ->method('inContext')
+ ->with($context)
+ ->will($this->returnValue($contextualValidator));
+
+ return $context;
+ }
+
+ /**
+ * @param mixed $message
+ * @param array $parameters
+ * @param string $propertyPath
+ * @param string $invalidValue
+ * @param null $plural
+ * @param null $code
+ *
+ * @return ConstraintViolation
+ *
+ * @deprecated To be removed in Symfony 3.0. Use
+ * {@link buildViolation()} instead.
+ */
+ protected function createViolation($message, array $parameters = array(), $propertyPath = 'property.path', $invalidValue = 'InvalidValue', $plural = null, $code = null)
+ {
+ return new ConstraintViolation(
+ null,
+ $message,
+ $parameters,
+ $this->root,
+ $propertyPath,
+ $invalidValue,
+ $plural,
+ $code,
+ $this->constraint
+ );
+ }
+
+ protected function setGroup($group)
+ {
+ $this->group = $group;
+
+ switch ($this->getApiVersion()) {
+ case Validation::API_VERSION_2_4:
+ $this->context = $this->createContext();
+ $this->validator->initialize($this->context);
+ break;
+ case Validation::API_VERSION_2_5:
+ case Validation::API_VERSION_2_5_BC:
+ $this->context->setGroup($group);
+ break;
+ }
+ }
+
+ protected function setObject($object)
+ {
+ $this->object = $object;
+ $this->metadata = is_object($object)
+ ? new ClassMetadata(get_class($object))
+ : null;
+
+ switch ($this->getApiVersion()) {
+ case Validation::API_VERSION_2_4:
+ $this->context = $this->createContext();
+ $this->validator->initialize($this->context);
+ break;
+ case Validation::API_VERSION_2_5:
+ case Validation::API_VERSION_2_5_BC:
+ $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath);
+ break;
+ }
+ }
+
+ protected function setProperty($object, $property)
+ {
+ $this->object = $object;
+ $this->metadata = is_object($object)
+ ? new PropertyMetadata(get_class($object), $property)
+ : null;
+
+ switch ($this->getApiVersion()) {
+ case Validation::API_VERSION_2_4:
+ $this->context = $this->createContext();
+ $this->validator->initialize($this->context);
+ break;
+ case Validation::API_VERSION_2_5:
+ case Validation::API_VERSION_2_5_BC:
+ $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath);
+ break;
+ }
+ }
+
+ protected function setValue($value)
+ {
+ $this->value = $value;
+
+ switch ($this->getApiVersion()) {
+ case Validation::API_VERSION_2_4:
+ $this->context = $this->createContext();
+ $this->validator->initialize($this->context);
+ break;
+ case Validation::API_VERSION_2_5:
+ case Validation::API_VERSION_2_5_BC:
+ $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath);
+ break;
+ }
+ }
+
+ protected function setRoot($root)
+ {
+ $this->root = $root;
+ $this->context = $this->createContext();
+ $this->validator->initialize($this->context);
+ }
+
+ protected function setPropertyPath($propertyPath)
+ {
+ $this->propertyPath = $propertyPath;
+
+ switch ($this->getApiVersion()) {
+ case Validation::API_VERSION_2_4:
+ $this->context = $this->createContext();
+ $this->validator->initialize($this->context);
+ break;
+ case Validation::API_VERSION_2_5:
+ case Validation::API_VERSION_2_5_BC:
+ $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath);
+ break;
+ }
+ }
+
+ protected function expectNoValidate()
+ {
+ switch ($this->getApiVersion()) {
+ case Validation::API_VERSION_2_4:
+ $this->context->expects($this->never())
+ ->method('validate');
+ $this->context->expects($this->never())
+ ->method('validateValue');
+ break;
+ case Validation::API_VERSION_2_5:
+ case Validation::API_VERSION_2_5_BC:
+ $validator = $this->context->getValidator()->inContext($this->context);
+ $validator->expects($this->never())
+ ->method('atPath');
+ $validator->expects($this->never())
+ ->method('validate');
+ break;
+ }
+ }
+
+ protected function expectValidateAt($i, $propertyPath, $value, $group)
+ {
+ switch ($this->getApiVersion()) {
+ case Validation::API_VERSION_2_4:
+ $this->context->expects($this->at($i))
+ ->method('validate')
+ ->with($value, $propertyPath, $group);
+ break;
+ case Validation::API_VERSION_2_5:
+ case Validation::API_VERSION_2_5_BC:
+ $validator = $this->context->getValidator()->inContext($this->context);
+ $validator->expects($this->at(2 * $i))
+ ->method('atPath')
+ ->with($propertyPath)
+ ->will($this->returnValue($validator));
+ $validator->expects($this->at(2 * $i + 1))
+ ->method('validate')
+ ->with($value, $this->logicalOr(null, array()), $group);
+ break;
+ }
+ }
+
+ protected function expectValidateValueAt($i, $propertyPath, $value, $constraints, $group = null)
+ {
+ switch ($this->getApiVersion()) {
+ case Validation::API_VERSION_2_4:
+ $this->context->expects($this->at($i))
+ ->method('validateValue')
+ ->with($value, $constraints, $propertyPath, $group);
+ break;
+ case Validation::API_VERSION_2_5:
+ case Validation::API_VERSION_2_5_BC:
+ $contextualValidator = $this->context->getValidator()->inContext($this->context);
+ $contextualValidator->expects($this->at(2 * $i))
+ ->method('atPath')
+ ->with($propertyPath)
+ ->will($this->returnValue($contextualValidator));
+ $contextualValidator->expects($this->at(2 * $i + 1))
+ ->method('validate')
+ ->with($value, $constraints, $group);
+ break;
+ }
+ }
+
+ protected function assertNoViolation()
+ {
+ $this->assertCount(0, $this->context->getViolations());
+ }
+
+ /**
+ * @param mixed $message
+ * @param array $parameters
+ * @param string $propertyPath
+ * @param string $invalidValue
+ * @param null $plural
+ * @param null $code
+ *
+ * @deprecated To be removed in Symfony 3.0. Use
+ * {@link buildViolation()} instead.
+ */
+ protected function assertViolation($message, array $parameters = array(), $propertyPath = 'property.path', $invalidValue = 'InvalidValue', $plural = null, $code = null)
+ {
+ $this->buildViolation($message)
+ ->setParameters($parameters)
+ ->atPath($propertyPath)
+ ->setInvalidValue($invalidValue)
+ ->setCode($code)
+ ->setPlural($plural)
+ ->assertRaised();
+ }
+
+ /**
+ * @param array $expected
+ *
+ * @deprecated To be removed in Symfony 3.0. Use
+ * {@link buildViolation()} instead.
+ */
+ protected function assertViolations(array $expected)
+ {
+ $violations = $this->context->getViolations();
+
+ $this->assertCount(count($expected), $violations);
+
+ $i = 0;
+
+ foreach ($expected as $violation) {
+ $this->assertEquals($violation, $violations[$i++]);
+ }
+ }
+
+ /**
+ * @param $message
+ *
+ * @return ConstraintViolationAssertion
+ */
+ protected function buildViolation($message)
+ {
+ return new ConstraintViolationAssertion($this->context, $message, $this->constraint);
+ }
+
+ abstract protected function getApiVersion();
+
+ abstract protected function createValidator();
+}
+
+/**
+ * @internal
+ */
+class ConstraintViolationAssertion
+{
+ /**
+ * @var LegacyExecutionContextInterface
+ */
+ private $context;
+
+ /**
+ * @var ConstraintViolationAssertion[]
+ */
+ private $assertions;
+
+ private $message;
+ private $parameters = array();
+ private $invalidValue = 'InvalidValue';
+ private $propertyPath = 'property.path';
+ private $translationDomain;
+ private $plural;
+ private $code;
+ private $constraint;
+ private $cause;
+
+ public function __construct(LegacyExecutionContextInterface $context, $message, Constraint $constraint = null, array $assertions = array())
+ {
+ $this->context = $context;
+ $this->message = $message;
+ $this->constraint = $constraint;
+ $this->assertions = $assertions;
+ }
+
+ public function atPath($path)
+ {
+ $this->propertyPath = $path;
+
+ return $this;
+ }
+
+ public function setParameter($key, $value)
+ {
+ $this->parameters[$key] = $value;
+
+ return $this;
+ }
+
+ public function setParameters(array $parameters)
+ {
+ $this->parameters = $parameters;
+
+ return $this;
+ }
+
+ public function setTranslationDomain($translationDomain)
+ {
+ $this->translationDomain = $translationDomain;
+
+ return $this;
+ }
+
+ public function setInvalidValue($invalidValue)
+ {
+ $this->invalidValue = $invalidValue;
+
+ return $this;
+ }
+
+ public function setPlural($number)
+ {
+ $this->plural = $number;
+
+ return $this;
+ }
+
+ public function setCode($code)
+ {
+ $this->code = $code;
+
+ return $this;
+ }
+
+ public function setCause($cause)
+ {
+ $this->cause = $cause;
+
+ return $this;
+ }
+
+ public function buildNextViolation($message)
+ {
+ $assertions = $this->assertions;
+ $assertions[] = $this;
+
+ return new self($this->context, $message, $this->constraint, $assertions);
+ }
+
+ public function assertRaised()
+ {
+ $expected = array();
+ foreach ($this->assertions as $assertion) {
+ $expected[] = $assertion->getViolation();
+ }
+ $expected[] = $this->getViolation();
+
+ $violations = iterator_to_array($this->context->getViolations());
+
+ \PHPUnit_Framework_Assert::assertCount(count($expected), $violations);
+
+ reset($violations);
+
+ foreach ($expected as $violation) {
+ \PHPUnit_Framework_Assert::assertEquals($violation, current($violations));
+ next($violations);
+ }
+ }
+
+ private function getViolation()
+ {
+ return new ConstraintViolation(
+ null,
+ $this->message,
+ $this->parameters,
+ $this->context->getRoot(),
+ $this->propertyPath,
+ $this->invalidValue,
+ $this->plural,
+ $this->code,
+ $this->constraint,
+ $this->cause
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllTest.php
new file mode 100644
index 0000000..36b5198
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllTest.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\All;
+use Symfony\Component\Validator\Constraints\Valid;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class AllTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testRejectNonConstraints()
+ {
+ new All(array(
+ 'foo',
+ ));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testRejectValidConstraint()
+ {
+ new All(array(
+ new Valid(),
+ ));
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php
new file mode 100644
index 0000000..57dd600
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\All;
+use Symfony\Component\Validator\Constraints\AllValidator;
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\Constraints\Range;
+use Symfony\Component\Validator\Validation;
+
+class AllValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new AllValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new All(new Range(array('min' => 4))));
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testThrowsExceptionIfNotTraversable()
+ {
+ $this->validator->validate('foo.barbar', new All(new Range(array('min' => 4))));
+ }
+
+ /**
+ * @dataProvider getValidArguments
+ */
+ public function testWalkSingleConstraint($array)
+ {
+ $constraint = new Range(array('min' => 4));
+
+ $i = 0;
+
+ foreach ($array as $key => $value) {
+ $this->expectValidateValueAt($i++, '['.$key.']', $value, array($constraint));
+ }
+
+ $this->validator->validate($array, new All($constraint));
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getValidArguments
+ */
+ public function testWalkMultipleConstraints($array)
+ {
+ $constraint1 = new Range(array('min' => 4));
+ $constraint2 = new NotNull();
+
+ $constraints = array($constraint1, $constraint2);
+
+ $i = 0;
+
+ foreach ($array as $key => $value) {
+ $this->expectValidateValueAt($i++, '['.$key.']', $value, array($constraint1, $constraint2));
+ }
+
+ $this->validator->validate($array, new All($constraints));
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidArguments()
+ {
+ return array(
+ array(array(5, 6, 7)),
+ array(new \ArrayObject(array(5, 6, 7))),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.php
new file mode 100644
index 0000000..a7f3d7d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Blank;
+use Symfony\Component\Validator\Constraints\BlankValidator;
+use Symfony\Component\Validator\Validation;
+
+class BlankValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new BlankValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Blank());
+
+ $this->assertNoViolation();
+ }
+
+ public function testBlankIsValid()
+ {
+ $this->validator->validate('', new Blank());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getInvalidValues
+ */
+ public function testInvalidValues($value, $valueAsString)
+ {
+ $constraint = new Blank(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', $valueAsString)
+ ->assertRaised();
+ }
+
+ public function getInvalidValues()
+ {
+ return array(
+ array('foobar', '"foobar"'),
+ array(0, '0'),
+ array(false, 'false'),
+ array(1234, '1234'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php
new file mode 100644
index 0000000..9bb12a2
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php
@@ -0,0 +1,336 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Constraints\Callback;
+use Symfony\Component\Validator\Constraints\CallbackValidator;
+use Symfony\Component\Validator\ExecutionContextInterface;
+use Symfony\Component\Validator\Validation;
+
+class CallbackValidatorTest_Class
+{
+ public static function validateCallback($object, ExecutionContextInterface $context)
+ {
+ $context->addViolation('Callback message', array('{{ value }}' => 'foobar'));
+
+ return false;
+ }
+}
+
+class CallbackValidatorTest_Object
+{
+ public function validate(ExecutionContextInterface $context)
+ {
+ $context->addViolation('My message', array('{{ value }}' => 'foobar'));
+
+ return false;
+ }
+
+ public static function validateStatic($object, ExecutionContextInterface $context)
+ {
+ $context->addViolation('Static message', array('{{ value }}' => 'baz'));
+
+ return false;
+ }
+}
+
+class CallbackValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new CallbackValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Callback(array('foo')));
+
+ $this->assertNoViolation();
+ }
+
+ public function testSingleMethod()
+ {
+ $object = new CallbackValidatorTest_Object();
+ $constraint = new Callback('validate');
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('My message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->assertRaised();
+ }
+
+ public function testSingleMethodExplicitName()
+ {
+ $object = new CallbackValidatorTest_Object();
+ $constraint = new Callback(array('callback' => 'validate'));
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('My message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->assertRaised();
+ }
+
+ public function testSingleStaticMethod()
+ {
+ $object = new CallbackValidatorTest_Object();
+ $constraint = new Callback('validateStatic');
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('Static message')
+ ->setParameter('{{ value }}', 'baz')
+ ->assertRaised();
+ }
+
+ public function testClosure()
+ {
+ $object = new CallbackValidatorTest_Object();
+ $constraint = new Callback(function ($object, ExecutionContextInterface $context) {
+ $context->addViolation('My message', array('{{ value }}' => 'foobar'));
+
+ return false;
+ });
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('My message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->assertRaised();
+ }
+
+ public function testClosureNullObject()
+ {
+ $constraint = new Callback(function ($object, ExecutionContextInterface $context) {
+ $context->addViolation('My message', array('{{ value }}' => 'foobar'));
+
+ return false;
+ });
+
+ $this->validator->validate(null, $constraint);
+
+ $this->buildViolation('My message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->assertRaised();
+ }
+
+ public function testClosureExplicitName()
+ {
+ $object = new CallbackValidatorTest_Object();
+ $constraint = new Callback(array(
+ 'callback' => function ($object, ExecutionContextInterface $context) {
+ $context->addViolation('My message', array('{{ value }}' => 'foobar'));
+
+ return false;
+ },
+ ));
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('My message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->assertRaised();
+ }
+
+ public function testArrayCallable()
+ {
+ $object = new CallbackValidatorTest_Object();
+ $constraint = new Callback(array(__CLASS__.'_Class', 'validateCallback'));
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('Callback message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->assertRaised();
+ }
+
+ public function testArrayCallableNullObject()
+ {
+ $constraint = new Callback(array(__CLASS__.'_Class', 'validateCallback'));
+
+ $this->validator->validate(null, $constraint);
+
+ $this->buildViolation('Callback message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->assertRaised();
+ }
+
+ public function testArrayCallableExplicitName()
+ {
+ $object = new CallbackValidatorTest_Object();
+ $constraint = new Callback(array(
+ 'callback' => array(__CLASS__.'_Class', 'validateCallback'),
+ ));
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('Callback message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->assertRaised();
+ }
+
+ // BC with Symfony < 2.4
+ public function testSingleMethodBc()
+ {
+ $object = new CallbackValidatorTest_Object();
+ $constraint = new Callback(array('validate'));
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('My message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->assertRaised();
+ }
+
+ // BC with Symfony < 2.4
+ public function testSingleMethodBcExplicitName()
+ {
+ $object = new CallbackValidatorTest_Object();
+ $constraint = new Callback(array('methods' => array('validate')));
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('My message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->assertRaised();
+ }
+
+ // BC with Symfony < 2.4
+ public function testMultipleMethodsBc()
+ {
+ $object = new CallbackValidatorTest_Object();
+ $constraint = new Callback(array('validate', 'validateStatic'));
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('My message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->buildNextViolation('Static message')
+ ->setParameter('{{ value }}', 'baz')
+ ->assertRaised();
+ }
+
+ // BC with Symfony < 2.4
+ public function testMultipleMethodsBcExplicitName()
+ {
+ $object = new CallbackValidatorTest_Object();
+ $constraint = new Callback(array(
+ 'methods' => array('validate', 'validateStatic'),
+ ));
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('My message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->buildNextViolation('Static message')
+ ->setParameter('{{ value }}', 'baz')
+ ->assertRaised();
+ }
+
+ // BC with Symfony < 2.4
+ public function testSingleStaticMethodBc()
+ {
+ $object = new CallbackValidatorTest_Object();
+ $constraint = new Callback(array(
+ array(__CLASS__.'_Class', 'validateCallback'),
+ ));
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('Callback message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->assertRaised();
+ }
+
+ // BC with Symfony < 2.4
+ public function testSingleStaticMethodBcExplicitName()
+ {
+ $object = new CallbackValidatorTest_Object();
+ $constraint = new Callback(array(
+ 'methods' => array(array(__CLASS__.'_Class', 'validateCallback')),
+ ));
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('Callback message')
+ ->setParameter('{{ value }}', 'foobar')
+ ->assertRaised();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testExpectValidMethods()
+ {
+ $object = new CallbackValidatorTest_Object();
+
+ $this->validator->validate($object, new Callback(array('foobar')));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testExpectValidCallbacks()
+ {
+ $object = new CallbackValidatorTest_Object();
+
+ $this->validator->validate($object, new Callback(array(array('foo', 'bar'))));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testExpectEitherCallbackOrMethods()
+ {
+ $object = new CallbackValidatorTest_Object();
+
+ $this->validator->validate($object, new Callback(array(
+ 'callback' => 'validate',
+ 'methods' => array('validateStatic'),
+ )));
+ }
+
+ public function testConstraintGetTargets()
+ {
+ $constraint = new Callback(array('foo'));
+ $targets = array(Constraint::CLASS_CONSTRAINT, Constraint::PROPERTY_CONSTRAINT);
+
+ $this->assertEquals($targets, $constraint->getTargets());
+ }
+
+ // Should succeed. Needed when defining constraints as annotations.
+ public function testNoConstructorArguments()
+ {
+ new Callback();
+ }
+
+ public function testAnnotationInvocationSingleValued()
+ {
+ $constraint = new Callback(array('value' => 'validateStatic'));
+
+ $this->assertEquals(new Callback('validateStatic'), $constraint);
+ }
+
+ public function testAnnotationInvocationMultiValued()
+ {
+ $constraint = new Callback(array('value' => array(__CLASS__.'_Class', 'validateCallback')));
+
+ $this->assertEquals(new Callback(array(__CLASS__.'_Class', 'validateCallback')), $constraint);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php
new file mode 100644
index 0000000..aab54e5
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php
@@ -0,0 +1,133 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\CardScheme;
+use Symfony\Component\Validator\Constraints\CardSchemeValidator;
+use Symfony\Component\Validator\Validation;
+
+class CardSchemeValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new CardSchemeValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new CardScheme(array('schemes' => array())));
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new CardScheme(array('schemes' => array())));
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getValidNumbers
+ */
+ public function testValidNumbers($scheme, $number)
+ {
+ $this->validator->validate($number, new CardScheme(array('schemes' => $scheme)));
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getInvalidNumbers
+ */
+ public function testInvalidNumbers($scheme, $number, $code)
+ {
+ $constraint = new CardScheme(array(
+ 'schemes' => $scheme,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($number, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', is_string($number) ? '"'.$number.'"' : $number)
+ ->setCode($code)
+ ->assertRaised();
+ }
+
+ public function getValidNumbers()
+ {
+ return array(
+ array('AMEX', '378282246310005'),
+ array('AMEX', '371449635398431'),
+ array('AMEX', '378734493671000'),
+ array('AMEX', '347298508610146'),
+ array('CHINA_UNIONPAY', '6228888888888888'),
+ array('CHINA_UNIONPAY', '62288888888888888'),
+ array('CHINA_UNIONPAY', '622888888888888888'),
+ array('CHINA_UNIONPAY', '6228888888888888888'),
+ array('DINERS', '30569309025904'),
+ array('DINERS', '36088894118515'),
+ array('DINERS', '38520000023237'),
+ array('DISCOVER', '6011111111111117'),
+ array('DISCOVER', '6011000990139424'),
+ array('INSTAPAYMENT', '6372476031350068'),
+ array('INSTAPAYMENT', '6385537775789749'),
+ array('INSTAPAYMENT', '6393440808445746'),
+ array('JCB', '3530111333300000'),
+ array('JCB', '3566002020360505'),
+ array('JCB', '213112345678901'),
+ array('JCB', '180012345678901'),
+ array('LASER', '6304678107004080'),
+ array('LASER', '6706440607428128629'),
+ array('LASER', '6771656738314582216'),
+ array('MAESTRO', '6759744069209'),
+ array('MAESTRO', '5020507657408074712'),
+ array('MAESTRO', '6759744069209'),
+ array('MAESTRO', '6759744069209'),
+ array('MASTERCARD', '5555555555554444'),
+ array('MASTERCARD', '5105105105105100'),
+ array('VISA', '4111111111111111'),
+ array('VISA', '4012888888881881'),
+ array('VISA', '4222222222222'),
+ array(array('AMEX', 'VISA'), '4111111111111111'),
+ array(array('AMEX', 'VISA'), '378282246310005'),
+ array(array('JCB', 'MASTERCARD'), '5105105105105100'),
+ array(array('VISA', 'MASTERCARD'), '5105105105105100'),
+ );
+ }
+
+ public function getInvalidNumbers()
+ {
+ return array(
+ array('VISA', '42424242424242424242', CardScheme::INVALID_FORMAT_ERROR),
+ array('AMEX', '357298508610146', CardScheme::INVALID_FORMAT_ERROR),
+ array('DINERS', '31569309025904', CardScheme::INVALID_FORMAT_ERROR),
+ array('DINERS', '37088894118515', CardScheme::INVALID_FORMAT_ERROR),
+ array('INSTAPAYMENT', '6313440808445746', CardScheme::INVALID_FORMAT_ERROR),
+ array('CHINA_UNIONPAY', '622888888888888', CardScheme::INVALID_FORMAT_ERROR),
+ array('CHINA_UNIONPAY', '62288888888888888888', CardScheme::INVALID_FORMAT_ERROR),
+ array('AMEX', '30569309025904', CardScheme::INVALID_FORMAT_ERROR), // DINERS number
+ array('AMEX', 'invalid', CardScheme::NOT_NUMERIC_ERROR), // A string
+ array('AMEX', 0, CardScheme::INVALID_FORMAT_ERROR), // a lone number
+ array('AMEX', '0', CardScheme::INVALID_FORMAT_ERROR), // a lone number
+ array('AMEX', '000000000000', CardScheme::INVALID_FORMAT_ERROR), // a lone number
+ array('DINERS', '3056930', CardScheme::INVALID_FORMAT_ERROR), // only first part of the number
+ array('DISCOVER', '1117', CardScheme::INVALID_FORMAT_ERROR), // only last 4 digits
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ChoiceValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ChoiceValidatorTest.php
new file mode 100644
index 0000000..579d6aa
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ChoiceValidatorTest.php
@@ -0,0 +1,287 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Choice;
+use Symfony\Component\Validator\Constraints\ChoiceValidator;
+use Symfony\Component\Validator\Validation;
+
+function choice_callback()
+{
+ return array('foo', 'bar');
+}
+
+class ChoiceValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new ChoiceValidator();
+ }
+
+ public static function staticCallback()
+ {
+ return array('foo', 'bar');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectArrayIfMultipleIsTrue()
+ {
+ $constraint = new Choice(array(
+ 'choices' => array('foo', 'bar'),
+ 'multiple' => true,
+ ));
+
+ $this->validator->validate('asdf', $constraint);
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Choice(array('choices' => array('foo', 'bar'))));
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testChoicesOrCallbackExpected()
+ {
+ $this->validator->validate('foobar', new Choice());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testValidCallbackExpected()
+ {
+ $this->validator->validate('foobar', new Choice(array('callback' => 'abcd')));
+ }
+
+ public function testValidChoiceArray()
+ {
+ $constraint = new Choice(array('choices' => array('foo', 'bar')));
+
+ $this->validator->validate('bar', $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testValidChoiceCallbackFunction()
+ {
+ $constraint = new Choice(array('callback' => __NAMESPACE__.'\choice_callback'));
+
+ $this->validator->validate('bar', $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testValidChoiceCallbackClosure()
+ {
+ $constraint = new Choice(array('callback' => function () {
+ return array('foo', 'bar');
+ }));
+
+ $this->validator->validate('bar', $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testValidChoiceCallbackStaticMethod()
+ {
+ $constraint = new Choice(array('callback' => array(__CLASS__, 'staticCallback')));
+
+ $this->validator->validate('bar', $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testValidChoiceCallbackContextMethod()
+ {
+ // search $this for "staticCallback"
+ $this->setObject($this);
+
+ $constraint = new Choice(array('callback' => 'staticCallback'));
+
+ $this->validator->validate('bar', $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testMultipleChoices()
+ {
+ $constraint = new Choice(array(
+ 'choices' => array('foo', 'bar', 'baz'),
+ 'multiple' => true,
+ ));
+
+ $this->validator->validate(array('baz', 'bar'), $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testInvalidChoice()
+ {
+ $constraint = new Choice(array(
+ 'choices' => array('foo', 'bar'),
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate('baz', $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"baz"')
+ ->setCode(Choice::NO_SUCH_CHOICE_ERROR)
+ ->assertRaised();
+ }
+
+ public function testInvalidChoiceMultiple()
+ {
+ $constraint = new Choice(array(
+ 'choices' => array('foo', 'bar'),
+ 'multipleMessage' => 'myMessage',
+ 'multiple' => true,
+ ));
+
+ $this->validator->validate(array('foo', 'baz'), $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"baz"')
+ ->setInvalidValue('baz')
+ ->setCode(Choice::NO_SUCH_CHOICE_ERROR)
+ ->assertRaised();
+ }
+
+ public function testTooFewChoices()
+ {
+ $constraint = new Choice(array(
+ 'choices' => array('foo', 'bar', 'moo', 'maa'),
+ 'multiple' => true,
+ 'min' => 2,
+ 'minMessage' => 'myMessage',
+ ));
+
+ $value = array('foo');
+
+ $this->setValue($value);
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ limit }}', 2)
+ ->setInvalidValue($value)
+ ->setPlural(2)
+ ->setCode(Choice::TOO_FEW_ERROR)
+ ->assertRaised();
+ }
+
+ public function testTooManyChoices()
+ {
+ $constraint = new Choice(array(
+ 'choices' => array('foo', 'bar', 'moo', 'maa'),
+ 'multiple' => true,
+ 'max' => 2,
+ 'maxMessage' => 'myMessage',
+ ));
+
+ $value = array('foo', 'bar', 'moo');
+
+ $this->setValue($value);
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ limit }}', 2)
+ ->setInvalidValue($value)
+ ->setPlural(2)
+ ->setCode(Choice::TOO_MANY_ERROR)
+ ->assertRaised();
+ }
+
+ public function testNonStrict()
+ {
+ $constraint = new Choice(array(
+ 'choices' => array(1, 2),
+ 'strict' => false,
+ ));
+
+ $this->validator->validate('2', $constraint);
+ $this->validator->validate(2, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testStrictAllowsExactValue()
+ {
+ $constraint = new Choice(array(
+ 'choices' => array(1, 2),
+ 'strict' => true,
+ ));
+
+ $this->validator->validate(2, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testStrictDisallowsDifferentType()
+ {
+ $constraint = new Choice(array(
+ 'choices' => array(1, 2),
+ 'strict' => true,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate('2', $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"2"')
+ ->setCode(Choice::NO_SUCH_CHOICE_ERROR)
+ ->assertRaised();
+ }
+
+ public function testNonStrictWithMultipleChoices()
+ {
+ $constraint = new Choice(array(
+ 'choices' => array(1, 2, 3),
+ 'multiple' => true,
+ 'strict' => false,
+ ));
+
+ $this->validator->validate(array('2', 3), $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testStrictWithMultipleChoices()
+ {
+ $constraint = new Choice(array(
+ 'choices' => array(1, 2, 3),
+ 'multiple' => true,
+ 'strict' => true,
+ 'multipleMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate(array(2, '3'), $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"3"')
+ ->setInvalidValue('3')
+ ->setCode(Choice::NO_SUCH_CHOICE_ERROR)
+ ->assertRaised();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionTest.php
new file mode 100644
index 0000000..79f50b0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionTest.php
@@ -0,0 +1,112 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Collection;
+use Symfony\Component\Validator\Constraints\Email;
+use Symfony\Component\Validator\Constraints\Optional;
+use Symfony\Component\Validator\Constraints\Required;
+use Symfony\Component\Validator\Constraints\Valid;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CollectionTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testRejectInvalidFieldsOption()
+ {
+ new Collection(array(
+ 'fields' => 'foo',
+ ));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testRejectNonConstraints()
+ {
+ new Collection(array(
+ 'foo' => 'bar',
+ ));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testRejectValidConstraint()
+ {
+ new Collection(array(
+ 'foo' => new Valid(),
+ ));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testRejectValidConstraintWithinOptional()
+ {
+ new Collection(array(
+ 'foo' => new Optional(new Valid()),
+ ));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testRejectValidConstraintWithinRequired()
+ {
+ new Collection(array(
+ 'foo' => new Required(new Valid()),
+ ));
+ }
+
+ public function testAcceptOptionalConstraintAsOneElementArray()
+ {
+ $collection1 = new Collection(array(
+ 'fields' => array(
+ 'alternate_email' => array(
+ new Optional(new Email()),
+ ),
+ ),
+ ));
+
+ $collection2 = new Collection(array(
+ 'fields' => array(
+ 'alternate_email' => new Optional(new Email()),
+ ),
+ ));
+
+ $this->assertEquals($collection1, $collection2);
+ }
+
+ public function testAcceptRequiredConstraintAsOneElementArray()
+ {
+ $collection1 = new Collection(array(
+ 'fields' => array(
+ 'alternate_email' => array(
+ new Required(new Email()),
+ ),
+ ),
+ ));
+
+ $collection2 = new Collection(array(
+ 'fields' => array(
+ 'alternate_email' => new Required(new Email()),
+ ),
+ ));
+
+ $this->assertEquals($collection1, $collection2);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayObjectTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayObjectTest.php
new file mode 100644
index 0000000..a3c4b33
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayObjectTest.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+class CollectionValidatorArrayObjectTest extends CollectionValidatorTest
+{
+ public function prepareTestData(array $contents)
+ {
+ return new \ArrayObject($contents);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayTest.php
new file mode 100644
index 0000000..7517d0c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayTest.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+class CollectionValidatorArrayTest extends CollectionValidatorTest
+{
+ public function prepareTestData(array $contents)
+ {
+ return $contents;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorCustomArrayObjectTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorCustomArrayObjectTest.php
new file mode 100644
index 0000000..3d4c296
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorCustomArrayObjectTest.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Tests\Fixtures\CustomArrayObject;
+
+class CollectionValidatorCustomArrayObjectTest extends CollectionValidatorTest
+{
+ public function prepareTestData(array $contents)
+ {
+ return new CustomArrayObject($contents);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php
new file mode 100644
index 0000000..0376814
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php
@@ -0,0 +1,389 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Collection;
+use Symfony\Component\Validator\Constraints\CollectionValidator;
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\Constraints\Optional;
+use Symfony\Component\Validator\Constraints\Range;
+use Symfony\Component\Validator\Constraints\Required;
+use Symfony\Component\Validator\Validation;
+
+abstract class CollectionValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new CollectionValidator();
+ }
+
+ abstract protected function prepareTestData(array $contents);
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Collection(array('fields' => array(
+ 'foo' => new Range(array('min' => 4)),
+ ))));
+
+ $this->assertNoViolation();
+ }
+
+ public function testFieldsAsDefaultOption()
+ {
+ $constraint = new Range(array('min' => 4));
+
+ $data = $this->prepareTestData(array('foo' => 'foobar'));
+
+ $this->expectValidateValueAt(0, '[foo]', $data['foo'], array($constraint));
+
+ $this->validator->validate($data, new Collection(array(
+ 'foo' => $constraint,
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testThrowsExceptionIfNotTraversable()
+ {
+ $this->validator->validate('foobar', new Collection(array('fields' => array(
+ 'foo' => new Range(array('min' => 4)),
+ ))));
+ }
+
+ public function testWalkSingleConstraint()
+ {
+ $constraint = new Range(array('min' => 4));
+
+ $array = array(
+ 'foo' => 3,
+ 'bar' => 5,
+ );
+
+ $i = 0;
+
+ foreach ($array as $key => $value) {
+ $this->expectValidateValueAt($i++, '['.$key.']', $value, array($constraint));
+ }
+
+ $data = $this->prepareTestData($array);
+
+ $this->validator->validate($data, new Collection(array(
+ 'fields' => array(
+ 'foo' => $constraint,
+ 'bar' => $constraint,
+ ),
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function testWalkMultipleConstraints()
+ {
+ $constraints = array(
+ new Range(array('min' => 4)),
+ new NotNull(),
+ );
+
+ $array = array(
+ 'foo' => 3,
+ 'bar' => 5,
+ );
+
+ $i = 0;
+
+ foreach ($array as $key => $value) {
+ $this->expectValidateValueAt($i++, '['.$key.']', $value, $constraints);
+ }
+
+ $data = $this->prepareTestData($array);
+
+ $this->validator->validate($data, new Collection(array(
+ 'fields' => array(
+ 'foo' => $constraints,
+ 'bar' => $constraints,
+ ),
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function testExtraFieldsDisallowed()
+ {
+ $constraint = new Range(array('min' => 4));
+
+ $data = $this->prepareTestData(array(
+ 'foo' => 5,
+ 'baz' => 6,
+ ));
+
+ $this->expectValidateValueAt(0, '[foo]', $data['foo'], array($constraint));
+
+ $this->validator->validate($data, new Collection(array(
+ 'fields' => array(
+ 'foo' => $constraint,
+ ),
+ 'extraFieldsMessage' => 'myMessage',
+ )));
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ field }}', '"baz"')
+ ->atPath('property.path[baz]')
+ ->setInvalidValue(6)
+ ->setCode(Collection::NO_SUCH_FIELD_ERROR)
+ ->assertRaised();
+ }
+
+ // bug fix
+ public function testNullNotConsideredExtraField()
+ {
+ $data = $this->prepareTestData(array(
+ 'foo' => null,
+ ));
+
+ $constraint = new Range(array('min' => 4));
+
+ $this->expectValidateValueAt(0, '[foo]', $data['foo'], array($constraint));
+
+ $this->validator->validate($data, new Collection(array(
+ 'fields' => array(
+ 'foo' => $constraint,
+ ),
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function testExtraFieldsAllowed()
+ {
+ $data = $this->prepareTestData(array(
+ 'foo' => 5,
+ 'bar' => 6,
+ ));
+
+ $constraint = new Range(array('min' => 4));
+
+ $this->expectValidateValueAt(0, '[foo]', $data['foo'], array($constraint));
+
+ $this->validator->validate($data, new Collection(array(
+ 'fields' => array(
+ 'foo' => $constraint,
+ ),
+ 'allowExtraFields' => true,
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function testMissingFieldsDisallowed()
+ {
+ $data = $this->prepareTestData(array());
+
+ $constraint = new Range(array('min' => 4));
+
+ $this->validator->validate($data, new Collection(array(
+ 'fields' => array(
+ 'foo' => $constraint,
+ ),
+ 'missingFieldsMessage' => 'myMessage',
+ )));
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ field }}', '"foo"')
+ ->atPath('property.path[foo]')
+ ->setInvalidValue(null)
+ ->setCode(Collection::MISSING_FIELD_ERROR)
+ ->assertRaised();
+ }
+
+ public function testMissingFieldsAllowed()
+ {
+ $data = $this->prepareTestData(array());
+
+ $constraint = new Range(array('min' => 4));
+
+ $this->validator->validate($data, new Collection(array(
+ 'fields' => array(
+ 'foo' => $constraint,
+ ),
+ 'allowMissingFields' => true,
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function testOptionalFieldPresent()
+ {
+ $data = $this->prepareTestData(array(
+ 'foo' => null,
+ ));
+
+ $this->validator->validate($data, new Collection(array(
+ 'foo' => new Optional(),
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function testOptionalFieldNotPresent()
+ {
+ $data = $this->prepareTestData(array());
+
+ $this->validator->validate($data, new Collection(array(
+ 'foo' => new Optional(),
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function testOptionalFieldSingleConstraint()
+ {
+ $array = array(
+ 'foo' => 5,
+ );
+
+ $constraint = new Range(array('min' => 4));
+
+ $this->expectValidateValueAt(0, '[foo]', $array['foo'], array($constraint));
+
+ $data = $this->prepareTestData($array);
+
+ $this->validator->validate($data, new Collection(array(
+ 'foo' => new Optional($constraint),
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function testOptionalFieldMultipleConstraints()
+ {
+ $array = array(
+ 'foo' => 5,
+ );
+
+ $constraints = array(
+ new NotNull(),
+ new Range(array('min' => 4)),
+ );
+
+ $this->expectValidateValueAt(0, '[foo]', $array['foo'], $constraints);
+
+ $data = $this->prepareTestData($array);
+
+ $this->validator->validate($data, new Collection(array(
+ 'foo' => new Optional($constraints),
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function testRequiredFieldPresent()
+ {
+ $data = $this->prepareTestData(array(
+ 'foo' => null,
+ ));
+
+ $this->validator->validate($data, new Collection(array(
+ 'foo' => new Required(),
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function testRequiredFieldNotPresent()
+ {
+ $data = $this->prepareTestData(array());
+
+ $this->validator->validate($data, new Collection(array(
+ 'fields' => array(
+ 'foo' => new Required(),
+ ),
+ 'missingFieldsMessage' => 'myMessage',
+ )));
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ field }}', '"foo"')
+ ->atPath('property.path[foo]')
+ ->setInvalidValue(null)
+ ->setCode(Collection::MISSING_FIELD_ERROR)
+ ->assertRaised();
+ }
+
+ public function testRequiredFieldSingleConstraint()
+ {
+ $array = array(
+ 'foo' => 5,
+ );
+
+ $constraint = new Range(array('min' => 4));
+
+ $this->expectValidateValueAt(0, '[foo]', $array['foo'], array($constraint));
+
+ $data = $this->prepareTestData($array);
+
+ $this->validator->validate($data, new Collection(array(
+ 'foo' => new Required($constraint),
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function testRequiredFieldMultipleConstraints()
+ {
+ $array = array(
+ 'foo' => 5,
+ );
+
+ $constraints = array(
+ new NotNull(),
+ new Range(array('min' => 4)),
+ );
+
+ $this->expectValidateValueAt(0, '[foo]', $array['foo'], $constraints);
+
+ $data = $this->prepareTestData($array);
+
+ $this->validator->validate($data, new Collection(array(
+ 'foo' => new Required($constraints),
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function testObjectShouldBeLeftUnchanged()
+ {
+ $value = new \ArrayObject(array(
+ 'foo' => 3,
+ ));
+
+ $constraint = new Range(array('min' => 2));
+
+ $this->expectValidateValueAt(0, '[foo]', $value['foo'], array($constraint));
+
+ $this->validator->validate($value, new Collection(array(
+ 'fields' => array(
+ 'foo' => $constraint,
+ ),
+ )));
+
+ $this->assertEquals(array(
+ 'foo' => 3,
+ ), (array) $value);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CompositeTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CompositeTest.php
new file mode 100644
index 0000000..21cb461
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CompositeTest.php
@@ -0,0 +1,137 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Composite;
+use Symfony\Component\Validator\Constraints\NotBlank;
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\Constraints\Valid;
+
+class ConcreteComposite extends Composite
+{
+ public $constraints;
+
+ protected function getCompositeOption()
+ {
+ return 'constraints';
+ }
+
+ public function getDefaultOption()
+ {
+ return 'constraints';
+ }
+}
+
+/**
+ * @since 2.6
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CompositeTest extends \PHPUnit_Framework_TestCase
+{
+ public function testMergeNestedGroupsIfNoExplicitParentGroup()
+ {
+ $constraint = new ConcreteComposite(array(
+ new NotNull(array('groups' => 'Default')),
+ new NotBlank(array('groups' => array('Default', 'Strict'))),
+ ));
+
+ $this->assertEquals(array('Default', 'Strict'), $constraint->groups);
+ $this->assertEquals(array('Default'), $constraint->constraints[0]->groups);
+ $this->assertEquals(array('Default', 'Strict'), $constraint->constraints[1]->groups);
+ }
+
+ public function testSetImplicitNestedGroupsIfExplicitParentGroup()
+ {
+ $constraint = new ConcreteComposite(array(
+ 'constraints' => array(
+ new NotNull(),
+ new NotBlank(),
+ ),
+ 'groups' => array('Default', 'Strict'),
+ ));
+
+ $this->assertEquals(array('Default', 'Strict'), $constraint->groups);
+ $this->assertEquals(array('Default', 'Strict'), $constraint->constraints[0]->groups);
+ $this->assertEquals(array('Default', 'Strict'), $constraint->constraints[1]->groups);
+ }
+
+ public function testExplicitNestedGroupsMustBeSubsetOfExplicitParentGroups()
+ {
+ $constraint = new ConcreteComposite(array(
+ 'constraints' => array(
+ new NotNull(array('groups' => 'Default')),
+ new NotBlank(array('groups' => 'Strict')),
+ ),
+ 'groups' => array('Default', 'Strict'),
+ ));
+
+ $this->assertEquals(array('Default', 'Strict'), $constraint->groups);
+ $this->assertEquals(array('Default'), $constraint->constraints[0]->groups);
+ $this->assertEquals(array('Strict'), $constraint->constraints[1]->groups);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testFailIfExplicitNestedGroupsNotSubsetOfExplicitParentGroups()
+ {
+ new ConcreteComposite(array(
+ 'constraints' => array(
+ new NotNull(array('groups' => array('Default', 'Foobar'))),
+ ),
+ 'groups' => array('Default', 'Strict'),
+ ));
+ }
+
+ public function testImplicitGroupNamesAreForwarded()
+ {
+ $constraint = new ConcreteComposite(array(
+ new NotNull(array('groups' => 'Default')),
+ new NotBlank(array('groups' => 'Strict')),
+ ));
+
+ $constraint->addImplicitGroupName('ImplicitGroup');
+
+ $this->assertEquals(array('Default', 'Strict', 'ImplicitGroup'), $constraint->groups);
+ $this->assertEquals(array('Default', 'ImplicitGroup'), $constraint->constraints[0]->groups);
+ $this->assertEquals(array('Strict'), $constraint->constraints[1]->groups);
+ }
+
+ public function testSingleConstraintsAccepted()
+ {
+ $nestedConstraint = new NotNull();
+ $constraint = new ConcreteComposite($nestedConstraint);
+
+ $this->assertEquals(array($nestedConstraint), $constraint->constraints);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testFailIfNoConstraint()
+ {
+ new ConcreteComposite(array(
+ new NotNull(array('groups' => 'Default')),
+ 'NotBlank',
+ ));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testValidCantBeNested()
+ {
+ new ConcreteComposite(array(
+ new Valid(),
+ ));
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorArrayTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorArrayTest.php
new file mode 100644
index 0000000..5f562e7
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorArrayTest.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CountValidatorArrayTest extends CountValidatorTest
+{
+ protected function createCollection(array $content)
+ {
+ return $content;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorCountableTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorCountableTest.php
new file mode 100644
index 0000000..7d46967
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorCountableTest.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Tests\Fixtures\Countable;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CountValidatorCountableTest extends CountValidatorTest
+{
+ protected function createCollection(array $content)
+ {
+ return new Countable($content);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorTest.php
new file mode 100644
index 0000000..6713166
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorTest.php
@@ -0,0 +1,203 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Count;
+use Symfony\Component\Validator\Constraints\CountValidator;
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+abstract class CountValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new CountValidator();
+ }
+
+ abstract protected function createCollection(array $content);
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Count(6));
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsCountableType()
+ {
+ $this->validator->validate(new \stdClass(), new Count(5));
+ }
+
+ public function getThreeOrLessElements()
+ {
+ return array(
+ array($this->createCollection(array(1))),
+ array($this->createCollection(array(1, 2))),
+ array($this->createCollection(array(1, 2, 3))),
+ array($this->createCollection(array('a' => 1, 'b' => 2, 'c' => 3))),
+ );
+ }
+
+ public function getFourElements()
+ {
+ return array(
+ array($this->createCollection(array(1, 2, 3, 4))),
+ array($this->createCollection(array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4))),
+ );
+ }
+
+ public function getFiveOrMoreElements()
+ {
+ return array(
+ array($this->createCollection(array(1, 2, 3, 4, 5))),
+ array($this->createCollection(array(1, 2, 3, 4, 5, 6))),
+ array($this->createCollection(array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5))),
+ );
+ }
+
+ /**
+ * @dataProvider getThreeOrLessElements
+ */
+ public function testValidValuesMax($value)
+ {
+ $constraint = new Count(array('max' => 3));
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getFiveOrMoreElements
+ */
+ public function testValidValuesMin($value)
+ {
+ $constraint = new Count(array('min' => 5));
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getFourElements
+ */
+ public function testValidValuesExact($value)
+ {
+ $constraint = new Count(4);
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getFiveOrMoreElements
+ */
+ public function testTooManyValues($value)
+ {
+ $constraint = new Count(array(
+ 'max' => 4,
+ 'maxMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ count }}', count($value))
+ ->setParameter('{{ limit }}', 4)
+ ->setInvalidValue($value)
+ ->setPlural(4)
+ ->setCode(Count::TOO_MANY_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getThreeOrLessElements
+ */
+ public function testTooFewValues($value)
+ {
+ $constraint = new Count(array(
+ 'min' => 4,
+ 'minMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ count }}', count($value))
+ ->setParameter('{{ limit }}', 4)
+ ->setInvalidValue($value)
+ ->setPlural(4)
+ ->setCode(Count::TOO_FEW_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getFiveOrMoreElements
+ */
+ public function testTooManyValuesExact($value)
+ {
+ $constraint = new Count(array(
+ 'min' => 4,
+ 'max' => 4,
+ 'exactMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ count }}', count($value))
+ ->setParameter('{{ limit }}', 4)
+ ->setInvalidValue($value)
+ ->setPlural(4)
+ ->setCode(Count::TOO_MANY_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getThreeOrLessElements
+ */
+ public function testTooFewValuesExact($value)
+ {
+ $constraint = new Count(array(
+ 'min' => 4,
+ 'max' => 4,
+ 'exactMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ count }}', count($value))
+ ->setParameter('{{ limit }}', 4)
+ ->setInvalidValue($value)
+ ->setPlural(4)
+ ->setCode(Count::TOO_FEW_ERROR)
+ ->assertRaised();
+ }
+
+ public function testDefaultOption()
+ {
+ $constraint = new Count(5);
+
+ $this->assertEquals(5, $constraint->min);
+ $this->assertEquals(5, $constraint->max);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php
new file mode 100644
index 0000000..b133511
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php
@@ -0,0 +1,116 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Intl\Util\IntlTestHelper;
+use Symfony\Component\Validator\Constraints\Country;
+use Symfony\Component\Validator\Constraints\CountryValidator;
+use Symfony\Component\Validator\Validation;
+
+class CountryValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function setUp()
+ {
+ IntlTestHelper::requireFullIntl($this);
+
+ parent::setUp();
+ }
+
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new CountryValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Country());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Country());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $this->validator->validate(new \stdClass(), new Country());
+ }
+
+ /**
+ * @dataProvider getValidCountries
+ */
+ public function testValidCountries($country)
+ {
+ $this->validator->validate($country, new Country());
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidCountries()
+ {
+ return array(
+ array('GB'),
+ array('AT'),
+ array('MY'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidCountries
+ */
+ public function testInvalidCountries($country)
+ {
+ $constraint = new Country(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($country, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$country.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidCountries()
+ {
+ return array(
+ array('foobar'),
+ array('EN'),
+ );
+ }
+
+ public function testValidateUsingCountrySpecificLocale()
+ {
+ // in order to test with "en_GB"
+ IntlTestHelper::requireFullIntl($this);
+
+ \Locale::setDefault('en_GB');
+
+ $existingCountry = 'GB';
+
+ $this->validator->validate($existingCountry, new Country());
+
+ $this->assertNoViolation();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php
new file mode 100644
index 0000000..e5bb060
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php
@@ -0,0 +1,116 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Intl\Util\IntlTestHelper;
+use Symfony\Component\Validator\Constraints\Currency;
+use Symfony\Component\Validator\Constraints\CurrencyValidator;
+use Symfony\Component\Validator\Validation;
+
+class CurrencyValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function setUp()
+ {
+ IntlTestHelper::requireFullIntl($this);
+
+ parent::setUp();
+ }
+
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new CurrencyValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Currency());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Currency());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $this->validator->validate(new \stdClass(), new Currency());
+ }
+
+ /**
+ * @dataProvider getValidCurrencies
+ */
+ public function testValidCurrencies($currency)
+ {
+ $this->validator->validate($currency, new Currency());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getValidCurrencies
+ **/
+ public function testValidCurrenciesWithCountrySpecificLocale($currency)
+ {
+ \Locale::setDefault('en_GB');
+
+ $this->validator->validate($currency, new Currency());
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidCurrencies()
+ {
+ return array(
+ array('EUR'),
+ array('USD'),
+ array('SIT'),
+ array('AUD'),
+ array('CAD'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidCurrencies
+ */
+ public function testInvalidCurrencies($currency)
+ {
+ $constraint = new Currency(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($currency, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$currency.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidCurrencies()
+ {
+ return array(
+ array('EN'),
+ array('foobar'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php
new file mode 100644
index 0000000..25d88aa
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php
@@ -0,0 +1,110 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\DateTime;
+use Symfony\Component\Validator\Constraints\DateTimeValidator;
+use Symfony\Component\Validator\Validation;
+
+class DateTimeValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new DateTimeValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new DateTime());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new DateTime());
+
+ $this->assertNoViolation();
+ }
+
+ public function testDateTimeClassIsValid()
+ {
+ $this->validator->validate(new \DateTime(), new DateTime());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $this->validator->validate(new \stdClass(), new DateTime());
+ }
+
+ /**
+ * @dataProvider getValidDateTimes
+ */
+ public function testValidDateTimes($dateTime)
+ {
+ $this->validator->validate($dateTime, new DateTime());
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidDateTimes()
+ {
+ return array(
+ array('2010-01-01 01:02:03'),
+ array('1955-12-12 00:00:00'),
+ array('2030-05-31 23:59:59'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidDateTimes
+ */
+ public function testInvalidDateTimes($dateTime, $code)
+ {
+ $constraint = new DateTime(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($dateTime, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$dateTime.'"')
+ ->setCode($code)
+ ->assertRaised();
+ }
+
+ public function getInvalidDateTimes()
+ {
+ return array(
+ array('foobar', DateTime::INVALID_FORMAT_ERROR),
+ array('2010-01-01', DateTime::INVALID_FORMAT_ERROR),
+ array('00:00:00', DateTime::INVALID_FORMAT_ERROR),
+ array('2010-01-01 00:00', DateTime::INVALID_FORMAT_ERROR),
+ array('2010-13-01 00:00:00', DateTime::INVALID_DATE_ERROR),
+ array('2010-04-32 00:00:00', DateTime::INVALID_DATE_ERROR),
+ array('2010-02-29 00:00:00', DateTime::INVALID_DATE_ERROR),
+ array('2010-01-01 24:00:00', DateTime::INVALID_TIME_ERROR),
+ array('2010-01-01 00:60:00', DateTime::INVALID_TIME_ERROR),
+ array('2010-01-01 00:00:60', DateTime::INVALID_TIME_ERROR),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php
new file mode 100644
index 0000000..21f0a2d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php
@@ -0,0 +1,106 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Date;
+use Symfony\Component\Validator\Constraints\DateValidator;
+use Symfony\Component\Validator\Validation;
+
+class DateValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new DateValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Date());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Date());
+
+ $this->assertNoViolation();
+ }
+
+ public function testDateTimeClassIsValid()
+ {
+ $this->validator->validate(new \DateTime(), new Date());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $this->validator->validate(new \stdClass(), new Date());
+ }
+
+ /**
+ * @dataProvider getValidDates
+ */
+ public function testValidDates($date)
+ {
+ $this->validator->validate($date, new Date());
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidDates()
+ {
+ return array(
+ array('2010-01-01'),
+ array('1955-12-12'),
+ array('2030-05-31'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidDates
+ */
+ public function testInvalidDates($date, $code)
+ {
+ $constraint = new Date(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($date, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$date.'"')
+ ->setCode($code)
+ ->assertRaised();
+ }
+
+ public function getInvalidDates()
+ {
+ return array(
+ array('foobar', Date::INVALID_FORMAT_ERROR),
+ array('foobar 2010-13-01', Date::INVALID_FORMAT_ERROR),
+ array('2010-13-01 foobar', Date::INVALID_FORMAT_ERROR),
+ array('2010-13-01', Date::INVALID_DATE_ERROR),
+ array('2010-04-32', Date::INVALID_DATE_ERROR),
+ array('2010-02-29', Date::INVALID_DATE_ERROR),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php
new file mode 100644
index 0000000..0361333
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Email;
+use Symfony\Component\Validator\Constraints\EmailValidator;
+use Symfony\Component\Validator\Validation;
+
+class EmailValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new EmailValidator(false);
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Email());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Email());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $this->validator->validate(new \stdClass(), new Email());
+ }
+
+ /**
+ * @dataProvider getValidEmails
+ */
+ public function testValidEmails($email)
+ {
+ $this->validator->validate($email, new Email());
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidEmails()
+ {
+ return array(
+ array('fabien@symfony.com'),
+ array('example@example.co.uk'),
+ array('fabien_potencier@example.fr'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidEmails
+ */
+ public function testInvalidEmails($email)
+ {
+ $constraint = new Email(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($email, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$email.'"')
+ ->setCode(Email::INVALID_FORMAT_ERROR)
+ ->assertRaised();
+ }
+
+ public function getInvalidEmails()
+ {
+ return array(
+ array('example'),
+ array('example@'),
+ array('example@localhost'),
+ );
+ }
+
+ public function testStrict()
+ {
+ $constraint = new Email(array('strict' => true));
+
+ $this->validator->validate('example@localhost', $constraint);
+
+ $this->assertNoViolation();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php
new file mode 100644
index 0000000..c20db15
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\EqualTo;
+use Symfony\Component\Validator\Constraints\EqualToValidator;
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class EqualToValidatorTest extends AbstractComparisonValidatorTestCase
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new EqualToValidator();
+ }
+
+ protected function createConstraint(array $options)
+ {
+ return new EqualTo($options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideValidComparisons()
+ {
+ return array(
+ array(3, 3),
+ array(3, '3'),
+ array('a', 'a'),
+ array(new \DateTime('2000-01-01'), new \DateTime('2000-01-01')),
+ array(new \DateTime('2000-01-01'), '2000-01-01'),
+ array(new \DateTime('2000-01-01 UTC'), '2000-01-01 UTC'),
+ array(new ComparisonTest_Class(5), new ComparisonTest_Class(5)),
+ array(null, 1),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideInvalidComparisons()
+ {
+ return array(
+ array(1, '1', 2, '2', 'integer'),
+ array('22', '"22"', '333', '"333"', 'string'),
+ array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', '2000-01-01', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2001-01-01 UTC'), 'Jan 1, 2001, 12:00 AM', '2000-01-01 UTC', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php
new file mode 100644
index 0000000..3d4ef75
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php
@@ -0,0 +1,214 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\PropertyAccess\PropertyAccess;
+use Symfony\Component\Validator\Constraints\Expression;
+use Symfony\Component\Validator\Constraints\ExpressionValidator;
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+use Symfony\Component\Validator\Validation;
+
+class ExpressionValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new ExpressionValidator(PropertyAccess::createPropertyAccessor());
+ }
+
+ public function testExpressionIsEvaluatedWithNullValue()
+ {
+ $constraint = new Expression(array(
+ 'expression' => 'false',
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate(null, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', 'null')
+ ->assertRaised();
+ }
+
+ public function testExpressionIsEvaluatedWithEmptyStringValue()
+ {
+ $constraint = new Expression(array(
+ 'expression' => 'false',
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate('', $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '""')
+ ->assertRaised();
+ }
+
+ public function testSucceedingExpressionAtObjectLevel()
+ {
+ $constraint = new Expression('this.data == 1');
+
+ $object = new Entity();
+ $object->data = '1';
+
+ $this->setObject($object);
+
+ $this->validator->validate($object, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testFailingExpressionAtObjectLevel()
+ {
+ $constraint = new Expression(array(
+ 'expression' => 'this.data == 1',
+ 'message' => 'myMessage',
+ ));
+
+ $object = new Entity();
+ $object->data = '2';
+
+ $this->setObject($object);
+
+ $this->validator->validate($object, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', 'object')
+ ->assertRaised();
+ }
+
+ public function testSucceedingExpressionAtPropertyLevel()
+ {
+ $constraint = new Expression('value == this.data');
+
+ $object = new Entity();
+ $object->data = '1';
+
+ $this->setRoot($object);
+ $this->setPropertyPath('data');
+ $this->setProperty($object, 'data');
+
+ $this->validator->validate('1', $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testFailingExpressionAtPropertyLevel()
+ {
+ $constraint = new Expression(array(
+ 'expression' => 'value == this.data',
+ 'message' => 'myMessage',
+ ));
+
+ $object = new Entity();
+ $object->data = '1';
+
+ $this->setRoot($object);
+ $this->setPropertyPath('data');
+ $this->setProperty($object, 'data');
+
+ $this->validator->validate('2', $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"2"')
+ ->atPath('data')
+ ->assertRaised();
+ }
+
+ public function testSucceedingExpressionAtNestedPropertyLevel()
+ {
+ $constraint = new Expression('value == this.data');
+
+ $object = new Entity();
+ $object->data = '1';
+
+ $root = new Entity();
+ $root->reference = $object;
+
+ $this->setRoot($root);
+ $this->setPropertyPath('reference.data');
+ $this->setProperty($object, 'data');
+
+ $this->validator->validate('1', $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testFailingExpressionAtNestedPropertyLevel()
+ {
+ $constraint = new Expression(array(
+ 'expression' => 'value == this.data',
+ 'message' => 'myMessage',
+ ));
+
+ $object = new Entity();
+ $object->data = '1';
+
+ $root = new Entity();
+ $root->reference = $object;
+
+ $this->setRoot($root);
+ $this->setPropertyPath('reference.data');
+ $this->setProperty($object, 'data');
+
+ $this->validator->validate('2', $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"2"')
+ ->atPath('reference.data')
+ ->assertRaised();
+ }
+
+ /**
+ * When validatePropertyValue() is called with a class name
+ * https://github.com/symfony/symfony/pull/11498
+ */
+ public function testSucceedingExpressionAtPropertyLevelWithoutRoot()
+ {
+ $constraint = new Expression('value == "1"');
+
+ $this->setRoot('1');
+ $this->setPropertyPath('');
+ $this->setProperty(null, 'property');
+
+ $this->validator->validate('1', $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * When validatePropertyValue() is called with a class name
+ * https://github.com/symfony/symfony/pull/11498
+ */
+ public function testFailingExpressionAtPropertyLevelWithoutRoot()
+ {
+ $constraint = new Expression(array(
+ 'expression' => 'value == "1"',
+ 'message' => 'myMessage',
+ ));
+
+ $this->setRoot('2');
+ $this->setPropertyPath('');
+ $this->setProperty(null, 'property');
+
+ $this->validator->validate('2', $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"2"')
+ ->atPath('')
+ ->assertRaised();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FalseValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FalseValidatorTest.php
new file mode 100644
index 0000000..479888e
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FalseValidatorTest.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\False;
+use Symfony\Component\Validator\Constraints\FalseValidator;
+use Symfony\Component\Validator\Validation;
+
+class FalseValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new FalseValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new False());
+
+ $this->assertNoViolation();
+ }
+
+ public function testFalseIsValid()
+ {
+ $this->validator->validate(false, new False());
+
+ $this->assertNoViolation();
+ }
+
+ public function testTrueIsInvalid()
+ {
+ $constraint = new False(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate(true, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', 'true')
+ ->assertRaised();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileTest.php
new file mode 100644
index 0000000..2ee4681
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileTest.php
@@ -0,0 +1,107 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\File;
+
+class FileTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @param mixed $maxSize
+ * @param int bytes
+ * @param bool $bytes
+ * @dataProvider provideValidSizes
+ */
+ public function testMaxSize($maxSize, $bytes, $binaryFormat)
+ {
+ $file = new File(array('maxSize' => $maxSize));
+
+ $this->assertSame($bytes, $file->maxSize);
+ $this->assertSame($binaryFormat, $file->binaryFormat);
+ }
+
+ /**
+ * @param mixed $maxSize
+ * @param int $bytes
+ * @dataProvider provideInValidSizes
+ * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testInvalideMaxSize($maxSize)
+ {
+ $file = new File(array('maxSize' => $maxSize));
+ }
+
+ /**
+ * @return array
+ */
+ public function provideValidSizes()
+ {
+ return array(
+ array('500', 500, false),
+ array(12300, 12300, false),
+ array('1ki', 1024, true),
+ array('1KI', 1024, true),
+ array('2k', 2000, false),
+ array('2K', 2000, false),
+ array('1mi', 1048576, true),
+ array('1MI', 1048576, true),
+ array('3m', 3000000, false),
+ array('3M', 3000000, false),
+ );
+ }
+
+ /**
+ * @return array
+ */
+ public function provideInvalidSizes()
+ {
+ return array(
+ array('+100'),
+ array('foo'),
+ array('1Ko'),
+ array('1kio'),
+ array('1G'),
+ array('1Gi'),
+ );
+ }
+
+ /**
+ * @param mixed $maxSize
+ * @param bool $guessedFormat
+ * @param bool $binaryFormat
+ * @dataProvider provideFormats
+ */
+ public function testBinaryFormat($maxSize, $guessedFormat, $binaryFormat)
+ {
+ $file = new File(array('maxSize' => $maxSize, 'binaryFormat' => $guessedFormat));
+
+ $this->assertSame($binaryFormat, $file->binaryFormat);
+ }
+
+ /**
+ * @return array
+ */
+ public function provideFormats()
+ {
+ return array(
+ array(100, null, false),
+ array(100, true, true),
+ array(100, false, false),
+ array('100K', null, false),
+ array('100K', true, true),
+ array('100K', false, false),
+ array('100Ki', null, true),
+ array('100Ki', true, true),
+ array('100Ki', false, false),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorObjectTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorObjectTest.php
new file mode 100644
index 0000000..f35f93b
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorObjectTest.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\HttpFoundation\File\File;
+
+class FileValidatorObjectTest extends FileValidatorTest
+{
+ protected function getFile($filename)
+ {
+ return new File($filename);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorPathTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorPathTest.php
new file mode 100644
index 0000000..11b8d4c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorPathTest.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\File;
+
+class FileValidatorPathTest extends FileValidatorTest
+{
+ protected function getFile($filename)
+ {
+ return $filename;
+ }
+
+ public function testFileNotFound()
+ {
+ $constraint = new File(array(
+ 'notFoundMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate('foobar', $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ file }}', '"foobar"')
+ ->setCode(File::NOT_FOUND_ERROR)
+ ->assertRaised();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php
new file mode 100644
index 0000000..176b49f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php
@@ -0,0 +1,477 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\HttpFoundation\File\UploadedFile;
+use Symfony\Component\Validator\Constraints\File;
+use Symfony\Component\Validator\Constraints\FileValidator;
+use Symfony\Component\Validator\Validation;
+
+abstract class FileValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected $path;
+
+ protected $file;
+
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new FileValidator();
+ }
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->path = sys_get_temp_dir().DIRECTORY_SEPARATOR.'FileValidatorTest';
+ $this->file = fopen($this->path, 'w');
+ fwrite($this->file, ' ', 1);
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+
+ if (is_resource($this->file)) {
+ fclose($this->file);
+ }
+
+ if (file_exists($this->path)) {
+ unlink($this->path);
+ }
+
+ $this->path = null;
+ $this->file = null;
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new File());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new File());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleTypeOrFile()
+ {
+ $this->validator->validate(new \stdClass(), new File());
+ }
+
+ public function testValidFile()
+ {
+ $this->validator->validate($this->path, new File());
+
+ $this->assertNoViolation();
+ }
+
+ public function testValidUploadedfile()
+ {
+ $file = new UploadedFile($this->path, 'originalName', null, null, null, true);
+ $this->validator->validate($file, new File());
+
+ $this->assertNoViolation();
+ }
+
+ public function provideMaxSizeExceededTests()
+ {
+ // We have various interesting limit - size combinations to test.
+ // Assume a limit of 1000 bytes (1 kB). Then the following table
+ // lists the violation messages for different file sizes:
+ // -----------+--------------------------------------------------------
+ // Size | Violation Message
+ // -----------+--------------------------------------------------------
+ // 1000 bytes | No violation
+ // 1001 bytes | "Size of 1001 bytes exceeded limit of 1000 bytes"
+ // 1004 bytes | "Size of 1004 bytes exceeded limit of 1000 bytes"
+ // | NOT: "Size of 1 kB exceeded limit of 1 kB"
+ // 1005 bytes | "Size of 1.01 kB exceeded limit of 1 kB"
+ // -----------+--------------------------------------------------------
+
+ // As you see, we have two interesting borders:
+
+ // 1000/1001 - The border as of which a violation occurs
+ // 1004/1005 - The border as of which the message can be rounded to kB
+
+ // Analogous for kB/MB.
+
+ // Prior to Symfony 2.5, violation messages are always displayed in the
+ // same unit used to specify the limit.
+
+ // As of Symfony 2.5, the above logic is implemented.
+ return array(
+ // limit in bytes
+ array(1001, 1000, '1001', '1000', 'bytes'),
+ array(1004, 1000, '1004', '1000', 'bytes'),
+ array(1005, 1000, '1.01', '1', 'kB'),
+
+ array(1000001, 1000000, '1000001', '1000000', 'bytes'),
+ array(1004999, 1000000, '1005', '1000', 'kB'),
+ array(1005000, 1000000, '1.01', '1', 'MB'),
+
+ // limit in kB
+ array(1001, '1k', '1001', '1000', 'bytes'),
+ array(1004, '1k', '1004', '1000', 'bytes'),
+ array(1005, '1k', '1.01', '1', 'kB'),
+
+ array(1000001, '1000k', '1000001', '1000000', 'bytes'),
+ array(1004999, '1000k', '1005', '1000', 'kB'),
+ array(1005000, '1000k', '1.01', '1', 'MB'),
+
+ // limit in MB
+ array(1000001, '1M', '1000001', '1000000', 'bytes'),
+ array(1004999, '1M', '1005', '1000', 'kB'),
+ array(1005000, '1M', '1.01', '1', 'MB'),
+
+ // limit in KiB
+ array(1025, '1Ki', '1025', '1024', 'bytes'),
+ array(1029, '1Ki', '1029', '1024', 'bytes'),
+ array(1030, '1Ki', '1.01', '1', 'KiB'),
+
+ array(1048577, '1024Ki', '1048577', '1048576', 'bytes'),
+ array(1053818, '1024Ki', '1029.12', '1024', 'KiB'),
+ array(1053819, '1024Ki', '1.01', '1', 'MiB'),
+
+ // limit in MiB
+ array(1048577, '1Mi', '1048577', '1048576', 'bytes'),
+ array(1053818, '1Mi', '1029.12', '1024', 'KiB'),
+ array(1053819, '1Mi', '1.01', '1', 'MiB'),
+ );
+ }
+
+ /**
+ * @dataProvider provideMaxSizeExceededTests
+ */
+ public function testMaxSizeExceeded($bytesWritten, $limit, $sizeAsString, $limitAsString, $suffix)
+ {
+ fseek($this->file, $bytesWritten - 1, SEEK_SET);
+ fwrite($this->file, '0');
+ fclose($this->file);
+
+ $constraint = new File(array(
+ 'maxSize' => $limit,
+ 'maxSizeMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($this->getFile($this->path), $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ limit }}', $limitAsString)
+ ->setParameter('{{ size }}', $sizeAsString)
+ ->setParameter('{{ suffix }}', $suffix)
+ ->setParameter('{{ file }}', '"'.$this->path.'"')
+ ->setCode(File::TOO_LARGE_ERROR)
+ ->assertRaised();
+ }
+
+ public function provideMaxSizeNotExceededTests()
+ {
+ return array(
+ // limit in bytes
+ array(1000, 1000),
+ array(1000000, 1000000),
+
+ // limit in kB
+ array(1000, '1k'),
+ array(1000000, '1000k'),
+
+ // limit in MB
+ array(1000000, '1M'),
+
+ // limit in KiB
+ array(1024, '1Ki'),
+ array(1048576, '1024Ki'),
+
+ // limit in MiB
+ array(1048576, '1Mi'),
+ );
+ }
+
+ /**
+ * @dataProvider provideMaxSizeNotExceededTests
+ */
+ public function testMaxSizeNotExceeded($bytesWritten, $limit)
+ {
+ fseek($this->file, $bytesWritten - 1, SEEK_SET);
+ fwrite($this->file, '0');
+ fclose($this->file);
+
+ $constraint = new File(array(
+ 'maxSize' => $limit,
+ 'maxSizeMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($this->getFile($this->path), $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testInvalidMaxSize()
+ {
+ $constraint = new File(array(
+ 'maxSize' => '1abc',
+ ));
+
+ $this->validator->validate($this->path, $constraint);
+ }
+
+ public function provideBinaryFormatTests()
+ {
+ return array(
+ array(11, 10, null, '11', '10', 'bytes'),
+ array(11, 10, true, '11', '10', 'bytes'),
+ array(11, 10, false, '11', '10', 'bytes'),
+
+ // round(size) == 1.01kB, limit == 1kB
+ array(ceil(1000*1.01), 1000, null, '1.01', '1', 'kB'),
+ array(ceil(1000*1.01), '1k', null, '1.01', '1', 'kB'),
+ array(ceil(1024*1.01), '1Ki', null, '1.01', '1', 'KiB'),
+
+ array(ceil(1024*1.01), 1024, true, '1.01', '1', 'KiB'),
+ array(ceil(1024*1.01*1000), '1024k', true, '1010', '1000', 'KiB'),
+ array(ceil(1024*1.01), '1Ki', true, '1.01', '1', 'KiB'),
+
+ array(ceil(1000*1.01), 1000, false, '1.01', '1', 'kB'),
+ array(ceil(1000*1.01), '1k', false, '1.01', '1', 'kB'),
+ array(ceil(1024*1.01*10), '10Ki', false, '10.34', '10.24', 'kB'),
+ );
+ }
+
+ /**
+ * @dataProvider provideBinaryFormatTests
+ */
+ public function testBinaryFormat($bytesWritten, $limit, $binaryFormat, $sizeAsString, $limitAsString, $suffix)
+ {
+ fseek($this->file, $bytesWritten-1, SEEK_SET);
+ fwrite($this->file, '0');
+ fclose($this->file);
+
+ $constraint = new File(array(
+ 'maxSize' => $limit,
+ 'binaryFormat' => $binaryFormat,
+ 'maxSizeMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($this->getFile($this->path), $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ limit }}', $limitAsString)
+ ->setParameter('{{ size }}', $sizeAsString)
+ ->setParameter('{{ suffix }}', $suffix)
+ ->setParameter('{{ file }}', '"'.$this->path.'"')
+ ->setCode(File::TOO_LARGE_ERROR)
+ ->assertRaised();
+ }
+
+ public function testValidMimeType()
+ {
+ $file = $this
+ ->getMockBuilder('Symfony\Component\HttpFoundation\File\File')
+ ->setConstructorArgs(array(__DIR__.'/Fixtures/foo'))
+ ->getMock();
+ $file
+ ->expects($this->once())
+ ->method('getPathname')
+ ->will($this->returnValue($this->path));
+ $file
+ ->expects($this->once())
+ ->method('getMimeType')
+ ->will($this->returnValue('image/jpg'));
+
+ $constraint = new File(array(
+ 'mimeTypes' => array('image/png', 'image/jpg'),
+ ));
+
+ $this->validator->validate($file, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testValidWildcardMimeType()
+ {
+ $file = $this
+ ->getMockBuilder('Symfony\Component\HttpFoundation\File\File')
+ ->setConstructorArgs(array(__DIR__.'/Fixtures/foo'))
+ ->getMock();
+ $file
+ ->expects($this->once())
+ ->method('getPathname')
+ ->will($this->returnValue($this->path));
+ $file
+ ->expects($this->once())
+ ->method('getMimeType')
+ ->will($this->returnValue('image/jpg'));
+
+ $constraint = new File(array(
+ 'mimeTypes' => array('image/*'),
+ ));
+
+ $this->validator->validate($file, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testInvalidMimeType()
+ {
+ $file = $this
+ ->getMockBuilder('Symfony\Component\HttpFoundation\File\File')
+ ->setConstructorArgs(array(__DIR__.'/Fixtures/foo'))
+ ->getMock();
+ $file
+ ->expects($this->once())
+ ->method('getPathname')
+ ->will($this->returnValue($this->path));
+ $file
+ ->expects($this->once())
+ ->method('getMimeType')
+ ->will($this->returnValue('application/pdf'));
+
+ $constraint = new File(array(
+ 'mimeTypes' => array('image/png', 'image/jpg'),
+ 'mimeTypesMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($file, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ type }}', '"application/pdf"')
+ ->setParameter('{{ types }}', '"image/png", "image/jpg"')
+ ->setParameter('{{ file }}', '"'.$this->path.'"')
+ ->setCode(File::INVALID_MIME_TYPE_ERROR)
+ ->assertRaised();
+ }
+
+ public function testInvalidWildcardMimeType()
+ {
+ $file = $this
+ ->getMockBuilder('Symfony\Component\HttpFoundation\File\File')
+ ->setConstructorArgs(array(__DIR__.'/Fixtures/foo'))
+ ->getMock();
+ $file
+ ->expects($this->once())
+ ->method('getPathname')
+ ->will($this->returnValue($this->path));
+ $file
+ ->expects($this->once())
+ ->method('getMimeType')
+ ->will($this->returnValue('application/pdf'));
+
+ $constraint = new File(array(
+ 'mimeTypes' => array('image/*', 'image/jpg'),
+ 'mimeTypesMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($file, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ type }}', '"application/pdf"')
+ ->setParameter('{{ types }}', '"image/*", "image/jpg"')
+ ->setParameter('{{ file }}', '"'.$this->path.'"')
+ ->setCode(File::INVALID_MIME_TYPE_ERROR)
+ ->assertRaised();
+ }
+
+ public function testDisallowEmpty()
+ {
+ ftruncate($this->file, 0);
+
+ $constraint = new File(array(
+ 'disallowEmptyMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($this->getFile($this->path), $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ file }}', '"'.$this->path.'"')
+ ->setCode(File::EMPTY_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider uploadedFileErrorProvider
+ */
+ public function testUploadedFileError($error, $message, array $params = array(), $maxSize = null)
+ {
+ $file = new UploadedFile('/path/to/file', 'originalName', 'mime', 0, $error);
+
+ $constraint = new File(array(
+ $message => 'myMessage',
+ 'maxSize' => $maxSize,
+ ));
+
+ $this->validator->validate($file, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameters($params)
+ ->setCode($error)
+ ->assertRaised();
+ }
+
+ public function uploadedFileErrorProvider()
+ {
+ $tests = array(
+ array(UPLOAD_ERR_FORM_SIZE, 'uploadFormSizeErrorMessage'),
+ array(UPLOAD_ERR_PARTIAL, 'uploadPartialErrorMessage'),
+ array(UPLOAD_ERR_NO_FILE, 'uploadNoFileErrorMessage'),
+ array(UPLOAD_ERR_NO_TMP_DIR, 'uploadNoTmpDirErrorMessage'),
+ array(UPLOAD_ERR_CANT_WRITE, 'uploadCantWriteErrorMessage'),
+ array(UPLOAD_ERR_EXTENSION, 'uploadExtensionErrorMessage'),
+ );
+
+ if (class_exists('Symfony\Component\HttpFoundation\File\UploadedFile')) {
+ // when no maxSize is specified on constraint, it should use the ini value
+ $tests[] = array(UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', array(
+ '{{ limit }}' => UploadedFile::getMaxFilesize() / 1048576,
+ '{{ suffix }}' => 'MiB',
+ ));
+
+ // it should use the smaller limitation (maxSize option in this case)
+ $tests[] = array(UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', array(
+ '{{ limit }}' => 1,
+ '{{ suffix }}' => 'bytes',
+ ), '1');
+
+ // it correctly parses the maxSize option and not only uses simple string comparison
+ // 1000M should be bigger than the ini value
+ $tests[] = array(UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', array(
+ '{{ limit }}' => UploadedFile::getMaxFilesize() / 1048576,
+ '{{ suffix }}' => 'MiB',
+ ), '1000M');
+
+ // it correctly parses the maxSize option and not only uses simple string comparison
+ // 1000M should be bigger than the ini value
+ $tests[] = array(UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', array(
+ '{{ limit }}' => '0.1',
+ '{{ suffix }}' => 'MB',
+ ), '100K');
+ }
+
+ return $tests;
+ }
+
+ abstract protected function getFile($filename);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/foo b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/foo
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/foo
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test.gif b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test.gif
new file mode 100644
index 0000000..6b44fc7
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test.gif
Binary files differ
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_4by3.gif b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_4by3.gif
new file mode 100644
index 0000000..64dd3ff
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_4by3.gif
Binary files differ
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_landscape.gif b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_landscape.gif
new file mode 100644
index 0000000..8701235
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_landscape.gif
Binary files differ
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_portrait.gif b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_portrait.gif
new file mode 100644
index 0000000..cc480ca
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_portrait.gif
Binary files differ
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GreaterThanOrEqualValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GreaterThanOrEqualValidatorTest.php
new file mode 100644
index 0000000..41708f6
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GreaterThanOrEqualValidatorTest.php
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
+use Symfony\Component\Validator\Constraints\GreaterThanOrEqualValidator;
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class GreaterThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCase
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new GreaterThanOrEqualValidator();
+ }
+
+ protected function createConstraint(array $options)
+ {
+ return new GreaterThanOrEqual($options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideValidComparisons()
+ {
+ return array(
+ array(3, 2),
+ array(1, 1),
+ array(new \DateTime('2010/01/01'), new \DateTime('2000/01/01')),
+ array(new \DateTime('2000/01/01'), new \DateTime('2000/01/01')),
+ array(new \DateTime('2010/01/01'), '2000/01/01'),
+ array(new \DateTime('2000/01/01'), '2000/01/01'),
+ array(new \DateTime('2010/01/01 UTC'), '2000/01/01 UTC'),
+ array(new \DateTime('2000/01/01 UTC'), '2000/01/01 UTC'),
+ array('a', 'a'),
+ array('z', 'a'),
+ array(null, 1),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideInvalidComparisons()
+ {
+ return array(
+ array(1, '1', 2, '2', 'integer'),
+ array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2005/01/01'), 'Jan 1, 2005, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', '2005/01/01', 'Jan 1, 2005, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2000/01/01 UTC'), 'Jan 1, 2000, 12:00 AM', '2005/01/01 UTC', 'Jan 1, 2005, 12:00 AM', 'DateTime'),
+ array('b', '"b"', 'c', '"c"', 'string'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php
new file mode 100644
index 0000000..85a2b1d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\GreaterThan;
+use Symfony\Component\Validator\Constraints\GreaterThanValidator;
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class GreaterThanValidatorTest extends AbstractComparisonValidatorTestCase
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new GreaterThanValidator();
+ }
+
+ protected function createConstraint(array $options)
+ {
+ return new GreaterThan($options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideValidComparisons()
+ {
+ return array(
+ array(2, 1),
+ array(new \DateTime('2005/01/01'), new \DateTime('2001/01/01')),
+ array(new \DateTime('2005/01/01'), '2001/01/01'),
+ array(new \DateTime('2005/01/01 UTC'), '2001/01/01 UTC'),
+ array(new ComparisonTest_Class(5), new ComparisonTest_Class(4)),
+ array('333', '22'),
+ array(null, 1),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideInvalidComparisons()
+ {
+ return array(
+ array(1, '1', 2, '2', 'integer'),
+ array(2, '2', 2, '2', 'integer'),
+ array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2005/01/01'), 'Jan 1, 2005, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', '2005/01/01', 'Jan 1, 2005, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', '2000/01/01', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2000/01/01 UTC'), 'Jan 1, 2000, 12:00 AM', '2005/01/01 UTC', 'Jan 1, 2005, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2000/01/01 UTC'), 'Jan 1, 2000, 12:00 AM', '2000/01/01 UTC', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
+ array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
+ array('22', '"22"', '333', '"333"', 'string'),
+ array('22', '"22"', '22', '"22"', 'string'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GroupSequenceTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GroupSequenceTest.php
new file mode 100644
index 0000000..85b60b5
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/GroupSequenceTest.php
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\GroupSequence;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class GroupSequenceTest extends \PHPUnit_Framework_TestCase
+{
+ public function testCreate()
+ {
+ $sequence = new GroupSequence(array('Group 1', 'Group 2'));
+
+ $this->assertSame(array('Group 1', 'Group 2'), $sequence->groups);
+ }
+
+ public function testCreateDoctrineStyle()
+ {
+ $sequence = new GroupSequence(array('value' => array('Group 1', 'Group 2')));
+
+ $this->assertSame(array('Group 1', 'Group 2'), $sequence->groups);
+ }
+
+ public function testIterate()
+ {
+ $sequence = new GroupSequence(array('Group 1', 'Group 2'));
+
+ $this->assertSame(array('Group 1', 'Group 2'), iterator_to_array($sequence));
+ }
+
+ public function testCount()
+ {
+ $sequence = new GroupSequence(array('Group 1', 'Group 2'));
+
+ $this->assertCount(2, $sequence);
+ }
+
+ public function testArrayAccess()
+ {
+ $sequence = new GroupSequence(array('Group 1', 'Group 2'));
+
+ $this->assertSame('Group 1', $sequence[0]);
+ $this->assertSame('Group 2', $sequence[1]);
+ $this->assertTrue(isset($sequence[0]));
+ $this->assertFalse(isset($sequence[2]));
+ unset($sequence[0]);
+ $this->assertFalse(isset($sequence[0]));
+ $sequence[] = 'Group 3';
+ $this->assertTrue(isset($sequence[2]));
+ $this->assertSame('Group 3', $sequence[2]);
+ $sequence[0] = 'Group 1';
+ $this->assertTrue(isset($sequence[0]));
+ $this->assertSame('Group 1', $sequence[0]);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\OutOfBoundsException
+ */
+ public function testGetExpectsExistingKey()
+ {
+ $sequence = new GroupSequence(array('Group 1', 'Group 2'));
+
+ $sequence[2];
+ }
+
+ public function testUnsetIgnoresNonExistingKeys()
+ {
+ $sequence = new GroupSequence(array('Group 1', 'Group 2'));
+
+ // should not fail
+ unset($sequence[2]);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php
new file mode 100644
index 0000000..ab9839a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php
@@ -0,0 +1,193 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Iban;
+use Symfony\Component\Validator\Constraints\IbanValidator;
+use Symfony\Component\Validator\Validation;
+
+class IbanValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new IbanValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Iban());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Iban());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getValidIbans
+ */
+ public function testValidIbans($iban)
+ {
+ $this->validator->validate($iban, new Iban());
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidIbans()
+ {
+ return array(
+ array('CH9300762011623852957'), // Switzerland without spaces
+ array('CH93 0076 2011 6238 5295 7'), // Switzerland with multiple spaces
+
+ //Country list
+ //http://www.rbs.co.uk/corporate/international/g0/guide-to-international-business/regulatory-information/iban/iban-example.ashx
+
+ array('AL47 2121 1009 0000 0002 3569 8741'), //Albania
+ array('AD12 0001 2030 2003 5910 0100'), //Andorra
+ array('AT61 1904 3002 3457 3201'), //Austria
+ array('AZ21 NABZ 0000 0000 1370 1000 1944'), //Azerbaijan
+ array('BH67 BMAG 0000 1299 1234 56'), //Bahrain
+ array('BE62 5100 0754 7061'), //Belgium
+ array('BA39 1290 0794 0102 8494'), //Bosnia and Herzegovina
+ array('BG80 BNBG 9661 1020 3456 78'), //Bulgaria
+ array('HR12 1001 0051 8630 0016 0'), //Croatia
+ array('CY17 0020 0128 0000 0012 0052 7600'), //Cyprus
+ array('CZ65 0800 0000 1920 0014 5399'), //Czech Republic
+ array('DK50 0040 0440 1162 43'), //Denmark
+ array('EE38 2200 2210 2014 5685'), //Estonia
+ array('FO97 5432 0388 8999 44'), //Faroe Islands
+ array('FI21 1234 5600 0007 85'), //Finland
+ array('FR14 2004 1010 0505 0001 3M02 606'), //France
+ array('GE29 NB00 0000 0101 9049 17'), //Georgia
+ array('DE89 3704 0044 0532 0130 00'), //Germany
+ array('GI75 NWBK 0000 0000 7099 453'), //Gibraltar
+ array('GR16 0110 1250 0000 0001 2300 695'), //Greece
+ array('GL56 0444 9876 5432 10'), //Greenland
+ array('HU42 1177 3016 1111 1018 0000 0000'), //Hungary
+ array('IS14 0159 2600 7654 5510 7303 39'), //Iceland
+ array('IE29 AIBK 9311 5212 3456 78'), //Ireland
+ array('IL62 0108 0000 0009 9999 999'), //Israel
+ array('IT40 S054 2811 1010 0000 0123 456'), //Italy
+ array('LV80 BANK 0000 4351 9500 1'), //Latvia
+ array('LB62 0999 0000 0001 0019 0122 9114'), //Lebanon
+ array('LI21 0881 0000 2324 013A A'), //Liechtenstein
+ array('LT12 1000 0111 0100 1000'), //Lithuania
+ array('LU28 0019 4006 4475 0000'), //Luxembourg
+ array('MK072 5012 0000 0589 84'), //Macedonia
+ array('MT84 MALT 0110 0001 2345 MTLC AST0 01S'), //Malta
+ array('MU17 BOMM 0101 1010 3030 0200 000M UR'), //Mauritius
+ array('MD24 AG00 0225 1000 1310 4168'), //Moldova
+ array('MC93 2005 2222 1001 1223 3M44 555'), //Monaco
+ array('ME25 5050 0001 2345 6789 51'), //Montenegro
+ array('NL39 RABO 0300 0652 64'), //Netherlands
+ array('NO93 8601 1117 947'), //Norway
+ array('PK36 SCBL 0000 0011 2345 6702'), //Pakistan
+ array('PL60 1020 1026 0000 0422 7020 1111'), //Poland
+ array('PT50 0002 0123 1234 5678 9015 4'), //Portugal
+ array('RO49 AAAA 1B31 0075 9384 0000'), //Romania
+ array('SM86 U032 2509 8000 0000 0270 100'), //San Marino
+ array('SA03 8000 0000 6080 1016 7519'), //Saudi Arabia
+ array('RS35 2600 0560 1001 6113 79'), //Serbia
+ array('SK31 1200 0000 1987 4263 7541'), //Slovak Republic
+ array('SI56 1910 0000 0123 438'), //Slovenia
+ array('ES80 2310 0001 1800 0001 2345'), //Spain
+ array('SE35 5000 0000 0549 1000 0003'), //Sweden
+ array('CH93 0076 2011 6238 5295 7'), //Switzerland
+ array('TN59 1000 6035 1835 9847 8831'), //Tunisia
+ array('TR33 0006 1005 1978 6457 8413 26'), //Turkey
+ array('AE07 0331 2345 6789 0123 456'), //UAE
+ array('GB 12 CPBK 0892 9965 0449 91'), //United Kingdom
+
+ //Extended country list
+ //http://www.nordea.com/Our+services/International+products+and+services/Cash+Management/IBAN+countries/908462.html
+ array('AO06000600000100037131174'), //Angola
+ array('AZ21NABZ00000000137010001944'), //Azerbaijan
+ array('BH29BMAG1299123456BH00'), //Bahrain
+ array('BJ11B00610100400271101192591'), //Benin
+ array('VG96VPVG0000012345678901'), //British Virgin Islands
+ array('BF1030134020015400945000643'), //Burkina Faso
+ array('BI43201011067444'), //Burundi
+ array('CM2110003001000500000605306'), //Cameroon
+ array('CV64000300004547069110176'), //Cape Verde
+ array('FR7630007000110009970004942'), //Central African Republic
+ array('CG5230011000202151234567890'), //Congo
+ array('CR0515202001026284066'), //Costa Rica
+ array('DO28BAGR00000001212453611324'), //Dominican Republic
+ array('GT82TRAJ01020000001210029690'), //Guatemala
+ array('IR580540105180021273113007'), //Iran
+ array('IL620108000000099999999'), //Israel
+ array('CI05A00060174100178530011852'), //Ivory Coast
+ array('KZ176010251000042993'), //Kazakhstan
+ array('KW74NBOK0000000000001000372151'), //Kuwait
+ array('LB30099900000001001925579115'), //Lebanon
+ array('MG4600005030010101914016056'), //Madagascar
+ array('ML03D00890170001002120000447'), //Mali
+ array('MR1300012000010000002037372'), //Mauritania
+ array('MU17BOMM0101101030300200000MUR'), //Mauritius
+ array('MZ59000100000011834194157'), //Mozambique
+ array('PS92PALS000000000400123456702'), //Palestinian Territory
+ array('PT50000200000163099310355'), //Sao Tome and Principe
+ array('SA0380000000608010167519'), //Saudi Arabia
+ array('SN12K00100152000025690007542'), //Senegal
+ array('TN5914207207100707129648'), //Tunisia
+ array('TR330006100519786457841326'), //Turkey
+ array('AE260211000000230064016'), //United Arab Emirates
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidIbans
+ */
+ public function testInvalidIbans($iban, $code)
+ {
+ $constraint = new Iban(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($iban, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$iban.'"')
+ ->setCode($code)
+ ->assertRaised();
+ }
+
+ public function getInvalidIbans()
+ {
+ return array(
+ array('CH93 0076 2011 6238 5295', Iban::CHECKSUM_FAILED_ERROR),
+ array('CH930076201162385295', Iban::CHECKSUM_FAILED_ERROR),
+ array('GB29 RBOS 6016 1331 9268 19', Iban::CHECKSUM_FAILED_ERROR),
+ array('CH930072011623852957', Iban::CHECKSUM_FAILED_ERROR),
+ array('NL39 RASO 0300 0652 64', Iban::CHECKSUM_FAILED_ERROR),
+ array('NO93 8601117 947', Iban::CHECKSUM_FAILED_ERROR),
+ array('CY170020 128 0000 0012 0052 7600', Iban::CHECKSUM_FAILED_ERROR),
+ array('foo', Iban::TOO_SHORT_ERROR),
+ array('123', Iban::TOO_SHORT_ERROR),
+ array('0750447346', Iban::INVALID_COUNTRY_CODE_ERROR),
+ array('CH930076201162385295]', Iban::INVALID_CHARACTERS_ERROR),
+
+ //Ibans with lower case values are invalid
+ array('Ae260211000000230064016', Iban::INVALID_CASE_ERROR),
+ array('ae260211000000230064016', Iban::INVALID_CASE_ERROR),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php
new file mode 100644
index 0000000..4b71062
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php
@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\IdenticalTo;
+use Symfony\Component\Validator\Constraints\IdenticalToValidator;
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class IdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new IdenticalToValidator();
+ }
+
+ protected function createConstraint(array $options)
+ {
+ return new IdenticalTo($options);
+ }
+
+ public function provideAllValidComparisons()
+ {
+ $this->setDefaultTimezone('UTC');
+
+ // Don't call addPhp5Dot5Comparisons() automatically, as it does
+ // not take care of identical objects
+ $comparisons = $this->provideValidComparisons();
+
+ $this->restoreDefaultTimezone();
+
+ return $comparisons;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideValidComparisons()
+ {
+ $date = new \DateTime('2000-01-01');
+ $object = new ComparisonTest_Class(2);
+
+ $comparisons = array(
+ array(3, 3),
+ array('a', 'a'),
+ array($date, $date),
+ array($object, $object),
+ array(null, 1),
+ );
+
+ if (version_compare(PHP_VERSION, '>=', '5.5')) {
+ $immutableDate = new \DateTimeImmutable('2000-01-01');
+ $comparisons[] = array($immutableDate, $immutableDate);
+ }
+
+ return $comparisons;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideInvalidComparisons()
+ {
+ return array(
+ array(1, '1', 2, '2', 'integer'),
+ array(2, '2', '2', '"2"', 'string'),
+ array('22', '"22"', '333', '"333"', 'string'),
+ array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('1999-01-01'), 'Jan 1, 1999, 12:00 AM', 'DateTime'),
+ array(new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php
new file mode 100644
index 0000000..18f9c1b
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php
@@ -0,0 +1,329 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Image;
+use Symfony\Component\Validator\Constraints\ImageValidator;
+use Symfony\Component\Validator\Validation;
+
+class ImageValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected $context;
+
+ /**
+ * @var ImageValidator
+ */
+ protected $validator;
+
+ protected $path;
+ protected $image;
+ protected $imageLandscape;
+ protected $imagePortrait;
+ protected $image4By3;
+
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new ImageValidator();
+ }
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->image = __DIR__.'/Fixtures/test.gif';
+ $this->imageLandscape = __DIR__.'/Fixtures/test_landscape.gif';
+ $this->imagePortrait = __DIR__.'/Fixtures/test_portrait.gif';
+ $this->image4By3 = __DIR__.'/Fixtures/test_4by3.gif';
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Image());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Image());
+
+ $this->assertNoViolation();
+ }
+
+ public function testValidImage()
+ {
+ $this->validator->validate($this->image, new Image());
+
+ $this->assertNoViolation();
+ }
+
+ public function testFileNotFound()
+ {
+ // Check that the logic from FileValidator still works
+ $constraint = new Image(array(
+ 'notFoundMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate('foobar', $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ file }}', '"foobar"')
+ ->setCode(Image::NOT_FOUND_ERROR)
+ ->assertRaised();
+ }
+
+ public function testValidSize()
+ {
+ $constraint = new Image(array(
+ 'minWidth' => 1,
+ 'maxWidth' => 2,
+ 'minHeight' => 1,
+ 'maxHeight' => 2,
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testWidthTooSmall()
+ {
+ $constraint = new Image(array(
+ 'minWidth' => 3,
+ 'minWidthMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ width }}', '2')
+ ->setParameter('{{ min_width }}', '3')
+ ->setCode(Image::TOO_NARROW_ERROR)
+ ->assertRaised();
+ }
+
+ public function testWidthTooBig()
+ {
+ $constraint = new Image(array(
+ 'maxWidth' => 1,
+ 'maxWidthMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ width }}', '2')
+ ->setParameter('{{ max_width }}', '1')
+ ->setCode(Image::TOO_WIDE_ERROR)
+ ->assertRaised();
+ }
+
+ public function testHeightTooSmall()
+ {
+ $constraint = new Image(array(
+ 'minHeight' => 3,
+ 'minHeightMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ height }}', '2')
+ ->setParameter('{{ min_height }}', '3')
+ ->setCode(Image::TOO_LOW_ERROR)
+ ->assertRaised();
+ }
+
+ public function testHeightTooBig()
+ {
+ $constraint = new Image(array(
+ 'maxHeight' => 1,
+ 'maxHeightMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ height }}', '2')
+ ->setParameter('{{ max_height }}', '1')
+ ->setCode(Image::TOO_HIGH_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testInvalidMinWidth()
+ {
+ $constraint = new Image(array(
+ 'minWidth' => '1abc',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testInvalidMaxWidth()
+ {
+ $constraint = new Image(array(
+ 'maxWidth' => '1abc',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testInvalidMinHeight()
+ {
+ $constraint = new Image(array(
+ 'minHeight' => '1abc',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testInvalidMaxHeight()
+ {
+ $constraint = new Image(array(
+ 'maxHeight' => '1abc',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+ }
+
+ public function testRatioTooSmall()
+ {
+ $constraint = new Image(array(
+ 'minRatio' => 2,
+ 'minRatioMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ ratio }}', 1)
+ ->setParameter('{{ min_ratio }}', 2)
+ ->setCode(Image::RATIO_TOO_SMALL_ERROR)
+ ->assertRaised();
+ }
+
+ public function testRatioTooBig()
+ {
+ $constraint = new Image(array(
+ 'maxRatio' => 0.5,
+ 'maxRatioMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ ratio }}', 1)
+ ->setParameter('{{ max_ratio }}', 0.5)
+ ->setCode(Image::RATIO_TOO_BIG_ERROR)
+ ->assertRaised();
+ }
+
+ public function testMaxRatioUsesTwoDecimalsOnly()
+ {
+ $constraint = new Image(array(
+ 'maxRatio' => 1.33,
+ ));
+
+ $this->validator->validate($this->image4By3, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testInvalidMinRatio()
+ {
+ $constraint = new Image(array(
+ 'minRatio' => '1abc',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testInvalidMaxRatio()
+ {
+ $constraint = new Image(array(
+ 'maxRatio' => '1abc',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+ }
+
+ public function testSquareNotAllowed()
+ {
+ $constraint = new Image(array(
+ 'allowSquare' => false,
+ 'allowSquareMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ width }}', 2)
+ ->setParameter('{{ height }}', 2)
+ ->setCode(Image::SQUARE_NOT_ALLOWED_ERROR)
+ ->assertRaised();
+ }
+
+ public function testLandscapeNotAllowed()
+ {
+ $constraint = new Image(array(
+ 'allowLandscape' => false,
+ 'allowLandscapeMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($this->imageLandscape, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ width }}', 2)
+ ->setParameter('{{ height }}', 1)
+ ->setCode(Image::LANDSCAPE_NOT_ALLOWED_ERROR)
+ ->assertRaised();
+ }
+
+ public function testPortraitNotAllowed()
+ {
+ $constraint = new Image(array(
+ 'allowPortrait' => false,
+ 'allowPortraitMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($this->imagePortrait, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ width }}', 1)
+ ->setParameter('{{ height }}', 2)
+ ->setCode(Image::PORTRAIT_NOT_ALLOWED_ERROR)
+ ->assertRaised();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php
new file mode 100644
index 0000000..fc40e61
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php
@@ -0,0 +1,444 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Ip;
+use Symfony\Component\Validator\Constraints\IpValidator;
+use Symfony\Component\Validator\Validation;
+
+class IpValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new IpValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Ip());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Ip());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $this->validator->validate(new \stdClass(), new Ip());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testInvalidValidatorVersion()
+ {
+ new Ip(array(
+ 'version' => 666,
+ ));
+ }
+
+ /**
+ * @dataProvider getValidIpsV4
+ */
+ public function testValidIpsV4($ip)
+ {
+ $this->validator->validate($ip, new Ip(array(
+ 'version' => Ip::V4,
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidIpsV4()
+ {
+ return array(
+ array('0.0.0.0'),
+ array('10.0.0.0'),
+ array('123.45.67.178'),
+ array('172.16.0.0'),
+ array('192.168.1.0'),
+ array('224.0.0.1'),
+ array('255.255.255.255'),
+ array('127.0.0.0'),
+ );
+ }
+
+ /**
+ * @dataProvider getValidIpsV6
+ */
+ public function testValidIpsV6($ip)
+ {
+ $this->validator->validate($ip, new Ip(array(
+ 'version' => Ip::V6,
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidIpsV6()
+ {
+ return array(
+ array('2001:0db8:85a3:0000:0000:8a2e:0370:7334'),
+ array('2001:0DB8:85A3:0000:0000:8A2E:0370:7334'),
+ array('2001:0Db8:85a3:0000:0000:8A2e:0370:7334'),
+ array('fdfe:dcba:9876:ffff:fdc6:c46b:bb8f:7d4c'),
+ array('fdc6:c46b:bb8f:7d4c:fdc6:c46b:bb8f:7d4c'),
+ array('fdc6:c46b:bb8f:7d4c:0000:8a2e:0370:7334'),
+ array('fe80:0000:0000:0000:0202:b3ff:fe1e:8329'),
+ array('fe80:0:0:0:202:b3ff:fe1e:8329'),
+ array('fe80::202:b3ff:fe1e:8329'),
+ array('0:0:0:0:0:0:0:0'),
+ array('::'),
+ array('0::'),
+ array('::0'),
+ array('0::0'),
+ // IPv4 mapped to IPv6
+ array('2001:0db8:85a3:0000:0000:8a2e:0.0.0.0'),
+ array('::0.0.0.0'),
+ array('::255.255.255.255'),
+ array('::123.45.67.178'),
+ );
+ }
+
+ /**
+ * @dataProvider getValidIpsAll
+ */
+ public function testValidIpsAll($ip)
+ {
+ $this->validator->validate($ip, new Ip(array(
+ 'version' => Ip::ALL,
+ )));
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidIpsAll()
+ {
+ return array_merge($this->getValidIpsV4(), $this->getValidIpsV6());
+ }
+
+ /**
+ * @dataProvider getInvalidIpsV4
+ */
+ public function testInvalidIpsV4($ip)
+ {
+ $constraint = new Ip(array(
+ 'version' => Ip::V4,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($ip, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$ip.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidIpsV4()
+ {
+ return array(
+ array('0'),
+ array('0.0'),
+ array('0.0.0'),
+ array('256.0.0.0'),
+ array('0.256.0.0'),
+ array('0.0.256.0'),
+ array('0.0.0.256'),
+ array('-1.0.0.0'),
+ array('foobar'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidPrivateIpsV4
+ */
+ public function testInvalidPrivateIpsV4($ip)
+ {
+ $constraint = new Ip(array(
+ 'version' => Ip::V4_NO_PRIV,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($ip, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$ip.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidPrivateIpsV4()
+ {
+ return array(
+ array('10.0.0.0'),
+ array('172.16.0.0'),
+ array('192.168.1.0'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidReservedIpsV4
+ */
+ public function testInvalidReservedIpsV4($ip)
+ {
+ $constraint = new Ip(array(
+ 'version' => Ip::V4_NO_RES,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($ip, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$ip.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidReservedIpsV4()
+ {
+ return array(
+ array('0.0.0.0'),
+ array('224.0.0.1'),
+ array('255.255.255.255'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidPublicIpsV4
+ */
+ public function testInvalidPublicIpsV4($ip)
+ {
+ $constraint = new Ip(array(
+ 'version' => Ip::V4_ONLY_PUBLIC,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($ip, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$ip.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidPublicIpsV4()
+ {
+ return array_merge($this->getInvalidPrivateIpsV4(), $this->getInvalidReservedIpsV4());
+ }
+
+ /**
+ * @dataProvider getInvalidIpsV6
+ */
+ public function testInvalidIpsV6($ip)
+ {
+ $constraint = new Ip(array(
+ 'version' => Ip::V6,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($ip, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$ip.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidIpsV6()
+ {
+ return array(
+ array('z001:0db8:85a3:0000:0000:8a2e:0370:7334'),
+ array('fe80'),
+ array('fe80:8329'),
+ array('fe80:::202:b3ff:fe1e:8329'),
+ array('fe80::202:b3ff::fe1e:8329'),
+ // IPv4 mapped to IPv6
+ array('2001:0db8:85a3:0000:0000:8a2e:0370:0.0.0.0'),
+ array('::0.0'),
+ array('::0.0.0'),
+ array('::256.0.0.0'),
+ array('::0.256.0.0'),
+ array('::0.0.256.0'),
+ array('::0.0.0.256'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidPrivateIpsV6
+ */
+ public function testInvalidPrivateIpsV6($ip)
+ {
+ $constraint = new Ip(array(
+ 'version' => Ip::V6_NO_PRIV,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($ip, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$ip.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidPrivateIpsV6()
+ {
+ return array(
+ array('fdfe:dcba:9876:ffff:fdc6:c46b:bb8f:7d4c'),
+ array('fdc6:c46b:bb8f:7d4c:fdc6:c46b:bb8f:7d4c'),
+ array('fdc6:c46b:bb8f:7d4c:0000:8a2e:0370:7334'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidReservedIpsV6
+ */
+ public function testInvalidReservedIpsV6($ip)
+ {
+ $constraint = new Ip(array(
+ 'version' => Ip::V6_NO_RES,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($ip, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$ip.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidReservedIpsV6()
+ {
+ // Quoting after official filter documentation:
+ // "FILTER_FLAG_NO_RES_RANGE = This flag does not apply to IPv6 addresses."
+ // Full description: http://php.net/manual/en/filter.filters.flags.php
+ return $this->getInvalidIpsV6();
+ }
+
+ /**
+ * @dataProvider getInvalidPublicIpsV6
+ */
+ public function testInvalidPublicIpsV6($ip)
+ {
+ $constraint = new Ip(array(
+ 'version' => Ip::V6_ONLY_PUBLIC,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($ip, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$ip.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidPublicIpsV6()
+ {
+ return array_merge($this->getInvalidPrivateIpsV6(), $this->getInvalidReservedIpsV6());
+ }
+
+ /**
+ * @dataProvider getInvalidIpsAll
+ */
+ public function testInvalidIpsAll($ip)
+ {
+ $constraint = new Ip(array(
+ 'version' => Ip::ALL,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($ip, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$ip.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidIpsAll()
+ {
+ return array_merge($this->getInvalidIpsV4(), $this->getInvalidIpsV6());
+ }
+
+ /**
+ * @dataProvider getInvalidPrivateIpsAll
+ */
+ public function testInvalidPrivateIpsAll($ip)
+ {
+ $constraint = new Ip(array(
+ 'version' => Ip::ALL_NO_PRIV,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($ip, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$ip.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidPrivateIpsAll()
+ {
+ return array_merge($this->getInvalidPrivateIpsV4(), $this->getInvalidPrivateIpsV6());
+ }
+
+ /**
+ * @dataProvider getInvalidReservedIpsAll
+ */
+ public function testInvalidReservedIpsAll($ip)
+ {
+ $constraint = new Ip(array(
+ 'version' => Ip::ALL_NO_RES,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($ip, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$ip.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidReservedIpsAll()
+ {
+ return array_merge($this->getInvalidReservedIpsV4(), $this->getInvalidReservedIpsV6());
+ }
+
+ /**
+ * @dataProvider getInvalidPublicIpsAll
+ */
+ public function testInvalidPublicIpsAll($ip)
+ {
+ $constraint = new Ip(array(
+ 'version' => Ip::ALL_ONLY_PUBLIC,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($ip, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$ip.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidPublicIpsAll()
+ {
+ return array_merge($this->getInvalidPublicIpsV4(), $this->getInvalidPublicIpsV6());
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IsbnValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IsbnValidatorTest.php
new file mode 100644
index 0000000..e73b89d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IsbnValidatorTest.php
@@ -0,0 +1,271 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Isbn;
+use Symfony\Component\Validator\Constraints\IsbnValidator;
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @see https://en.wikipedia.org/wiki/Isbn
+ */
+class IsbnValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new IsbnValidator();
+ }
+
+ public function getValidIsbn10()
+ {
+ return array(
+ array('2723442284'),
+ array('2723442276'),
+ array('2723455041'),
+ array('2070546810'),
+ array('2711858839'),
+ array('2756406767'),
+ array('2870971648'),
+ array('226623854X'),
+ array('2851806424'),
+ array('0321812700'),
+ array('0-45122-5244'),
+ array('0-4712-92311'),
+ array('0-9752298-0-X'),
+ );
+ }
+
+ public function getInvalidIsbn10()
+ {
+ return array(
+ array('27234422841', Isbn::TOO_LONG_ERROR),
+ array('272344228', Isbn::TOO_SHORT_ERROR),
+ array('0-4712-9231', Isbn::TOO_SHORT_ERROR),
+ array('1234567890', Isbn::CHECKSUM_FAILED_ERROR),
+ array('0987656789', Isbn::CHECKSUM_FAILED_ERROR),
+ array('7-35622-5444', Isbn::CHECKSUM_FAILED_ERROR),
+ array('0-4X19-92611', Isbn::CHECKSUM_FAILED_ERROR),
+ array('0_45122_5244', Isbn::INVALID_CHARACTERS_ERROR),
+ array('2870#971#648', Isbn::INVALID_CHARACTERS_ERROR),
+ array('0-9752298-0-x', Isbn::INVALID_CHARACTERS_ERROR),
+ array('1A34567890', Isbn::INVALID_CHARACTERS_ERROR),
+ // chr(1) evaluates to 0
+ // 2070546810 is valid
+ array('2'.chr(1).'70546810', Isbn::INVALID_CHARACTERS_ERROR),
+ );
+ }
+
+ public function getValidIsbn13()
+ {
+ return array(
+ array('978-2723442282'),
+ array('978-2723442275'),
+ array('978-2723455046'),
+ array('978-2070546817'),
+ array('978-2711858835'),
+ array('978-2756406763'),
+ array('978-2870971642'),
+ array('978-2266238540'),
+ array('978-2851806420'),
+ array('978-0321812704'),
+ array('978-0451225245'),
+ array('978-0471292319'),
+ );
+ }
+
+ public function getInvalidIsbn13()
+ {
+ return array(
+ array('978-27234422821', Isbn::TOO_LONG_ERROR),
+ array('978-272344228', Isbn::TOO_SHORT_ERROR),
+ array('978-2723442-82', Isbn::TOO_SHORT_ERROR),
+ array('978-2723442281', Isbn::CHECKSUM_FAILED_ERROR),
+ array('978-0321513774', Isbn::CHECKSUM_FAILED_ERROR),
+ array('979-0431225385', Isbn::CHECKSUM_FAILED_ERROR),
+ array('980-0474292319', Isbn::CHECKSUM_FAILED_ERROR),
+ array('0-4X19-92619812', Isbn::INVALID_CHARACTERS_ERROR),
+ array('978_2723442282', Isbn::INVALID_CHARACTERS_ERROR),
+ array('978#2723442282', Isbn::INVALID_CHARACTERS_ERROR),
+ array('978-272C442282', Isbn::INVALID_CHARACTERS_ERROR),
+ // chr(1) evaluates to 0
+ // 978-2070546817 is valid
+ array('978-2'.chr(1).'70546817', Isbn::INVALID_CHARACTERS_ERROR),
+ );
+ }
+
+ public function getValidIsbn()
+ {
+ return array_merge(
+ $this->getValidIsbn10(),
+ $this->getValidIsbn13()
+ );
+ }
+
+ public function getInvalidIsbn()
+ {
+ return array_merge(
+ $this->getInvalidIsbn10(),
+ $this->getInvalidIsbn13()
+ );
+ }
+
+ public function testNullIsValid()
+ {
+ $constraint = new Isbn(true);
+
+ $this->validator->validate(null, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $constraint = new Isbn(true);
+
+ $this->validator->validate('', $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $constraint = new Isbn(true);
+
+ $this->validator->validate(new \stdClass(), $constraint);
+ }
+
+ /**
+ * @dataProvider getValidIsbn10
+ */
+ public function testValidIsbn10($isbn)
+ {
+ $constraint = new Isbn(array(
+ 'type' => 'isbn10',
+ ));
+
+ $this->validator->validate($isbn, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getInvalidIsbn10
+ */
+ public function testInvalidIsbn10($isbn, $code)
+ {
+ $constraint = new Isbn(array(
+ 'type' => 'isbn10',
+ 'isbn10Message' => 'myMessage',
+ ));
+
+ $this->validator->validate($isbn, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$isbn.'"')
+ ->setCode($code)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getValidIsbn13
+ */
+ public function testValidIsbn13($isbn)
+ {
+ $constraint = new Isbn(array('type' => 'isbn13'));
+
+ $this->validator->validate($isbn, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getInvalidIsbn13
+ */
+ public function testInvalidIsbn13($isbn, $code)
+ {
+ $constraint = new Isbn(array(
+ 'type' => 'isbn13',
+ 'isbn13Message' => 'myMessage',
+ ));
+
+ $this->validator->validate($isbn, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$isbn.'"')
+ ->setCode($code)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getValidIsbn
+ */
+ public function testValidIsbnAny($isbn)
+ {
+ $constraint = new Isbn();
+
+ $this->validator->validate($isbn, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getInvalidIsbn10
+ */
+ public function testInvalidIsbnAnyIsbn10($isbn, $code)
+ {
+ $constraint = new Isbn(array(
+ 'bothIsbnMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($isbn, $constraint);
+
+ // Too long for an ISBN-10, but not long enough for an ISBN-13
+ if (Isbn::TOO_LONG_ERROR === $code) {
+ $code = Isbn::TYPE_NOT_RECOGNIZED_ERROR;
+ }
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$isbn.'"')
+ ->setCode($code)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getInvalidIsbn13
+ */
+ public function testInvalidIsbnAnyIsbn13($isbn, $code)
+ {
+ $constraint = new Isbn(array(
+ 'bothIsbnMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($isbn, $constraint);
+
+ // Too short for an ISBN-13, but not short enough for an ISBN-10
+ if (Isbn::TOO_SHORT_ERROR === $code) {
+ $code = Isbn::TYPE_NOT_RECOGNIZED_ERROR;
+ }
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$isbn.'"')
+ ->setCode($code)
+ ->assertRaised();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IssnValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IssnValidatorTest.php
new file mode 100644
index 0000000..a6d3994
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IssnValidatorTest.php
@@ -0,0 +1,187 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Issn;
+use Symfony\Component\Validator\Constraints\IssnValidator;
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @see https://en.wikipedia.org/wiki/Issn
+ */
+class IssnValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new IssnValidator();
+ }
+
+ public function getValidLowerCasedIssn()
+ {
+ return array(
+ array('2162-321x'),
+ array('2160-200x'),
+ array('1537-453x'),
+ array('1937-710x'),
+ array('0002-922x'),
+ array('1553-345x'),
+ array('1553-619x'),
+ );
+ }
+
+ public function getValidNonHyphenatedIssn()
+ {
+ return array(
+ array('2162321X'),
+ array('01896016'),
+ array('15744647'),
+ array('14350645'),
+ array('07174055'),
+ array('20905076'),
+ array('14401592'),
+ );
+ }
+
+ public function getFullValidIssn()
+ {
+ return array(
+ array('1550-7416'),
+ array('1539-8560'),
+ array('2156-5376'),
+ array('1119-023X'),
+ array('1684-5315'),
+ array('1996-0786'),
+ array('1684-5374'),
+ array('1996-0794'),
+ );
+ }
+
+ public function getValidIssn()
+ {
+ return array_merge(
+ $this->getValidLowerCasedIssn(),
+ $this->getValidNonHyphenatedIssn(),
+ $this->getFullValidIssn()
+ );
+ }
+
+ public function getInvalidIssn()
+ {
+ return array(
+ array(0, Issn::TOO_SHORT_ERROR),
+ array('1539', Issn::TOO_SHORT_ERROR),
+ array('2156-537A', Issn::INVALID_CHARACTERS_ERROR),
+ array('1119-0231', Issn::CHECKSUM_FAILED_ERROR),
+ array('1684-5312', Issn::CHECKSUM_FAILED_ERROR),
+ array('1996-0783', Issn::CHECKSUM_FAILED_ERROR),
+ array('1684-537X', Issn::CHECKSUM_FAILED_ERROR),
+ array('1996-0795', Issn::CHECKSUM_FAILED_ERROR),
+ );
+ }
+
+ public function testNullIsValid()
+ {
+ $constraint = new Issn();
+
+ $this->validator->validate(null, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $constraint = new Issn();
+
+ $this->validator->validate('', $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $constraint = new Issn();
+ $this->validator->validate(new \stdClass(), $constraint);
+ }
+
+ /**
+ * @dataProvider getValidLowerCasedIssn
+ */
+ public function testCaseSensitiveIssns($issn)
+ {
+ $constraint = new Issn(array(
+ 'caseSensitive' => true,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($issn, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$issn.'"')
+ ->setCode(Issn::INVALID_CASE_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getValidNonHyphenatedIssn
+ */
+ public function testRequireHyphenIssns($issn)
+ {
+ $constraint = new Issn(array(
+ 'requireHyphen' => true,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($issn, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$issn.'"')
+ ->setCode(Issn::MISSING_HYPHEN_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getValidIssn
+ */
+ public function testValidIssn($issn)
+ {
+ $constraint = new Issn();
+
+ $this->validator->validate($issn, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getInvalidIssn
+ */
+ public function testInvalidIssn($issn, $code)
+ {
+ $constraint = new Issn(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($issn, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$issn.'"')
+ ->setCode($code)
+ ->assertRaised();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php
new file mode 100644
index 0000000..6f7c390
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php
@@ -0,0 +1,114 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Intl\Util\IntlTestHelper;
+use Symfony\Component\Validator\Constraints\Language;
+use Symfony\Component\Validator\Constraints\LanguageValidator;
+use Symfony\Component\Validator\Validation;
+
+class LanguageValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new LanguageValidator();
+ }
+
+ protected function setUp()
+ {
+ IntlTestHelper::requireFullIntl($this);
+
+ parent::setUp();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Language());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Language());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $this->validator->validate(new \stdClass(), new Language());
+ }
+
+ /**
+ * @dataProvider getValidLanguages
+ */
+ public function testValidLanguages($language)
+ {
+ $this->validator->validate($language, new Language());
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidLanguages()
+ {
+ return array(
+ array('en'),
+ array('en_US'),
+ array('my'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidLanguages
+ */
+ public function testInvalidLanguages($language)
+ {
+ $constraint = new Language(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($language, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$language.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidLanguages()
+ {
+ return array(
+ array('EN'),
+ array('foobar'),
+ );
+ }
+
+ public function testValidateUsingCountrySpecificLocale()
+ {
+ \Locale::setDefault('fr_FR');
+ $existingLanguage = 'en';
+
+ $this->validator->validate($existingLanguage, new Language(array(
+ 'message' => 'aMessage',
+ )));
+
+ $this->assertNoViolation();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyAllValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyAllValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..d5a41fb
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyAllValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyAllValidator2Dot4ApiTest extends AllValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyAllValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyAllValidatorLegacyApiTest.php
new file mode 100644
index 0000000..649bfe1
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyAllValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyAllValidatorLegacyApiTest extends AllValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyBlankValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyBlankValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..0cfb1aa
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyBlankValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyBlankValidator2Dot4ApiTest extends BlankValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyBlankValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyBlankValidatorLegacyApiTest.php
new file mode 100644
index 0000000..00b8a7a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyBlankValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyBlankValidatorLegacyApiTest extends BlankValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCallbackValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCallbackValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..efcb5ec
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCallbackValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyCallbackValidator2Dot4ApiTest extends CallbackValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCallbackValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCallbackValidatorLegacyApiTest.php
new file mode 100644
index 0000000..8f3ea2b
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCallbackValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyCallbackValidatorLegacyApiTest extends CallbackValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCardSchemeValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCardSchemeValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..0f467dd
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCardSchemeValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyCardSchemeValidator2Dot4ApiTest extends CardSchemeValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCardSchemeValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCardSchemeValidatorLegacyApiTest.php
new file mode 100644
index 0000000..e4b4184
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCardSchemeValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyCardSchemeValidatorLegacyApiTest extends CardSchemeValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyChoiceValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyChoiceValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..71277f7
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyChoiceValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyChoiceValidator2Dot4ApiTest extends ChoiceValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyChoiceValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyChoiceValidatorLegacyApiTest.php
new file mode 100644
index 0000000..9237df5
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyChoiceValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyChoiceValidatorLegacyApiTest extends ChoiceValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArray2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArray2Dot4ApiTest.php
new file mode 100644
index 0000000..3826914
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArray2Dot4ApiTest.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @group legacy
+ */
+class LegacyCollectionValidatorArray2Dot4ApiTest extends CollectionValidatorArrayTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayLegacyApiTest.php
new file mode 100644
index 0000000..45ca1df
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayLegacyApiTest.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @group legacy
+ */
+class LegacyCollectionValidatorArrayLegacyApiTest extends CollectionValidatorArrayTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayObject2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayObject2Dot4ApiTest.php
new file mode 100644
index 0000000..22dbe46
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayObject2Dot4ApiTest.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @group legacy
+ */
+class LegacyCollectionValidatorArrayObject2Dot4ApiTest extends CollectionValidatorArrayObjectTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayObjectLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayObjectLegacyApiTest.php
new file mode 100644
index 0000000..f28aed3
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorArrayObjectLegacyApiTest.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @group legacy
+ */
+class LegacyCollectionValidatorArrayObjectLegacyApiTest extends CollectionValidatorArrayObjectTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorCustomArrayObject2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorCustomArrayObject2Dot4ApiTest.php
new file mode 100644
index 0000000..29ce241
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorCustomArrayObject2Dot4ApiTest.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @group legacy
+ */
+class LegacyCollectionValidatorCustomArrayObject2Dot4ApiTest extends CollectionValidatorCustomArrayObjectTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorCustomArrayObjectLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorCustomArrayObjectLegacyApiTest.php
new file mode 100644
index 0000000..b04053f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCollectionValidatorCustomArrayObjectLegacyApiTest.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @group legacy
+ */
+class LegacyCollectionValidatorCustomArrayObjectLegacyApiTest extends CollectionValidatorCustomArrayObjectTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorArray2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorArray2Dot4ApiTest.php
new file mode 100644
index 0000000..2ab8b19
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorArray2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyCountValidatorArray2Dot4ApiTest extends CountValidatorArrayTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorArrayLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorArrayLegacyApiTest.php
new file mode 100644
index 0000000..d362988
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorArrayLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyCountValidatorArrayLegacyApiTest extends CountValidatorArrayTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorCountable2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorCountable2Dot4ApiTest.php
new file mode 100644
index 0000000..d0239bb
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorCountable2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyCountValidatorCountable2Dot4ApiTest extends CountValidatorCountableTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorCountableLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorCountableLegacyApiTest.php
new file mode 100644
index 0000000..33b8795
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCountValidatorCountableLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyCountValidatorCountableLegacyApiTest extends CountValidatorCountableTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCurrencyValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCurrencyValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..30685d4
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCurrencyValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyCurrencyValidator2Dot4ApiTest extends CurrencyValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCurrencyValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCurrencyValidatorLegacyApiTest.php
new file mode 100644
index 0000000..85cd5d0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyCurrencyValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyCurrencyValidatorLegacyApiTest extends CurrencyValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateTimeValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateTimeValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..6c2f6a5
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateTimeValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyDateTimeValidator2Dot4ApiTest extends DateTimeValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateTimeValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateTimeValidatorLegacyApiTest.php
new file mode 100644
index 0000000..be19302
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateTimeValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyDateTimeValidatorLegacyApiTest extends DateTimeValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..aab7d43
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyDateValidator2Dot4ApiTest extends DateValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateValidatorLegacyApiTest.php
new file mode 100644
index 0000000..3235f42
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyDateValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyDateValidatorLegacyApiTest extends DateValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEmailValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEmailValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..12ccb5e
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEmailValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyEmailValidator2Dot4ApiTest extends EmailValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEmailValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEmailValidatorLegacyApiTest.php
new file mode 100644
index 0000000..e5f1019
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEmailValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyEmailValidatorLegacyApiTest extends EmailValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEqualToValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEqualToValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..1c7008a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEqualToValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyEqualToValidator2Dot4ApiTest extends EqualToValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEqualToValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEqualToValidatorLegacyApiTest.php
new file mode 100644
index 0000000..3a72cfb
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyEqualToValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyEqualToValidatorLegacyApiTest extends EqualToValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyExpressionValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyExpressionValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..914e580
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyExpressionValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyExpressionValidator2Dot4ApiTest extends ExpressionValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyExpressionValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyExpressionValidatorLegacyApiTest.php
new file mode 100644
index 0000000..374bba0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyExpressionValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyExpressionValidatorLegacyApiTest extends ExpressionValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFalseValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFalseValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..3d65f4e
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFalseValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyFalseValidator2Dot4ApiTest extends FalseValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFalseValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFalseValidatorLegacyApiTest.php
new file mode 100644
index 0000000..5f7cb12
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFalseValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyFalseValidatorLegacyApiTest extends FalseValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorObject2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorObject2Dot4ApiTest.php
new file mode 100644
index 0000000..3035e41
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorObject2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyFileValidatorObject2Dot4ApiTest extends FileValidatorObjectTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorObjectLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorObjectLegacyApiTest.php
new file mode 100644
index 0000000..97d5f59
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorObjectLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyFileValidatorObjectLegacyApiTest extends FileValidatorObjectTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorPath2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorPath2Dot4ApiTest.php
new file mode 100644
index 0000000..a154144
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorPath2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyFileValidatorPath2Dot4ApiTest extends FileValidatorPathTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorPathLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorPathLegacyApiTest.php
new file mode 100644
index 0000000..2c298df
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyFileValidatorPathLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyFileValidatorPathLegacyApiTest extends FileValidatorPathTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanOrEqualValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanOrEqualValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..5f4a17e
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanOrEqualValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyGreaterThanOrEqualValidator2Dot4ApiTest extends GreaterThanOrEqualValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanOrEqualValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanOrEqualValidatorLegacyApiTest.php
new file mode 100644
index 0000000..08822a5
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanOrEqualValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyGreaterThanOrEqualValidatorLegacyApiTest extends GreaterThanOrEqualValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..799e5d8
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyGreaterThanValidator2Dot4ApiTest extends GreaterThanValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanValidatorLegacyApiTest.php
new file mode 100644
index 0000000..0808e9b
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyGreaterThanValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyGreaterThanValidatorLegacyApiTest extends GreaterThanValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIbanValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIbanValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..6dac309
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIbanValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyIbanValidator2Dot4ApiTest extends IbanValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIbanValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIbanValidatorLegacyApiTest.php
new file mode 100644
index 0000000..0ffc4b1
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIbanValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyIbanValidatorLegacyApiTest extends IbanValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIdenticalToValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIdenticalToValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..99cd986
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIdenticalToValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyIdenticalToValidator2Dot4ApiTest extends IdenticalToValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIdenticalToValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIdenticalToValidatorLegacyApiTest.php
new file mode 100644
index 0000000..aade84f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIdenticalToValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyIdenticalToValidatorLegacyApiTest extends IdenticalToValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyImageValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyImageValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..1fee081
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyImageValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyImageValidator2Dot4ApiTest extends ImageValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyImageValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyImageValidatorLegacyApiTest.php
new file mode 100644
index 0000000..d36c175
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyImageValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyImageValidatorLegacyApiTest extends ImageValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIpValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIpValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..99933cf
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIpValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyIpValidator2Dot4ApiTest extends IpValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIpValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIpValidatorLegacyApiTest.php
new file mode 100644
index 0000000..315f2f9
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIpValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyIpValidatorLegacyApiTest extends IpValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIsbnValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIsbnValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..29455bd
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIsbnValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyIsbnValidator2Dot4ApiTest extends IsbnValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIsbnValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIsbnValidatorLegacyApiTest.php
new file mode 100644
index 0000000..1568270
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIsbnValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyIsbnValidatorLegacyApiTest extends IsbnValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIssnValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIssnValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..3713fb0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIssnValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyIssnValidator2Dot4ApiTest extends IssnValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIssnValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIssnValidatorLegacyApiTest.php
new file mode 100644
index 0000000..2ff3104
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyIssnValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyIssnValidatorLegacyApiTest extends IssnValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLanguageValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLanguageValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..f712075
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLanguageValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyLanguageValidator2Dot4ApiTest extends LanguageValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLanguageValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLanguageValidatorLegacyApiTest.php
new file mode 100644
index 0000000..a6471b3
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLanguageValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyLanguageValidatorLegacyApiTest extends LanguageValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLengthValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLengthValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..686d376
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLengthValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyLengthValidator2Dot4ApiTest extends LengthValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLengthValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLengthValidatorLegacyApiTest.php
new file mode 100644
index 0000000..655f3d6
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLengthValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyLengthValidatorLegacyApiTest extends LengthValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanOrEqualValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanOrEqualValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..f345ec3
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanOrEqualValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyLessThanOrEqualValidator2Dot4ApiTest extends LessThanOrEqualValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanOrEqualValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanOrEqualValidatorLegacyApiTest.php
new file mode 100644
index 0000000..2e07ab0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanOrEqualValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyLessThanOrEqualValidatorLegacyApiTest extends LessThanOrEqualValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..074450d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyLessThanValidator2Dot4ApiTest extends LessThanValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanValidatorLegacyApiTest.php
new file mode 100644
index 0000000..27592b0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLessThanValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyLessThanValidatorLegacyApiTest extends LessThanValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLocaleValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLocaleValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..4d119bb
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLocaleValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyLocaleValidator2Dot4ApiTest extends LocaleValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLocaleValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLocaleValidatorLegacyApiTest.php
new file mode 100644
index 0000000..f55d422
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLocaleValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyLocaleValidatorLegacyApiTest extends LocaleValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLuhnValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLuhnValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..8207ca0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLuhnValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyLuhnValidator2Dot4ApiTest extends LuhnValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLuhnValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLuhnValidatorLegacyApiTest.php
new file mode 100644
index 0000000..5855526
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyLuhnValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyLuhnValidatorLegacyApiTest extends LuhnValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotBlankValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotBlankValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..a6d0faa
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotBlankValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyNotBlankValidator2Dot4ApiTest extends NotBlankValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotBlankValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotBlankValidatorLegacyApiTest.php
new file mode 100644
index 0000000..0aaaa77
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotBlankValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyNotBlankValidatorLegacyApiTest extends NotBlankValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotEqualToValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotEqualToValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..e48450e
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotEqualToValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyNotEqualToValidator2Dot4ApiTest extends NotEqualToValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotEqualToValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotEqualToValidatorLegacyApiTest.php
new file mode 100644
index 0000000..df88f96
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotEqualToValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyNotEqualToValidatorLegacyApiTest extends NotEqualToValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotIdenticalToValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotIdenticalToValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..2c00cf5
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotIdenticalToValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyNotIdenticalToValidator2Dot4ApiTest extends NotIdenticalToValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotIdenticalToValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotIdenticalToValidatorLegacyApiTest.php
new file mode 100644
index 0000000..25819a6
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotIdenticalToValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyNotIdenticalToValidatorLegacyApiTest extends NotIdenticalToValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotNullValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotNullValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..39b0038
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotNullValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyNotNullValidator2Dot4ApiTest extends NotNullValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotNullValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotNullValidatorLegacyApiTest.php
new file mode 100644
index 0000000..41a9e54
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNotNullValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyNotNullValidatorLegacyApiTest extends NotNullValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNullValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNullValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..958e446
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNullValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyNullValidator2Dot4ApiTest extends NullValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNullValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNullValidatorLegacyApiTest.php
new file mode 100644
index 0000000..79536ce
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyNullValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyNullValidatorLegacyApiTest extends NullValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRangeValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRangeValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..fe23ce8
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRangeValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyRangeValidator2Dot4ApiTest extends RangeValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRangeValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRangeValidatorLegacyApiTest.php
new file mode 100644
index 0000000..866a59a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRangeValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyRangeValidatorLegacyApiTest extends RangeValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRegexValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRegexValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..dbae24e
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRegexValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyRegexValidator2Dot4ApiTest extends RegexValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRegexValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRegexValidatorLegacyApiTest.php
new file mode 100644
index 0000000..ed1a464
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyRegexValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyRegexValidatorLegacyApiTest extends RegexValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTimeValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTimeValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..d4a0678
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTimeValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyTimeValidator2Dot4ApiTest extends TimeValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTimeValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTimeValidatorLegacyApiTest.php
new file mode 100644
index 0000000..2458d87
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTimeValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyTimeValidatorLegacyApiTest extends TimeValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTrueValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTrueValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..3d00252
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTrueValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyTrueValidator2Dot4ApiTest extends TrueValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTrueValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTrueValidatorLegacyApiTest.php
new file mode 100644
index 0000000..706c083
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTrueValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyTrueValidatorLegacyApiTest extends TrueValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTypeValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTypeValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..aed1d0a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTypeValidator2Dot4ApiTest.php
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyTypeValidator2Dot4ApiTest extends TypeValidatorTest
+{
+ /**
+ * PhpUnit calls data providers of test suites before launching the test
+ * suite. If this property is not replicated in every test class, only one
+ * file will ever be created and stored in TypeValidatorTest::$file. After
+ * the execution of the first TypeValidator test case, tearDownAfterClass()
+ * is called and closes the file. Hence the resource is not available
+ * anymore in the other TypeValidator test cases.
+ */
+ protected static $file;
+
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTypeValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTypeValidatorLegacyApiTest.php
new file mode 100644
index 0000000..26eb39f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyTypeValidatorLegacyApiTest.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyTypeValidatorLegacyApiTest extends TypeValidatorTest
+{
+ protected static $file;
+
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUrlValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUrlValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..287d719
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUrlValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyUrlValidator2Dot4ApiTest extends UrlValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUrlValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUrlValidatorLegacyApiTest.php
new file mode 100644
index 0000000..0830ddb
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUrlValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyUrlValidatorLegacyApiTest extends UrlValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUuidValidator2Dot4ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUuidValidator2Dot4ApiTest.php
new file mode 100644
index 0000000..b5efc76
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUuidValidator2Dot4ApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyUuidValidator2Dot4ApiTest extends UrlValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_4;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUuidValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUuidValidatorLegacyApiTest.php
new file mode 100644
index 0000000..4a4e362
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LegacyUuidValidatorLegacyApiTest.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @since 2.5.3
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @group legacy
+ */
+class LegacyUuidValidatorLegacyApiTest extends UuidValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5_BC;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LengthValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LengthValidatorTest.php
new file mode 100644
index 0000000..24b6306
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LengthValidatorTest.php
@@ -0,0 +1,255 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Length;
+use Symfony\Component\Validator\Constraints\LengthValidator;
+use Symfony\Component\Validator\Validation;
+
+class LengthValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new LengthValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Length(6));
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Length(6));
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $this->validator->validate(new \stdClass(), new Length(5));
+ }
+
+ public function getThreeOrLessCharacters()
+ {
+ return array(
+ array(12),
+ array('12'),
+ array('üü'),
+ array('éé'),
+ array(123),
+ array('123'),
+ array('üüü'),
+ array('ééé'),
+ );
+ }
+
+ public function getFourCharacters()
+ {
+ return array(
+ array(1234),
+ array('1234'),
+ array('üüüü'),
+ array('éééé'),
+ );
+ }
+
+ public function getFiveOrMoreCharacters()
+ {
+ return array(
+ array(12345),
+ array('12345'),
+ array('üüüüü'),
+ array('ééééé'),
+ array(123456),
+ array('123456'),
+ array('üüüüüü'),
+ array('éééééé'),
+ );
+ }
+
+ public function getOneCharset()
+ {
+ if (!function_exists('iconv') && !function_exists('mb_convert_encoding')) {
+ $this->markTestSkipped('Mbstring or iconv is required for this test.');
+ }
+
+ return array(
+ array('é', 'utf8', true),
+ array("\xE9", 'CP1252', true),
+ array("\xE9", 'XXX', false),
+ array("\xE9", 'utf8', false),
+ );
+ }
+
+ /**
+ * @dataProvider getFiveOrMoreCharacters
+ */
+ public function testValidValuesMin($value)
+ {
+ $constraint = new Length(array('min' => 5));
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getThreeOrLessCharacters
+ */
+ public function testValidValuesMax($value)
+ {
+ $constraint = new Length(array('max' => 3));
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getFourCharacters
+ */
+ public function testValidValuesExact($value)
+ {
+ $constraint = new Length(4);
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getThreeOrLessCharacters
+ */
+ public function testInvalidValuesMin($value)
+ {
+ $constraint = new Length(array(
+ 'min' => 4,
+ 'minMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$value.'"')
+ ->setParameter('{{ limit }}', 4)
+ ->setInvalidValue($value)
+ ->setPlural(4)
+ ->setCode(Length::TOO_SHORT_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getFiveOrMoreCharacters
+ */
+ public function testInvalidValuesMax($value)
+ {
+ $constraint = new Length(array(
+ 'max' => 4,
+ 'maxMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$value.'"')
+ ->setParameter('{{ limit }}', 4)
+ ->setInvalidValue($value)
+ ->setPlural(4)
+ ->setCode(Length::TOO_LONG_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getThreeOrLessCharacters
+ */
+ public function testInvalidValuesExactLessThanFour($value)
+ {
+ $constraint = new Length(array(
+ 'min' => 4,
+ 'max' => 4,
+ 'exactMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$value.'"')
+ ->setParameter('{{ limit }}', 4)
+ ->setInvalidValue($value)
+ ->setPlural(4)
+ ->setCode(Length::TOO_SHORT_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getFiveOrMoreCharacters
+ */
+ public function testInvalidValuesExactMoreThanFour($value)
+ {
+ $constraint = new Length(array(
+ 'min' => 4,
+ 'max' => 4,
+ 'exactMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$value.'"')
+ ->setParameter('{{ limit }}', 4)
+ ->setInvalidValue($value)
+ ->setPlural(4)
+ ->setCode(Length::TOO_LONG_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getOneCharset
+ */
+ public function testOneCharset($value, $charset, $isValid)
+ {
+ $constraint = new Length(array(
+ 'min' => 1,
+ 'max' => 1,
+ 'charset' => $charset,
+ 'charsetMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ if ($isValid) {
+ $this->assertNoViolation();
+ } else {
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$value.'"')
+ ->setParameter('{{ charset }}', $charset)
+ ->setInvalidValue($value)
+ ->assertRaised();
+ }
+ }
+
+ public function testConstraintGetDefaultOption()
+ {
+ $constraint = new Length(5);
+
+ $this->assertEquals(5, $constraint->min);
+ $this->assertEquals(5, $constraint->max);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php
new file mode 100644
index 0000000..7518135
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\LessThanOrEqual;
+use Symfony\Component\Validator\Constraints\LessThanOrEqualValidator;
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class LessThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCase
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new LessThanOrEqualValidator();
+ }
+
+ protected function createConstraint(array $options)
+ {
+ return new LessThanOrEqual($options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideValidComparisons()
+ {
+ return array(
+ array(1, 2),
+ array(1, 1),
+ array(new \DateTime('2000-01-01'), new \DateTime('2000-01-01')),
+ array(new \DateTime('2000-01-01'), new \DateTime('2020-01-01')),
+ array(new \DateTime('2000-01-01'), '2000-01-01'),
+ array(new \DateTime('2000-01-01'), '2020-01-01'),
+ array(new \DateTime('2000-01-01 UTC'), '2000-01-01 UTC'),
+ array(new \DateTime('2000-01-01 UTC'), '2020-01-01 UTC'),
+ array(new ComparisonTest_Class(4), new ComparisonTest_Class(5)),
+ array(new ComparisonTest_Class(5), new ComparisonTest_Class(5)),
+ array('a', 'a'),
+ array('a', 'z'),
+ array(null, 1),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideInvalidComparisons()
+ {
+ return array(
+ array(2, '2', 1, '1', 'integer'),
+ array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', '2000-01-01', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2010-01-01 UTC'), 'Jan 1, 2010, 12:00 AM', '2000-01-01 UTC', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(4), '4', __NAMESPACE__.'\ComparisonTest_Class'),
+ array('c', '"c"', 'b', '"b"', 'string'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php
new file mode 100644
index 0000000..d555870
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\LessThan;
+use Symfony\Component\Validator\Constraints\LessThanValidator;
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class LessThanValidatorTest extends AbstractComparisonValidatorTestCase
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new LessThanValidator();
+ }
+
+ protected function createConstraint(array $options)
+ {
+ return new LessThan($options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideValidComparisons()
+ {
+ return array(
+ array(1, 2),
+ array(new \DateTime('2000-01-01'), new \DateTime('2010-01-01')),
+ array(new \DateTime('2000-01-01'), '2010-01-01'),
+ array(new \DateTime('2000-01-01 UTC'), '2010-01-01 UTC'),
+ array(new ComparisonTest_Class(4), new ComparisonTest_Class(5)),
+ array('22', '333'),
+ array(null, 1),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideInvalidComparisons()
+ {
+ return array(
+ array(3, '3', 2, '2', 'integer'),
+ array(2, '2', 2, '2', 'integer'),
+ array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', '2000-01-01', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', '2000-01-01', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2010-01-01 UTC'), 'Jan 1, 2010, 12:00 AM', '2000-01-01 UTC', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2000-01-01 UTC'), 'Jan 1, 2000, 12:00 AM', '2000-01-01 UTC', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
+ array(new ComparisonTest_Class(6), '6', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
+ array('333', '"333"', '22', '"22"', 'string'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.php
new file mode 100644
index 0000000..e5e2f30
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.php
@@ -0,0 +1,104 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Intl\Util\IntlTestHelper;
+use Symfony\Component\Validator\Constraints\Locale;
+use Symfony\Component\Validator\Constraints\LocaleValidator;
+use Symfony\Component\Validator\Validation;
+
+class LocaleValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new LocaleValidator();
+ }
+
+ protected function setUp()
+ {
+ IntlTestHelper::requireIntl($this);
+
+ parent::setUp();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Locale());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Locale());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $this->validator->validate(new \stdClass(), new Locale());
+ }
+
+ /**
+ * @dataProvider getValidLocales
+ */
+ public function testValidLocales($locale)
+ {
+ $this->validator->validate($locale, new Locale());
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidLocales()
+ {
+ return array(
+ array('en'),
+ array('en_US'),
+ array('pt'),
+ array('pt_PT'),
+ array('zh_Hans'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidLocales
+ */
+ public function testInvalidLocales($locale)
+ {
+ $constraint = new Locale(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($locale, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$locale.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidLocales()
+ {
+ return array(
+ array('EN'),
+ array('foobar'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LuhnValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LuhnValidatorTest.php
new file mode 100644
index 0000000..b0e88c3
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LuhnValidatorTest.php
@@ -0,0 +1,127 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Luhn;
+use Symfony\Component\Validator\Constraints\LuhnValidator;
+use Symfony\Component\Validator\Validation;
+
+class LuhnValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new LuhnValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Luhn());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Luhn());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getValidNumbers
+ */
+ public function testValidNumbers($number)
+ {
+ $this->validator->validate($number, new Luhn());
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidNumbers()
+ {
+ return array(
+ array('42424242424242424242'),
+ array('378282246310005'),
+ array('371449635398431'),
+ array('378734493671000'),
+ array('5610591081018250'),
+ array('30569309025904'),
+ array('38520000023237'),
+ array('6011111111111117'),
+ array('6011000990139424'),
+ array('3530111333300000'),
+ array('3566002020360505'),
+ array('5555555555554444'),
+ array('5105105105105100'),
+ array('4111111111111111'),
+ array('4012888888881881'),
+ array('4222222222222'),
+ array('5019717010103742'),
+ array('6331101999990016'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidNumbers
+ */
+ public function testInvalidNumbers($number, $code)
+ {
+ $constraint = new Luhn(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($number, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$number.'"')
+ ->setCode($code)
+ ->assertRaised();
+ }
+
+ public function getInvalidNumbers()
+ {
+ return array(
+ array('1234567812345678', Luhn::CHECKSUM_FAILED_ERROR),
+ array('4222222222222222', Luhn::CHECKSUM_FAILED_ERROR),
+ array('0000000000000000', Luhn::CHECKSUM_FAILED_ERROR),
+ array('000000!000000000', Luhn::INVALID_CHARACTERS_ERROR),
+ array('42-22222222222222', Luhn::INVALID_CHARACTERS_ERROR),
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ * @dataProvider getInvalidTypes
+ */
+ public function testInvalidTypes($number)
+ {
+ $constraint = new Luhn();
+
+ $this->validator->validate($number, $constraint);
+ }
+
+ public function getInvalidTypes()
+ {
+ return array(
+ array(0),
+ array(123),
+ array(42424242424242424242),
+ array(378282246310005),
+ array(371449635398431),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php
new file mode 100644
index 0000000..c248246
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php
@@ -0,0 +1,102 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\NotBlank;
+use Symfony\Component\Validator\Constraints\NotBlankValidator;
+use Symfony\Component\Validator\Validation;
+
+class NotBlankValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new NotBlankValidator();
+ }
+
+ /**
+ * @dataProvider getValidValues
+ */
+ public function testValidValues($value)
+ {
+ $this->validator->validate($value, new NotBlank());
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidValues()
+ {
+ return array(
+ array('foobar'),
+ array(0),
+ array(0.0),
+ array('0'),
+ array(1234),
+ );
+ }
+
+ public function testNullIsInvalid()
+ {
+ $constraint = new NotBlank(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate(null, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', 'null')
+ ->assertRaised();
+ }
+
+ public function testBlankIsInvalid()
+ {
+ $constraint = new NotBlank(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate('', $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '""')
+ ->assertRaised();
+ }
+
+ public function testFalseIsInvalid()
+ {
+ $constraint = new NotBlank(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate(false, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', 'false')
+ ->assertRaised();
+ }
+
+ public function testEmptyArrayIsInvalid()
+ {
+ $constraint = new NotBlank(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate(array(), $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', 'array')
+ ->assertRaised();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php
new file mode 100644
index 0000000..bc2c348
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\NotEqualTo;
+use Symfony\Component\Validator\Constraints\NotEqualToValidator;
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class NotEqualToValidatorTest extends AbstractComparisonValidatorTestCase
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new NotEqualToValidator();
+ }
+
+ protected function createConstraint(array $options)
+ {
+ return new NotEqualTo($options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideValidComparisons()
+ {
+ return array(
+ array(1, 2),
+ array('22', '333'),
+ array(new \DateTime('2001-01-01'), new \DateTime('2000-01-01')),
+ array(new \DateTime('2001-01-01'), '2000-01-01'),
+ array(new \DateTime('2001-01-01 UTC'), '2000-01-01 UTC'),
+ array(new ComparisonTest_Class(6), new ComparisonTest_Class(5)),
+ array(null, 1),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideInvalidComparisons()
+ {
+ return array(
+ array(3, '3', 3, '3', 'integer'),
+ array('2', '"2"', 2, '2', 'integer'),
+ array('a', '"a"', 'a', '"a"', 'string'),
+ array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', '2000-01-01', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new \DateTime('2000-01-01 UTC'), 'Jan 1, 2000, 12:00 AM', '2000-01-01 UTC', 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php
new file mode 100644
index 0000000..1fbd806
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php
@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\NotIdenticalTo;
+use Symfony\Component\Validator\Constraints\NotIdenticalToValidator;
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @author Daniel Holmes <daniel@danielholmes.org>
+ */
+class NotIdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new NotIdenticalToValidator();
+ }
+
+ protected function createConstraint(array $options)
+ {
+ return new NotIdenticalTo($options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideValidComparisons()
+ {
+ return array(
+ array(1, 2),
+ array('2', 2),
+ array('22', '333'),
+ array(new \DateTime('2001-01-01'), new \DateTime('2000-01-01')),
+ array(new \DateTime('2000-01-01'), new \DateTime('2000-01-01')),
+ array(new \DateTime('2001-01-01'), '2000-01-01'),
+ array(new \DateTime('2000-01-01'), '2000-01-01'),
+ array(new \DateTime('2001-01-01'), '2000-01-01'),
+ array(new \DateTime('2000-01-01 UTC'), '2000-01-01 UTC'),
+ array(null, 1),
+ );
+ }
+
+ public function provideAllInvalidComparisons()
+ {
+ $this->setDefaultTimezone('UTC');
+
+ // Don't call addPhp5Dot5Comparisons() automatically, as it does
+ // not take care of identical objects
+ $comparisons = $this->provideInvalidComparisons();
+
+ $this->restoreDefaultTimezone();
+
+ return $comparisons;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function provideInvalidComparisons()
+ {
+ $date = new \DateTime('2000-01-01');
+ $object = new ComparisonTest_Class(2);
+
+ $comparisons = array(
+ array(3, '3', 3, '3', 'integer'),
+ array('a', '"a"', 'a', '"a"', 'string'),
+ array($date, 'Jan 1, 2000, 12:00 AM', $date, 'Jan 1, 2000, 12:00 AM', 'DateTime'),
+ array($object, '2', $object, '2', __NAMESPACE__.'\ComparisonTest_Class'),
+ );
+
+ if (version_compare(PHP_VERSION, '>=', '5.5')) {
+ $immutableDate = new \DateTimeImmutable('2000-01-01');
+ $comparisons[] = array($immutableDate, 'Jan 1, 2000, 12:00 AM', $immutableDate, 'Jan 1, 2000, 12:00 AM', 'DateTime');
+ }
+
+ return $comparisons;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.php
new file mode 100644
index 0000000..d338f31
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\Constraints\NotNullValidator;
+use Symfony\Component\Validator\Validation;
+
+class NotNullValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new NotNullValidator();
+ }
+
+ /**
+ * @dataProvider getValidValues
+ */
+ public function testValidValues($value)
+ {
+ $this->validator->validate($value, new NotNull());
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidValues()
+ {
+ return array(
+ array(0),
+ array(false),
+ array(true),
+ array(''),
+ );
+ }
+
+ public function testNullIsInvalid()
+ {
+ $constraint = new NotNull(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate(null, $constraint);
+
+ $this->buildViolation('myMessage')->assertRaised();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NullValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NullValidatorTest.php
new file mode 100644
index 0000000..85df90a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NullValidatorTest.php
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Null;
+use Symfony\Component\Validator\Constraints\NullValidator;
+use Symfony\Component\Validator\Validation;
+
+class NullValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new NullValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Null());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getInvalidValues
+ */
+ public function testInvalidValues($value, $valueAsString)
+ {
+ $constraint = new Null(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', $valueAsString)
+ ->assertRaised();
+ }
+
+ public function getInvalidValues()
+ {
+ return array(
+ array(0, '0'),
+ array(false, 'false'),
+ array(true, 'true'),
+ array('', '""'),
+ array('foo bar', '"foo bar"'),
+ array(new \DateTime(), 'object'),
+ array(new \stdClass(), 'object'),
+ array(array(), 'array'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php
new file mode 100644
index 0000000..9b7056b
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php
@@ -0,0 +1,403 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Intl\Util\IntlTestHelper;
+use Symfony\Component\Validator\Constraints\Range;
+use Symfony\Component\Validator\Constraints\RangeValidator;
+use Symfony\Component\Validator\Validation;
+
+class RangeValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new RangeValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Range(array('min' => 10, 'max' => 20)));
+
+ $this->assertNoViolation();
+ }
+
+ public function getTenToTwenty()
+ {
+ return array(
+ array(10.00001),
+ array(19.99999),
+ array('10.00001'),
+ array('19.99999'),
+ array(10),
+ array(20),
+ array(10.0),
+ array(20.0),
+ );
+ }
+
+ public function getLessThanTen()
+ {
+ return array(
+ array(9.99999, '9.99999'),
+ array('9.99999', '"9.99999"'),
+ array(5, '5'),
+ array(1.0, '1.0'),
+ );
+ }
+
+ public function getMoreThanTwenty()
+ {
+ return array(
+ array(20.000001, '20.000001'),
+ array('20.000001', '"20.000001"'),
+ array(21, '21'),
+ array(30.0, '30.0'),
+ );
+ }
+
+ /**
+ * @dataProvider getTenToTwenty
+ */
+ public function testValidValuesMin($value)
+ {
+ $constraint = new Range(array('min' => 10));
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getTenToTwenty
+ */
+ public function testValidValuesMax($value)
+ {
+ $constraint = new Range(array('max' => 20));
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getTenToTwenty
+ */
+ public function testValidValuesMinMax($value)
+ {
+ $constraint = new Range(array('min' => 10, 'max' => 20));
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getLessThanTen
+ */
+ public function testInvalidValuesMin($value, $formattedValue)
+ {
+ $constraint = new Range(array(
+ 'min' => 10,
+ 'minMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', $formattedValue)
+ ->setParameter('{{ limit }}', 10)
+ ->setCode(Range::BELOW_RANGE_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getMoreThanTwenty
+ */
+ public function testInvalidValuesMax($value, $formattedValue)
+ {
+ $constraint = new Range(array(
+ 'max' => 20,
+ 'maxMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', $formattedValue)
+ ->setParameter('{{ limit }}', 20)
+ ->setCode(Range::BEYOND_RANGE_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getMoreThanTwenty
+ */
+ public function testInvalidValuesCombinedMax($value, $formattedValue)
+ {
+ $constraint = new Range(array(
+ 'min' => 10,
+ 'max' => 20,
+ 'minMessage' => 'myMinMessage',
+ 'maxMessage' => 'myMaxMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMaxMessage')
+ ->setParameter('{{ value }}', $formattedValue)
+ ->setParameter('{{ limit }}', 20)
+ ->setCode(Range::BEYOND_RANGE_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getLessThanTen
+ */
+ public function testInvalidValuesCombinedMin($value, $formattedValue)
+ {
+ $constraint = new Range(array(
+ 'min' => 10,
+ 'max' => 20,
+ 'minMessage' => 'myMinMessage',
+ 'maxMessage' => 'myMaxMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMinMessage')
+ ->setParameter('{{ value }}', $formattedValue)
+ ->setParameter('{{ limit }}', 10)
+ ->setCode(Range::BELOW_RANGE_ERROR)
+ ->assertRaised();
+ }
+
+ public function getTenthToTwentiethMarch2014()
+ {
+ // The provider runs before setUp(), so we need to manually fix
+ // the default timezone
+ $this->setDefaultTimezone('UTC');
+
+ $tests = array(
+ array(new \DateTime('March 10, 2014')),
+ array(new \DateTime('March 15, 2014')),
+ array(new \DateTime('March 20, 2014')),
+ );
+
+ if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
+ $tests[] = array(new \DateTimeImmutable('March 10, 2014'));
+ $tests[] = array(new \DateTimeImmutable('March 15, 2014'));
+ $tests[] = array(new \DateTimeImmutable('March 20, 2014'));
+ }
+
+ $this->restoreDefaultTimezone();
+
+ return $tests;
+ }
+
+ public function getSoonerThanTenthMarch2014()
+ {
+ // The provider runs before setUp(), so we need to manually fix
+ // the default timezone
+ $this->setDefaultTimezone('UTC');
+
+ $tests = array(
+ array(new \DateTime('March 20, 2013'), 'Mar 20, 2013, 12:00 AM'),
+ array(new \DateTime('March 9, 2014'), 'Mar 9, 2014, 12:00 AM'),
+ );
+
+ if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
+ $tests[] = array(new \DateTimeImmutable('March 20, 2013'), 'Mar 20, 2013, 12:00 AM');
+ $tests[] = array(new \DateTimeImmutable('March 9, 2014'), 'Mar 9, 2014, 12:00 AM');
+ }
+
+ $this->restoreDefaultTimezone();
+
+ return $tests;
+ }
+
+ public function getLaterThanTwentiethMarch2014()
+ {
+ // The provider runs before setUp(), so we need to manually fix
+ // the default timezone
+ $this->setDefaultTimezone('UTC');
+
+ $tests = array(
+ array(new \DateTime('March 21, 2014'), 'Mar 21, 2014, 12:00 AM'),
+ array(new \DateTime('March 9, 2015'), 'Mar 9, 2015, 12:00 AM'),
+ );
+
+ if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
+ $tests[] = array(new \DateTimeImmutable('March 21, 2014'), 'Mar 21, 2014, 12:00 AM');
+ $tests[] = array(new \DateTimeImmutable('March 9, 2015'), 'Mar 9, 2015, 12:00 AM');
+ }
+
+ $this->restoreDefaultTimezone();
+
+ return $tests;
+ }
+
+ /**
+ * @dataProvider getTenthToTwentiethMarch2014
+ */
+ public function testValidDatesMin($value)
+ {
+ $constraint = new Range(array('min' => 'March 10, 2014'));
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getTenthToTwentiethMarch2014
+ */
+ public function testValidDatesMax($value)
+ {
+ $constraint = new Range(array('max' => 'March 20, 2014'));
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getTenthToTwentiethMarch2014
+ */
+ public function testValidDatesMinMax($value)
+ {
+ $constraint = new Range(array('min' => 'March 10, 2014', 'max' => 'March 20, 2014'));
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @dataProvider getSoonerThanTenthMarch2014
+ */
+ public function testInvalidDatesMin($value, $dateTimeAsString)
+ {
+ // Conversion of dates to string differs between ICU versions
+ // Make sure we have the correct version loaded
+ IntlTestHelper::requireIntl($this);
+
+ $constraint = new Range(array(
+ 'min' => 'March 10, 2014',
+ 'minMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', $dateTimeAsString)
+ ->setParameter('{{ limit }}', 'Mar 10, 2014, 12:00 AM')
+ ->setCode(Range::BELOW_RANGE_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getLaterThanTwentiethMarch2014
+ */
+ public function testInvalidDatesMax($value, $dateTimeAsString)
+ {
+ // Conversion of dates to string differs between ICU versions
+ // Make sure we have the correct version loaded
+ IntlTestHelper::requireIntl($this);
+
+ $constraint = new Range(array(
+ 'max' => 'March 20, 2014',
+ 'maxMessage' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', $dateTimeAsString)
+ ->setParameter('{{ limit }}', 'Mar 20, 2014, 12:00 AM')
+ ->setCode(Range::BEYOND_RANGE_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getLaterThanTwentiethMarch2014
+ */
+ public function testInvalidDatesCombinedMax($value, $dateTimeAsString)
+ {
+ // Conversion of dates to string differs between ICU versions
+ // Make sure we have the correct version loaded
+ IntlTestHelper::requireIntl($this);
+
+ $constraint = new Range(array(
+ 'min' => 'March 10, 2014',
+ 'max' => 'March 20, 2014',
+ 'minMessage' => 'myMinMessage',
+ 'maxMessage' => 'myMaxMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMaxMessage')
+ ->setParameter('{{ value }}', $dateTimeAsString)
+ ->setParameter('{{ limit }}', 'Mar 20, 2014, 12:00 AM')
+ ->setCode(Range::BEYOND_RANGE_ERROR)
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getSoonerThanTenthMarch2014
+ */
+ public function testInvalidDatesCombinedMin($value, $dateTimeAsString)
+ {
+ // Conversion of dates to string differs between ICU versions
+ // Make sure we have the correct version loaded
+ IntlTestHelper::requireIntl($this);
+
+ $constraint = new Range(array(
+ 'min' => 'March 10, 2014',
+ 'max' => 'March 20, 2014',
+ 'minMessage' => 'myMinMessage',
+ 'maxMessage' => 'myMaxMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMinMessage')
+ ->setParameter('{{ value }}', $dateTimeAsString)
+ ->setParameter('{{ limit }}', 'Mar 10, 2014, 12:00 AM')
+ ->setCode(Range::BELOW_RANGE_ERROR)
+ ->assertRaised();
+ }
+
+ public function getInvalidValues()
+ {
+ return array(
+ array(9.999999),
+ array(20.000001),
+ array('9.999999'),
+ array('20.000001'),
+ array(new \stdClass()),
+ );
+ }
+
+ public function testNonNumeric()
+ {
+ $this->validator->validate('abcd', new Range(array(
+ 'min' => 10,
+ 'max' => 20,
+ 'invalidMessage' => 'myMessage',
+ )));
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"abcd"')
+ ->setCode(Range::INVALID_VALUE_ERROR)
+ ->assertRaised();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RegexTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RegexTest.php
new file mode 100644
index 0000000..ea37bb4
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RegexTest.php
@@ -0,0 +1,87 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Constraints;
+
+use Symfony\Component\Validator\Constraints\Regex;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class RegexTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstraintGetDefaultOption()
+ {
+ $constraint = new Regex('/^[0-9]+$/');
+
+ $this->assertSame('/^[0-9]+$/', $constraint->pattern);
+ }
+
+ public function provideHtmlPatterns()
+ {
+ return array(
+ // HTML5 wraps the pattern in ^(?:pattern)$
+ array('/^[0-9]+$/', '[0-9]+'),
+ array('/[0-9]+$/', '.*[0-9]+'),
+ array('/^[0-9]+/', '[0-9]+.*'),
+ array('/[0-9]+/', '.*[0-9]+.*'),
+ // We need a smart way to allow matching of patterns that contain
+ // ^ and $ at various sub-clauses of an or-clause
+ // .*(pattern).* seems to work correctly
+ array('/[0-9]$|[a-z]+/', '.*([0-9]$|[a-z]+).*'),
+ array('/[0-9]$|^[a-z]+/', '.*([0-9]$|^[a-z]+).*'),
+ array('/^[0-9]|[a-z]+$/', '.*(^[0-9]|[a-z]+$).*'),
+ // Unescape escaped delimiters
+ array('/^[0-9]+\/$/', '[0-9]+/'),
+ array('#^[0-9]+\#$#', '[0-9]+#'),
+ // Cannot be converted
+ array('/^[0-9]+$/i', null),
+
+ // Inverse matches are simple, just wrap in
+ // ((?!pattern).)*
+ array('/^[0-9]+$/', '((?!^[0-9]+$).)*', false),
+ array('/[0-9]+$/', '((?![0-9]+$).)*', false),
+ array('/^[0-9]+/', '((?!^[0-9]+).)*', false),
+ array('/[0-9]+/', '((?![0-9]+).)*', false),
+ array('/[0-9]$|[a-z]+/', '((?![0-9]$|[a-z]+).)*', false),
+ array('/[0-9]$|^[a-z]+/', '((?![0-9]$|^[a-z]+).)*', false),
+ array('/^[0-9]|[a-z]+$/', '((?!^[0-9]|[a-z]+$).)*', false),
+ array('/^[0-9]+\/$/', '((?!^[0-9]+/$).)*', false),
+ array('#^[0-9]+\#$#', '((?!^[0-9]+#$).)*', false),
+ array('/^[0-9]+$/i', null, false),
+ );
+ }
+
+ /**
+ * @dataProvider provideHtmlPatterns
+ */
+ public function testGetHtmlPattern($pattern, $htmlPattern, $match = true)
+ {
+ $constraint = new Regex(array(
+ 'pattern' => $pattern,
+ 'match' => $match,
+ ));
+
+ $this->assertSame($pattern, $constraint->pattern);
+ $this->assertSame($htmlPattern, $constraint->getHtmlPattern());
+ }
+
+ public function testGetCustomHtmlPattern()
+ {
+ $constraint = new Regex(array(
+ 'pattern' => '((?![0-9]$|[a-z]+).)*',
+ 'htmlPattern' => 'foobar',
+ ));
+
+ $this->assertSame('((?![0-9]$|[a-z]+).)*', $constraint->pattern);
+ $this->assertSame('foobar', $constraint->getHtmlPattern());
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.php
new file mode 100644
index 0000000..61917e3
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.php
@@ -0,0 +1,97 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Regex;
+use Symfony\Component\Validator\Constraints\RegexValidator;
+use Symfony\Component\Validator\Validation;
+
+class RegexValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new RegexValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Regex(array('pattern' => '/^[0-9]+$/')));
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Regex(array('pattern' => '/^[0-9]+$/')));
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $this->validator->validate(new \stdClass(), new Regex(array('pattern' => '/^[0-9]+$/')));
+ }
+
+ /**
+ * @dataProvider getValidValues
+ */
+ public function testValidValues($value)
+ {
+ $constraint = new Regex(array('pattern' => '/^[0-9]+$/'));
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidValues()
+ {
+ return array(
+ array(0),
+ array('0'),
+ array('090909'),
+ array(90909),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidValues
+ */
+ public function testInvalidValues($value)
+ {
+ $constraint = new Regex(array(
+ 'pattern' => '/^[0-9]+$/',
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$value.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidValues()
+ {
+ return array(
+ array('abcd'),
+ array('090foo'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TimeValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TimeValidatorTest.php
new file mode 100644
index 0000000..a6ca143
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TimeValidatorTest.php
@@ -0,0 +1,107 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Time;
+use Symfony\Component\Validator\Constraints\TimeValidator;
+use Symfony\Component\Validator\Validation;
+
+class TimeValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new TimeValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Time());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Time());
+
+ $this->assertNoViolation();
+ }
+
+ public function testDateTimeClassIsValid()
+ {
+ $this->validator->validate(new \DateTime(), new Time());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $this->validator->validate(new \stdClass(), new Time());
+ }
+
+ /**
+ * @dataProvider getValidTimes
+ */
+ public function testValidTimes($time)
+ {
+ $this->validator->validate($time, new Time());
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidTimes()
+ {
+ return array(
+ array('01:02:03'),
+ array('00:00:00'),
+ array('23:59:59'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidTimes
+ */
+ public function testInvalidTimes($time, $code)
+ {
+ $constraint = new Time(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($time, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$time.'"')
+ ->setCode($code)
+ ->assertRaised();
+ }
+
+ public function getInvalidTimes()
+ {
+ return array(
+ array('foobar', Time::INVALID_FORMAT_ERROR),
+ array('foobar 12:34:56', Time::INVALID_FORMAT_ERROR),
+ array('12:34:56 foobar', Time::INVALID_FORMAT_ERROR),
+ array('00:00', Time::INVALID_FORMAT_ERROR),
+ array('24:00:00', Time::INVALID_TIME_ERROR),
+ array('00:60:00', Time::INVALID_TIME_ERROR),
+ array('00:00:60', Time::INVALID_TIME_ERROR),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TrueValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TrueValidatorTest.php
new file mode 100644
index 0000000..2cdc703
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TrueValidatorTest.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\True;
+use Symfony\Component\Validator\Constraints\TrueValidator;
+use Symfony\Component\Validator\Validation;
+
+class TrueValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new TrueValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new True());
+
+ $this->assertNoViolation();
+ }
+
+ public function testTrueIsValid()
+ {
+ $this->validator->validate(true, new True());
+
+ $this->assertNoViolation();
+ }
+
+ public function testFalseIsInvalid()
+ {
+ $constraint = new True(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate(false, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', 'false')
+ ->assertRaised();
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php
new file mode 100644
index 0000000..4836928
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php
@@ -0,0 +1,185 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Type;
+use Symfony\Component\Validator\Constraints\TypeValidator;
+use Symfony\Component\Validator\Validation;
+
+class TypeValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected static $file;
+
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new TypeValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $constraint = new Type(array('type' => 'integer'));
+
+ $this->validator->validate(null, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyIsValidIfString()
+ {
+ $constraint = new Type(array('type' => 'string'));
+
+ $this->validator->validate('', $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyIsInvalidIfNoString()
+ {
+ $constraint = new Type(array(
+ 'type' => 'integer',
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate('', $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '""')
+ ->setParameter('{{ type }}', 'integer')
+ ->assertRaised();
+ }
+
+ /**
+ * @dataProvider getValidValues
+ */
+ public function testValidValues($value, $type)
+ {
+ $constraint = new Type(array('type' => $type));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidValues()
+ {
+ $object = new \stdClass();
+ $file = $this->createFile();
+
+ return array(
+ array(true, 'Boolean'),
+ array(false, 'Boolean'),
+ array(true, 'boolean'),
+ array(false, 'boolean'),
+ array(true, 'bool'),
+ array(false, 'bool'),
+ array(0, 'numeric'),
+ array('0', 'numeric'),
+ array(1.5, 'numeric'),
+ array('1.5', 'numeric'),
+ array(0, 'integer'),
+ array(1.5, 'float'),
+ array('12345', 'string'),
+ array(array(), 'array'),
+ array($object, 'object'),
+ array($object, 'stdClass'),
+ array($file, 'resource'),
+ array('12345', 'digit'),
+ array('12a34', 'alnum'),
+ array('abcde', 'alpha'),
+ array("\n\r\t", 'cntrl'),
+ array('arf12', 'graph'),
+ array('abcde', 'lower'),
+ array('ABCDE', 'upper'),
+ array('arf12', 'print'),
+ array('*&$()', 'punct'),
+ array("\n\r\t", 'space'),
+ array('AB10BC99', 'xdigit'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidValues
+ */
+ public function testInvalidValues($value, $type, $valueAsString)
+ {
+ $constraint = new Type(array(
+ 'type' => $type,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($value, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', $valueAsString)
+ ->setParameter('{{ type }}', $type)
+ ->assertRaised();
+ }
+
+ public function getInvalidValues()
+ {
+ $object = new \stdClass();
+ $file = $this->createFile();
+
+ return array(
+ array('foobar', 'numeric', '"foobar"'),
+ array('foobar', 'boolean', '"foobar"'),
+ array('0', 'integer', '"0"'),
+ array('1.5', 'float', '"1.5"'),
+ array(12345, 'string', '12345'),
+ array($object, 'boolean', 'object'),
+ array($object, 'numeric', 'object'),
+ array($object, 'integer', 'object'),
+ array($object, 'float', 'object'),
+ array($object, 'string', 'object'),
+ array($object, 'resource', 'object'),
+ array($file, 'boolean', 'resource'),
+ array($file, 'numeric', 'resource'),
+ array($file, 'integer', 'resource'),
+ array($file, 'float', 'resource'),
+ array($file, 'string', 'resource'),
+ array($file, 'object', 'resource'),
+ array('12a34', 'digit', '"12a34"'),
+ array('1a#23', 'alnum', '"1a#23"'),
+ array('abcd1', 'alpha', '"abcd1"'),
+ array("\nabc", 'cntrl', "\"\nabc\""),
+ array("abc\n", 'graph', "\"abc\n\""),
+ array('abCDE', 'lower', '"abCDE"'),
+ array('ABcde', 'upper', '"ABcde"'),
+ array("\nabc", 'print', "\"\nabc\""),
+ array('abc&$!', 'punct', '"abc&$!"'),
+ array("\nabc", 'space', "\"\nabc\""),
+ array('AR1012', 'xdigit', '"AR1012"'),
+ );
+ }
+
+ protected function createFile()
+ {
+ if (!static::$file) {
+ static::$file = fopen(__FILE__, 'r');
+ }
+
+ return static::$file;
+ }
+
+ public static function tearDownAfterClass()
+ {
+ if (static::$file) {
+ fclose(static::$file);
+ static::$file = null;
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php
new file mode 100644
index 0000000..3358c79
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php
@@ -0,0 +1,179 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Url;
+use Symfony\Component\Validator\Constraints\UrlValidator;
+use Symfony\Component\Validator\Validation;
+
+class UrlValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new UrlValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Url());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Url());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $this->validator->validate(new \stdClass(), new Url());
+ }
+
+ /**
+ * @dataProvider getValidUrls
+ */
+ public function testValidUrls($url)
+ {
+ $this->validator->validate($url, new Url());
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidUrls()
+ {
+ return array(
+ array('http://a.pl'),
+ array('http://www.google.com'),
+ array('http://www.google.com.'),
+ array('http://www.google.museum'),
+ array('https://google.com/'),
+ array('https://google.com:80/'),
+ array('http://www.example.coop/'),
+ array('http://www.test-example.com/'),
+ array('http://www.symfony.com/'),
+ array('http://symfony.fake/blog/'),
+ array('http://symfony.com/?'),
+ array('http://symfony.com/search?type=&q=url+validator'),
+ array('http://symfony.com/#'),
+ array('http://symfony.com/#?'),
+ array('http://www.symfony.com/doc/current/book/validation.html#supported-constraints'),
+ array('http://very.long.domain.name.com/'),
+ array('http://localhost/'),
+ array('http://127.0.0.1/'),
+ array('http://127.0.0.1:80/'),
+ array('http://[::1]/'),
+ array('http://[::1]:80/'),
+ array('http://[1:2:3::4:5:6:7]/'),
+ array('http://sãopaulo.com/'),
+ array('http://xn--sopaulo-xwa.com/'),
+ array('http://sãopaulo.com.br/'),
+ array('http://xn--sopaulo-xwa.com.br/'),
+ array('http://пример.испытание/'),
+ array('http://xn--e1afmkfd.xn--80akhbyknj4f/'),
+ array('http://مثال.إختبار/'),
+ array('http://xn--mgbh0fb.xn--kgbechtv/'),
+ array('http://例子.测试/'),
+ array('http://xn--fsqu00a.xn--0zwm56d/'),
+ array('http://例子.測試/'),
+ array('http://xn--fsqu00a.xn--g6w251d/'),
+ array('http://例え.テスト/'),
+ array('http://xn--r8jz45g.xn--zckzah/'),
+ array('http://مثال.آزمایشی/'),
+ array('http://xn--mgbh0fb.xn--hgbk6aj7f53bba/'),
+ array('http://실례.테스트/'),
+ array('http://xn--9n2bp8q.xn--9t4b11yi5a/'),
+ array('http://العربية.idn.icann.org/'),
+ array('http://xn--ogb.idn.icann.org/'),
+ array('http://xn--e1afmkfd.xn--80akhbyknj4f.xn--e1afmkfd/'),
+ array('http://xn--espaa-rta.xn--ca-ol-fsay5a/'),
+ array('http://xn--d1abbgf6aiiy.xn--p1ai/'),
+ array('http://☎.com/'),
+ array('http://username:password@symfony.com'),
+ array('http://user-name@symfony.com'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidUrls
+ */
+ public function testInvalidUrls($url)
+ {
+ $constraint = new Url(array(
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($url, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$url.'"')
+ ->assertRaised();
+ }
+
+ public function getInvalidUrls()
+ {
+ return array(
+ array('google.com'),
+ array('://google.com'),
+ array('http ://google.com'),
+ array('http:/google.com'),
+ array('http://goog_le.com'),
+ array('http://google.com::aa'),
+ array('http://google.com:aa'),
+ array('http://symfony.com?'),
+ array('http://symfony.com#'),
+ array('ftp://google.fr'),
+ array('faked://google.fr'),
+ array('http://127.0.0.1:aa/'),
+ array('ftp://[::1]/'),
+ array('http://[::1'),
+ array('http://hello.☎/'),
+ array('http://:password@symfony.com'),
+ array('http://:password@@symfony.com'),
+ array('http://username:passwordsymfony.com'),
+ array('http://usern@me:password@symfony.com'),
+ );
+ }
+
+ /**
+ * @dataProvider getValidCustomUrls
+ */
+ public function testCustomProtocolIsValid($url)
+ {
+ $constraint = new Url(array(
+ 'protocols' => array('ftp', 'file', 'git'),
+ ));
+
+ $this->validator->validate($url, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidCustomUrls()
+ {
+ return array(
+ array('ftp://google.com'),
+ array('file://127.0.0.1'),
+ array('git://[::1]/'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/UuidValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/UuidValidatorTest.php
new file mode 100644
index 0000000..0abda39
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/UuidValidatorTest.php
@@ -0,0 +1,211 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Uuid;
+use Symfony\Component\Validator\Constraints\UuidValidator;
+use Symfony\Component\Validator\Validation;
+
+/**
+ * @author Colin O'Dell <colinodell@gmail.com>
+ */
+class UuidValidatorTest extends AbstractConstraintValidatorTest
+{
+ protected function getApiVersion()
+ {
+ return Validation::API_VERSION_2_5;
+ }
+
+ protected function createValidator()
+ {
+ return new UuidValidator();
+ }
+
+ public function testNullIsValid()
+ {
+ $this->validator->validate(null, new Uuid());
+
+ $this->assertNoViolation();
+ }
+
+ public function testEmptyStringIsValid()
+ {
+ $this->validator->validate('', new Uuid());
+
+ $this->assertNoViolation();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnexpectedTypeException
+ */
+ public function testExpectsStringCompatibleType()
+ {
+ $this->validator->validate(new \stdClass(), new Uuid());
+ }
+
+ /**
+ * @dataProvider getValidStrictUuids
+ */
+ public function testValidStrictUuids($uuid, $versions = null)
+ {
+ $constraint = new Uuid();
+
+ if (null !== $versions) {
+ $constraint->versions = $versions;
+ }
+
+ $this->validator->validate($uuid, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidStrictUuids()
+ {
+ return array(
+ array('216fff40-98d9-11e3-a5e2-0800200c9a66'), // Version 1 UUID in lowercase
+ array('216fff40-98d9-11e3-a5e2-0800200c9a66', array(Uuid::V1_MAC)),
+ array('216FFF40-98D9-11E3-A5E2-0800200C9A66'), // Version 1 UUID in UPPERCASE
+ array('456daefb-5aa6-41b5-8dbc-068b05a8b201'), // Version 4 UUID in lowercase
+ array('456daEFb-5AA6-41B5-8DBC-068B05A8B201'), // Version 4 UUID in mixed case
+ array('456daEFb-5AA6-41B5-8DBC-068B05A8B201', array(Uuid::V4_RANDOM)),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidStrictUuids
+ */
+ public function testInvalidStrictUuids($uuid, $code, $versions = null)
+ {
+ $constraint = new Uuid(array(
+ 'message' => 'testMessage',
+ ));
+
+ if (null !== $versions) {
+ $constraint->versions = $versions;
+ }
+
+ $this->validator->validate($uuid, $constraint);
+
+ $this->buildViolation('testMessage')
+ ->setParameter('{{ value }}', '"'.$uuid.'"')
+ ->setCode($code)
+ ->assertRaised();
+ }
+
+ public function getInvalidStrictUuids()
+ {
+ return array(
+ array('216fff40-98d9-11e3-a5e2_0800200c9a66', Uuid::INVALID_CHARACTERS_ERROR),
+ array('216gff40-98d9-11e3-a5e2-0800200c9a66', Uuid::INVALID_CHARACTERS_ERROR),
+ array('216Gff40-98d9-11e3-a5e2-0800200c9a66', Uuid::INVALID_CHARACTERS_ERROR),
+ array('216fff40-98d9-11e3-a5e-20800200c9a66', Uuid::INVALID_HYPHEN_PLACEMENT_ERROR),
+ array('216f-ff40-98d9-11e3-a5e2-0800200c9a66', Uuid::INVALID_HYPHEN_PLACEMENT_ERROR),
+ array('216fff40-98d9-11e3-a5e2-0800-200c9a66', Uuid::INVALID_HYPHEN_PLACEMENT_ERROR),
+ array('216fff40-98d9-11e3-a5e2-0800200c-9a66', Uuid::INVALID_HYPHEN_PLACEMENT_ERROR),
+ array('216fff40-98d9-11e3-a5e20800200c9a66', Uuid::INVALID_HYPHEN_PLACEMENT_ERROR),
+ array('216fff4098d911e3a5e20800200c9a66', Uuid::INVALID_HYPHEN_PLACEMENT_ERROR),
+ array('216fff40-98d9-11e3-a5e2-0800200c9a6', Uuid::TOO_SHORT_ERROR),
+ array('216fff40-98d9-11e3-a5e2-0800200c9a666', Uuid::TOO_LONG_ERROR),
+ array('216fff40-98d9-01e3-a5e2-0800200c9a66', Uuid::INVALID_VERSION_ERROR),
+ array('216fff40-98d9-61e3-a5e2-0800200c9a66', Uuid::INVALID_VERSION_ERROR),
+ array('216fff40-98d9-71e3-a5e2-0800200c9a66', Uuid::INVALID_VERSION_ERROR),
+ array('216fff40-98d9-81e3-a5e2-0800200c9a66', Uuid::INVALID_VERSION_ERROR),
+ array('216fff40-98d9-91e3-a5e2-0800200c9a66', Uuid::INVALID_VERSION_ERROR),
+ array('216fff40-98d9-a1e3-a5e2-0800200c9a66', Uuid::INVALID_VERSION_ERROR),
+ array('216fff40-98d9-b1e3-a5e2-0800200c9a66', Uuid::INVALID_VERSION_ERROR),
+ array('216fff40-98d9-c1e3-a5e2-0800200c9a66', Uuid::INVALID_VERSION_ERROR),
+ array('216fff40-98d9-d1e3-a5e2-0800200c9a66', Uuid::INVALID_VERSION_ERROR),
+ array('216fff40-98d9-e1e3-a5e2-0800200c9a66', Uuid::INVALID_VERSION_ERROR),
+ array('216fff40-98d9-f1e3-a5e2-0800200c9a66', Uuid::INVALID_VERSION_ERROR),
+ array('216fff40-98d9-11e3-a5e2-0800200c9a66', Uuid::INVALID_VERSION_ERROR, array(Uuid::V2_DCE, Uuid::V3_MD5, Uuid::V4_RANDOM, Uuid::V5_SHA1)),
+ array('216fff40-98d9-21e3-a5e2-0800200c9a66', Uuid::INVALID_VERSION_ERROR, array(Uuid::V1_MAC, Uuid::V3_MD5, Uuid::V4_RANDOM, Uuid::V5_SHA1)),
+ array('216fff40-98d9-11e3-05e2-0800200c9a66', Uuid::INVALID_VARIANT_ERROR),
+ array('216fff40-98d9-11e3-15e2-0800200c9a66', Uuid::INVALID_VARIANT_ERROR),
+ array('216fff40-98d9-11e3-25e2-0800200c9a66', Uuid::INVALID_VARIANT_ERROR),
+ array('216fff40-98d9-11e3-35e2-0800200c9a66', Uuid::INVALID_VARIANT_ERROR),
+ array('216fff40-98d9-11e3-45e2-0800200c9a66', Uuid::INVALID_VARIANT_ERROR),
+ array('216fff40-98d9-11e3-55e2-0800200c9a66', Uuid::INVALID_VARIANT_ERROR),
+ array('216fff40-98d9-11e3-65e2-0800200c9a66', Uuid::INVALID_VARIANT_ERROR),
+ array('216fff40-98d9-11e3-75e2-0800200c9a66', Uuid::INVALID_VARIANT_ERROR),
+ array('216fff40-98d9-11e3-c5e2-0800200c9a66', Uuid::INVALID_VARIANT_ERROR),
+ array('216fff40-98d9-11e3-d5e2-0800200c9a66', Uuid::INVALID_VARIANT_ERROR),
+ array('216fff40-98d9-11e3-e5e2-0800200c9a66', Uuid::INVALID_VARIANT_ERROR),
+ array('216fff40-98d9-11e3-f5e2-0800200c9a66', Uuid::INVALID_VARIANT_ERROR),
+
+ // Non-standard UUID allowed by some other systems
+ array('{216fff40-98d9-11e3-a5e2-0800200c9a66}', Uuid::INVALID_CHARACTERS_ERROR),
+ array('[216fff40-98d9-11e3-a5e2-0800200c9a66]', Uuid::INVALID_CHARACTERS_ERROR),
+ );
+ }
+
+ /**
+ * @dataProvider getValidNonStrictUuids
+ */
+ public function testValidNonStrictUuids($uuid)
+ {
+ $constraint = new Uuid(array(
+ 'strict' => false,
+ ));
+
+ $this->validator->validate($uuid, $constraint);
+
+ $this->assertNoViolation();
+ }
+
+ public function getValidNonStrictUuids()
+ {
+ return array(
+ array('216fff40-98d9-11e3-a5e2-0800200c9a66'), // Version 1 UUID in lowercase
+ array('216FFF40-98D9-11E3-A5E2-0800200C9A66'), // Version 1 UUID in UPPERCASE
+ array('456daefb-5aa6-41b5-8dbc-068b05a8b201'), // Version 4 UUID in lowercase
+ array('456DAEFb-5AA6-41B5-8DBC-068b05a8B201'), // Version 4 UUID in mixed case
+
+ // Non-standard UUIDs allowed by some other systems
+ array('216f-ff40-98d9-11e3-a5e2-0800-200c-9a66'), // Non-standard dash positions (every 4 chars)
+ array('216fff40-98d911e3-a5e20800-200c9a66'), // Non-standard dash positions (every 8 chars)
+ array('216fff4098d911e3a5e20800200c9a66'), // No dashes at all
+ array('{216fff40-98d9-11e3-a5e2-0800200c9a66}'), // Wrapped with curly braces
+ array('[216fff40-98d9-11e3-a5e2-0800200c9a66]'), // Wrapped with squared braces
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidNonStrictUuids
+ */
+ public function testInvalidNonStrictUuids($uuid, $code)
+ {
+ $constraint = new Uuid(array(
+ 'strict' => false,
+ 'message' => 'myMessage',
+ ));
+
+ $this->validator->validate($uuid, $constraint);
+
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', '"'.$uuid.'"')
+ ->setCode($code)
+ ->assertRaised();
+ }
+
+ public function getInvalidNonStrictUuids()
+ {
+ return array(
+ array('216fff40-98d9-11e3-a5e2_0800200c9a66', Uuid::INVALID_CHARACTERS_ERROR),
+ array('216gff40-98d9-11e3-a5e2-0800200c9a66', Uuid::INVALID_CHARACTERS_ERROR),
+ array('216Gff40-98d9-11e3-a5e2-0800200c9a66', Uuid::INVALID_CHARACTERS_ERROR),
+ array('216fff40-98d9-11e3-a5e2_0800200c9a6', Uuid::INVALID_CHARACTERS_ERROR),
+ array('216fff40-98d9-11e3-a5e-20800200c9a66', Uuid::INVALID_HYPHEN_PLACEMENT_ERROR),
+ array('216fff40-98d9-11e3-a5e2-0800200c9a6', Uuid::TOO_SHORT_ERROR),
+ array('216fff40-98d9-11e3-a5e2-0800200c9a666', Uuid::TOO_LONG_ERROR),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ValidTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ValidTest.php
new file mode 100644
index 0000000..3de6ab3
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ValidTest.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Valid;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ValidTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testRejectGroupsOption()
+ {
+ new Valid(array('groups' => 'foo'));
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/CallbackClass.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/CallbackClass.php
new file mode 100644
index 0000000..0f6a2f4
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/CallbackClass.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\ExecutionContextInterface;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CallbackClass
+{
+ public static function callback($object, ExecutionContextInterface $context)
+ {
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ClassConstraint.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ClassConstraint.php
new file mode 100644
index 0000000..a4dc777
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ClassConstraint.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+class ClassConstraint extends Constraint
+{
+ public function getTargets()
+ {
+ return self::CLASS_CONSTRAINT;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintA.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintA.php
new file mode 100644
index 0000000..8a196dc
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintA.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+/** @Annotation */
+class ConstraintA extends Constraint
+{
+ public $property1;
+ public $property2;
+
+ public function getDefaultOption()
+ {
+ return 'property2';
+ }
+
+ public function getTargets()
+ {
+ return array(self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintAValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintAValidator.php
new file mode 100644
index 0000000..b3b85c8
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintAValidator.php
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\ExecutionContextInterface;
+
+class ConstraintAValidator extends ConstraintValidator
+{
+ public static $passedContext;
+
+ public function initialize(ExecutionContextInterface $context)
+ {
+ parent::initialize($context);
+
+ self::$passedContext = $context;
+ }
+
+ public function validate($value, Constraint $constraint)
+ {
+ if ('VALID' != $value) {
+ $this->context->addViolation('message', array('param' => 'value'));
+
+ return;
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintB.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintB.php
new file mode 100644
index 0000000..6258923
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintB.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+/** @Annotation */
+class ConstraintB extends Constraint
+{
+ public function getTargets()
+ {
+ return array(self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintC.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintC.php
new file mode 100644
index 0000000..b0418b8
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintC.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+/** @Annotation */
+class ConstraintC extends Constraint
+{
+ public $option1;
+
+ public function getRequiredOptions()
+ {
+ return array('option1');
+ }
+
+ public function getTargets()
+ {
+ return array(self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithValue.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithValue.php
new file mode 100644
index 0000000..4ebd981
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithValue.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+/** @Annotation */
+class ConstraintWithValue extends Constraint
+{
+ public $property;
+ public $value;
+
+ public function getDefaultOption()
+ {
+ return 'property';
+ }
+
+ public function getTargets()
+ {
+ return array(self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithValueAsDefault.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithValueAsDefault.php
new file mode 100644
index 0000000..a975e07
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithValueAsDefault.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+/** @Annotation */
+class ConstraintWithValueAsDefault extends Constraint
+{
+ public $property;
+ public $value;
+
+ public function getDefaultOption()
+ {
+ return 'value';
+ }
+
+ public function getTargets()
+ {
+ return array(self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Countable.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Countable.php
new file mode 100644
index 0000000..282d78d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Countable.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+class Countable implements \Countable
+{
+ private $content;
+
+ public function __construct(array $content)
+ {
+ $this->content = $content;
+ }
+
+ public function count()
+ {
+ return count($this->content);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/CustomArrayObject.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/CustomArrayObject.php
new file mode 100644
index 0000000..41eac96
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/CustomArrayObject.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+/**
+ * This class is a hand written simplified version of PHP native `ArrayObject`
+ * class, to show that it behaves differently than the PHP native implementation.
+ */
+class CustomArrayObject implements \ArrayAccess, \IteratorAggregate, \Countable, \Serializable
+{
+ private $array;
+
+ public function __construct(array $array = null)
+ {
+ $this->array = $array ?: array();
+ }
+
+ public function offsetExists($offset)
+ {
+ return array_key_exists($offset, $this->array);
+ }
+
+ public function offsetGet($offset)
+ {
+ return $this->array[$offset];
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ if (null === $offset) {
+ $this->array[] = $value;
+ } else {
+ $this->array[$offset] = $value;
+ }
+ }
+
+ public function offsetUnset($offset)
+ {
+ unset($this->array[$offset]);
+ }
+
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->array);
+ }
+
+ public function count()
+ {
+ return count($this->array);
+ }
+
+ public function serialize()
+ {
+ return serialize($this->array);
+ }
+
+ public function unserialize($serialized)
+ {
+ $this->array = (array) unserialize((string) $serialized);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Entity.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Entity.php
new file mode 100644
index 0000000..2230d30
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Entity.php
@@ -0,0 +1,100 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraints as Assert;
+use Symfony\Component\Validator\ExecutionContextInterface;
+
+/**
+ * @Symfony\Component\Validator\Tests\Fixtures\ConstraintA
+ * @Assert\GroupSequence({"Foo", "Entity"})
+ * @Assert\Callback({"Symfony\Component\Validator\Tests\Fixtures\CallbackClass", "callback"})
+ */
+class Entity extends EntityParent implements EntityInterface
+{
+ /**
+ * @Assert\NotNull
+ * @Assert\Range(min=3)
+ * @Assert\All({@Assert\NotNull, @Assert\Range(min=3)}),
+ * @Assert\All(constraints={@Assert\NotNull, @Assert\Range(min=3)})
+ * @Assert\Collection(fields={
+ * "foo" = {@Assert\NotNull, @Assert\Range(min=3)},
+ * "bar" = @Assert\Range(min=5)
+ * })
+ * @Assert\Choice(choices={"A", "B"}, message="Must be one of %choices%")
+ */
+ public $firstName;
+ protected $lastName;
+ public $reference;
+ public $reference2;
+ private $internal;
+ public $data = 'Overridden data';
+ public $initialized = false;
+
+ public function __construct($internal = null)
+ {
+ $this->internal = $internal;
+ }
+
+ public function getInternal()
+ {
+ return $this->internal.' from getter';
+ }
+
+ public function setLastName($lastName)
+ {
+ $this->lastName = $lastName;
+ }
+
+ /**
+ * @Assert\NotNull
+ */
+ public function getLastName()
+ {
+ return $this->lastName;
+ }
+
+ /**
+ * @Assert\True
+ */
+ public function isValid()
+ {
+ return 'valid';
+ }
+
+ /**
+ * @Assert\True
+ */
+ public function hasPermissions()
+ {
+ return 'permissions';
+ }
+
+ public function getData()
+ {
+ return 'Overridden data';
+ }
+
+ /**
+ * @Assert\Callback
+ */
+ public function validateMe(ExecutionContextInterface $context)
+ {
+ }
+
+ /**
+ * @Assert\Callback
+ */
+ public static function validateMeStatic($object, ExecutionContextInterface $context)
+ {
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityInterface.php
new file mode 100644
index 0000000..2901f26
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityInterface.php
@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+interface EntityInterface
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php
new file mode 100644
index 0000000..422bb28
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraints\NotNull;
+
+class EntityParent
+{
+ protected $firstName;
+ private $internal;
+ private $data = 'Data';
+
+ /**
+ * @NotNull
+ */
+ protected $other;
+
+ public function getData()
+ {
+ return 'Data';
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraint.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraint.php
new file mode 100644
index 0000000..03019fc
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraint.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+class FailingConstraint extends Constraint
+{
+ public $message = 'Failed';
+
+ public function getTargets()
+ {
+ return array(self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraintValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraintValidator.php
new file mode 100644
index 0000000..a019dd6
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraintValidator.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+class FailingConstraintValidator extends ConstraintValidator
+{
+ public function validate($value, Constraint $constraint)
+ {
+ $this->context->addViolation($constraint->message, array());
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FakeClassMetadata.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FakeClassMetadata.php
new file mode 100644
index 0000000..8c76a21
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FakeClassMetadata.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+class FakeClassMetadata extends ClassMetadata
+{
+ public function addCustomPropertyMetadata($propertyName, $metadata)
+ {
+ if (!isset($this->members[$propertyName])) {
+ $this->members[$propertyName] = array();
+ }
+
+ $this->members[$propertyName][] = $metadata;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FakeMetadataFactory.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FakeMetadataFactory.php
new file mode 100644
index 0000000..e3f0d9a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FakeMetadataFactory.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Exception\NoSuchMetadataException;
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\MetadataInterface;
+
+class FakeMetadataFactory implements MetadataFactoryInterface
+{
+ protected $metadatas = array();
+
+ public function getMetadataFor($class)
+ {
+ $hash = null;
+
+ if (is_object($class)) {
+ $hash = spl_object_hash($class);
+ $class = get_class($class);
+ }
+
+ if (!is_string($class)) {
+ throw new NoSuchMetadataException(sprintf('No metadata for type %s', gettype($class)));
+ }
+
+ if (!isset($this->metadatas[$class])) {
+ if (isset($this->metadatas[$hash])) {
+ return $this->metadatas[$hash];
+ }
+
+ throw new NoSuchMetadataException(sprintf('No metadata for "%s"', $class));
+ }
+
+ return $this->metadatas[$class];
+ }
+
+ public function hasMetadataFor($class)
+ {
+ $hash = null;
+
+ if (is_object($class)) {
+ $hash = spl_object_hash($class);
+ $class = get_class($class);
+ }
+
+ if (!is_string($class)) {
+ return false;
+ }
+
+ return isset($this->metadatas[$class]) || isset($this->metadatas[$hash]);
+ }
+
+ public function addMetadata($metadata)
+ {
+ $this->metadatas[$metadata->getClassName()] = $metadata;
+ }
+
+ public function addMetadataForValue($value, MetadataInterface $metadata)
+ {
+ $key = is_object($value) ? spl_object_hash($value) : $value;
+ $this->metadatas[$key] = $metadata;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FilesLoader.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FilesLoader.php
new file mode 100644
index 0000000..59d8ee8
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FilesLoader.php
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Mapping\Loader\FilesLoader as BaseFilesLoader;
+use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
+
+abstract class FilesLoader extends BaseFilesLoader
+{
+ protected $timesCalled = 0;
+ protected $loader;
+
+ public function __construct(array $paths, LoaderInterface $loader)
+ {
+ $this->loader = $loader;
+ parent::__construct($paths);
+ }
+
+ protected function getFileLoaderInstance($file)
+ {
+ $this->timesCalled++;
+
+ return $this->loader;
+ }
+
+ public function getTimesCalled()
+ {
+ return $this->timesCalled;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderEntity.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderEntity.php
new file mode 100644
index 0000000..2b0beaf
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderEntity.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraints as Assert;
+use Symfony\Component\Validator\GroupSequenceProviderInterface;
+
+/**
+ * @Assert\GroupSequenceProvider
+ */
+class GroupSequenceProviderEntity implements GroupSequenceProviderInterface
+{
+ public $firstName;
+ public $lastName;
+
+ protected $sequence = array();
+
+ public function __construct($sequence)
+ {
+ $this->sequence = $sequence;
+ }
+
+ public function getGroupSequence()
+ {
+ return $this->sequence;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraint.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraint.php
new file mode 100644
index 0000000..6a9eaa7
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraint.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+class InvalidConstraint extends Constraint
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraintValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraintValidator.php
new file mode 100644
index 0000000..bd9a5cf
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraintValidator.php
@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+class InvalidConstraintValidator
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/LegacyClassMetadata.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/LegacyClassMetadata.php
new file mode 100644
index 0000000..6a832a1
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/LegacyClassMetadata.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\ClassBasedInterface;
+use Symfony\Component\Validator\MetadataInterface;
+use Symfony\Component\Validator\PropertyMetadataContainerInterface;
+
+interface LegacyClassMetadata extends MetadataInterface, PropertyMetadataContainerInterface, ClassBasedInterface
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/PropertyConstraint.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/PropertyConstraint.php
new file mode 100644
index 0000000..fadb535
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/PropertyConstraint.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+class PropertyConstraint extends Constraint
+{
+ public function getTargets()
+ {
+ return self::PROPERTY_CONSTRAINT;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Reference.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Reference.php
new file mode 100644
index 0000000..af29735
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Reference.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+class Reference
+{
+ public $value;
+
+ private $privateValue;
+
+ public function setPrivateValue($privateValue)
+ {
+ $this->privateValue = $privateValue;
+ }
+
+ public function getPrivateValue()
+ {
+ return $this->privateValue;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/StubGlobalExecutionContext.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/StubGlobalExecutionContext.php
new file mode 100644
index 0000000..6ae3663
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/StubGlobalExecutionContext.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\ConstraintViolationList;
+use Symfony\Component\Validator\GlobalExecutionContextInterface;
+use Symfony\Component\Validator\ValidationVisitorInterface;
+
+/**
+ * @since 2.5.3
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated
+ */
+class StubGlobalExecutionContext implements GlobalExecutionContextInterface
+{
+ private $violations;
+
+ private $root;
+
+ private $visitor;
+
+ public function __construct($root = null, ValidationVisitorInterface $visitor = null)
+ {
+ $this->violations = new ConstraintViolationList();
+ $this->root = $root;
+ $this->visitor = $visitor;
+ }
+
+ public function getViolations()
+ {
+ return $this->violations;
+ }
+
+ public function setRoot($root)
+ {
+ $this->root = $root;
+ }
+
+ public function getRoot()
+ {
+ return $this->root;
+ }
+
+ public function setVisitor(ValidationVisitorInterface $visitor)
+ {
+ $this->visitor = $visitor;
+ }
+
+ public function getVisitor()
+ {
+ return $this->visitor;
+ }
+
+ public function getValidatorFactory()
+ {
+ }
+
+ public function getMetadataFactory()
+ {
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/LegacyExecutionContextTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/LegacyExecutionContextTest.php
new file mode 100644
index 0000000..4fec2aa
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/LegacyExecutionContextTest.php
@@ -0,0 +1,336 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests;
+
+use Symfony\Component\Validator\Constraints\Collection;
+use Symfony\Component\Validator\Constraints\All;
+use Symfony\Component\Validator\ConstraintValidatorFactory;
+use Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\ConstraintViolationList;
+use Symfony\Component\Validator\ExecutionContext;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\ValidationVisitor;
+
+/**
+ * @group legacy
+ */
+class LegacyExecutionContextTest extends \PHPUnit_Framework_TestCase
+{
+ const TRANS_DOMAIN = 'trans_domain';
+
+ private $visitor;
+ private $violations;
+ private $metadata;
+ private $metadataFactory;
+ private $globalContext;
+ private $translator;
+
+ /**
+ * @var ExecutionContext
+ */
+ private $context;
+
+ protected function setUp()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ $this->visitor = $this->getMockBuilder('Symfony\Component\Validator\ValidationVisitor')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->violations = new ConstraintViolationList();
+ $this->metadata = $this->getMock('Symfony\Component\Validator\MetadataInterface');
+ $this->metadataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface');
+ $this->globalContext = $this->getMock('Symfony\Component\Validator\GlobalExecutionContextInterface');
+ $this->globalContext->expects($this->any())
+ ->method('getRoot')
+ ->will($this->returnValue('Root'));
+ $this->globalContext->expects($this->any())
+ ->method('getViolations')
+ ->will($this->returnValue($this->violations));
+ $this->globalContext->expects($this->any())
+ ->method('getVisitor')
+ ->will($this->returnValue($this->visitor));
+ $this->globalContext->expects($this->any())
+ ->method('getMetadataFactory')
+ ->will($this->returnValue($this->metadataFactory));
+ $this->translator = $this->getMock('Symfony\Component\Translation\TranslatorInterface');
+ $this->context = new ExecutionContext($this->globalContext, $this->translator, self::TRANS_DOMAIN, $this->metadata, 'currentValue', 'Group', 'foo.bar');
+ }
+
+ protected function tearDown()
+ {
+ $this->globalContext = null;
+ $this->context = null;
+ }
+
+ public function testInit()
+ {
+ $this->assertCount(0, $this->context->getViolations());
+ $this->assertSame('Root', $this->context->getRoot());
+ $this->assertSame('foo.bar', $this->context->getPropertyPath());
+ $this->assertSame('Group', $this->context->getGroup());
+ }
+
+ public function testClone()
+ {
+ $clone = clone $this->context;
+
+ // Cloning the context keeps the reference to the original violation
+ // list. This way we can efficiently duplicate context instances during
+ // the validation run and only modify the properties that need to be
+ // changed.
+ $this->assertSame($this->context->getViolations(), $clone->getViolations());
+ }
+
+ public function testAddViolation()
+ {
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array('foo' => 'bar'))
+ ->will($this->returnValue('Translated error'));
+
+ $this->context->addViolation('Error', array('foo' => 'bar'), 'invalid');
+
+ $this->assertEquals(new ConstraintViolationList(array(
+ new ConstraintViolation(
+ 'Translated error',
+ 'Error',
+ array('foo' => 'bar'),
+ 'Root',
+ 'foo.bar',
+ 'invalid'
+ ),
+ )), $this->context->getViolations());
+ }
+
+ public function testAddViolationUsesPreconfiguredValueIfNotPassed()
+ {
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array())
+ ->will($this->returnValue('Translated error'));
+
+ $this->context->addViolation('Error');
+
+ $this->assertEquals(new ConstraintViolationList(array(
+ new ConstraintViolation(
+ 'Translated error',
+ 'Error',
+ array(),
+ 'Root',
+ 'foo.bar',
+ 'currentValue'
+ ),
+ )), $this->context->getViolations());
+ }
+
+ public function testAddViolationUsesPassedNullValue()
+ {
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array('foo1' => 'bar1'))
+ ->will($this->returnValue('Translated error'));
+ $this->translator->expects($this->once())
+ ->method('transChoice')
+ ->with('Choice error', 1, array('foo2' => 'bar2'))
+ ->will($this->returnValue('Translated choice error'));
+
+ // passed null value should override preconfigured value "invalid"
+ $this->context->addViolation('Error', array('foo1' => 'bar1'), null);
+ $this->context->addViolation('Choice error', array('foo2' => 'bar2'), null, 1);
+
+ $this->assertEquals(new ConstraintViolationList(array(
+ new ConstraintViolation(
+ 'Translated error',
+ 'Error',
+ array('foo1' => 'bar1'),
+ 'Root',
+ 'foo.bar',
+ null
+ ),
+ new ConstraintViolation(
+ 'Translated choice error',
+ 'Choice error',
+ array('foo2' => 'bar2'),
+ 'Root',
+ 'foo.bar',
+ null,
+ 1
+ ),
+ )), $this->context->getViolations());
+ }
+
+ public function testAddViolationAt()
+ {
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array('foo' => 'bar'))
+ ->will($this->returnValue('Translated error'));
+
+ // override preconfigured property path
+ $this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), 'invalid');
+
+ $this->assertEquals(new ConstraintViolationList(array(
+ new ConstraintViolation(
+ 'Translated error',
+ 'Error',
+ array('foo' => 'bar'),
+ 'Root',
+ 'foo.bar.bam.baz',
+ 'invalid'
+ ),
+ )), $this->context->getViolations());
+ }
+
+ public function testAddViolationAtUsesPreconfiguredValueIfNotPassed()
+ {
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array())
+ ->will($this->returnValue('Translated error'));
+
+ $this->context->addViolationAt('bam.baz', 'Error');
+
+ $this->assertEquals(new ConstraintViolationList(array(
+ new ConstraintViolation(
+ 'Translated error',
+ 'Error',
+ array(),
+ 'Root',
+ 'foo.bar.bam.baz',
+ 'currentValue'
+ ),
+ )), $this->context->getViolations());
+ }
+
+ public function testAddViolationAtUsesPassedNullValue()
+ {
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array('foo' => 'bar'))
+ ->will($this->returnValue('Translated error'));
+ $this->translator->expects($this->once())
+ ->method('transChoice')
+ ->with('Choice error', 2, array('foo' => 'bar'))
+ ->will($this->returnValue('Translated choice error'));
+
+ // passed null value should override preconfigured value "invalid"
+ $this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), null);
+ $this->context->addViolationAt('bam.baz', 'Choice error', array('foo' => 'bar'), null, 2);
+
+ $this->assertEquals(new ConstraintViolationList(array(
+ new ConstraintViolation(
+ 'Translated error',
+ 'Error',
+ array('foo' => 'bar'),
+ 'Root',
+ 'foo.bar.bam.baz',
+ null
+ ),
+ new ConstraintViolation(
+ 'Translated choice error',
+ 'Choice error',
+ array('foo' => 'bar'),
+ 'Root',
+ 'foo.bar.bam.baz',
+ null,
+ 2
+ ),
+ )), $this->context->getViolations());
+ }
+
+ public function testAddViolationPluralTranslationError()
+ {
+ $this->translator->expects($this->once())
+ ->method('transChoice')
+ ->with('foo')
+ ->will($this->throwException(new \InvalidArgumentException()));
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('foo');
+
+ $this->context->addViolation('foo', array(), null, 2);
+ }
+
+ public function testGetPropertyPath()
+ {
+ $this->assertEquals('foo.bar', $this->context->getPropertyPath());
+ }
+
+ public function testGetPropertyPathWithIndexPath()
+ {
+ $this->assertEquals('foo.bar[bam]', $this->context->getPropertyPath('[bam]'));
+ }
+
+ public function testGetPropertyPathWithEmptyPath()
+ {
+ $this->assertEquals('foo.bar', $this->context->getPropertyPath(''));
+ }
+
+ public function testGetPropertyPathWithEmptyCurrentPropertyPath()
+ {
+ $this->context = new ExecutionContext($this->globalContext, $this->translator, self::TRANS_DOMAIN, $this->metadata, 'currentValue', 'Group', '');
+
+ $this->assertEquals('bam.baz', $this->context->getPropertyPath('bam.baz'));
+ }
+
+ public function testGetPropertyPathWithNestedCollectionsAndAllMixed()
+ {
+ $constraints = new Collection(array(
+ 'shelves' => new All(array('constraints' => array(
+ new Collection(array(
+ 'name' => new ConstraintA(),
+ 'books' => new All(array('constraints' => array(
+ new ConstraintA(),
+ ))),
+ )),
+ ))),
+ 'name' => new ConstraintA(),
+ ));
+ $data = array(
+ 'shelves' => array(
+ array(
+ 'name' => 'Research',
+ 'books' => array('foo', 'bar'),
+ ),
+ array(
+ 'name' => 'VALID',
+ 'books' => array('foozy', 'VALID', 'bazzy'),
+ ),
+ ),
+ 'name' => 'Library',
+ );
+ $expectedViolationPaths = array(
+ '[shelves][0][name]',
+ '[shelves][0][books][0]',
+ '[shelves][0][books][1]',
+ '[shelves][1][books][0]',
+ '[shelves][1][books][2]',
+ '[name]',
+ );
+
+ $visitor = new ValidationVisitor('Root', $this->metadataFactory, new ConstraintValidatorFactory(), $this->translator);
+ $context = new ExecutionContext($visitor, $this->translator, self::TRANS_DOMAIN);
+ $context->validateValue($data, $constraints);
+
+ foreach ($context->getViolations() as $violation) {
+ $violationPaths[] = $violation->getPropertyPath();
+ }
+
+ $this->assertEquals($expectedViolationPaths, $violationPaths);
+ }
+}
+
+class ExecutionContextTest_TestClass
+{
+ public $myProperty;
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Cache/DoctrineCacheTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Cache/DoctrineCacheTest.php
new file mode 100644
index 0000000..a2de306
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Cache/DoctrineCacheTest.php
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping\Cache;
+
+use Doctrine\Common\Cache\ArrayCache;
+use Symfony\Component\Validator\Mapping\Cache\DoctrineCache;
+
+class DoctrineCacheTest extends \PHPUnit_Framework_TestCase
+{
+ private $cache;
+
+ public function testWrite()
+ {
+ $meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata')
+ ->disableOriginalConstructor()
+ ->setMethods(array('getClassName'))
+ ->getMock();
+
+ $meta->expects($this->once())
+ ->method('getClassName')
+ ->will($this->returnValue('bar'));
+
+ $this->cache->write($meta);
+
+ $this->assertInstanceOf(
+ 'Symfony\\Component\\Validator\\Mapping\\ClassMetadata',
+ $this->cache->read('bar'),
+ 'write() stores metadata'
+ );
+ }
+
+ public function testHas()
+ {
+ $meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata')
+ ->disableOriginalConstructor()
+ ->setMethods(array('getClassName'))
+ ->getMock();
+
+ $meta->expects($this->once())
+ ->method('getClassName')
+ ->will($this->returnValue('bar'));
+
+ $this->assertFalse($this->cache->has('bar'), 'has() returns false when there is no entry');
+
+ $this->cache->write($meta);
+ $this->assertTrue($this->cache->has('bar'), 'has() returns true when the is an entry');
+ }
+
+ public function testRead()
+ {
+ $meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata')
+ ->disableOriginalConstructor()
+ ->setMethods(array('getClassName'))
+ ->getMock();
+
+ $meta->expects($this->once())
+ ->method('getClassName')
+ ->will($this->returnValue('bar'));
+
+ $this->assertFalse($this->cache->read('bar'), 'read() returns false when there is no entry');
+
+ $this->cache->write($meta);
+
+ $this->assertInstanceOf(
+ 'Symfony\\Component\\Validator\\Mapping\\ClassMetadata',
+ $this->cache->read('bar'),
+ 'read() returns metadata'
+ );
+ }
+
+ protected function setUp()
+ {
+ $this->cache = new DoctrineCache(new ArrayCache());
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Cache/LegacyApcCacheTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Cache/LegacyApcCacheTest.php
new file mode 100644
index 0000000..bb69cf5
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Cache/LegacyApcCacheTest.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping\Cache;
+
+use Symfony\Component\Validator\Mapping\Cache\ApcCache;
+
+/**
+ * @group legacy
+ */
+class LegacyApcCacheTest extends \PHPUnit_Framework_TestCase
+{
+ protected function setUp()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ if (!extension_loaded('apc') || !ini_get('apc.enable_cli')) {
+ $this->markTestSkipped('APC is not loaded.');
+ }
+ }
+
+ public function testWrite()
+ {
+ $meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata')
+ ->disableOriginalConstructor()
+ ->setMethods(array('getClassName'))
+ ->getMock();
+
+ $meta->expects($this->once())
+ ->method('getClassName')
+ ->will($this->returnValue('bar'));
+
+ $cache = new ApcCache('foo');
+ $cache->write($meta);
+
+ $this->assertInstanceOf('Symfony\\Component\\Validator\\Mapping\\ClassMetadata', apc_fetch('foobar'), '->write() stores metadata in APC');
+ }
+
+ public function testHas()
+ {
+ $meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata')
+ ->disableOriginalConstructor()
+ ->setMethods(array('getClassName'))
+ ->getMock();
+
+ $meta->expects($this->once())
+ ->method('getClassName')
+ ->will($this->returnValue('bar'));
+
+ apc_delete('foobar');
+
+ $cache = new ApcCache('foo');
+ $this->assertFalse($cache->has('bar'), '->has() returns false when there is no entry');
+
+ $cache->write($meta);
+ $this->assertTrue($cache->has('bar'), '->has() returns true when the is an entry');
+ }
+
+ public function testRead()
+ {
+ $meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata')
+ ->disableOriginalConstructor()
+ ->setMethods(array('getClassName'))
+ ->getMock();
+
+ $meta->expects($this->once())
+ ->method('getClassName')
+ ->will($this->returnValue('bar'));
+
+ $cache = new ApcCache('foo');
+ $cache->write($meta);
+
+ $this->assertInstanceOf('Symfony\\Component\\Validator\\Mapping\\ClassMetadata', $cache->read('bar'), '->read() returns metadata');
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php
new file mode 100644
index 0000000..8634ac5
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php
@@ -0,0 +1,280 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
+use Symfony\Component\Validator\Tests\Fixtures\PropertyConstraint;
+
+class ClassMetadataTest extends \PHPUnit_Framework_TestCase
+{
+ const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
+ const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent';
+ const PROVIDERCLASS = 'Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity';
+
+ protected $metadata;
+
+ protected function setUp()
+ {
+ $this->metadata = new ClassMetadata(self::CLASSNAME);
+ }
+
+ protected function tearDown()
+ {
+ $this->metadata = null;
+ }
+
+ public function testAddConstraintDoesNotAcceptValid()
+ {
+ $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
+
+ $this->metadata->addConstraint(new Valid());
+ }
+
+ public function testAddConstraintRequiresClassConstraints()
+ {
+ $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
+
+ $this->metadata->addConstraint(new PropertyConstraint());
+ }
+
+ public function testAddPropertyConstraints()
+ {
+ $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
+ $this->metadata->addPropertyConstraint('lastName', new ConstraintB());
+
+ $this->assertEquals(array('firstName', 'lastName'), $this->metadata->getConstrainedProperties());
+ }
+
+ public function testAddMultiplePropertyConstraints()
+ {
+ $this->metadata->addPropertyConstraints('lastName', array(new ConstraintA(), new ConstraintB()));
+
+ $constraints = array(
+ new ConstraintA(array('groups' => array('Default', 'Entity'))),
+ new ConstraintB(array('groups' => array('Default', 'Entity'))),
+ );
+
+ $properties = $this->metadata->getPropertyMetadata('lastName');
+
+ $this->assertCount(1, $properties);
+ $this->assertEquals('lastName', $properties[0]->getName());
+ $this->assertEquals($constraints, $properties[0]->getConstraints());
+ }
+
+ public function testAddGetterConstraints()
+ {
+ $this->metadata->addGetterConstraint('lastName', new ConstraintA());
+ $this->metadata->addGetterConstraint('lastName', new ConstraintB());
+
+ $constraints = array(
+ new ConstraintA(array('groups' => array('Default', 'Entity'))),
+ new ConstraintB(array('groups' => array('Default', 'Entity'))),
+ );
+
+ $properties = $this->metadata->getPropertyMetadata('lastName');
+
+ $this->assertCount(1, $properties);
+ $this->assertEquals('getLastName', $properties[0]->getName());
+ $this->assertEquals($constraints, $properties[0]->getConstraints());
+ }
+
+ public function testAddMultipleGetterConstraints()
+ {
+ $this->metadata->addGetterConstraints('lastName', array(new ConstraintA(), new ConstraintB()));
+
+ $constraints = array(
+ new ConstraintA(array('groups' => array('Default', 'Entity'))),
+ new ConstraintB(array('groups' => array('Default', 'Entity'))),
+ );
+
+ $properties = $this->metadata->getPropertyMetadata('lastName');
+
+ $this->assertCount(1, $properties);
+ $this->assertEquals('getLastName', $properties[0]->getName());
+ $this->assertEquals($constraints, $properties[0]->getConstraints());
+ }
+
+ public function testMergeConstraintsMergesClassConstraints()
+ {
+ $parent = new ClassMetadata(self::PARENTCLASS);
+ $parent->addConstraint(new ConstraintA());
+
+ $this->metadata->mergeConstraints($parent);
+ $this->metadata->addConstraint(new ConstraintA());
+
+ $constraints = array(
+ new ConstraintA(array('groups' => array(
+ 'Default',
+ 'EntityParent',
+ 'Entity',
+ ))),
+ new ConstraintA(array('groups' => array(
+ 'Default',
+ 'Entity',
+ ))),
+ );
+
+ $this->assertEquals($constraints, $this->metadata->getConstraints());
+ }
+
+ public function testMergeConstraintsMergesMemberConstraints()
+ {
+ $parent = new ClassMetadata(self::PARENTCLASS);
+ $parent->addPropertyConstraint('firstName', new ConstraintA());
+
+ $this->metadata->mergeConstraints($parent);
+ $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
+
+ $constraints = array(
+ new ConstraintA(array('groups' => array(
+ 'Default',
+ 'EntityParent',
+ 'Entity',
+ ))),
+ new ConstraintA(array('groups' => array(
+ 'Default',
+ 'Entity',
+ ))),
+ );
+
+ $members = $this->metadata->getPropertyMetadata('firstName');
+
+ $this->assertCount(1, $members);
+ $this->assertEquals(self::PARENTCLASS, $members[0]->getClassName());
+ $this->assertEquals($constraints, $members[0]->getConstraints());
+ }
+
+ public function testMemberMetadatas()
+ {
+ $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
+
+ $this->assertTrue($this->metadata->hasPropertyMetadata('firstName'));
+ $this->assertFalse($this->metadata->hasPropertyMetadata('non_existant_field'));
+ }
+
+ public function testMergeConstraintsKeepsPrivateMembersSeparate()
+ {
+ $parent = new ClassMetadata(self::PARENTCLASS);
+ $parent->addPropertyConstraint('internal', new ConstraintA());
+
+ $this->metadata->mergeConstraints($parent);
+ $this->metadata->addPropertyConstraint('internal', new ConstraintA());
+
+ $parentConstraints = array(
+ new ConstraintA(array('groups' => array(
+ 'Default',
+ 'EntityParent',
+ 'Entity',
+ ))),
+ );
+ $constraints = array(
+ new ConstraintA(array('groups' => array(
+ 'Default',
+ 'Entity',
+ ))),
+ );
+
+ $members = $this->metadata->getPropertyMetadata('internal');
+
+ $this->assertCount(2, $members);
+ $this->assertEquals(self::PARENTCLASS, $members[0]->getClassName());
+ $this->assertEquals($parentConstraints, $members[0]->getConstraints());
+ $this->assertEquals(self::CLASSNAME, $members[1]->getClassName());
+ $this->assertEquals($constraints, $members[1]->getConstraints());
+ }
+
+ public function testGetReflectionClass()
+ {
+ $reflClass = new \ReflectionClass(self::CLASSNAME);
+
+ $this->assertEquals($reflClass, $this->metadata->getReflectionClass());
+ }
+
+ public function testSerialize()
+ {
+ $this->metadata->addConstraint(new ConstraintA(array('property1' => 'A')));
+ $this->metadata->addConstraint(new ConstraintB(array('groups' => 'TestGroup')));
+ $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
+ $this->metadata->addGetterConstraint('lastName', new ConstraintB());
+
+ $metadata = unserialize(serialize($this->metadata));
+
+ $this->assertEquals($this->metadata, $metadata);
+ }
+
+ public function testGroupSequencesWorkIfContainingDefaultGroup()
+ {
+ $this->metadata->setGroupSequence(array('Foo', $this->metadata->getDefaultGroup()));
+ }
+
+ public function testGroupSequencesFailIfNotContainingDefaultGroup()
+ {
+ $this->setExpectedException('Symfony\Component\Validator\Exception\GroupDefinitionException');
+
+ $this->metadata->setGroupSequence(array('Foo', 'Bar'));
+ }
+
+ public function testGroupSequencesFailIfContainingDefault()
+ {
+ $this->setExpectedException('Symfony\Component\Validator\Exception\GroupDefinitionException');
+
+ $this->metadata->setGroupSequence(array('Foo', $this->metadata->getDefaultGroup(), Constraint::DEFAULT_GROUP));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\GroupDefinitionException
+ */
+ public function testGroupSequenceFailsIfGroupSequenceProviderIsSet()
+ {
+ $metadata = new ClassMetadata(self::PROVIDERCLASS);
+ $metadata->setGroupSequenceProvider(true);
+ $metadata->setGroupSequence(array('GroupSequenceProviderEntity', 'Foo'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\GroupDefinitionException
+ */
+ public function testGroupSequenceProviderFailsIfGroupSequenceIsSet()
+ {
+ $metadata = new ClassMetadata(self::PROVIDERCLASS);
+ $metadata->setGroupSequence(array('GroupSequenceProviderEntity', 'Foo'));
+ $metadata->setGroupSequenceProvider(true);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\GroupDefinitionException
+ */
+ public function testGroupSequenceProviderFailsIfDomainClassIsInvalid()
+ {
+ $metadata = new ClassMetadata('stdClass');
+ $metadata->setGroupSequenceProvider(true);
+ }
+
+ public function testGroupSequenceProvider()
+ {
+ $metadata = new ClassMetadata(self::PROVIDERCLASS);
+ $metadata->setGroupSequenceProvider(true);
+ $this->assertTrue($metadata->isGroupSequenceProvider());
+ }
+
+ /**
+ * https://github.com/symfony/symfony/issues/11604.
+ */
+ public function testGetPropertyMetadataReturnsEmptyArrayWithoutConfiguredMetadata()
+ {
+ $this->assertCount(0, $this->metadata->getPropertyMetadata('foo'), '->getPropertyMetadata() returns an empty collection if no metadata is configured for the given property');
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Factory/BlackHoleMetadataFactoryTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Factory/BlackHoleMetadataFactoryTest.php
new file mode 100644
index 0000000..641bf91
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Factory/BlackHoleMetadataFactoryTest.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping\Factory;
+
+use Symfony\Component\Validator\Mapping\Factory\BlackHoleMetadataFactory;
+
+class BlackHoleMetadataFactoryTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \LogicException
+ */
+ public function testGetMetadataForThrowsALogicException()
+ {
+ $metadataFactory = new BlackHoleMetadataFactory();
+ $metadataFactory->getMetadataFor('foo');
+ }
+
+ public function testHasMetadataForReturnsFalse()
+ {
+ $metadataFactory = new BlackHoleMetadataFactory();
+
+ $this->assertFalse($metadataFactory->hasMetadataFor('foo'));
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php
new file mode 100644
index 0000000..74ee912
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php
@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping\Factory;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
+use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+
+class LazyLoadingMetadataFactoryTest extends \PHPUnit_Framework_TestCase
+{
+ const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
+ const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent';
+
+ public function testLoadClassMetadata()
+ {
+ $factory = new LazyLoadingMetadataFactory(new TestLoader());
+ $metadata = $factory->getMetadataFor(self::PARENTCLASS);
+
+ $constraints = array(
+ new ConstraintA(array('groups' => array('Default', 'EntityParent'))),
+ );
+
+ $this->assertEquals($constraints, $metadata->getConstraints());
+ }
+
+ public function testMergeParentConstraints()
+ {
+ $factory = new LazyLoadingMetadataFactory(new TestLoader());
+ $metadata = $factory->getMetadataFor(self::CLASSNAME);
+
+ $constraints = array(
+ new ConstraintA(array('groups' => array(
+ 'Default',
+ 'EntityParent',
+ 'Entity',
+ ))),
+ new ConstraintA(array('groups' => array(
+ 'Default',
+ 'EntityInterface',
+ 'Entity',
+ ))),
+ new ConstraintA(array('groups' => array(
+ 'Default',
+ 'Entity',
+ ))),
+ );
+
+ $this->assertEquals($constraints, $metadata->getConstraints());
+ }
+
+ public function testWriteMetadataToCache()
+ {
+ $cache = $this->getMock('Symfony\Component\Validator\Mapping\Cache\CacheInterface');
+ $factory = new LazyLoadingMetadataFactory(new TestLoader(), $cache);
+
+ $tester = $this;
+ $constraints = array(
+ new ConstraintA(array('groups' => array('Default', 'EntityParent'))),
+ );
+
+ $cache->expects($this->never())
+ ->method('has');
+ $cache->expects($this->once())
+ ->method('read')
+ ->with($this->equalTo(self::PARENTCLASS))
+ ->will($this->returnValue(false));
+ $cache->expects($this->once())
+ ->method('write')
+ ->will($this->returnCallback(function ($metadata) use ($tester, $constraints) {
+ $tester->assertEquals($constraints, $metadata->getConstraints());
+ }));
+
+ $metadata = $factory->getMetadataFor(self::PARENTCLASS);
+
+ $this->assertEquals(self::PARENTCLASS, $metadata->getClassName());
+ $this->assertEquals($constraints, $metadata->getConstraints());
+ }
+
+ public function testReadMetadataFromCache()
+ {
+ $loader = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+ $cache = $this->getMock('Symfony\Component\Validator\Mapping\Cache\CacheInterface');
+ $factory = new LazyLoadingMetadataFactory($loader, $cache);
+
+ $tester = $this;
+ $metadata = new ClassMetadata(self::PARENTCLASS);
+ $metadata->addConstraint(new ConstraintA());
+
+ $loader->expects($this->never())
+ ->method('loadClassMetadata');
+
+ $cache->expects($this->never())
+ ->method('has');
+ $cache->expects($this->once())
+ ->method('read')
+ ->will($this->returnValue($metadata));
+
+ $this->assertEquals($metadata, $factory->getMetadataFor(self::PARENTCLASS));
+ }
+}
+
+class TestLoader implements LoaderInterface
+{
+ public function loadClassMetadata(ClassMetadata $metadata)
+ {
+ $metadata->addConstraint(new ConstraintA());
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php
new file mode 100644
index 0000000..0781599
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping;
+
+use Symfony\Component\Validator\Mapping\GetterMetadata;
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+
+class GetterMetadataTest extends \PHPUnit_Framework_TestCase
+{
+ const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
+
+ public function testInvalidPropertyName()
+ {
+ $this->setExpectedException('Symfony\Component\Validator\Exception\ValidatorException');
+
+ new GetterMetadata(self::CLASSNAME, 'foobar');
+ }
+
+ public function testGetPropertyValueFromPublicGetter()
+ {
+ // private getters don't work yet because ReflectionMethod::setAccessible()
+ // does not exist yet in a stable PHP release
+
+ $entity = new Entity('foobar');
+ $metadata = new GetterMetadata(self::CLASSNAME, 'internal');
+
+ $this->assertEquals('foobar from getter', $metadata->getPropertyValue($entity));
+ }
+
+ public function testGetPropertyValueFromOverriddenPublicGetter()
+ {
+ $entity = new Entity();
+ $metadata = new GetterMetadata(self::CLASSNAME, 'data');
+
+ $this->assertEquals('Overridden data', $metadata->getPropertyValue($entity));
+ }
+
+ public function testGetPropertyValueFromIsser()
+ {
+ $entity = new Entity();
+ $metadata = new GetterMetadata(self::CLASSNAME, 'valid');
+
+ $this->assertEquals('valid', $metadata->getPropertyValue($entity));
+ }
+
+ public function testGetPropertyValueFromHasser()
+ {
+ $entity = new Entity();
+ $metadata = new GetterMetadata(self::CLASSNAME, 'permissions');
+
+ $this->assertEquals('permissions', $metadata->getPropertyValue($entity));
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/LegacyElementMetadataTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/LegacyElementMetadataTest.php
new file mode 100644
index 0000000..c77e6fe
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/LegacyElementMetadataTest.php
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping;
+
+use Symfony\Component\Validator\Mapping\ElementMetadata;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
+
+/**
+ * @group legacy
+ */
+class LegacyElementMetadataTest extends \PHPUnit_Framework_TestCase
+{
+ protected $metadata;
+
+ protected function setUp()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ $this->metadata = new TestElementMetadata();
+ }
+
+ protected function tearDown()
+ {
+ $this->metadata = null;
+ }
+
+ public function testAddConstraints()
+ {
+ $this->metadata->addConstraint($constraint1 = new ConstraintA());
+ $this->metadata->addConstraint($constraint2 = new ConstraintA());
+
+ $this->assertEquals(array($constraint1, $constraint2), $this->metadata->getConstraints());
+ }
+
+ public function testMultipleConstraintsOfTheSameType()
+ {
+ $constraint1 = new ConstraintA(array('property1' => 'A'));
+ $constraint2 = new ConstraintA(array('property1' => 'B'));
+
+ $this->metadata->addConstraint($constraint1);
+ $this->metadata->addConstraint($constraint2);
+
+ $this->assertEquals(array($constraint1, $constraint2), $this->metadata->getConstraints());
+ }
+
+ public function testFindConstraintsByGroup()
+ {
+ $constraint1 = new ConstraintA(array('groups' => 'TestGroup'));
+ $constraint2 = new ConstraintB();
+
+ $this->metadata->addConstraint($constraint1);
+ $this->metadata->addConstraint($constraint2);
+
+ $this->assertEquals(array($constraint1), $this->metadata->findConstraints('TestGroup'));
+ }
+
+ public function testSerialize()
+ {
+ $this->metadata->addConstraint(new ConstraintA(array('property1' => 'A')));
+ $this->metadata->addConstraint(new ConstraintB(array('groups' => 'TestGroup')));
+
+ $metadata = unserialize(serialize($this->metadata));
+
+ $this->assertEquals($this->metadata, $metadata);
+ }
+}
+
+class TestElementMetadata extends ElementMetadata
+{
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AbstractStaticMethodLoader.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AbstractStaticMethodLoader.php
new file mode 100644
index 0000000..08f219d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AbstractStaticMethodLoader.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace Symfony\Component\Validator\Tests\Mapping\Loader;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+abstract class AbstractStaticMethodLoader
+{
+ abstract public static function loadMetadata(ClassMetadata $metadata);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php
new file mode 100644
index 0000000..ad98aa1
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php
@@ -0,0 +1,172 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping\Loader;
+
+use Doctrine\Common\Annotations\AnnotationReader;
+use Symfony\Component\Validator\Constraints\All;
+use Symfony\Component\Validator\Constraints\Callback;
+use Symfony\Component\Validator\Constraints\Choice;
+use Symfony\Component\Validator\Constraints\Collection;
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\Constraints\Range;
+use Symfony\Component\Validator\Constraints\True;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+
+require_once __DIR__.'/../../../Constraints/All.php';
+require_once __DIR__.'/../../../Constraints/Callback.php';
+require_once __DIR__.'/../../../Constraints/Choice.php';
+require_once __DIR__.'/../../../Constraints/Collection.php';
+require_once __DIR__.'/../../../Constraints/GroupSequence.php';
+require_once __DIR__.'/../../../Constraints/GroupSequenceProvider.php';
+require_once __DIR__.'/../../../Constraints/NotNull.php';
+require_once __DIR__.'/../../../Constraints/Range.php';
+require_once __DIR__.'/../../Fixtures/ConstraintA.php';
+
+class AnnotationLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testLoadClassMetadataReturnsTrueIfSuccessful()
+ {
+ $reader = new AnnotationReader();
+ $loader = new AnnotationLoader($reader);
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+ $this->assertTrue($loader->loadClassMetadata($metadata));
+ }
+
+ public function testLoadClassMetadataReturnsFalseIfNotSuccessful()
+ {
+ $loader = new AnnotationLoader(new AnnotationReader());
+ $metadata = new ClassMetadata('\stdClass');
+
+ $this->assertFalse($loader->loadClassMetadata($metadata));
+ }
+
+ public function testLoadClassMetadata()
+ {
+ $loader = new AnnotationLoader(new AnnotationReader());
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+ $loader->loadClassMetadata($metadata);
+
+ $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+ $expected->setGroupSequence(array('Foo', 'Entity'));
+ $expected->addConstraint(new ConstraintA());
+ $expected->addConstraint(new Callback(array('Symfony\Component\Validator\Tests\Fixtures\CallbackClass', 'callback')));
+ $expected->addConstraint(new Callback('validateMe'));
+ $expected->addConstraint(new Callback('validateMeStatic'));
+ $expected->addPropertyConstraint('firstName', new NotNull());
+ $expected->addPropertyConstraint('firstName', new Range(array('min' => 3)));
+ $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Range(array('min' => 3)))));
+ $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Range(array('min' => 3))))));
+ $expected->addPropertyConstraint('firstName', new Collection(array('fields' => array(
+ 'foo' => array(new NotNull(), new Range(array('min' => 3))),
+ 'bar' => new Range(array('min' => 5)),
+ ))));
+ $expected->addPropertyConstraint('firstName', new Choice(array(
+ 'message' => 'Must be one of %choices%',
+ 'choices' => array('A', 'B'),
+ )));
+ $expected->addGetterConstraint('lastName', new NotNull());
+ $expected->addGetterConstraint('valid', new True());
+ $expected->addGetterConstraint('permissions', new True());
+
+ // load reflection class so that the comparison passes
+ $expected->getReflectionClass();
+
+ $this->assertEquals($expected, $metadata);
+ }
+
+ /**
+ * Test MetaData merge with parent annotation.
+ */
+ public function testLoadParentClassMetadata()
+ {
+ $loader = new AnnotationLoader(new AnnotationReader());
+
+ // Load Parent MetaData
+ $parent_metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\EntityParent');
+ $loader->loadClassMetadata($parent_metadata);
+
+ $expected_parent = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\EntityParent');
+ $expected_parent->addPropertyConstraint('other', new NotNull());
+ $expected_parent->getReflectionClass();
+
+ $this->assertEquals($expected_parent, $parent_metadata);
+ }
+ /**
+ * Test MetaData merge with parent annotation.
+ */
+ public function testLoadClassMetadataAndMerge()
+ {
+ $loader = new AnnotationLoader(new AnnotationReader());
+
+ // Load Parent MetaData
+ $parent_metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\EntityParent');
+ $loader->loadClassMetadata($parent_metadata);
+
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+ // Merge parent metaData.
+ $metadata->mergeConstraints($parent_metadata);
+
+ $loader->loadClassMetadata($metadata);
+
+ $expected_parent = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\EntityParent');
+ $expected_parent->addPropertyConstraint('other', new NotNull());
+ $expected_parent->getReflectionClass();
+
+ $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+ $expected->mergeConstraints($expected_parent);
+
+ $expected->setGroupSequence(array('Foo', 'Entity'));
+ $expected->addConstraint(new ConstraintA());
+ $expected->addConstraint(new Callback(array('Symfony\Component\Validator\Tests\Fixtures\CallbackClass', 'callback')));
+ $expected->addConstraint(new Callback('validateMe'));
+ $expected->addConstraint(new Callback('validateMeStatic'));
+ $expected->addPropertyConstraint('firstName', new NotNull());
+ $expected->addPropertyConstraint('firstName', new Range(array('min' => 3)));
+ $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Range(array('min' => 3)))));
+ $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Range(array('min' => 3))))));
+ $expected->addPropertyConstraint('firstName', new Collection(array('fields' => array(
+ 'foo' => array(new NotNull(), new Range(array('min' => 3))),
+ 'bar' => new Range(array('min' => 5)),
+ ))));
+ $expected->addPropertyConstraint('firstName', new Choice(array(
+ 'message' => 'Must be one of %choices%',
+ 'choices' => array('A', 'B'),
+ )));
+ $expected->addGetterConstraint('lastName', new NotNull());
+ $expected->addGetterConstraint('valid', new True());
+ $expected->addGetterConstraint('permissions', new True());
+
+ // load reflection class so that the comparison passes
+ $expected->getReflectionClass();
+
+ $this->assertEquals($expected, $metadata);
+ }
+
+ public function testLoadGroupSequenceProviderAnnotation()
+ {
+ $loader = new AnnotationLoader(new AnnotationReader());
+
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity');
+ $loader->loadClassMetadata($metadata);
+
+ $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity');
+ $expected->setGroupSequenceProvider(true);
+ $expected->getReflectionClass();
+
+ $this->assertEquals($expected, $metadata);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/FilesLoaderTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/FilesLoaderTest.php
new file mode 100644
index 0000000..09e6e44
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/FilesLoaderTest.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping\Loader;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
+
+class FilesLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testCallsGetFileLoaderInstanceForeachPath()
+ {
+ $loader = $this->getFilesLoader($this->getFileLoader());
+ $this->assertEquals(4, $loader->getTimesCalled());
+ }
+
+ public function testCallsActualFileLoaderForMetadata()
+ {
+ $fileLoader = $this->getFileLoader();
+ $fileLoader->expects($this->exactly(4))
+ ->method('loadClassMetadata');
+ $loader = $this->getFilesLoader($fileLoader);
+ $loader->loadClassMetadata(new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity'));
+ }
+
+ public function getFilesLoader(LoaderInterface $loader)
+ {
+ return $this->getMockForAbstractClass('Symfony\Component\Validator\Tests\Fixtures\FilesLoader', array(array(
+ __DIR__.'/constraint-mapping.xml',
+ __DIR__.'/constraint-mapping.yaml',
+ __DIR__.'/constraint-mapping.test',
+ __DIR__.'/constraint-mapping.txt',
+ ), $loader));
+ }
+
+ public function getFileLoader()
+ {
+ return $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/LoaderChainTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/LoaderChainTest.php
new file mode 100644
index 0000000..647a568
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/LoaderChainTest.php
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping\Loader;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Loader\LoaderChain;
+
+class LoaderChainTest extends \PHPUnit_Framework_TestCase
+{
+ public function testAllLoadersAreCalled()
+ {
+ $metadata = new ClassMetadata('\stdClass');
+
+ $loader1 = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+ $loader1->expects($this->once())
+ ->method('loadClassMetadata')
+ ->with($this->equalTo($metadata));
+
+ $loader2 = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+ $loader2->expects($this->once())
+ ->method('loadClassMetadata')
+ ->with($this->equalTo($metadata));
+
+ $chain = new LoaderChain(array(
+ $loader1,
+ $loader2,
+ ));
+
+ $chain->loadClassMetadata($metadata);
+ }
+
+ public function testReturnsTrueIfAnyLoaderReturnedTrue()
+ {
+ $metadata = new ClassMetadata('\stdClass');
+
+ $loader1 = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+ $loader1->expects($this->any())
+ ->method('loadClassMetadata')
+ ->will($this->returnValue(true));
+
+ $loader2 = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+ $loader2->expects($this->any())
+ ->method('loadClassMetadata')
+ ->will($this->returnValue(false));
+
+ $chain = new LoaderChain(array(
+ $loader1,
+ $loader2,
+ ));
+
+ $this->assertTrue($chain->loadClassMetadata($metadata));
+ }
+
+ public function testReturnsFalseIfNoLoaderReturnedTrue()
+ {
+ $metadata = new ClassMetadata('\stdClass');
+
+ $loader1 = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+ $loader1->expects($this->any())
+ ->method('loadClassMetadata')
+ ->will($this->returnValue(false));
+
+ $loader2 = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+ $loader2->expects($this->any())
+ ->method('loadClassMetadata')
+ ->will($this->returnValue(false));
+
+ $chain = new LoaderChain(array(
+ $loader1,
+ $loader2,
+ ));
+
+ $this->assertFalse($chain->loadClassMetadata($metadata));
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/StaticMethodLoaderTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/StaticMethodLoaderTest.php
new file mode 100644
index 0000000..5829336
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/StaticMethodLoaderTest.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping\Loader;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+
+class StaticMethodLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ private $errorLevel;
+
+ protected function setUp()
+ {
+ $this->errorLevel = error_reporting();
+ }
+
+ protected function tearDown()
+ {
+ error_reporting($this->errorLevel);
+ }
+
+ public function testLoadClassMetadataReturnsTrueIfSuccessful()
+ {
+ $loader = new StaticMethodLoader('loadMetadata');
+ $metadata = new ClassMetadata(__NAMESPACE__.'\StaticLoaderEntity');
+
+ $this->assertTrue($loader->loadClassMetadata($metadata));
+ }
+
+ public function testLoadClassMetadataReturnsFalseIfNotSuccessful()
+ {
+ $loader = new StaticMethodLoader('loadMetadata');
+ $metadata = new ClassMetadata('\stdClass');
+
+ $this->assertFalse($loader->loadClassMetadata($metadata));
+ }
+
+ public function testLoadClassMetadata()
+ {
+ $loader = new StaticMethodLoader('loadMetadata');
+ $metadata = new ClassMetadata(__NAMESPACE__.'\StaticLoaderEntity');
+
+ $loader->loadClassMetadata($metadata);
+
+ $this->assertEquals(StaticLoaderEntity::$invokedWith, $metadata);
+ }
+
+ public function testLoadClassMetadataDoesNotRepeatLoadWithParentClasses()
+ {
+ $loader = new StaticMethodLoader('loadMetadata');
+ $metadata = new ClassMetadata(__NAMESPACE__.'\StaticLoaderDocument');
+ $loader->loadClassMetadata($metadata);
+ $this->assertCount(0, $metadata->getConstraints());
+
+ $loader = new StaticMethodLoader('loadMetadata');
+ $metadata = new ClassMetadata(__NAMESPACE__.'\BaseStaticLoaderDocument');
+ $loader->loadClassMetadata($metadata);
+ $this->assertCount(1, $metadata->getConstraints());
+ }
+
+ public function testLoadClassMetadataIgnoresInterfaces()
+ {
+ $loader = new StaticMethodLoader('loadMetadata');
+ $metadata = new ClassMetadata(__NAMESPACE__.'\StaticLoaderInterface');
+
+ $loader->loadClassMetadata($metadata);
+
+ $this->assertCount(0, $metadata->getConstraints());
+ }
+
+ public function testLoadClassMetadataInAbstractClasses()
+ {
+ $loader = new StaticMethodLoader('loadMetadata');
+ $metadata = new ClassMetadata(__NAMESPACE__.'\AbstractStaticLoader');
+
+ $loader->loadClassMetadata($metadata);
+
+ $this->assertCount(1, $metadata->getConstraints());
+ }
+
+ public function testLoadClassMetadataIgnoresAbstractMethods()
+ {
+ // Disable error reporting, as AbstractStaticMethodLoader produces a
+ // strict standards error
+ error_reporting(0);
+
+ if (0 !== error_reporting()) {
+ $this->markTestSkipped('Could not disable error reporting');
+ }
+
+ $metadata = new ClassMetadata(__NAMESPACE__.'\AbstractStaticMethodLoader');
+
+ $loader = new StaticMethodLoader('loadMetadata');
+ $loader->loadClassMetadata($metadata);
+
+ $this->assertCount(0, $metadata->getConstraints());
+ }
+}
+
+interface StaticLoaderInterface
+{
+ public static function loadMetadata(ClassMetadata $metadata);
+}
+
+abstract class AbstractStaticLoader
+{
+ public static function loadMetadata(ClassMetadata $metadata)
+ {
+ $metadata->addConstraint(new ConstraintA());
+ }
+}
+
+class StaticLoaderEntity
+{
+ public static $invokedWith = null;
+
+ public static function loadMetadata(ClassMetadata $metadata)
+ {
+ self::$invokedWith = $metadata;
+ }
+}
+
+class StaticLoaderDocument extends BaseStaticLoaderDocument
+{
+}
+
+class BaseStaticLoaderDocument
+{
+ public static function loadMetadata(ClassMetadata $metadata)
+ {
+ $metadata->addConstraint(new ConstraintA());
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php
new file mode 100644
index 0000000..8ab2065
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php
@@ -0,0 +1,133 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping\Loader;
+
+use Symfony\Component\Validator\Constraints\All;
+use Symfony\Component\Validator\Constraints\Callback;
+use Symfony\Component\Validator\Constraints\Choice;
+use Symfony\Component\Validator\Constraints\Collection;
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\Constraints\Range;
+use Symfony\Component\Validator\Constraints\Regex;
+use Symfony\Component\Validator\Constraints\True;
+use Symfony\Component\Validator\Exception\MappingException;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
+
+class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testLoadClassMetadataReturnsTrueIfSuccessful()
+ {
+ $loader = new XmlFileLoader(__DIR__.'/constraint-mapping.xml');
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+ $this->assertTrue($loader->loadClassMetadata($metadata));
+ }
+
+ public function testLoadClassMetadataReturnsFalseIfNotSuccessful()
+ {
+ $loader = new XmlFileLoader(__DIR__.'/constraint-mapping.xml');
+ $metadata = new ClassMetadata('\stdClass');
+
+ $this->assertFalse($loader->loadClassMetadata($metadata));
+ }
+
+ public function testLoadClassMetadata()
+ {
+ $loader = new XmlFileLoader(__DIR__.'/constraint-mapping.xml');
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+ $loader->loadClassMetadata($metadata);
+
+ $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+ $expected->setGroupSequence(array('Foo', 'Entity'));
+ $expected->addConstraint(new ConstraintA());
+ $expected->addConstraint(new ConstraintB());
+ $expected->addConstraint(new Callback('validateMe'));
+ $expected->addConstraint(new Callback('validateMeStatic'));
+ $expected->addConstraint(new Callback(array('Symfony\Component\Validator\Tests\Fixtures\CallbackClass', 'callback')));
+ $expected->addPropertyConstraint('firstName', new NotNull());
+ $expected->addPropertyConstraint('firstName', new Range(array('min' => 3)));
+ $expected->addPropertyConstraint('firstName', new Choice(array('A', 'B')));
+ $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Range(array('min' => 3)))));
+ $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Range(array('min' => 3))))));
+ $expected->addPropertyConstraint('firstName', new Collection(array('fields' => array(
+ 'foo' => array(new NotNull(), new Range(array('min' => 3))),
+ 'bar' => array(new Range(array('min' => 5))),
+ ))));
+ $expected->addPropertyConstraint('firstName', new Choice(array(
+ 'message' => 'Must be one of %choices%',
+ 'choices' => array('A', 'B'),
+ )));
+ $expected->addGetterConstraint('lastName', new NotNull());
+ $expected->addGetterConstraint('valid', new True());
+ $expected->addGetterConstraint('permissions', new True());
+
+ $this->assertEquals($expected, $metadata);
+ }
+
+ public function testLoadClassMetadataWithNonStrings()
+ {
+ $loader = new XmlFileLoader(__DIR__.'/constraint-mapping-non-strings.xml');
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+ $loader->loadClassMetadata($metadata);
+
+ $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+ $expected->addPropertyConstraint('firstName', new Regex(array('pattern' => '/^1/', 'match' => false)));
+
+ $properties = $metadata->getPropertyMetadata('firstName');
+ $constraints = $properties[0]->getConstraints();
+
+ $this->assertFalse($constraints[0]->match);
+ }
+
+ public function testLoadGroupSequenceProvider()
+ {
+ $loader = new XmlFileLoader(__DIR__.'/constraint-mapping.xml');
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity');
+
+ $loader->loadClassMetadata($metadata);
+
+ $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity');
+ $expected->setGroupSequenceProvider(true);
+
+ $this->assertEquals($expected, $metadata);
+ }
+
+ public function testThrowExceptionIfDocTypeIsSet()
+ {
+ $loader = new XmlFileLoader(__DIR__.'/withdoctype.xml');
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+ $this->setExpectedException('\Symfony\Component\Validator\Exception\MappingException');
+ $loader->loadClassMetadata($metadata);
+ }
+
+ /**
+ * @see https://github.com/symfony/symfony/pull/12158
+ */
+ public function testDoNotModifyStateIfExceptionIsThrown()
+ {
+ $loader = new XmlFileLoader(__DIR__.'/withdoctype.xml');
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+ try {
+ $loader->loadClassMetadata($metadata);
+ } catch (MappingException $e) {
+ $this->setExpectedException('\Symfony\Component\Validator\Exception\MappingException');
+ $loader->loadClassMetadata($metadata);
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php
new file mode 100644
index 0000000..806a2b0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping\Loader;
+
+use Symfony\Component\Validator\Constraints\All;
+use Symfony\Component\Validator\Constraints\Callback;
+use Symfony\Component\Validator\Constraints\Choice;
+use Symfony\Component\Validator\Constraints\Collection;
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\Constraints\Range;
+use Symfony\Component\Validator\Constraints\True;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
+
+class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testLoadClassMetadataReturnsFalseIfEmpty()
+ {
+ $loader = new YamlFileLoader(__DIR__.'/empty-mapping.yml');
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+ $this->assertFalse($loader->loadClassMetadata($metadata));
+ }
+
+ public function testLoadClassMetadataThrowsExceptionIfNotAnArray()
+ {
+ $loader = new YamlFileLoader(__DIR__.'/nonvalid-mapping.yml');
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+ $this->setExpectedException('\InvalidArgumentException');
+ $loader->loadClassMetadata($metadata);
+ }
+
+ /**
+ * @see https://github.com/symfony/symfony/pull/12158
+ */
+ public function testDoNotModifyStateIfExceptionIsThrown()
+ {
+ $loader = new YamlFileLoader(__DIR__.'/nonvalid-mapping.yml');
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+ try {
+ $loader->loadClassMetadata($metadata);
+ } catch (\InvalidArgumentException $e) {
+ // Call again. Again an exception should be thrown
+ $this->setExpectedException('\InvalidArgumentException');
+ $loader->loadClassMetadata($metadata);
+ }
+ }
+
+ public function testLoadClassMetadataReturnsTrueIfSuccessful()
+ {
+ $loader = new YamlFileLoader(__DIR__.'/constraint-mapping.yml');
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+ $this->assertTrue($loader->loadClassMetadata($metadata));
+ }
+
+ public function testLoadClassMetadataReturnsFalseIfNotSuccessful()
+ {
+ $loader = new YamlFileLoader(__DIR__.'/constraint-mapping.yml');
+ $metadata = new ClassMetadata('\stdClass');
+
+ $this->assertFalse($loader->loadClassMetadata($metadata));
+ }
+
+ public function testLoadClassMetadata()
+ {
+ $loader = new YamlFileLoader(__DIR__.'/constraint-mapping.yml');
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+ $loader->loadClassMetadata($metadata);
+
+ $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+ $expected->setGroupSequence(array('Foo', 'Entity'));
+ $expected->addConstraint(new ConstraintA());
+ $expected->addConstraint(new ConstraintB());
+ $expected->addConstraint(new Callback('validateMe'));
+ $expected->addConstraint(new Callback('validateMeStatic'));
+ $expected->addConstraint(new Callback(array('Symfony\Component\Validator\Tests\Fixtures\CallbackClass', 'callback')));
+ $expected->addPropertyConstraint('firstName', new NotNull());
+ $expected->addPropertyConstraint('firstName', new Range(array('min' => 3)));
+ $expected->addPropertyConstraint('firstName', new Choice(array('A', 'B')));
+ $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Range(array('min' => 3)))));
+ $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Range(array('min' => 3))))));
+ $expected->addPropertyConstraint('firstName', new Collection(array('fields' => array(
+ 'foo' => array(new NotNull(), new Range(array('min' => 3))),
+ 'bar' => array(new Range(array('min' => 5))),
+ ))));
+ $expected->addPropertyConstraint('firstName', new Choice(array(
+ 'message' => 'Must be one of %choices%',
+ 'choices' => array('A', 'B'),
+ )));
+ $expected->addGetterConstraint('lastName', new NotNull());
+ $expected->addGetterConstraint('valid', new True());
+ $expected->addGetterConstraint('permissions', new True());
+
+ $this->assertEquals($expected, $metadata);
+ }
+
+ public function testLoadGroupSequenceProvider()
+ {
+ $loader = new YamlFileLoader(__DIR__.'/constraint-mapping.yml');
+ $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity');
+
+ $loader->loadClassMetadata($metadata);
+
+ $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity');
+ $expected->setGroupSequenceProvider(true);
+
+ $this->assertEquals($expected, $metadata);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping-non-strings.xml b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping-non-strings.xml
new file mode 100644
index 0000000..dfd5edd
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping-non-strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" ?>
+
+<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
+
+ <namespace prefix="custom">Symfony\Component\Validator\Tests\Fixtures\</namespace>
+
+ <class name="Symfony\Component\Validator\Tests\Fixtures\Entity">
+ <property name="firstName">
+ <!-- Constraint with a Boolean -->
+ <constraint name="Regex">
+ <option name="pattern">/^1/</option>
+ <option name="match">false</option>
+ </constraint>
+ </property>
+ </class>
+
+</constraint-mapping>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml
new file mode 100644
index 0000000..9b637e9
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" ?>
+
+<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
+
+ <namespace prefix="custom">Symfony\Component\Validator\Tests\Fixtures\</namespace>
+
+ <class name="Symfony\Component\Validator\Tests\Fixtures\Entity">
+
+ <group-sequence>
+ <value>Foo</value>
+ <value>Entity</value>
+ </group-sequence>
+
+ <!-- CLASS CONSTRAINTS -->
+
+ <!-- Custom constraint -->
+ <constraint name="Symfony\Component\Validator\Tests\Fixtures\ConstraintA" />
+
+ <!-- Custom constraint with namespace abbreviation-->
+ <constraint name="custom:ConstraintB" />
+
+ <!-- Callbacks -->
+ <constraint name="Callback">validateMe</constraint>
+
+ <constraint name="Callback">validateMeStatic</constraint>
+
+ <constraint name="Callback">
+ <value>Symfony\Component\Validator\Tests\Fixtures\CallbackClass</value>
+ <value>callback</value>
+ </constraint>
+
+ <!-- PROPERTY CONSTRAINTS -->
+
+ <property name="firstName">
+
+ <!-- Constraint without value -->
+ <constraint name="NotNull" />
+
+ <!-- Constraint with single value -->
+ <constraint name="Range">
+ <option name="min">3</option>
+ </constraint>
+
+ <!-- Constraint with multiple values -->
+ <constraint name="Choice">
+ <value>A</value>
+ <value>B</value>
+ </constraint>
+
+ <!-- Constraint with child constraints -->
+ <constraint name="All">
+ <constraint name="NotNull" />
+ <constraint name="Range">
+ <option name="min">3</option>
+ </constraint>
+
+ </constraint>
+
+ <!-- Option with child constraints -->
+ <constraint name="All">
+ <option name="constraints">
+ <constraint name="NotNull" />
+ <constraint name="Range">
+ <option name="min">3</option>
+ </constraint>
+ </option>
+ </constraint>
+
+ <!-- Value with child constraints -->
+ <constraint name="Collection">
+ <option name="fields">
+ <value key="foo">
+ <constraint name="NotNull" />
+ <constraint name="Range">
+ <option name="min">3</option>
+ </constraint>
+ </value>
+ <value key="bar">
+ <constraint name="Range">
+ <option name="min">5</option>
+ </constraint>
+ </value>
+ </option>
+ </constraint>
+
+ <!-- Constraint with options -->
+ <constraint name="Choice">
+ <!-- Option with single value -->
+ <option name="message"> Must be one of %choices% </option>
+ <!-- Option with multiple values -->
+ <option name="choices">
+ <value>A</value>
+ <value>B</value>
+ </option>
+ </constraint>
+ </property>
+
+ <!-- GETTER CONSTRAINTS -->
+
+ <getter property="lastName">
+ <constraint name="NotNull" />
+ </getter>
+ <getter property="valid">
+ <constraint name="True" />
+ </getter>
+ <getter property="permissions">
+ <constraint name="True" />
+ </getter>
+ </class>
+
+ <class name="Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity">
+
+ <!-- GROUP SEQUENCE PROVIDER -->
+ <group-sequence-provider />
+
+ </class>
+</constraint-mapping>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml
new file mode 100644
index 0000000..e96c5e0
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml
@@ -0,0 +1,62 @@
+namespaces:
+ custom: Symfony\Component\Validator\Tests\Fixtures\
+
+Symfony\Component\Validator\Tests\Fixtures\Entity:
+ group_sequence:
+ - Foo
+ - Entity
+
+ constraints:
+ # Custom constraint
+ - Symfony\Component\Validator\Tests\Fixtures\ConstraintA: ~
+ # Custom constraint with namespaces prefix
+ - "custom:ConstraintB": ~
+ # Callbacks
+ - Callback: validateMe
+ - Callback: validateMeStatic
+ - Callback: [Symfony\Component\Validator\Tests\Fixtures\CallbackClass, callback]
+
+ properties:
+ firstName:
+ # Constraint without value
+ - NotNull: ~
+ # Constraint with single value
+ - Range:
+ min: 3
+ # Constraint with multiple values
+ - Choice: [A, B]
+ # Constraint with child constraints
+ - All:
+ - NotNull: ~
+ - Range:
+ min: 3
+ # Option with child constraints
+ - All:
+ constraints:
+ - NotNull: ~
+ - Range:
+ min: 3
+ # Value with child constraints
+ - Collection:
+ fields:
+ foo:
+ - NotNull: ~
+ - Range:
+ min: 3
+ bar:
+ - Range:
+ min: 5
+ # Constraint with options
+ - Choice: { choices: [A, B], message: Must be one of %choices% }
+ dummy:
+
+ getters:
+ lastName:
+ - NotNull: ~
+ valid:
+ - "True": ~
+ permissions:
+ - "True": ~
+
+Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity:
+ group_sequence_provider: true
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/empty-mapping.yml b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/empty-mapping.yml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/empty-mapping.yml
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/nonvalid-mapping.yml b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/nonvalid-mapping.yml
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/nonvalid-mapping.yml
@@ -0,0 +1 @@
+foo
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/withdoctype.xml b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/withdoctype.xml
new file mode 100644
index 0000000..0beacc3
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/withdoctype.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE foo>
+<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
+ <class name="Symfony\Component\Validator\Tests\Fixtures\Entity" />
+</constraint-mapping>
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.php
new file mode 100644
index 0000000..f91088d
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.php
@@ -0,0 +1,110 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping;
+
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\Mapping\MemberMetadata;
+use Symfony\Component\Validator\Tests\Fixtures\ClassConstraint;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
+
+class MemberMetadataTest extends \PHPUnit_Framework_TestCase
+{
+ protected $metadata;
+
+ protected function setUp()
+ {
+ $this->metadata = new TestMemberMetadata(
+ 'Symfony\Component\Validator\Tests\Fixtures\Entity',
+ 'getLastName',
+ 'lastName'
+ );
+ }
+
+ protected function tearDown()
+ {
+ $this->metadata = null;
+ }
+
+ public function testAddValidSetsMemberToCascaded()
+ {
+ $result = $this->metadata->addConstraint(new Valid());
+
+ $this->assertEquals(array(), $this->metadata->getConstraints());
+ $this->assertEquals($result, $this->metadata);
+ $this->assertTrue($this->metadata->isCascaded());
+ }
+
+ public function testAddOtherConstraintDoesNotSetMemberToCascaded()
+ {
+ $result = $this->metadata->addConstraint($constraint = new ConstraintA());
+
+ $this->assertEquals(array($constraint), $this->metadata->getConstraints());
+ $this->assertEquals($result, $this->metadata);
+ $this->assertFalse($this->metadata->isCascaded());
+ }
+
+ public function testAddConstraintRequiresClassConstraints()
+ {
+ $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
+
+ $this->metadata->addConstraint(new ClassConstraint());
+ }
+
+ public function testSerialize()
+ {
+ $this->metadata->addConstraint(new ConstraintA(array('property1' => 'A')));
+ $this->metadata->addConstraint(new ConstraintB(array('groups' => 'TestGroup')));
+
+ $metadata = unserialize(serialize($this->metadata));
+
+ $this->assertEquals($this->metadata, $metadata);
+ }
+
+ public function testSerializeCollectionCascaded()
+ {
+ $this->metadata->addConstraint(new Valid(array('traverse' => true, 'deep' => false)));
+
+ $metadata = unserialize(serialize($this->metadata));
+
+ $this->assertEquals($this->metadata, $metadata);
+ }
+
+ public function testSerializeCollectionCascadedDeeply()
+ {
+ $this->metadata->addConstraint(new Valid(array('traverse' => true, 'deep' => true)));
+
+ $metadata = unserialize(serialize($this->metadata));
+
+ $this->assertEquals($this->metadata, $metadata);
+ }
+
+ public function testSerializeCollectionNotCascaded()
+ {
+ $this->metadata->addConstraint(new Valid(array('traverse' => false)));
+
+ $metadata = unserialize(serialize($this->metadata));
+
+ $this->assertEquals($this->metadata, $metadata);
+ }
+}
+
+class TestMemberMetadata extends MemberMetadata
+{
+ public function getPropertyValue($object)
+ {
+ }
+
+ protected function newReflectionMember($object)
+ {
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php
new file mode 100644
index 0000000..f411d95
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping;
+
+use Symfony\Component\Validator\Mapping\PropertyMetadata;
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+
+class PropertyMetadataTest extends \PHPUnit_Framework_TestCase
+{
+ const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
+ const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent';
+
+ public function testInvalidPropertyName()
+ {
+ $this->setExpectedException('Symfony\Component\Validator\Exception\ValidatorException');
+
+ new PropertyMetadata(self::CLASSNAME, 'foobar');
+ }
+
+ public function testGetPropertyValueFromPrivateProperty()
+ {
+ $entity = new Entity('foobar');
+ $metadata = new PropertyMetadata(self::CLASSNAME, 'internal');
+
+ $this->assertEquals('foobar', $metadata->getPropertyValue($entity));
+ }
+
+ public function testGetPropertyValueFromOverriddenPrivateProperty()
+ {
+ $entity = new Entity('foobar');
+ $metadata = new PropertyMetadata(self::PARENTCLASS, 'data');
+
+ $this->assertTrue($metadata->isPublic($entity));
+ $this->assertEquals('Overridden data', $metadata->getPropertyValue($entity));
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Util/PropertyPathTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Util/PropertyPathTest.php
new file mode 100644
index 0000000..94802b6
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Util/PropertyPathTest.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Util;
+
+use Symfony\Component\Validator\Util\PropertyPath;
+
+class PropertyPathTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider provideAppendPaths
+ */
+ public function testAppend($basePath, $subPath, $expectedPath, $message)
+ {
+ $this->assertSame($expectedPath, PropertyPath::append($basePath, $subPath), $message);
+ }
+
+ public function provideAppendPaths()
+ {
+ return array(
+ array('foo', '', 'foo', 'It returns the basePath if subPath is empty'),
+ array('', 'bar', 'bar', 'It returns the subPath if basePath is empty'),
+ array('foo', 'bar', 'foo.bar', 'It append the subPath to the basePath'),
+ array('foo', '[bar]', 'foo[bar]', 'It does not include the dot separator if subPath uses the array notation'),
+ );
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php
new file mode 100644
index 0000000..684731f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php
@@ -0,0 +1,776 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Validator;
+
+use Symfony\Component\Validator\Constraints\Callback;
+use Symfony\Component\Validator\Constraints\GroupSequence;
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\Constraints\Traverse;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+use Symfony\Component\Validator\Context\ExecutionContextInterface;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+use Symfony\Component\Validator\Tests\Fixtures\FailingConstraint;
+use Symfony\Component\Validator\Tests\Fixtures\FakeClassMetadata;
+use Symfony\Component\Validator\Tests\Fixtures\Reference;
+use Symfony\Component\Validator\Validator\ValidatorInterface;
+
+/**
+ * Verifies that a validator satisfies the API of Symfony 2.5+.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+abstract class Abstract2Dot5ApiTest extends AbstractValidatorTest
+{
+ /**
+ * @var ValidatorInterface
+ */
+ protected $validator;
+
+ /**
+ * @param MetadataFactoryInterface $metadataFactory
+ *
+ * @return ValidatorInterface
+ */
+ abstract protected function createValidator(MetadataFactoryInterface $metadataFactory, array $objectInitializers = array());
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->validator = $this->createValidator($this->metadataFactory);
+ }
+
+ protected function validate($value, $constraints = null, $groups = null)
+ {
+ return $this->validator->validate($value, $constraints, $groups);
+ }
+
+ protected function validateProperty($object, $propertyName, $groups = null)
+ {
+ return $this->validator->validateProperty($object, $propertyName, $groups);
+ }
+
+ protected function validatePropertyValue($object, $propertyName, $value, $groups = null)
+ {
+ return $this->validator->validatePropertyValue($object, $propertyName, $value, $groups);
+ }
+
+ public function testValidateConstraintWithoutGroup()
+ {
+ $violations = $this->validator->validate(null, new NotNull());
+
+ $this->assertCount(1, $violations);
+ }
+
+ public function testGroupSequenceAbortsAfterFailedGroup()
+ {
+ $entity = new Entity();
+
+ $callback1 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Message 1');
+ };
+ $callback2 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Message 2');
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => function () {},
+ 'groups' => 'Group 1',
+ )));
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group 2',
+ )));
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group 3',
+ )));
+
+ $sequence = new GroupSequence(array('Group 1', 'Group 2', 'Group 3'));
+ $violations = $this->validator->validate($entity, new Valid(), $sequence);
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message 1', $violations[0]->getMessage());
+ }
+
+ public function testGroupSequenceIncludesReferences()
+ {
+ $entity = new Entity();
+ $entity->reference = new Reference();
+
+ $callback1 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Reference violation 1');
+ };
+ $callback2 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Reference violation 2');
+ };
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group 1',
+ )));
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group 2',
+ )));
+
+ $sequence = new GroupSequence(array('Group 1', 'Entity'));
+ $violations = $this->validator->validate($entity, new Valid(), $sequence);
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Reference violation 1', $violations[0]->getMessage());
+ }
+
+ public function testValidateInSeparateContext()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new Reference();
+
+ $callback1 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $violations = $context
+ ->getValidator()
+ // Since the validator is not context aware, the group must
+ // be passed explicitly
+ ->validate($value->reference, new Valid(), 'Group')
+ ;
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $test->assertCount(1, $violations);
+ $test->assertSame('Message value', $violations[0]->getMessage());
+ $test->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $test->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $test->assertSame('', $violations[0]->getPropertyPath());
+ // The root is different as we're in a new context
+ $test->assertSame($entity->reference, $violations[0]->getRoot());
+ $test->assertSame($entity->reference, $violations[0]->getInvalidValue());
+ $test->assertNull($violations[0]->getMessagePluralization());
+ $test->assertNull($violations[0]->getCode());
+
+ // Verify that this method is called
+ $context->addViolation('Separate violation');
+ };
+
+ $callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->referenceMetadata, $context->getMetadata());
+ $test->assertSame($entity->reference, $context->getRoot());
+ $test->assertSame($entity->reference, $context->getValue());
+ $test->assertSame($entity->reference, $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group',
+ )));
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validator->validate($entity, new Valid(), 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $test->assertSame('Separate violation', $violations[0]->getMessage());
+ }
+
+ public function testValidateInContext()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new Reference();
+
+ $callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
+ $previousValue = $context->getValue();
+ $previousObject = $context->getObject();
+ $previousMetadata = $context->getMetadata();
+ $previousPath = $context->getPropertyPath();
+ $previousGroup = $context->getGroup();
+
+ $context
+ ->getValidator()
+ ->inContext($context)
+ ->atPath('subpath')
+ ->validate($value->reference)
+ ;
+
+ // context changes shouldn't leak out of the validate() call
+ $test->assertSame($previousValue, $context->getValue());
+ $test->assertSame($previousObject, $context->getObject());
+ $test->assertSame($previousMetadata, $context->getMetadata());
+ $test->assertSame($previousPath, $context->getPropertyPath());
+ $test->assertSame($previousGroup, $context->getGroup());
+ };
+
+ $callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('subpath', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->referenceMetadata, $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame($entity->reference, $context->getValue());
+ $test->assertSame($entity->reference, $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group',
+ )));
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validator->validate($entity, new Valid(), 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('subpath', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame($entity->reference, $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testValidateArrayInContext()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new Reference();
+
+ $callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
+ $previousValue = $context->getValue();
+ $previousObject = $context->getObject();
+ $previousMetadata = $context->getMetadata();
+ $previousPath = $context->getPropertyPath();
+ $previousGroup = $context->getGroup();
+
+ $context
+ ->getValidator()
+ ->inContext($context)
+ ->atPath('subpath')
+ ->validate(array('key' => $value->reference))
+ ;
+
+ // context changes shouldn't leak out of the validate() call
+ $test->assertSame($previousValue, $context->getValue());
+ $test->assertSame($previousObject, $context->getObject());
+ $test->assertSame($previousMetadata, $context->getMetadata());
+ $test->assertSame($previousPath, $context->getPropertyPath());
+ $test->assertSame($previousGroup, $context->getGroup());
+ };
+
+ $callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('subpath[key]', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->referenceMetadata, $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame($entity->reference, $context->getValue());
+ $test->assertSame($entity->reference, $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group',
+ )));
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validator->validate($entity, new Valid(), 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('subpath[key]', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame($entity->reference, $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testTraverseTraversableByDefault()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $traversable = new \ArrayIterator(array('key' => $entity));
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity, $traversable) {
+ $test->assertSame($test::ENTITY_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('[key]', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->metadata, $context->getMetadata());
+ $test->assertSame($traversable, $context->getRoot());
+ $test->assertSame($entity, $context->getValue());
+ $test->assertSame($entity, $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator'));
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($traversable, new Valid(), 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('[key]', $violations[0]->getPropertyPath());
+ $this->assertSame($traversable, $violations[0]->getRoot());
+ $this->assertSame($entity, $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testTraversalEnabledOnClass()
+ {
+ $entity = new Entity();
+ $traversable = new \ArrayIterator(array('key' => $entity));
+
+ $callback = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Message');
+ };
+
+ $traversableMetadata = new ClassMetadata('ArrayIterator');
+ $traversableMetadata->addConstraint(new Traverse(true));
+
+ $this->metadataFactory->addMetadata($traversableMetadata);
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($traversable, new Valid(), 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ }
+
+ public function testTraversalDisabledOnClass()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $traversable = new \ArrayIterator(array('key' => $entity));
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test) {
+ $test->fail('Should not be called');
+ };
+
+ $traversableMetadata = new ClassMetadata('ArrayIterator');
+ $traversableMetadata->addConstraint(new Traverse(false));
+
+ $this->metadataFactory->addMetadata($traversableMetadata);
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($traversable, new Valid(), 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(0, $violations);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testExpectTraversableIfTraversalEnabledOnClass()
+ {
+ $entity = new Entity();
+
+ $this->metadata->addConstraint(new Traverse(true));
+
+ $this->validator->validate($entity);
+ }
+
+ public function testReferenceTraversalDisabledOnClass()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new \ArrayIterator(array('key' => new Reference()));
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test) {
+ $test->fail('Should not be called');
+ };
+
+ $traversableMetadata = new ClassMetadata('ArrayIterator');
+ $traversableMetadata->addConstraint(new Traverse(false));
+
+ $this->metadataFactory->addMetadata($traversableMetadata);
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+
+ $violations = $this->validate($entity, new Valid(), 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(0, $violations);
+ }
+
+ public function testReferenceTraversalEnabledOnReferenceDisabledOnClass()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new \ArrayIterator(array('key' => new Reference()));
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test) {
+ $test->fail('Should not be called');
+ };
+
+ $traversableMetadata = new ClassMetadata('ArrayIterator');
+ $traversableMetadata->addConstraint(new Traverse(false));
+
+ $this->metadataFactory->addMetadata($traversableMetadata);
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+ $this->metadata->addPropertyConstraint('reference', new Valid(array(
+ 'traverse' => true,
+ )));
+
+ $violations = $this->validate($entity, new Valid(), 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(0, $violations);
+ }
+
+ public function testReferenceTraversalDisabledOnReferenceEnabledOnClass()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new \ArrayIterator(array('key' => new Reference()));
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test) {
+ $test->fail('Should not be called');
+ };
+
+ $traversableMetadata = new ClassMetadata('ArrayIterator');
+ $traversableMetadata->addConstraint(new Traverse(true));
+
+ $this->metadataFactory->addMetadata($traversableMetadata);
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+ $this->metadata->addPropertyConstraint('reference', new Valid(array(
+ 'traverse' => false,
+ )));
+
+ $violations = $this->validate($entity, new Valid(), 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(0, $violations);
+ }
+
+ public function testReferenceTraversalRecursionEnabledOnReferenceTraversalEnabledOnClass()
+ {
+ $entity = new Entity();
+ $entity->reference = new \ArrayIterator(array(
+ 2 => new \ArrayIterator(array('key' => new Reference())),
+ ));
+
+ $callback = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Message');
+ };
+
+ $traversableMetadata = new ClassMetadata('ArrayIterator');
+ $traversableMetadata->addConstraint(new Traverse(true));
+
+ $this->metadataFactory->addMetadata($traversableMetadata);
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+ $this->metadata->addPropertyConstraint('reference', new Valid(array(
+ 'deep' => true,
+ )));
+
+ $violations = $this->validate($entity, new Valid(), 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ }
+
+ public function testReferenceTraversalRecursionDisabledOnReferenceTraversalEnabledOnClass()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new \ArrayIterator(array(
+ 2 => new \ArrayIterator(array('key' => new Reference())),
+ ));
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test) {
+ $test->fail('Should not be called');
+ };
+
+ $traversableMetadata = new ClassMetadata('ArrayIterator');
+ $traversableMetadata->addConstraint(new Traverse(true));
+
+ $this->metadataFactory->addMetadata($traversableMetadata);
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+ $this->metadata->addPropertyConstraint('reference', new Valid(array(
+ 'deep' => false,
+ )));
+
+ $violations = $this->validate($entity, new Valid(), 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(0, $violations);
+ }
+
+ public function testAddCustomizedViolation()
+ {
+ $entity = new Entity();
+
+ $callback = function ($value, ExecutionContextInterface $context) {
+ $context->buildViolation('Message %param%')
+ ->setParameter('%param%', 'value')
+ ->setInvalidValue('Invalid value')
+ ->setPlural(2)
+ ->setCode(42)
+ ->addViolation();
+ };
+
+ $this->metadata->addConstraint(new Callback($callback));
+
+ $violations = $this->validator->validate($entity);
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame('Invalid value', $violations[0]->getInvalidValue());
+ $this->assertSame(2, $violations[0]->getMessagePluralization());
+ $this->assertSame(42, $violations[0]->getCode());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnsupportedMetadataException
+ */
+ public function testMetadataMustImplementClassMetadataInterface()
+ {
+ $entity = new Entity();
+
+ $metadata = $this->getMock('Symfony\Component\Validator\Tests\Fixtures\LegacyClassMetadata');
+ $metadata->expects($this->any())
+ ->method('getClassName')
+ ->will($this->returnValue(get_class($entity)));
+
+ $this->metadataFactory->addMetadata($metadata);
+
+ $this->validator->validate($entity);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnsupportedMetadataException
+ */
+ public function testReferenceMetadataMustImplementClassMetadataInterface()
+ {
+ $entity = new Entity();
+ $entity->reference = new Reference();
+
+ $metadata = $this->getMock('Symfony\Component\Validator\Tests\Fixtures\LegacyClassMetadata');
+ $metadata->expects($this->any())
+ ->method('getClassName')
+ ->will($this->returnValue(get_class($entity->reference)));
+
+ $this->metadataFactory->addMetadata($metadata);
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+
+ $this->validator->validate($entity);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\UnsupportedMetadataException
+ * @group legacy
+ */
+ public function testLegacyPropertyMetadataMustImplementPropertyMetadataInterface()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ $entity = new Entity();
+
+ // Legacy interface
+ $propertyMetadata = $this->getMock('Symfony\Component\Validator\MetadataInterface');
+ $metadata = new FakeClassMetadata(get_class($entity));
+ $metadata->addCustomPropertyMetadata('firstName', $propertyMetadata);
+
+ $this->metadataFactory->addMetadata($metadata);
+
+ $this->validator->validate($entity);
+ }
+
+ public function testNoDuplicateValidationIfClassConstraintInMultipleGroups()
+ {
+ $entity = new Entity();
+
+ $callback = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Message');
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => array('Group 1', 'Group 2'),
+ )));
+
+ $violations = $this->validator->validate($entity, new Valid(), array('Group 1', 'Group 2'));
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ }
+
+ public function testNoDuplicateValidationIfPropertyConstraintInMultipleGroups()
+ {
+ $entity = new Entity();
+
+ $callback = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Message');
+ };
+
+ $this->metadata->addPropertyConstraint('firstName', new Callback(array(
+ 'callback' => $callback,
+ 'groups' => array('Group 1', 'Group 2'),
+ )));
+
+ $violations = $this->validator->validate($entity, new Valid(), array('Group 1', 'Group 2'));
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\RuntimeException
+ */
+ public function testValidateFailsIfNoConstraintsAndNoObjectOrArray()
+ {
+ $this->validate('Foobar');
+ }
+
+ public function testAccessCurrentObject()
+ {
+ $test = $this;
+ $called = false;
+ $entity = new Entity();
+ $entity->firstName = 'Bernhard';
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity, &$called) {
+ $called = true;
+ $test->assertSame($entity, $context->getObject());
+ };
+
+ $this->metadata->addConstraint(new Callback($callback));
+ $this->metadata->addPropertyConstraint('firstName', new Callback($callback));
+
+ $this->validator->validate($entity);
+
+ $this->assertTrue($called);
+ }
+
+ public function testInitializeObjectsOnFirstValidation()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->initialized = false;
+
+ // prepare initializers that set "initialized" to true
+ $initializer1 = $this->getMock('Symfony\\Component\\Validator\\ObjectInitializerInterface');
+ $initializer2 = $this->getMock('Symfony\\Component\\Validator\\ObjectInitializerInterface');
+
+ $initializer1->expects($this->once())
+ ->method('initialize')
+ ->with($entity)
+ ->will($this->returnCallback(function ($object) {
+ $object->initialized = true;
+ }));
+
+ $initializer2->expects($this->once())
+ ->method('initialize')
+ ->with($entity);
+
+ $this->validator = $this->createValidator($this->metadataFactory, array(
+ $initializer1,
+ $initializer2,
+ ));
+
+ // prepare constraint which
+ // * checks that "initialized" is set to true
+ // * validates the object again
+ $callback = function ($object, ExecutionContextInterface $context) use ($test) {
+ $test->assertTrue($object->initialized);
+
+ // validate again in same group
+ $validator = $context->getValidator()->inContext($context);
+
+ $validator->validate($object);
+
+ // validate again in other group
+ $validator->validate($object, null, 'SomeGroup');
+ };
+
+ $this->metadata->addConstraint(new Callback($callback));
+
+ $this->validate($entity);
+
+ $this->assertTrue($entity->initialized);
+ }
+
+ public function testPassConstraintToViolation()
+ {
+ $constraint = new FailingConstraint();
+ $violations = $this->validate('Foobar', $constraint);
+
+ $this->assertCount(1, $violations);
+ $this->assertSame($constraint, $violations[0]->getConstraint());
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/AbstractLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/AbstractLegacyApiTest.php
new file mode 100644
index 0000000..a4c1fe8
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/AbstractLegacyApiTest.php
@@ -0,0 +1,315 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Validator;
+
+use Symfony\Component\Validator\Constraints\Callback;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+use Symfony\Component\Validator\ExecutionContextInterface;
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+use Symfony\Component\Validator\Tests\Fixtures\Reference;
+use Symfony\Component\Validator\ValidatorInterface as LegacyValidatorInterface;
+
+/**
+ * Verifies that a validator satisfies the API of Symfony < 2.5.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+abstract class AbstractLegacyApiTest extends AbstractValidatorTest
+{
+ /**
+ * @var LegacyValidatorInterface
+ */
+ protected $validator;
+
+ /**
+ * @param MetadataFactoryInterface $metadataFactory
+ *
+ * @return LegacyValidatorInterface
+ */
+ abstract protected function createValidator(MetadataFactoryInterface $metadataFactory, array $objectInitializers = array());
+
+ protected function setUp()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ parent::setUp();
+
+ $this->validator = $this->createValidator($this->metadataFactory);
+ }
+
+ protected function validate($value, $constraints = null, $groups = null)
+ {
+ if (null === $constraints) {
+ $constraints = new Valid();
+ }
+
+ if ($constraints instanceof Valid) {
+ return $this->validator->validate($value, $groups, $constraints->traverse, $constraints->deep);
+ }
+
+ return $this->validator->validateValue($value, $constraints, $groups);
+ }
+
+ protected function validateProperty($object, $propertyName, $groups = null)
+ {
+ return $this->validator->validateProperty($object, $propertyName, $groups);
+ }
+
+ protected function validatePropertyValue($object, $propertyName, $value, $groups = null)
+ {
+ return $this->validator->validatePropertyValue($object, $propertyName, $value, $groups);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\NoSuchMetadataException
+ */
+ public function testTraversableTraverseDisabled()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $traversable = new \ArrayIterator(array('key' => $entity));
+
+ $callback = function () use ($test) {
+ $test->fail('Should not be called');
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $this->validator->validate($traversable, 'Group');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\NoSuchMetadataException
+ */
+ public function testRecursiveTraversableRecursiveTraversalDisabled()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $traversable = new \ArrayIterator(array(
+ 2 => new \ArrayIterator(array('key' => $entity)),
+ ));
+
+ $callback = function () use ($test) {
+ $test->fail('Should not be called');
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $this->validator->validate($traversable, 'Group');
+ }
+
+ public function testValidateInContext()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new Reference();
+
+ $callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
+ $previousValue = $context->getValue();
+ $previousMetadata = $context->getMetadata();
+ $previousPath = $context->getPropertyPath();
+ $previousGroup = $context->getGroup();
+
+ $context->validate($value->reference, 'subpath');
+
+ // context changes shouldn't leak out of the validate() call
+ $test->assertSame($previousValue, $context->getValue());
+ $test->assertSame($previousMetadata, $context->getMetadata());
+ $test->assertSame($previousPath, $context->getPropertyPath());
+ $test->assertSame($previousGroup, $context->getGroup());
+ };
+
+ $callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('subpath', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->referenceMetadata, $context->getMetadata());
+ $test->assertSame($test->metadataFactory, $context->getMetadataFactory());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame($entity->reference, $context->getValue());
+ $test->assertSame($entity->reference, $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group',
+ )));
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validator->validate($entity, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('subpath', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame($entity->reference, $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testValidateArrayInContext()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new Reference();
+
+ $callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
+ $previousValue = $context->getValue();
+ $previousMetadata = $context->getMetadata();
+ $previousPath = $context->getPropertyPath();
+ $previousGroup = $context->getGroup();
+
+ $context->validate(array('key' => $value->reference), 'subpath');
+
+ // context changes shouldn't leak out of the validate() call
+ $test->assertSame($previousValue, $context->getValue());
+ $test->assertSame($previousMetadata, $context->getMetadata());
+ $test->assertSame($previousPath, $context->getPropertyPath());
+ $test->assertSame($previousGroup, $context->getGroup());
+ };
+
+ $callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('subpath[key]', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->referenceMetadata, $context->getMetadata());
+ $test->assertSame($test->metadataFactory, $context->getMetadataFactory());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame($entity->reference, $context->getValue());
+ $test->assertSame($entity->reference, $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group',
+ )));
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validator->validate($entity, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('subpath[key]', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame($entity->reference, $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testAddCustomizedViolation()
+ {
+ $entity = new Entity();
+
+ $callback = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation(
+ 'Message %param%',
+ array('%param%' => 'value'),
+ 'Invalid value',
+ 2,
+ 'Code'
+ );
+ };
+
+ $this->metadata->addConstraint(new Callback($callback));
+
+ $violations = $this->validator->validate($entity);
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame('Invalid value', $violations[0]->getInvalidValue());
+ $this->assertSame(2, $violations[0]->getMessagePluralization());
+ $this->assertSame('Code', $violations[0]->getCode());
+ }
+
+ public function testInitializeObjectsOnFirstValidation()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->initialized = false;
+
+ // prepare initializers that set "initialized" to true
+ $initializer1 = $this->getMock('Symfony\\Component\\Validator\\ObjectInitializerInterface');
+ $initializer2 = $this->getMock('Symfony\\Component\\Validator\\ObjectInitializerInterface');
+
+ $initializer1->expects($this->once())
+ ->method('initialize')
+ ->with($entity)
+ ->will($this->returnCallback(function ($object) {
+ $object->initialized = true;
+ }));
+
+ $initializer2->expects($this->once())
+ ->method('initialize')
+ ->with($entity);
+
+ $this->validator = $this->createValidator($this->metadataFactory, array(
+ $initializer1,
+ $initializer2,
+ ));
+
+ // prepare constraint which
+ // * checks that "initialized" is set to true
+ // * validates the object again
+ $callback = function ($object, ExecutionContextInterface $context) use ($test) {
+ $test->assertTrue($object->initialized);
+
+ // validate again in same group
+ $context->validate($object);
+
+ // validate again in other group
+ $context->validate($object, '', 'SomeGroup');
+ };
+
+ $this->metadata->addConstraint(new Callback($callback));
+
+ $this->validate($entity);
+
+ $this->assertTrue($entity->initialized);
+ }
+
+ public function testGetMetadataFactory()
+ {
+ $this->assertSame($this->metadataFactory, $this->validator->getMetadataFactory());
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/AbstractValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/AbstractValidatorTest.php
new file mode 100644
index 0000000..b1c4edb
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/AbstractValidatorTest.php
@@ -0,0 +1,1288 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Validator;
+
+use Symfony\Component\Validator\Constraints\Callback;
+use Symfony\Component\Validator\Constraints\GroupSequence;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+use Symfony\Component\Validator\ExecutionContextInterface;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
+use Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity;
+use Symfony\Component\Validator\Tests\Fixtures\Reference;
+
+/**
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+abstract class AbstractValidatorTest extends \PHPUnit_Framework_TestCase
+{
+ const ENTITY_CLASS = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
+
+ const REFERENCE_CLASS = 'Symfony\Component\Validator\Tests\Fixtures\Reference';
+
+ /**
+ * @var FakeMetadataFactory
+ */
+ public $metadataFactory;
+
+ /**
+ * @var ClassMetadata
+ */
+ public $metadata;
+
+ /**
+ * @var ClassMetadata
+ */
+ public $referenceMetadata;
+
+ protected function setUp()
+ {
+ $this->metadataFactory = new FakeMetadataFactory();
+ $this->metadata = new ClassMetadata(self::ENTITY_CLASS);
+ $this->referenceMetadata = new ClassMetadata(self::REFERENCE_CLASS);
+ $this->metadataFactory->addMetadata($this->metadata);
+ $this->metadataFactory->addMetadata($this->referenceMetadata);
+ }
+
+ protected function tearDown()
+ {
+ $this->metadataFactory = null;
+ $this->metadata = null;
+ $this->referenceMetadata = null;
+ }
+
+ abstract protected function validate($value, $constraints = null, $groups = null);
+
+ abstract protected function validateProperty($object, $propertyName, $groups = null);
+
+ abstract protected function validatePropertyValue($object, $propertyName, $value, $groups = null);
+
+ public function testValidate()
+ {
+ $test = $this;
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test) {
+ $test->assertNull($context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame('Bernhard', $context->getRoot());
+ $test->assertSame('Bernhard', $context->getValue());
+ $test->assertSame('Bernhard', $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $constraint = new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ ));
+
+ $violations = $this->validate('Bernhard', $constraint, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('', $violations[0]->getPropertyPath());
+ $this->assertSame('Bernhard', $violations[0]->getRoot());
+ $this->assertSame('Bernhard', $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testClassConstraint()
+ {
+ $test = $this;
+ $entity = new Entity();
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $test->assertSame($test::ENTITY_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->metadata, $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame($entity, $context->getValue());
+ $test->assertSame($entity, $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($entity, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame($entity, $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testPropertyConstraint()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->firstName = 'Bernhard';
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $propertyMetadatas = $test->metadata->getPropertyMetadata('firstName');
+
+ $test->assertSame($test::ENTITY_CLASS, $context->getClassName());
+ $test->assertSame('firstName', $context->getPropertyName());
+ $test->assertSame('firstName', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($propertyMetadatas[0], $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame('Bernhard', $context->getValue());
+ $test->assertSame('Bernhard', $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addPropertyConstraint('firstName', new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($entity, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('firstName', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame('Bernhard', $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testGetterConstraint()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->setLastName('Schussek');
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $propertyMetadatas = $test->metadata->getPropertyMetadata('lastName');
+
+ $test->assertSame($test::ENTITY_CLASS, $context->getClassName());
+ $test->assertSame('lastName', $context->getPropertyName());
+ $test->assertSame('lastName', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($propertyMetadatas[0], $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame('Schussek', $context->getValue());
+ $test->assertSame('Schussek', $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addGetterConstraint('lastName', new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($entity, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('lastName', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame('Schussek', $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testArray()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $array = array('key' => $entity);
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity, $array) {
+ $test->assertSame($test::ENTITY_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('[key]', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->metadata, $context->getMetadata());
+ $test->assertSame($array, $context->getRoot());
+ $test->assertSame($entity, $context->getValue());
+ $test->assertSame($entity, $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($array, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('[key]', $violations[0]->getPropertyPath());
+ $this->assertSame($array, $violations[0]->getRoot());
+ $this->assertSame($entity, $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testRecursiveArray()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $array = array(2 => array('key' => $entity));
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity, $array) {
+ $test->assertSame($test::ENTITY_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('[2][key]', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->metadata, $context->getMetadata());
+ $test->assertSame($array, $context->getRoot());
+ $test->assertSame($entity, $context->getValue());
+ $test->assertSame($entity, $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($array, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('[2][key]', $violations[0]->getPropertyPath());
+ $this->assertSame($array, $violations[0]->getRoot());
+ $this->assertSame($entity, $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testTraversable()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $traversable = new \ArrayIterator(array('key' => $entity));
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity, $traversable) {
+ $test->assertSame($test::ENTITY_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('[key]', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->metadata, $context->getMetadata());
+ $test->assertSame($traversable, $context->getRoot());
+ $test->assertSame($entity, $context->getValue());
+ $test->assertSame($entity, $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($traversable, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('[key]', $violations[0]->getPropertyPath());
+ $this->assertSame($traversable, $violations[0]->getRoot());
+ $this->assertSame($entity, $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testRecursiveTraversable()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $traversable = new \ArrayIterator(array(
+ 2 => new \ArrayIterator(array('key' => $entity)),
+ ));
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity, $traversable) {
+ $test->assertSame($test::ENTITY_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('[2][key]', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->metadata, $context->getMetadata());
+ $test->assertSame($traversable, $context->getRoot());
+ $test->assertSame($entity, $context->getValue());
+ $test->assertSame($entity, $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($traversable, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('[2][key]', $violations[0]->getPropertyPath());
+ $this->assertSame($traversable, $violations[0]->getRoot());
+ $this->assertSame($entity, $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testReferenceClassConstraint()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new Reference();
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('reference', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->referenceMetadata, $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame($entity->reference, $context->getValue());
+ $test->assertSame($entity->reference, $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($entity, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('reference', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame($entity->reference, $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testReferencePropertyConstraint()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new Reference();
+ $entity->reference->value = 'Foobar';
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $propertyMetadatas = $test->referenceMetadata->getPropertyMetadata('value');
+
+ $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
+ $test->assertSame('value', $context->getPropertyName());
+ $test->assertSame('reference.value', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($propertyMetadatas[0], $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame('Foobar', $context->getValue());
+ $test->assertSame('Foobar', $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+ $this->referenceMetadata->addPropertyConstraint('value', new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($entity, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('reference.value', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame('Foobar', $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testReferenceGetterConstraint()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new Reference();
+ $entity->reference->setPrivateValue('Bamboo');
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $propertyMetadatas = $test->referenceMetadata->getPropertyMetadata('privateValue');
+
+ $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
+ $test->assertSame('privateValue', $context->getPropertyName());
+ $test->assertSame('reference.privateValue', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($propertyMetadatas[0], $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame('Bamboo', $context->getValue());
+ $test->assertSame('Bamboo', $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+ $this->referenceMetadata->addPropertyConstraint('privateValue', new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($entity, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('reference.privateValue', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame('Bamboo', $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testsIgnoreNullReference()
+ {
+ $entity = new Entity();
+ $entity->reference = null;
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+
+ $violations = $this->validate($entity);
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(0, $violations);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\NoSuchMetadataException
+ */
+ public function testFailOnScalarReferences()
+ {
+ $entity = new Entity();
+ $entity->reference = 'string';
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+
+ $this->validate($entity);
+ }
+
+ public function testArrayReference()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = array('key' => new Reference());
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('reference[key]', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->referenceMetadata, $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame($entity->reference['key'], $context->getValue());
+ $test->assertSame($entity->reference['key'], $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($entity, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('reference[key]', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame($entity->reference['key'], $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ // https://github.com/symfony/symfony/issues/6246
+ public function testRecursiveArrayReference()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = array(2 => array('key' => new Reference()));
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('reference[2][key]', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->referenceMetadata, $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame($entity->reference[2]['key'], $context->getValue());
+ $test->assertSame($entity->reference[2]['key'], $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($entity, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('reference[2][key]', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame($entity->reference[2]['key'], $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testArrayTraversalCannotBeDisabled()
+ {
+ $entity = new Entity();
+ $entity->reference = array('key' => new Reference());
+
+ $callback = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addPropertyConstraint('reference', new Valid(array(
+ 'traverse' => false,
+ )));
+ $this->referenceMetadata->addConstraint(new Callback($callback));
+
+ $violations = $this->validate($entity);
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ }
+
+ public function testRecursiveArrayTraversalCannotBeDisabled()
+ {
+ $entity = new Entity();
+ $entity->reference = array(2 => array('key' => new Reference()));
+
+ $callback = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addPropertyConstraint('reference', new Valid(array(
+ 'traverse' => false,
+ )));
+ $this->referenceMetadata->addConstraint(new Callback($callback));
+
+ $violations = $this->validate($entity);
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ }
+
+ public function testIgnoreScalarsDuringArrayTraversal()
+ {
+ $entity = new Entity();
+ $entity->reference = array('string', 1234);
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+
+ $violations = $this->validate($entity);
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(0, $violations);
+ }
+
+ public function testIgnoreNullDuringArrayTraversal()
+ {
+ $entity = new Entity();
+ $entity->reference = array(null);
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+
+ $violations = $this->validate($entity);
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(0, $violations);
+ }
+
+ public function testTraversableReference()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new \ArrayIterator(array('key' => new Reference()));
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('reference[key]', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->referenceMetadata, $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame($entity->reference['key'], $context->getValue());
+ $test->assertSame($entity->reference['key'], $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($entity, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('reference[key]', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame($entity->reference['key'], $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testDisableTraversableTraversal()
+ {
+ $entity = new Entity();
+ $entity->reference = new \ArrayIterator(array('key' => new Reference()));
+
+ $callback = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator'));
+ $this->metadata->addPropertyConstraint('reference', new Valid(array(
+ 'traverse' => false,
+ )));
+ $this->referenceMetadata->addConstraint(new Callback($callback));
+
+ $violations = $this->validate($entity);
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(0, $violations);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\NoSuchMetadataException
+ */
+ public function testMetadataMustExistIfTraversalIsDisabled()
+ {
+ $entity = new Entity();
+ $entity->reference = new \ArrayIterator();
+
+ $this->metadata->addPropertyConstraint('reference', new Valid(array(
+ 'traverse' => false,
+ )));
+
+ $this->validate($entity);
+ }
+
+ public function testEnableRecursiveTraversableTraversal()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->reference = new \ArrayIterator(array(
+ 2 => new \ArrayIterator(array('key' => new Reference())),
+ ));
+
+ $callback = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
+ $test->assertNull($context->getPropertyName());
+ $test->assertSame('reference[2][key]', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($test->referenceMetadata, $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame($entity->reference[2]['key'], $context->getValue());
+ $test->assertSame($entity->reference[2]['key'], $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $this->metadata->addPropertyConstraint('reference', new Valid(array(
+ 'deep' => true,
+ )));
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validate($entity, null, 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('reference[2][key]', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame($entity->reference[2]['key'], $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testValidateProperty()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->firstName = 'Bernhard';
+ $entity->setLastName('Schussek');
+
+ $callback1 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $propertyMetadatas = $test->metadata->getPropertyMetadata('firstName');
+
+ $test->assertSame($test::ENTITY_CLASS, $context->getClassName());
+ $test->assertSame('firstName', $context->getPropertyName());
+ $test->assertSame('firstName', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($propertyMetadatas[0], $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame('Bernhard', $context->getValue());
+ $test->assertSame('Bernhard', $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $callback2 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Other violation');
+ };
+
+ $this->metadata->addPropertyConstraint('firstName', new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group',
+ )));
+ $this->metadata->addPropertyConstraint('lastName', new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validateProperty($entity, 'firstName', 'Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('firstName', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame('Bernhard', $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ /**
+ * Cannot be UnsupportedMetadataException for BC with Symfony < 2.5.
+ *
+ * @expectedException \Symfony\Component\Validator\Exception\ValidatorException
+ * @group legacy
+ */
+ public function testLegacyValidatePropertyFailsIfPropertiesNotSupported()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ // $metadata does not implement PropertyMetadataContainerInterface
+ $metadata = $this->getMock('Symfony\Component\Validator\MetadataInterface');
+
+ $this->metadataFactory->addMetadataForValue('VALUE', $metadata);
+
+ $this->validateProperty('VALUE', 'someProperty');
+ }
+
+ /**
+ * https://github.com/symfony/symfony/issues/11604
+ */
+ public function testValidatePropertyWithoutConstraints()
+ {
+ $entity = new Entity();
+ $violations = $this->validateProperty($entity, 'lastName');
+
+ $this->assertCount(0, $violations, '->validateProperty() returns no violations if no constraints have been configured for the property being validated');
+ }
+
+ public function testValidatePropertyValue()
+ {
+ $test = $this;
+ $entity = new Entity();
+ $entity->setLastName('Schussek');
+
+ $callback1 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
+ $propertyMetadatas = $test->metadata->getPropertyMetadata('firstName');
+
+ $test->assertSame($test::ENTITY_CLASS, $context->getClassName());
+ $test->assertSame('firstName', $context->getPropertyName());
+ $test->assertSame('firstName', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($propertyMetadatas[0], $context->getMetadata());
+ $test->assertSame($entity, $context->getRoot());
+ $test->assertSame('Bernhard', $context->getValue());
+ $test->assertSame('Bernhard', $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $callback2 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Other violation');
+ };
+
+ $this->metadata->addPropertyConstraint('firstName', new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group',
+ )));
+ $this->metadata->addPropertyConstraint('lastName', new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validatePropertyValue(
+ $entity,
+ 'firstName',
+ 'Bernhard',
+ 'Group'
+ );
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('firstName', $violations[0]->getPropertyPath());
+ $this->assertSame($entity, $violations[0]->getRoot());
+ $this->assertSame('Bernhard', $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ public function testValidatePropertyValueWithClassName()
+ {
+ $test = $this;
+
+ $callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
+ $propertyMetadatas = $test->metadata->getPropertyMetadata('firstName');
+
+ $test->assertSame($test::ENTITY_CLASS, $context->getClassName());
+ $test->assertSame('firstName', $context->getPropertyName());
+ $test->assertSame('', $context->getPropertyPath());
+ $test->assertSame('Group', $context->getGroup());
+ $test->assertSame($propertyMetadatas[0], $context->getMetadata());
+ $test->assertSame('Bernhard', $context->getRoot());
+ $test->assertSame('Bernhard', $context->getValue());
+ $test->assertSame('Bernhard', $value);
+
+ $context->addViolation('Message %param%', array('%param%' => 'value'));
+ };
+
+ $callback2 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Other violation');
+ };
+
+ $this->metadata->addPropertyConstraint('firstName', new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group',
+ )));
+ $this->metadata->addPropertyConstraint('lastName', new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group',
+ )));
+
+ $violations = $this->validatePropertyValue(
+ self::ENTITY_CLASS,
+ 'firstName',
+ 'Bernhard',
+ 'Group'
+ );
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Message value', $violations[0]->getMessage());
+ $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
+ $this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
+ $this->assertSame('', $violations[0]->getPropertyPath());
+ $this->assertSame('Bernhard', $violations[0]->getRoot());
+ $this->assertSame('Bernhard', $violations[0]->getInvalidValue());
+ $this->assertNull($violations[0]->getMessagePluralization());
+ $this->assertNull($violations[0]->getCode());
+ }
+
+ /**
+ * Cannot be UnsupportedMetadataException for BC with Symfony < 2.5.
+ *
+ * @expectedException \Symfony\Component\Validator\Exception\ValidatorException
+ * @group legacy
+ */
+ public function testLegacyValidatePropertyValueFailsIfPropertiesNotSupported()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ // $metadata does not implement PropertyMetadataContainerInterface
+ $metadata = $this->getMock('Symfony\Component\Validator\MetadataInterface');
+
+ $this->metadataFactory->addMetadataForValue('VALUE', $metadata);
+
+ $this->validatePropertyValue('VALUE', 'someProperty', 'someValue');
+ }
+
+ /**
+ * https://github.com/symfony/symfony/issues/11604
+ */
+ public function testValidatePropertyValueWithoutConstraints()
+ {
+ $entity = new Entity();
+ $violations = $this->validatePropertyValue($entity, 'lastName', 'foo');
+
+ $this->assertCount(0, $violations, '->validatePropertyValue() returns no violations if no constraints have been configured for the property being validated');
+ }
+
+ public function testValidateObjectOnlyOncePerGroup()
+ {
+ $entity = new Entity();
+ $entity->reference = new Reference();
+ $entity->reference2 = $entity->reference;
+
+ $callback = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Message');
+ };
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+ $this->metadata->addPropertyConstraint('reference2', new Valid());
+ $this->referenceMetadata->addConstraint(new Callback($callback));
+
+ $violations = $this->validate($entity);
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ }
+
+ public function testValidateDifferentObjectsSeparately()
+ {
+ $entity = new Entity();
+ $entity->reference = new Reference();
+ $entity->reference2 = new Reference();
+
+ $callback = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Message');
+ };
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+ $this->metadata->addPropertyConstraint('reference2', new Valid());
+ $this->referenceMetadata->addConstraint(new Callback($callback));
+
+ $violations = $this->validate($entity);
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(2, $violations);
+ }
+
+ public function testValidateSingleGroup()
+ {
+ $entity = new Entity();
+
+ $callback = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Message');
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group 1',
+ )));
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group 2',
+ )));
+
+ $violations = $this->validate($entity, null, 'Group 2');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ }
+
+ public function testValidateMultipleGroups()
+ {
+ $entity = new Entity();
+
+ $callback = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Message');
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group 1',
+ )));
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback,
+ 'groups' => 'Group 2',
+ )));
+
+ $violations = $this->validate($entity, null, array('Group 1', 'Group 2'));
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(2, $violations);
+ }
+
+ public function testReplaceDefaultGroupByGroupSequenceObject()
+ {
+ $entity = new Entity();
+
+ $callback1 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Violation in Group 2');
+ };
+ $callback2 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Violation in Group 3');
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => function () {},
+ 'groups' => 'Group 1',
+ )));
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group 2',
+ )));
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group 3',
+ )));
+
+ $sequence = new GroupSequence(array('Group 1', 'Group 2', 'Group 3', 'Entity'));
+ $this->metadata->setGroupSequence($sequence);
+
+ $violations = $this->validate($entity, null, 'Default');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Violation in Group 2', $violations[0]->getMessage());
+ }
+
+ public function testReplaceDefaultGroupByGroupSequenceArray()
+ {
+ $entity = new Entity();
+
+ $callback1 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Violation in Group 2');
+ };
+ $callback2 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Violation in Group 3');
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => function () {},
+ 'groups' => 'Group 1',
+ )));
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group 2',
+ )));
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group 3',
+ )));
+
+ $sequence = array('Group 1', 'Group 2', 'Group 3', 'Entity');
+ $this->metadata->setGroupSequence($sequence);
+
+ $violations = $this->validate($entity, null, 'Default');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Violation in Group 2', $violations[0]->getMessage());
+ }
+
+ public function testPropagateDefaultGroupToReferenceWhenReplacingDefaultGroup()
+ {
+ $entity = new Entity();
+ $entity->reference = new Reference();
+
+ $callback1 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Violation in Default group');
+ };
+ $callback2 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Violation in group sequence');
+ };
+
+ $this->metadata->addPropertyConstraint('reference', new Valid());
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Default',
+ )));
+ $this->referenceMetadata->addConstraint(new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group 1',
+ )));
+
+ $sequence = new GroupSequence(array('Group 1', 'Entity'));
+ $this->metadata->setGroupSequence($sequence);
+
+ $violations = $this->validate($entity, null, 'Default');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Violation in Default group', $violations[0]->getMessage());
+ }
+
+ public function testValidateCustomGroupWhenDefaultGroupWasReplaced()
+ {
+ $entity = new Entity();
+
+ $callback1 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Violation in other group');
+ };
+ $callback2 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Violation in group sequence');
+ };
+
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Other Group',
+ )));
+ $this->metadata->addConstraint(new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group 1',
+ )));
+
+ $sequence = new GroupSequence(array('Group 1', 'Entity'));
+ $this->metadata->setGroupSequence($sequence);
+
+ $violations = $this->validate($entity, null, 'Other Group');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Violation in other group', $violations[0]->getMessage());
+ }
+
+ public function testReplaceDefaultGroupWithObjectFromGroupSequenceProvider()
+ {
+ $sequence = new GroupSequence(array('Group 1', 'Group 2', 'Group 3', 'Entity'));
+ $entity = new GroupSequenceProviderEntity($sequence);
+
+ $callback1 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Violation in Group 2');
+ };
+ $callback2 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Violation in Group 3');
+ };
+
+ $metadata = new ClassMetadata(get_class($entity));
+ $metadata->addConstraint(new Callback(array(
+ 'callback' => function () {},
+ 'groups' => 'Group 1',
+ )));
+ $metadata->addConstraint(new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group 2',
+ )));
+ $metadata->addConstraint(new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group 3',
+ )));
+ $metadata->setGroupSequenceProvider(true);
+
+ $this->metadataFactory->addMetadata($metadata);
+
+ $violations = $this->validate($entity, null, 'Default');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Violation in Group 2', $violations[0]->getMessage());
+ }
+
+ public function testReplaceDefaultGroupWithArrayFromGroupSequenceProvider()
+ {
+ $sequence = array('Group 1', 'Group 2', 'Group 3', 'Entity');
+ $entity = new GroupSequenceProviderEntity($sequence);
+
+ $callback1 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Violation in Group 2');
+ };
+ $callback2 = function ($value, ExecutionContextInterface $context) {
+ $context->addViolation('Violation in Group 3');
+ };
+
+ $metadata = new ClassMetadata(get_class($entity));
+ $metadata->addConstraint(new Callback(array(
+ 'callback' => function () {},
+ 'groups' => 'Group 1',
+ )));
+ $metadata->addConstraint(new Callback(array(
+ 'callback' => $callback1,
+ 'groups' => 'Group 2',
+ )));
+ $metadata->addConstraint(new Callback(array(
+ 'callback' => $callback2,
+ 'groups' => 'Group 3',
+ )));
+ $metadata->setGroupSequenceProvider(true);
+
+ $this->metadataFactory->addMetadata($metadata);
+
+ $violations = $this->validate($entity, null, 'Default');
+
+ /** @var ConstraintViolationInterface[] $violations */
+ $this->assertCount(1, $violations);
+ $this->assertSame('Violation in Group 2', $violations[0]->getMessage());
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/LegacyValidator2Dot5ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/LegacyValidator2Dot5ApiTest.php
new file mode 100644
index 0000000..624abd4
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/LegacyValidator2Dot5ApiTest.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Validator;
+
+use Symfony\Component\Validator\ConstraintValidatorFactory;
+use Symfony\Component\Validator\Context\LegacyExecutionContextFactory;
+use Symfony\Component\Validator\DefaultTranslator;
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\Validator\LegacyValidator;
+
+/**
+ * @group legacy
+ */
+class LegacyValidator2Dot5ApiTest extends Abstract2Dot5ApiTest
+{
+ protected function setUp()
+ {
+ if (PHP_VERSION_ID < 50309) {
+ $this->markTestSkipped('Not supported prior to PHP 5.3.9');
+ }
+
+ parent::setUp();
+ }
+
+ protected function createValidator(MetadataFactoryInterface $metadataFactory, array $objectInitializers = array())
+ {
+ $contextFactory = new LegacyExecutionContextFactory($metadataFactory, new DefaultTranslator());
+ $validatorFactory = new ConstraintValidatorFactory();
+
+ return new LegacyValidator($contextFactory, $metadataFactory, $validatorFactory, $objectInitializers);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/LegacyValidatorLegacyApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/LegacyValidatorLegacyApiTest.php
new file mode 100644
index 0000000..965a769
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/LegacyValidatorLegacyApiTest.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Validator;
+
+use Symfony\Component\Validator\ConstraintValidatorFactory;
+use Symfony\Component\Validator\Context\LegacyExecutionContextFactory;
+use Symfony\Component\Validator\DefaultTranslator;
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\Validator\LegacyValidator;
+
+/**
+ * @group legacy
+ */
+class LegacyValidatorLegacyApiTest extends AbstractLegacyApiTest
+{
+ protected function setUp()
+ {
+ if (PHP_VERSION_ID < 50309) {
+ $this->markTestSkipped('Not supported prior to PHP 5.3.9');
+ }
+
+ parent::setUp();
+ }
+
+ protected function createValidator(MetadataFactoryInterface $metadataFactory, array $objectInitializers = array())
+ {
+ $contextFactory = new LegacyExecutionContextFactory($metadataFactory, new DefaultTranslator());
+ $validatorFactory = new ConstraintValidatorFactory();
+
+ return new LegacyValidator($contextFactory, $metadataFactory, $validatorFactory, $objectInitializers);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/RecursiveValidator2Dot5ApiTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/RecursiveValidator2Dot5ApiTest.php
new file mode 100644
index 0000000..6235fda
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/Validator/RecursiveValidator2Dot5ApiTest.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Validator;
+
+use Symfony\Component\Validator\ConstraintValidatorFactory;
+use Symfony\Component\Validator\Context\ExecutionContextFactory;
+use Symfony\Component\Validator\DefaultTranslator;
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\Validator\RecursiveValidator;
+
+class RecursiveValidator2Dot5ApiTest extends Abstract2Dot5ApiTest
+{
+ protected function createValidator(MetadataFactoryInterface $metadataFactory, array $objectInitializers = array())
+ {
+ $contextFactory = new ExecutionContextFactory(new DefaultTranslator());
+ $validatorFactory = new ConstraintValidatorFactory();
+
+ return new RecursiveValidator($contextFactory, $metadataFactory, $validatorFactory, $objectInitializers);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php
new file mode 100644
index 0000000..e2585d7
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php
@@ -0,0 +1,160 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests;
+
+use Symfony\Component\Validator\Validation;
+use Symfony\Component\Validator\ValidatorBuilder;
+use Symfony\Component\Validator\ValidatorBuilderInterface;
+
+class ValidatorBuilderTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var ValidatorBuilderInterface
+ */
+ protected $builder;
+
+ protected function setUp()
+ {
+ $this->builder = new ValidatorBuilder();
+ }
+
+ protected function tearDown()
+ {
+ $this->builder = null;
+ }
+
+ public function testAddObjectInitializer()
+ {
+ $this->assertSame($this->builder, $this->builder->addObjectInitializer(
+ $this->getMock('Symfony\Component\Validator\ObjectInitializerInterface')
+ ));
+ }
+
+ public function testAddObjectInitializers()
+ {
+ $this->assertSame($this->builder, $this->builder->addObjectInitializers(array()));
+ }
+
+ public function testAddXmlMapping()
+ {
+ $this->assertSame($this->builder, $this->builder->addXmlMapping('mapping'));
+ }
+
+ public function testAddXmlMappings()
+ {
+ $this->assertSame($this->builder, $this->builder->addXmlMappings(array()));
+ }
+
+ public function testAddYamlMapping()
+ {
+ $this->assertSame($this->builder, $this->builder->addYamlMapping('mapping'));
+ }
+
+ public function testAddYamlMappings()
+ {
+ $this->assertSame($this->builder, $this->builder->addYamlMappings(array()));
+ }
+
+ public function testAddMethodMapping()
+ {
+ $this->assertSame($this->builder, $this->builder->addMethodMapping('mapping'));
+ }
+
+ public function testAddMethodMappings()
+ {
+ $this->assertSame($this->builder, $this->builder->addMethodMappings(array()));
+ }
+
+ public function testEnableAnnotationMapping()
+ {
+ $this->assertSame($this->builder, $this->builder->enableAnnotationMapping());
+ }
+
+ public function testDisableAnnotationMapping()
+ {
+ $this->assertSame($this->builder, $this->builder->disableAnnotationMapping());
+ }
+
+ public function testSetMetadataCache()
+ {
+ $this->assertSame($this->builder, $this->builder->setMetadataCache(
+ $this->getMock('Symfony\Component\Validator\Mapping\Cache\CacheInterface'))
+ );
+ }
+
+ public function testSetConstraintValidatorFactory()
+ {
+ $this->assertSame($this->builder, $this->builder->setConstraintValidatorFactory(
+ $this->getMock('Symfony\Component\Validator\ConstraintValidatorFactoryInterface'))
+ );
+ }
+
+ public function testSetTranslator()
+ {
+ $this->assertSame($this->builder, $this->builder->setTranslator(
+ $this->getMock('Symfony\Component\Translation\TranslatorInterface'))
+ );
+ }
+
+ public function testSetTranslationDomain()
+ {
+ $this->assertSame($this->builder, $this->builder->setTranslationDomain('TRANS_DOMAIN'));
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testLegacyDefaultApiVersion()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ if (PHP_VERSION_ID < 50309) {
+ // Old implementation on PHP < 5.3.9
+ $this->assertInstanceOf('Symfony\Component\Validator\Validator', $this->builder->getValidator());
+ } else {
+ // Legacy compatible implementation on PHP >= 5.3.9
+ $this->assertInstanceOf('Symfony\Component\Validator\Validator\LegacyValidator', $this->builder->getValidator());
+ }
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testLegacySetApiVersion24()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ $this->assertSame($this->builder, $this->builder->setApiVersion(Validation::API_VERSION_2_4));
+ $this->assertInstanceOf('Symfony\Component\Validator\Validator', $this->builder->getValidator());
+ }
+
+ public function testSetApiVersion25()
+ {
+ $this->assertSame($this->builder, $this->builder->setApiVersion(Validation::API_VERSION_2_5));
+ $this->assertInstanceOf('Symfony\Component\Validator\Validator\RecursiveValidator', $this->builder->getValidator());
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testLegacySetApiVersion24And25()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ if (PHP_VERSION_ID < 50309) {
+ $this->markTestSkipped('Not supported prior to PHP 5.3.9');
+ }
+
+ $this->assertSame($this->builder, $this->builder->setApiVersion(Validation::API_VERSION_2_5_BC));
+ $this->assertInstanceOf('Symfony\Component\Validator\Validator\LegacyValidator', $this->builder->getValidator());
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorTest.php b/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorTest.php
new file mode 100644
index 0000000..3cc36f5
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorTest.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests;
+
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\ConstraintValidatorFactory;
+use Symfony\Component\Validator\DefaultTranslator;
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+use Symfony\Component\Validator\Tests\Validator\AbstractLegacyApiTest;
+use Symfony\Component\Validator\Validator as LegacyValidator;
+
+class ValidatorTest extends AbstractLegacyApiTest
+{
+ protected function createValidator(MetadataFactoryInterface $metadataFactory, array $objectInitializers = array())
+ {
+ return new LegacyValidator($metadataFactory, new ConstraintValidatorFactory(), new DefaultTranslator(), 'validators', $objectInitializers);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ValidatorException
+ */
+ public function testValidateValueRejectsValid()
+ {
+ $this->validator->validateValue(new Entity(), new Valid());
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Util/PropertyPath.php b/vendor/symfony/validator/Symfony/Component/Validator/Util/PropertyPath.php
new file mode 100644
index 0000000..4d397a9
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Util/PropertyPath.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Util;
+
+/**
+ * Contains utility methods for dealing with property paths.
+ *
+ * For more extensive functionality, use Symfony's PropertyAccess component.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+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 (".").
+ *
+ * @param string $basePath The base path
+ * @param string $subPath The path to append
+ *
+ * @return string The concatenation of the two property paths
+ */
+ public static function append($basePath, $subPath)
+ {
+ if ('' !== (string) $subPath) {
+ if ('[' === $subPath{0}) {
+ return $basePath.$subPath;
+ }
+
+ return $basePath ? $basePath.'.'.$subPath : $subPath;
+ }
+
+ return $basePath;
+ }
+
+ /**
+ * Not instantiable.
+ */
+ private function __construct()
+ {
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Validation.php b/vendor/symfony/validator/Symfony/Component/Validator/Validation.php
new file mode 100644
index 0000000..b304dbb
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Validation.php
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * Entry point for the Validator component.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+final class Validation
+{
+ /**
+ * The Validator API provided by Symfony 2.4 and older.
+ */
+ const API_VERSION_2_4 = 1;
+
+ /**
+ * The Validator API provided by Symfony 2.5 and newer.
+ */
+ const API_VERSION_2_5 = 2;
+
+ /**
+ * The Validator API provided by Symfony 2.5 and newer with a backwards
+ * compatibility layer for 2.4 and older.
+ */
+ const API_VERSION_2_5_BC = 3;
+
+ /**
+ * Creates a new validator.
+ *
+ * If you want to configure the validator, use
+ * {@link createValidatorBuilder()} instead.
+ *
+ * @return ValidatorInterface The new validator.
+ */
+ public static function createValidator()
+ {
+ return self::createValidatorBuilder()->getValidator();
+ }
+
+ /**
+ * Creates a configurable builder for validator objects.
+ *
+ * @return ValidatorBuilderInterface The new builder.
+ */
+ public static function createValidatorBuilder()
+ {
+ return new ValidatorBuilder();
+ }
+
+ /**
+ * This class cannot be instantiated.
+ */
+ private function __construct()
+ {
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitor.php b/vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitor.php
new file mode 100644
index 0000000..3af8249
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitor.php
@@ -0,0 +1,210 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+use Symfony\Component\Translation\TranslatorInterface;
+use Symfony\Component\Validator\Exception\NoSuchMetadataException;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Default implementation of {@link ValidationVisitorInterface} and
+ * {@link GlobalExecutionContextInterface}.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ */
+class ValidationVisitor implements ValidationVisitorInterface, GlobalExecutionContextInterface
+{
+ /**
+ * @var mixed
+ */
+ private $root;
+
+ /**
+ * @var MetadataFactoryInterface
+ */
+ private $metadataFactory;
+
+ /**
+ * @var ConstraintValidatorFactoryInterface
+ */
+ private $validatorFactory;
+
+ /**
+ * @var TranslatorInterface
+ */
+ private $translator;
+
+ /**
+ * @var null|string
+ */
+ private $translationDomain;
+
+ /**
+ * @var array
+ */
+ private $objectInitializers;
+
+ /**
+ * @var ConstraintViolationList
+ */
+ private $violations;
+
+ /**
+ * @var array
+ */
+ private $validatedObjects = array();
+
+ /**
+ * Creates a new validation visitor.
+ *
+ * @param mixed $root The value passed to the validator.
+ * @param MetadataFactoryInterface $metadataFactory The factory for obtaining metadata instances.
+ * @param ConstraintValidatorFactoryInterface $validatorFactory The factory for creating constraint validators.
+ * @param TranslatorInterface $translator The translator for translating violation messages.
+ * @param string|null $translationDomain The domain of the translation messages.
+ * @param ObjectInitializerInterface[] $objectInitializers The initializers for preparing objects before validation.
+ *
+ * @throws UnexpectedTypeException If any of the object initializers is not an instance of ObjectInitializerInterface
+ */
+ public function __construct($root, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, TranslatorInterface $translator, $translationDomain = null, array $objectInitializers = array())
+ {
+ foreach ($objectInitializers as $initializer) {
+ if (!$initializer instanceof ObjectInitializerInterface) {
+ throw new UnexpectedTypeException($initializer, 'Symfony\Component\Validator\ObjectInitializerInterface');
+ }
+ }
+
+ $this->root = $root;
+ $this->metadataFactory = $metadataFactory;
+ $this->validatorFactory = $validatorFactory;
+ $this->translator = $translator;
+ $this->translationDomain = $translationDomain;
+ $this->objectInitializers = $objectInitializers;
+ $this->violations = new ConstraintViolationList();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function visit(MetadataInterface $metadata, $value, $group, $propertyPath)
+ {
+ $context = new ExecutionContext(
+ $this,
+ $this->translator,
+ $this->translationDomain,
+ $metadata,
+ $value,
+ $group,
+ $propertyPath
+ );
+
+ $context->validateValue($value, $metadata->findConstraints($group));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, $group, $propertyPath, $traverse = false, $deep = false)
+ {
+ if (null === $value) {
+ return;
+ }
+
+ if (is_object($value)) {
+ $hash = spl_object_hash($value);
+
+ // Exit, if the object is already validated for the current group
+ if (isset($this->validatedObjects[$hash][$group])) {
+ return;
+ }
+
+ // Initialize if the object wasn't initialized before
+ if (!isset($this->validatedObjects[$hash])) {
+ foreach ($this->objectInitializers as $initializer) {
+ if (!$initializer instanceof ObjectInitializerInterface) {
+ throw new \LogicException('Validator initializers must implement ObjectInitializerInterface.');
+ }
+ $initializer->initialize($value);
+ }
+ }
+
+ // Remember validating this object before starting and possibly
+ // traversing the object graph
+ $this->validatedObjects[$hash][$group] = true;
+ }
+
+ // Validate arrays recursively by default, otherwise every driver needs
+ // to implement special handling for arrays.
+ // https://github.com/symfony/symfony/issues/6246
+ if (is_array($value) || ($traverse && $value instanceof \Traversable)) {
+ foreach ($value as $key => $element) {
+ // Ignore any scalar values in the collection
+ if (is_object($element) || is_array($element)) {
+ // Only repeat the traversal if $deep is set
+ $this->validate($element, $group, $propertyPath.'['.$key.']', $deep, $deep);
+ }
+ }
+
+ try {
+ $this->metadataFactory->getMetadataFor($value)->accept($this, $value, $group, $propertyPath);
+ } catch (NoSuchMetadataException $e) {
+ // Metadata doesn't necessarily have to exist for
+ // traversable objects, because we know how to validate
+ // them anyway. Optionally, additional metadata is supported.
+ }
+ } else {
+ $this->metadataFactory->getMetadataFor($value)->accept($this, $value, $group, $propertyPath);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getViolations()
+ {
+ return $this->violations;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRoot()
+ {
+ return $this->root;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getVisitor()
+ {
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getValidatorFactory()
+ {
+ return $this->validatorFactory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadataFactory()
+ {
+ return $this->metadataFactory;
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitorInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitorInterface.php
new file mode 100644
index 0000000..483a1b5
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitorInterface.php
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * Validates values against constraints defined in {@link MetadataInterface}
+ * instances.
+ *
+ * This interface is an implementation of the Visitor design pattern. A value
+ * is validated by first passing it to the {@link validate} method. That method
+ * will determine the matching {@link MetadataInterface} for validating the
+ * value. It then calls the {@link MetadataInterface::accept} method of that
+ * metadata. <tt>accept()</tt> does two things:
+ *
+ * <ol>
+ * <li>It calls {@link visit} to validate the value against the constraints of
+ * the metadata.</li>
+ * <li>It calls <tt>accept()</tt> on all nested metadata instances with the
+ * corresponding values extracted from the current value. For example, if the
+ * current metadata represents a class and the current value is an object of
+ * that class, the metadata contains nested instances for each property of that
+ * class. It forwards the call to these nested metadata with the values of the
+ * corresponding properties in the original object.</li>
+ * </ol>
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ */
+interface ValidationVisitorInterface
+{
+ /**
+ * Validates a value.
+ *
+ * If the value is an array or a traversable object, you can set the
+ * parameter <tt>$traverse</tt> to <tt>true</tt> in order to run through
+ * the collection and validate each element. If these elements can be
+ * collections again and you want to traverse them recursively, set the
+ * parameter <tt>$deep</tt> to <tt>true</tt> as well.
+ *
+ * If you set <tt>$traversable</tt> to <tt>true</tt>, the visitor will
+ * nevertheless try to find metadata for the collection and validate its
+ * constraints. If no such metadata is found, the visitor ignores that and
+ * only iterates the collection.
+ *
+ * If you don't set <tt>$traversable</tt> to <tt>true</tt> and the visitor
+ * does not find metadata for the given value, it will fail with an
+ * exception.
+ *
+ * @param mixed $value The value to validate.
+ * @param string $group The validation group to validate.
+ * @param string $propertyPath The current property path in the validation graph.
+ * @param bool $traverse Whether to traverse the value if it is traversable.
+ * @param bool $deep Whether to traverse nested traversable values recursively.
+ *
+ * @throws Exception\NoSuchMetadataException If no metadata can be found for
+ * the given value.
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ */
+ public function validate($value, $group, $propertyPath, $traverse = false, $deep = false);
+
+ /**
+ * Validates a value against the constraints defined in some metadata.
+ *
+ * This method implements the Visitor design pattern. See also
+ * {@link ValidationVisitorInterface}.
+ *
+ * @param MetadataInterface $metadata The metadata holding the constraints.
+ * @param mixed $value The value to validate.
+ * @param string $group The validation group to validate.
+ * @param string $propertyPath The current property path in the validation graph.
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ */
+ public function visit(MetadataInterface $metadata, $value, $group, $propertyPath);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Validator.php b/vendor/symfony/validator/Symfony/Component/Validator/Validator.php
new file mode 100644
index 0000000..6edbb7a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Validator.php
@@ -0,0 +1,235 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+use Symfony\Component\Translation\TranslatorInterface;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\Exception\ValidatorException;
+
+/**
+ * Default implementation of {@link ValidatorInterface}.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Validator\RecursiveValidator} instead.
+ */
+class Validator implements ValidatorInterface, Mapping\Factory\MetadataFactoryInterface
+{
+ /**
+ * @var MetadataFactoryInterface
+ */
+ private $metadataFactory;
+
+ /**
+ * @var ConstraintValidatorFactoryInterface
+ */
+ private $validatorFactory;
+
+ /**
+ * @var TranslatorInterface
+ */
+ private $translator;
+
+ /**
+ * @var null|string
+ */
+ private $translationDomain;
+
+ /**
+ * @var array
+ */
+ private $objectInitializers;
+
+ public function __construct(
+ MetadataFactoryInterface $metadataFactory,
+ ConstraintValidatorFactoryInterface $validatorFactory,
+ TranslatorInterface $translator,
+ $translationDomain = 'validators',
+ array $objectInitializers = array()
+ ) {
+ $this->metadataFactory = $metadataFactory;
+ $this->validatorFactory = $validatorFactory;
+ $this->translator = $translator;
+ $this->translationDomain = $translationDomain;
+ $this->objectInitializers = $objectInitializers;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadataFactory()
+ {
+ return $this->metadataFactory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadataFor($value)
+ {
+ return $this->metadataFactory->getMetadataFor($value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasMetadataFor($value)
+ {
+ return $this->metadataFactory->hasMetadataFor($value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, $groups = null, $traverse = false, $deep = false)
+ {
+ $visitor = $this->createVisitor($value);
+
+ foreach ($this->resolveGroups($groups) as $group) {
+ $visitor->validate($value, $group, '', $traverse, $deep);
+ }
+
+ return $visitor->getViolations();
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws ValidatorException If the metadata for the value does not support properties.
+ */
+ public function validateProperty($containingValue, $property, $groups = null)
+ {
+ $visitor = $this->createVisitor($containingValue);
+ $metadata = $this->metadataFactory->getMetadataFor($containingValue);
+
+ if (!$metadata instanceof PropertyMetadataContainerInterface) {
+ $valueAsString = is_scalar($containingValue)
+ ? '"'.$containingValue.'"'
+ : 'the value of type '.gettype($containingValue);
+
+ throw new ValidatorException(sprintf('The metadata for %s does not support properties.', $valueAsString));
+ }
+
+ foreach ($this->resolveGroups($groups) as $group) {
+ if (!$metadata->hasPropertyMetadata($property)) {
+ continue;
+ }
+
+ foreach ($metadata->getPropertyMetadata($property) as $propMeta) {
+ $propMeta->accept($visitor, $propMeta->getPropertyValue($containingValue), $group, $property);
+ }
+ }
+
+ return $visitor->getViolations();
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws ValidatorException If the metadata for the value does not support properties.
+ */
+ public function validatePropertyValue($containingValue, $property, $value, $groups = null)
+ {
+ $visitor = $this->createVisitor(is_object($containingValue) ? $containingValue : $value);
+ $metadata = $this->metadataFactory->getMetadataFor($containingValue);
+
+ if (!$metadata instanceof PropertyMetadataContainerInterface) {
+ $valueAsString = is_scalar($containingValue)
+ ? '"'.$containingValue.'"'
+ : 'the value of type '.gettype($containingValue);
+
+ throw new ValidatorException(sprintf('The metadata for '.$valueAsString.' does not support properties.'));
+ }
+
+ // If $containingValue is passed as class name, take $value as root
+ // and start the traversal with an empty property path
+ $propertyPath = is_object($containingValue) ? $property : '';
+
+ foreach ($this->resolveGroups($groups) as $group) {
+ if (!$metadata->hasPropertyMetadata($property)) {
+ continue;
+ }
+
+ foreach ($metadata->getPropertyMetadata($property) as $propMeta) {
+ $propMeta->accept($visitor, $value, $group, $propertyPath);
+ }
+ }
+
+ return $visitor->getViolations();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateValue($value, $constraints, $groups = null)
+ {
+ $context = new ExecutionContext($this->createVisitor($value), $this->translator, $this->translationDomain);
+
+ $constraints = is_array($constraints) ? $constraints : array($constraints);
+
+ foreach ($constraints as $constraint) {
+ if ($constraint instanceof Valid) {
+ // Why can't the Valid constraint be executed directly?
+ //
+ // It cannot be executed like regular other constraints, because regular
+ // constraints are only executed *if they belong to the validated group*.
+ // The Valid constraint, on the other hand, is always executed and propagates
+ // the group to the cascaded object. The propagated group depends on
+ //
+ // * Whether a group sequence is currently being executed. Then the default
+ // group is propagated.
+ //
+ // * Otherwise the validated group is propagated.
+
+ throw new ValidatorException(
+ sprintf(
+ 'The constraint %s cannot be validated. Use the method validate() instead.',
+ get_class($constraint)
+ )
+ );
+ }
+
+ $context->validateValue($value, $constraint, '', $groups);
+ }
+
+ return $context->getViolations();
+ }
+
+ /**
+ * @param mixed $root
+ *
+ * @return ValidationVisitor
+ */
+ private function createVisitor($root)
+ {
+ return new ValidationVisitor(
+ $root,
+ $this->metadataFactory,
+ $this->validatorFactory,
+ $this->translator,
+ $this->translationDomain,
+ $this->objectInitializers
+ );
+ }
+
+ /**
+ * @param null|string|string[] $groups
+ *
+ * @return string[]
+ */
+ private function resolveGroups($groups)
+ {
+ return $groups ? (array) $groups : array(Constraint::DEFAULT_GROUP);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Validator/ContextualValidatorInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/Validator/ContextualValidatorInterface.php
new file mode 100644
index 0000000..767f895
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Validator/ContextualValidatorInterface.php
@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Validator;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintViolationListInterface;
+
+/**
+ * A validator in a specific execution context.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+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.
+ *
+ * @param string $path The path to append
+ *
+ * @return ContextualValidatorInterface This validator
+ */
+ public function atPath($path);
+
+ /**
+ * 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[] $constraints The constraint(s) to validate
+ * against
+ * @param array|null $groups The validation groups to
+ * validate. If none is given,
+ * "Default" is assumed
+ *
+ * @return ContextualValidatorInterface This validator
+ */
+ public function validate($value, $constraints = null, $groups = null);
+
+ /**
+ * Validates a property of an object against the constraints specified
+ * for this property.
+ *
+ * @param object $object The object
+ * @param string $propertyName The name of the validated property
+ * @param array|null $groups The validation groups to validate. If
+ * none is given, "Default" is assumed
+ *
+ * @return ContextualValidatorInterface This validator
+ */
+ public function validateProperty($object, $propertyName, $groups = null);
+
+ /**
+ * 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 array|null $groups The validation groups to validate. If
+ * none is given, "Default" is assumed
+ *
+ * @return ContextualValidatorInterface This validator
+ */
+ public function validatePropertyValue($objectOrClass, $propertyName, $value, $groups = null);
+
+ /**
+ * Returns the violations that have been generated so far in the context
+ * of the validator.
+ *
+ * @return ConstraintViolationListInterface The constraint violations
+ */
+ public function getViolations();
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Validator/LegacyValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Validator/LegacyValidator.php
new file mode 100644
index 0000000..ce3501f
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Validator/LegacyValidator.php
@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Validator;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Constraints\GroupSequence;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\ValidatorInterface as LegacyValidatorInterface;
+
+/**
+ * A validator that supports both the API of Symfony < 2.5 and Symfony 2.5+.
+ *
+ * This class is incompatible with PHP versions < 5.3.9, because it implements
+ * two different interfaces specifying the same method validate():
+ *
+ * - {@link \Symfony\Component\Validator\ValidatorInterface}
+ * - {@link \Symfony\Component\Validator\Validator\ValidatorInterface}
+ *
+ * In PHP versions prior to 5.3.9, either use {@link RecursiveValidator} or the
+ * deprecated class {@link \Symfony\Component\Validator\Validator} instead.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see \Symfony\Component\Validator\ValidatorInterface
+ * @see \Symfony\Component\Validator\Validator\ValidatorInterface
+ *
+ * @deprecated Implemented for backwards compatibility with Symfony < 2.5.
+ * To be removed in Symfony 3.0.
+ */
+class LegacyValidator extends RecursiveValidator implements LegacyValidatorInterface
+{
+ public function validate($value, $groups = null, $traverse = false, $deep = false)
+ {
+ $numArgs = func_num_args();
+
+ // Use new signature if constraints are given in the second argument
+ if (self::testConstraints($groups) && ($numArgs < 3 || 3 === $numArgs && self::testGroups($traverse))) {
+ // Rename to avoid total confusion ;)
+ $constraints = $groups;
+ $groups = $traverse;
+
+ return parent::validate($value, $constraints, $groups);
+ }
+
+ $constraint = new Valid(array('traverse' => $traverse, 'deep' => $deep));
+
+ return parent::validate($value, $constraint, $groups);
+ }
+
+ public function validateValue($value, $constraints, $groups = null)
+ {
+ return parent::validate($value, $constraints, $groups);
+ }
+
+ public function getMetadataFactory()
+ {
+ return $this->metadataFactory;
+ }
+
+ private static function testConstraints($constraints)
+ {
+ return null === $constraints || $constraints instanceof Constraint || (is_array($constraints) && current($constraints) instanceof Constraint);
+ }
+
+ private static function testGroups($groups)
+ {
+ return null === $groups || is_string($groups) || $groups instanceof GroupSequence || (is_array($groups) && (is_string(current($groups)) || current($groups) instanceof GroupSequence));
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php
new file mode 100644
index 0000000..191decd
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php
@@ -0,0 +1,866 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Validator;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Constraints\GroupSequence;
+use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
+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\UnsupportedMetadataException;
+use Symfony\Component\Validator\Exception\ValidatorException;
+use Symfony\Component\Validator\Mapping\CascadingStrategy;
+use Symfony\Component\Validator\Mapping\ClassMetadataInterface;
+use Symfony\Component\Validator\Mapping\GenericMetadata;
+use Symfony\Component\Validator\Mapping\MetadataInterface;
+use Symfony\Component\Validator\Mapping\PropertyMetadataInterface;
+use Symfony\Component\Validator\Mapping\TraversalStrategy;
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\ObjectInitializerInterface;
+use Symfony\Component\Validator\Util\PropertyPath;
+
+/**
+ * Recursive implementation of {@link ContextualValidatorInterface}.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class RecursiveContextualValidator implements ContextualValidatorInterface
+{
+ /**
+ * @var ExecutionContextInterface
+ */
+ private $context;
+
+ /**
+ * @var MetadataFactoryInterface
+ */
+ private $metadataFactory;
+
+ /**
+ * @var ConstraintValidatorFactoryInterface
+ */
+ private $validatorFactory;
+
+ /**
+ * @var ObjectInitializerInterface[]
+ */
+ private $objectInitializers;
+
+ /**
+ * Creates a validator for the given context.
+ *
+ * @param ExecutionContextInterface $context The execution context
+ * @param MetadataFactoryInterface $metadataFactory The factory for
+ * fetching the metadata
+ * of validated objects
+ * @param ConstraintValidatorFactoryInterface $validatorFactory The factory for creating
+ * constraint validators
+ * @param ObjectInitializerInterface[] $objectInitializers The object initializers
+ */
+ public function __construct(ExecutionContextInterface $context, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, array $objectInitializers = array())
+ {
+ $this->context = $context;
+ $this->defaultPropertyPath = $context->getPropertyPath();
+ $this->defaultGroups = array($context->getGroup() ?: Constraint::DEFAULT_GROUP);
+ $this->metadataFactory = $metadataFactory;
+ $this->validatorFactory = $validatorFactory;
+ $this->objectInitializers = $objectInitializers;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function atPath($path)
+ {
+ $this->defaultPropertyPath = $this->context->getPropertyPath($path);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, $constraints = null, $groups = null)
+ {
+ $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();
+
+ // 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 = array($constraints);
+ }
+
+ $metadata = new GenericMetadata();
+ $metadata->addConstraints($constraints);
+
+ $this->validateGenericNode(
+ $value,
+ null,
+ is_object($value) ? spl_object_hash($value) : null,
+ $metadata,
+ $this->defaultPropertyPath,
+ $groups,
+ null,
+ TraversalStrategy::IMPLICIT,
+ $this->context
+ );
+
+ $this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
+ $this->context->setGroup($previousGroup);
+
+ 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,
+ true,
+ $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.',
+ gettype($value)
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateProperty($object, $propertyName, $groups = null)
+ {
+ $classMetadata = $this->metadataFactory->getMetadataFor($object);
+
+ if (!$classMetadata instanceof ClassMetadataInterface) {
+ // Cannot be UnsupportedMetadataException because of BC with
+ // Symfony < 2.5
+ throw new ValidatorException(sprintf(
+ 'The metadata factory should return instances of '.
+ '"\Symfony\Component\Validator\Mapping\ClassMetadataInterface", '.
+ 'got: "%s".',
+ is_object($classMetadata) ? get_class($classMetadata) : gettype($classMetadata)
+ ));
+ }
+
+ $propertyMetadatas = $classMetadata->getPropertyMetadata($propertyName);
+ $groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups;
+ $cacheKey = spl_object_hash($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.':'.$propertyName,
+ $propertyMetadata,
+ $propertyPath,
+ $groups,
+ null,
+ TraversalStrategy::IMPLICIT,
+ $this->context
+ );
+ }
+
+ $this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
+ $this->context->setGroup($previousGroup);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validatePropertyValue($objectOrClass, $propertyName, $value, $groups = null)
+ {
+ $classMetadata = $this->metadataFactory->getMetadataFor($objectOrClass);
+
+ if (!$classMetadata instanceof ClassMetadataInterface) {
+ // Cannot be UnsupportedMetadataException because of BC with
+ // Symfony < 2.5
+ throw new ValidatorException(sprintf(
+ 'The metadata factory should return instances of '.
+ '"\Symfony\Component\Validator\Mapping\ClassMetadataInterface", '.
+ 'got: "%s".',
+ is_object($classMetadata) ? get_class($classMetadata) : gettype($classMetadata)
+ ));
+ }
+
+ $propertyMetadatas = $classMetadata->getPropertyMetadata($propertyName);
+ $groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups;
+
+ if (is_object($objectOrClass)) {
+ $object = $objectOrClass;
+ $cacheKey = spl_object_hash($objectOrClass);
+ $propertyPath = PropertyPath::append($this->defaultPropertyPath, $propertyName);
+ } else {
+ // $objectOrClass contains a class name
+ $object = null;
+ $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.':'.$propertyName,
+ $propertyMetadata,
+ $propertyPath,
+ $groups,
+ null,
+ TraversalStrategy::IMPLICIT,
+ $this->context
+ );
+ }
+
+ $this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
+ $this->context->setGroup($previousGroup);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getViolations()
+ {
+ return $this->context->getViolations();
+ }
+
+ /**
+ * Normalizes the given group or list of groups to an array.
+ *
+ * @param mixed $groups The groups to normalize
+ *
+ * @return array A group array
+ */
+ protected function normalizeGroups($groups)
+ {
+ if (is_array($groups)) {
+ return $groups;
+ }
+
+ return array($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.
+ *
+ * @param object $object The object to cascade
+ * @param string $propertyPath The current property path
+ * @param string[] $groups The validated groups
+ * @param int $traversalStrategy The strategy for traversing the
+ * cascaded object
+ * @param ExecutionContextInterface $context The current execution context
+ *
+ * @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, $propertyPath, array $groups, $traversalStrategy, ExecutionContextInterface $context)
+ {
+ 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".',
+ is_object($classMetadata) ? get_class($classMetadata) : gettype($classMetadata)
+ ));
+ }
+
+ $this->validateClassNode(
+ $object,
+ spl_object_hash($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,
+ $traversalStrategy & TraversalStrategy::STOP_RECURSION,
+ $context
+ );
+ }
+ }
+
+ /**
+ * Validates each object in a collection against the constraints defined
+ * for their classes.
+ *
+ * If the parameter $recursive is set to true, nested {@link \Traversable}
+ * objects are iterated as well. Nested arrays are always iterated,
+ * regardless of the value of $recursive.
+ *
+ * @param array|\Traversable $collection The collection
+ * @param string $propertyPath The current property path
+ * @param string[] $groups The validated groups
+ * @param bool $stopRecursion Whether to disable
+ * recursive iteration. For
+ * backwards compatibility
+ * with Symfony < 2.5.
+ * @param ExecutionContextInterface $context The current execution context
+ *
+ * @see ClassNode
+ * @see CollectionNode
+ */
+ private function validateEachObjectIn($collection, $propertyPath, array $groups, $stopRecursion, ExecutionContextInterface $context)
+ {
+ if ($stopRecursion) {
+ $traversalStrategy = TraversalStrategy::NONE;
+ } else {
+ $traversalStrategy = TraversalStrategy::IMPLICIT;
+ }
+
+ foreach ($collection as $key => $value) {
+ if (is_array($value)) {
+ // Arrays are always cascaded, independent of the specified
+ // traversal strategy
+ // (BC with Symfony < 2.5)
+ $this->validateEachObjectIn(
+ $value,
+ $propertyPath.'['.$key.']',
+ $groups,
+ $stopRecursion,
+ $context
+ );
+
+ continue;
+ }
+
+ // Scalar and null values in the collection are ignored
+ // (BC with Symfony < 2.5)
+ if (is_object($value)) {
+ $this->validateObject(
+ $value,
+ $propertyPath.'['.$key.']',
+ $groups,
+ $traversalStrategy,
+ $context
+ );
+ }
+ }
+ }
+
+ /**
+ * Validates a class node.
+ *
+ * A class node is a combination of an object with a {@link ClassMetadataInterface}
+ * instance. Each class node (conceptionally) 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.
+ *
+ * @param object $object The validated object
+ * @param string $cacheKey The key for caching
+ * the validated object
+ * @param ClassMetadataInterface $metadata The class metadata of
+ * the object
+ * @param string $propertyPath The property path leading
+ * to the object
+ * @param string[] $groups The groups in which the
+ * object should be validated
+ * @param string[]|null $cascadedGroups The groups in which
+ * cascaded objects should
+ * be validated
+ * @param int $traversalStrategy The strategy used for
+ * traversing the object
+ * @param ExecutionContextInterface $context The current execution context
+ *
+ * @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, $cacheKey, ClassMetadataInterface $metadata = null, $propertyPath, array $groups, $cascadedGroups, $traversalStrategy, ExecutionContextInterface $context)
+ {
+ $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) ? spl_object_hash($group) : $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()) {
+ // 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 (=[<G1,G2>,G3,G4]) contain a group sequence
+ // (=<G1,G2>), 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".',
+ is_object($propertyMetadata) ? get_class($propertyMetadata) : gettype($propertyMetadata)
+ ));
+ }
+
+ $propertyValue = $propertyMetadata->getPropertyValue($object);
+
+ $this->validateGenericNode(
+ $propertyValue,
+ $object,
+ $cacheKey.':'.$propertyName,
+ $propertyMetadata,
+ $propertyPath
+ ? $propertyPath.'.'.$propertyName
+ : $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) {
+ // Keep the STOP_RECURSION flag, if it was set
+ $traversalStrategy = $metadata->getTraversalStrategy()
+ | ($traversalStrategy & TraversalStrategy::STOP_RECURSION);
+ }
+
+ // 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) {
+ // Must throw a ConstraintDefinitionException for backwards
+ // compatibility reasons with Symfony < 2.5
+ throw new ConstraintDefinitionException(sprintf(
+ 'Traversal was enabled for "%s", but this class '.
+ 'does not implement "\Traversable".',
+ get_class($object)
+ ));
+ }
+
+ $this->validateEachObjectIn(
+ $object,
+ $propertyPath,
+ $groups,
+ $traversalStrategy & TraversalStrategy::STOP_RECURSION,
+ $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. Arrays are always traversed.
+ *
+ * @param mixed $value The validated value
+ * @param object|null $object The current object
+ * @param string $cacheKey The key for caching
+ * the validated value
+ * @param MetadataInterface $metadata The metadata of the
+ * value
+ * @param string $propertyPath The property path leading
+ * to the value
+ * @param string[] $groups The groups in which the
+ * value should be validated
+ * @param string[]|null $cascadedGroups The groups in which
+ * cascaded objects should
+ * be validated
+ * @param int $traversalStrategy The strategy used for
+ * traversing the value
+ * @param ExecutionContextInterface $context The current execution context
+ *
+ * @see TraversalStrategy
+ */
+ private function validateGenericNode($value, $object, $cacheKey, MetadataInterface $metadata = null, $propertyPath, array $groups, $cascadedGroups, $traversalStrategy, ExecutionContextInterface $context)
+ {
+ $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 have an array or a cascaded object
+ if (!is_array($value) && !($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) {
+ // Keep the STOP_RECURSION flag, if it was set
+ $traversalStrategy = $metadata->getTraversalStrategy()
+ | ($traversalStrategy & TraversalStrategy::STOP_RECURSION);
+ }
+
+ // The $cascadedGroups property is set, if the "Default" group is
+ // overridden by a group sequence
+ // See validateClassNode()
+ $cascadedGroups = count($cascadedGroups) > 0
+ ? $cascadedGroups
+ : $groups;
+
+ if (is_array($value)) {
+ // Arrays are always traversed, independent of the specified
+ // traversal strategy
+ // (BC with Symfony < 2.5)
+ $this->validateEachObjectIn(
+ $value,
+ $propertyPath,
+ $cascadedGroups,
+ $traversalStrategy & TraversalStrategy::STOP_RECURSION,
+ $context
+ );
+
+ return;
+ }
+
+ // If the value is a scalar, pass it anyway, because we want
+ // a NoSuchMetadataException to be thrown in that case
+ // (BC with Symfony < 2.5)
+ $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.
+ *
+ * @param mixed $value The validated value
+ * @param object|null $object The current object
+ * @param string $cacheKey The key for caching
+ * the validated value
+ * @param MetadataInterface $metadata The metadata of the
+ * value
+ * @param string $propertyPath The property path leading
+ * to the value
+ * @param int $traversalStrategy The strategy used for
+ * traversing the value
+ * @param GroupSequence $groupSequence The group sequence
+ * @param string[]|null $cascadedGroup The group that should
+ * be passed to cascaded
+ * objects instead of
+ * the group sequence
+ * @param ExecutionContextInterface $context The execution context
+ */
+ private function stepThroughGroupSequence($value, $object, $cacheKey, MetadataInterface $metadata = null, $propertyPath, $traversalStrategy, GroupSequence $groupSequence, $cascadedGroup, ExecutionContextInterface $context)
+ {
+ $violationCount = count($context->getViolations());
+ $cascadedGroups = $cascadedGroup ? array($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.
+ *
+ * @param mixed $value The validated value
+ * @param string $cacheKey The key for caching the
+ * validated value
+ * @param MetadataInterface $metadata The metadata of the value
+ * @param string $group The group to validate
+ * @param ExecutionContextInterface $context The execution context
+ */
+ private function validateInGroup($value, $cacheKey, MetadataInterface $metadata, $group, ExecutionContextInterface $context)
+ {
+ $context->setGroup($group);
+
+ foreach ($metadata->findConstraints($group) as $constraint) {
+ // Prevent duplicate validation of constraints, in the case
+ // that constraints belong to multiple validated groups
+ if (null !== $cacheKey) {
+ $constraintHash = spl_object_hash($constraint);
+
+ if ($context->isConstraintValidated($cacheKey, $constraintHash)) {
+ continue;
+ }
+
+ $context->markConstraintAsValidated($cacheKey, $constraintHash);
+ }
+
+ $context->setConstraint($constraint);
+
+ $validator = $this->validatorFactory->getInstance($constraint);
+ $validator->initialize($context);
+ $validator->validate($value, $constraint);
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Validator/RecursiveValidator.php b/vendor/symfony/validator/Symfony/Component/Validator/Validator/RecursiveValidator.php
new file mode 100644
index 0000000..ddf0850
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Validator/RecursiveValidator.php
@@ -0,0 +1,140 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Validator;
+
+use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
+use Symfony\Component\Validator\Context\ExecutionContextFactoryInterface;
+use Symfony\Component\Validator\Context\ExecutionContextInterface;
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\ObjectInitializerInterface;
+
+/**
+ * Recursive implementation of {@link ValidatorInterface}.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class RecursiveValidator implements ValidatorInterface
+{
+ /**
+ * @var ExecutionContextFactoryInterface
+ */
+ protected $contextFactory;
+
+ /**
+ * @var MetadataFactoryInterface
+ */
+ protected $metadataFactory;
+
+ /**
+ * @var ConstraintValidatorFactoryInterface
+ */
+ protected $validatorFactory;
+
+ /**
+ * @var ObjectInitializerInterface[]
+ */
+ protected $objectInitializers;
+
+ /**
+ * Creates a new validator.
+ *
+ * @param ExecutionContextFactoryInterface $contextFactory The factory for
+ * creating new contexts
+ * @param MetadataFactoryInterface $metadataFactory The factory for
+ * fetching the metadata
+ * of validated objects
+ * @param ConstraintValidatorFactoryInterface $validatorFactory The factory for creating
+ * constraint validators
+ * @param ObjectInitializerInterface[] $objectInitializers The object initializers
+ */
+ public function __construct(ExecutionContextFactoryInterface $contextFactory, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, array $objectInitializers = array())
+ {
+ $this->contextFactory = $contextFactory;
+ $this->metadataFactory = $metadataFactory;
+ $this->validatorFactory = $validatorFactory;
+ $this->objectInitializers = $objectInitializers;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function startContext($root = null)
+ {
+ return new RecursiveContextualValidator(
+ $this->contextFactory->createContext($this, $root),
+ $this->metadataFactory,
+ $this->validatorFactory,
+ $this->objectInitializers
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function inContext(ExecutionContextInterface $context)
+ {
+ return new RecursiveContextualValidator(
+ $context,
+ $this->metadataFactory,
+ $this->validatorFactory,
+ $this->objectInitializers
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadataFor($object)
+ {
+ return $this->metadataFactory->getMetadataFor($object);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasMetadataFor($object)
+ {
+ return $this->metadataFactory->hasMetadataFor($object);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value, $constraints = null, $groups = null)
+ {
+ return $this->startContext($value)
+ ->validate($value, $constraints, $groups)
+ ->getViolations();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateProperty($object, $propertyName, $groups = null)
+ {
+ return $this->startContext($object)
+ ->validateProperty($object, $propertyName, $groups)
+ ->getViolations();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validatePropertyValue($objectOrClass, $propertyName, $value, $groups = null)
+ {
+ // 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/vendor/symfony/validator/Symfony/Component/Validator/Validator/ValidatorInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/Validator/ValidatorInterface.php
new file mode 100644
index 0000000..2582bf6
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Validator/ValidatorInterface.php
@@ -0,0 +1,100 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Validator;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintViolationListInterface;
+use Symfony\Component\Validator\Context\ExecutionContextInterface;
+use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface;
+
+/**
+ * Validates PHP values against constraints.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+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 mixed $value The value to validate
+ * @param Constraint|Constraint[] $constraints The constraint(s) to validate
+ * against
+ * @param 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($value, $constraints = null, $groups = null);
+
+ /**
+ * Validates a property of an object against the constraints specified
+ * for this property.
+ *
+ * @param object $object The object
+ * @param string $propertyName The name of the validated property
+ * @param 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, $propertyName, $groups = null);
+
+ /**
+ * 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 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($objectOrClass, $propertyName, $value, $groups = null);
+
+ /**
+ * 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.
+ *
+ * @return ContextualValidatorInterface The validator for the new context
+ */
+ public function startContext();
+
+ /**
+ * Returns a validator in the given execution context.
+ *
+ * The returned validator adds all generated violations to the given
+ * context.
+ *
+ * @param ExecutionContextInterface $context The execution context
+ *
+ * @return ContextualValidatorInterface The validator for that context
+ */
+ public function inContext(ExecutionContextInterface $context);
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilder.php b/vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilder.php
new file mode 100644
index 0000000..1d65478
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilder.php
@@ -0,0 +1,412 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+use Doctrine\Common\Annotations\AnnotationReader;
+use Doctrine\Common\Annotations\CachedReader;
+use Doctrine\Common\Annotations\Reader;
+use Doctrine\Common\Cache\ArrayCache;
+use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
+use Symfony\Component\Translation\TranslatorInterface;
+use Symfony\Component\Validator\Context\ExecutionContextFactory;
+use Symfony\Component\Validator\Context\LegacyExecutionContextFactory;
+use Symfony\Component\Validator\Exception\InvalidArgumentException;
+use Symfony\Component\Validator\Exception\ValidatorException;
+use Symfony\Component\Validator\Mapping\Cache\CacheInterface;
+use Symfony\Component\Validator\Mapping\ClassMetadataFactory;
+use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
+use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
+use Symfony\Component\Validator\Mapping\Loader\LoaderChain;
+use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
+use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader;
+use Symfony\Component\Validator\Mapping\Loader\XmlFilesLoader;
+use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader;
+use Symfony\Component\Validator\Mapping\Loader\YamlFilesLoader;
+use Symfony\Component\Validator\Validator\LegacyValidator;
+use Symfony\Component\Validator\Validator\RecursiveValidator;
+use Symfony\Component\Validator\Validator as ValidatorV24;
+
+/**
+ * The default implementation of {@link ValidatorBuilderInterface}.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ValidatorBuilder implements ValidatorBuilderInterface
+{
+ /**
+ * @var array
+ */
+ private $initializers = array();
+
+ /**
+ * @var array
+ */
+ private $xmlMappings = array();
+
+ /**
+ * @var array
+ */
+ private $yamlMappings = array();
+
+ /**
+ * @var array
+ */
+ private $methodMappings = array();
+
+ /**
+ * @var Reader|null
+ */
+ private $annotationReader;
+
+ /**
+ * @var MetadataFactoryInterface|null
+ */
+ private $metadataFactory;
+
+ /**
+ * @var ConstraintValidatorFactoryInterface|null
+ */
+ private $validatorFactory;
+
+ /**
+ * @var CacheInterface|null
+ */
+ private $metadataCache;
+
+ /**
+ * @var TranslatorInterface|null
+ */
+ private $translator;
+
+ /**
+ * @var null|string
+ */
+ private $translationDomain;
+
+ /**
+ * @var PropertyAccessorInterface|null
+ */
+ private $propertyAccessor;
+
+ /**
+ * @var int|null
+ */
+ private $apiVersion;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addObjectInitializer(ObjectInitializerInterface $initializer)
+ {
+ $this->initializers[] = $initializer;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addObjectInitializers(array $initializers)
+ {
+ $this->initializers = array_merge($this->initializers, $initializers);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addXmlMapping($path)
+ {
+ 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;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addXmlMappings(array $paths)
+ {
+ 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;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addYamlMapping($path)
+ {
+ 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;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addYamlMappings(array $paths)
+ {
+ 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;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addMethodMapping($methodName)
+ {
+ 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;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addMethodMappings(array $methodNames)
+ {
+ 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;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function enableAnnotationMapping(Reader $annotationReader = null)
+ {
+ if (null !== $this->metadataFactory) {
+ throw new ValidatorException('You cannot enable annotation mapping after setting a custom metadata factory. Configure your metadata factory instead.');
+ }
+
+ if (null === $annotationReader) {
+ if (!class_exists('Doctrine\Common\Annotations\AnnotationReader') || !class_exists('Doctrine\Common\Cache\ArrayCache')) {
+ throw new \RuntimeException('Enabling annotation based constraint mapping requires the packages doctrine/annotations and doctrine/cache to be installed.');
+ }
+
+ $annotationReader = new CachedReader(new AnnotationReader(), new ArrayCache());
+ }
+
+ $this->annotationReader = $annotationReader;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function disableAnnotationMapping()
+ {
+ $this->annotationReader = null;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMetadataFactory(MetadataFactoryInterface $metadataFactory)
+ {
+ if (count($this->xmlMappings) > 0 || count($this->yamlMappings) > 0 || count($this->methodMappings) > 0 || null !== $this->annotationReader) {
+ 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;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMetadataCache(CacheInterface $cache)
+ {
+ if (null !== $this->metadataFactory) {
+ throw new ValidatorException('You cannot set a custom metadata cache after setting a custom metadata factory. Configure your metadata factory instead.');
+ }
+
+ $this->metadataCache = $cache;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $validatorFactory)
+ {
+ if (null !== $this->propertyAccessor) {
+ throw new ValidatorException('You cannot set a validator factory after setting a custom property accessor. Remove the call to setPropertyAccessor() if you want to call setConstraintValidatorFactory().');
+ }
+
+ $this->validatorFactory = $validatorFactory;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setTranslator(TranslatorInterface $translator)
+ {
+ $this->translator = $translator;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setTranslationDomain($translationDomain)
+ {
+ $this->translationDomain = $translationDomain;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setPropertyAccessor(PropertyAccessorInterface $propertyAccessor)
+ {
+ if (null !== $this->validatorFactory) {
+ throw new ValidatorException('You cannot set a property accessor after setting a custom validator factory. Configure your validator factory instead.');
+ }
+
+ $this->propertyAccessor = $propertyAccessor;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setApiVersion($apiVersion)
+ {
+ if (!in_array($apiVersion, array(Validation::API_VERSION_2_4, Validation::API_VERSION_2_5, Validation::API_VERSION_2_5_BC))) {
+ throw new InvalidArgumentException(sprintf(
+ 'The requested API version is invalid: "%s"',
+ $apiVersion
+ ));
+ }
+
+ if (PHP_VERSION_ID < 50309 && $apiVersion === Validation::API_VERSION_2_5_BC) {
+ throw new InvalidArgumentException(sprintf(
+ 'The Validator API that is compatible with both Symfony 2.4 '.
+ 'and Symfony 2.5 can only be used on PHP 5.3.9 and higher. '.
+ 'Your current PHP version is %s.',
+ PHP_VERSION
+ ));
+ }
+
+ $this->apiVersion = $apiVersion;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getValidator()
+ {
+ $metadataFactory = $this->metadataFactory;
+ $apiVersion = $this->apiVersion;
+
+ if (null === $apiVersion) {
+ $apiVersion = PHP_VERSION_ID < 50309
+ ? Validation::API_VERSION_2_4
+ : Validation::API_VERSION_2_5_BC;
+ }
+
+ if (!$metadataFactory) {
+ $loaders = array();
+
+ if (count($this->xmlMappings) > 1) {
+ $loaders[] = new XmlFilesLoader($this->xmlMappings);
+ } elseif (1 === count($this->xmlMappings)) {
+ $loaders[] = new XmlFileLoader($this->xmlMappings[0]);
+ }
+
+ if (count($this->yamlMappings) > 1) {
+ $loaders[] = new YamlFilesLoader($this->yamlMappings);
+ } elseif (1 === count($this->yamlMappings)) {
+ $loaders[] = new YamlFileLoader($this->yamlMappings[0]);
+ }
+
+ foreach ($this->methodMappings as $methodName) {
+ $loaders[] = new StaticMethodLoader($methodName);
+ }
+
+ if ($this->annotationReader) {
+ $loaders[] = new AnnotationLoader($this->annotationReader);
+ }
+
+ $loader = null;
+
+ if (count($loaders) > 1) {
+ $loader = new LoaderChain($loaders);
+ } elseif (1 === count($loaders)) {
+ $loader = $loaders[0];
+ }
+
+ if (Validation::API_VERSION_2_5 === $apiVersion) {
+ $metadataFactory = new LazyLoadingMetadataFactory($loader, $this->metadataCache);
+ } else {
+ $metadataFactory = new ClassMetadataFactory($loader, $this->metadataCache);
+ }
+ }
+
+ $validatorFactory = $this->validatorFactory ?: new ConstraintValidatorFactory($this->propertyAccessor);
+ $translator = $this->translator ?: new DefaultTranslator();
+
+ if (Validation::API_VERSION_2_4 === $apiVersion) {
+ return new ValidatorV24($metadataFactory, $validatorFactory, $translator, $this->translationDomain, $this->initializers);
+ }
+
+ if (Validation::API_VERSION_2_5 === $apiVersion) {
+ $contextFactory = new ExecutionContextFactory($translator, $this->translationDomain);
+
+ return new RecursiveValidator($contextFactory, $metadataFactory, $validatorFactory, $this->initializers);
+ }
+
+ $contextFactory = new LegacyExecutionContextFactory($metadataFactory, $translator, $this->translationDomain);
+
+ return new LegacyValidator($contextFactory, $metadataFactory, $validatorFactory, $this->initializers);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilderInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilderInterface.php
new file mode 100644
index 0000000..2fd0f9c
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilderInterface.php
@@ -0,0 +1,193 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+use Doctrine\Common\Annotations\Reader;
+use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
+use Symfony\Component\Translation\TranslatorInterface;
+use Symfony\Component\Validator\Mapping\Cache\CacheInterface;
+
+/**
+ * A configurable builder for ValidatorInterface objects.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface ValidatorBuilderInterface
+{
+ /**
+ * Adds an object initializer to the validator.
+ *
+ * @param ObjectInitializerInterface $initializer The initializer
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function addObjectInitializer(ObjectInitializerInterface $initializer);
+
+ /**
+ * Adds a list of object initializers to the validator.
+ *
+ * @param array $initializers The initializer
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function addObjectInitializers(array $initializers);
+
+ /**
+ * Adds an XML constraint mapping file to the validator.
+ *
+ * @param string $path The path to the mapping file
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function addXmlMapping($path);
+
+ /**
+ * Adds a list of XML constraint mapping files to the validator.
+ *
+ * @param array $paths The paths to the mapping files
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function addXmlMappings(array $paths);
+
+ /**
+ * Adds a YAML constraint mapping file to the validator.
+ *
+ * @param string $path The path to the mapping file
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function addYamlMapping($path);
+
+ /**
+ * Adds a list of YAML constraint mappings file to the validator.
+ *
+ * @param array $paths The paths to the mapping files
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function addYamlMappings(array $paths);
+
+ /**
+ * Enables constraint mapping using the given static method.
+ *
+ * @param string $methodName The name of the method
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function addMethodMapping($methodName);
+
+ /**
+ * Enables constraint mapping using the given static methods.
+ *
+ * @param array $methodNames The names of the methods
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function addMethodMappings(array $methodNames);
+
+ /**
+ * Enables annotation based constraint mapping.
+ *
+ * @param Reader $annotationReader The annotation reader to be used
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function enableAnnotationMapping(Reader $annotationReader = null);
+
+ /**
+ * Disables annotation based constraint mapping.
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function disableAnnotationMapping();
+
+ /**
+ * Sets the class metadata factory used by the validator.
+ *
+ * @param MetadataFactoryInterface $metadataFactory The metadata factory
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function setMetadataFactory(MetadataFactoryInterface $metadataFactory);
+
+ /**
+ * Sets the cache for caching class metadata.
+ *
+ * @param CacheInterface $cache The cache instance
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function setMetadataCache(CacheInterface $cache);
+
+ /**
+ * Sets the constraint validator factory used by the validator.
+ *
+ * @param ConstraintValidatorFactoryInterface $validatorFactory The validator factory
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $validatorFactory);
+
+ /**
+ * Sets the translator used for translating violation messages.
+ *
+ * @param TranslatorInterface $translator The translator instance
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function setTranslator(TranslatorInterface $translator);
+
+ /**
+ * 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.
+ *
+ * @param string $translationDomain The translation domain of the violation messages
+ *
+ * @return ValidatorBuilderInterface The builder object
+ */
+ public function setTranslationDomain($translationDomain);
+
+ /**
+ * Sets the property accessor for resolving property paths.
+ *
+ * @param PropertyAccessorInterface $propertyAccessor The property accessor
+ *
+ * @return ValidatorBuilderInterface The builder object
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ */
+ public function setPropertyAccessor(PropertyAccessorInterface $propertyAccessor);
+
+ /**
+ * Sets the API version that the returned validator should support.
+ *
+ * @param int $apiVersion The required API version
+ *
+ * @return ValidatorBuilderInterface The builder object
+ *
+ * @see Validation::API_VERSION_2_4
+ * @see Validation::API_VERSION_2_5
+ * @see Validation::API_VERSION_2_5_BC
+ */
+ public function setApiVersion($apiVersion);
+
+ /**
+ * Builds and returns a new validator object.
+ *
+ * @return ValidatorInterface The built validator.
+ */
+ public function getValidator();
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/ValidatorInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/ValidatorInterface.php
new file mode 100644
index 0000000..03c8921
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/ValidatorInterface.php
@@ -0,0 +1,114 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * Validates values and graphs of objects and arrays.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Validator\ValidatorInterface} instead.
+ */
+interface ValidatorInterface
+{
+ /**
+ * Validates a value.
+ *
+ * The accepted values depend on the {@link MetadataFactoryInterface}
+ * implementation.
+ *
+ * The signature changed with Symfony 2.5 (see
+ * {@link Validator\ValidatorInterface::validate()}. This signature will be
+ * disabled in Symfony 3.0.
+ *
+ * @param mixed $value The value to validate
+ * @param array|null $groups The validation groups to validate.
+ * @param bool $traverse Whether to traverse the value if it is traversable.
+ * @param bool $deep Whether to traverse nested traversable values recursively.
+ *
+ * @return ConstraintViolationListInterface A list of constraint violations. If the
+ * list is empty, validation succeeded.
+ *
+ * @api
+ */
+ public function validate($value, $groups = null, $traverse = false, $deep = false);
+
+ /**
+ * Validates a property of a value against its current value.
+ *
+ * The accepted values depend on the {@link MetadataFactoryInterface}
+ * implementation.
+ *
+ * @param mixed $containingValue The value containing the property.
+ * @param string $property The name of the property to validate.
+ * @param array|null $groups The validation groups to validate.
+ *
+ * @return ConstraintViolationListInterface A list of constraint violations. If the
+ * list is empty, validation succeeded.
+ *
+ * @api
+ */
+ public function validateProperty($containingValue, $property, $groups = null);
+
+ /**
+ * Validate a property of a value against a potential value.
+ *
+ * The accepted values depend on the {@link MetadataFactoryInterface}
+ * implementation.
+ *
+ * @param mixed $containingValue The value containing the property.
+ * @param string $property The name of the property to validate
+ * @param string $value The value to validate against the
+ * constraints of the property.
+ * @param array|null $groups The validation groups to validate.
+ *
+ * @return ConstraintViolationListInterface A list of constraint violations. If the
+ * list is empty, validation succeeded.
+ *
+ * @api
+ */
+ public function validatePropertyValue($containingValue, $property, $value, $groups = null);
+
+ /**
+ * Validates a value against a constraint or a list of constraints.
+ *
+ * @param mixed $value The value to validate.
+ * @param Constraint|Constraint[] $constraints The constraint(s) to validate against.
+ * @param array|null $groups The validation groups to validate.
+ *
+ * @return ConstraintViolationListInterface A list of constraint violations. If the
+ * list is empty, validation succeeded.
+ *
+ * @api
+ *
+ * @deprecated Renamed to {@link Validator\ValidatorInterface::validate()}
+ * in Symfony 2.5. Will be removed in Symfony 3.0.
+ */
+ public function validateValue($value, $constraints, $groups = null);
+
+ /**
+ * Returns the factory for metadata instances.
+ *
+ * @return MetadataFactoryInterface The metadata factory.
+ *
+ * @api
+ *
+ * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0.
+ * Use {@link Validator\ValidatorInterface::getMetadataFor()} or
+ * {@link Validator\ValidatorInterface::hasMetadataFor()}
+ * instead.
+ */
+ public function getMetadataFactory();
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php b/vendor/symfony/validator/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php
new file mode 100644
index 0000000..b752c39
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php
@@ -0,0 +1,225 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Violation;
+
+use Symfony\Component\Translation\TranslatorInterface;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\ConstraintViolationList;
+use Symfony\Component\Validator\Util\PropertyPath;
+
+/**
+ * Default implementation of {@link ConstraintViolationBuilderInterface}.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @internal You should not instantiate or use this class. Code against
+ * {@link ConstraintViolationBuilderInterface} instead.
+ */
+class ConstraintViolationBuilder implements ConstraintViolationBuilderInterface
+{
+ /**
+ * @var ConstraintViolationList
+ */
+ private $violations;
+
+ /**
+ * @var string
+ */
+ private $message;
+
+ /**
+ * @var array
+ */
+ private $parameters;
+
+ /**
+ * @var mixed
+ */
+ private $root;
+
+ /**
+ * @var mixed
+ */
+ private $invalidValue;
+
+ /**
+ * @var string
+ */
+ private $propertyPath;
+
+ /**
+ * @var TranslatorInterface
+ */
+ private $translator;
+
+ /**
+ * @var string|null
+ */
+ private $translationDomain;
+
+ /**
+ * @var int|null
+ */
+ private $plural;
+
+ /**
+ * @var Constraint
+ */
+ private $constraint;
+
+ /**
+ * @var mixed
+ */
+ private $code;
+
+ /**
+ * @var mixed
+ */
+ private $cause;
+
+ public function __construct(ConstraintViolationList $violations, Constraint $constraint, $message, array $parameters, $root, $propertyPath, $invalidValue, TranslatorInterface $translator, $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;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function atPath($path)
+ {
+ $this->propertyPath = PropertyPath::append($this->propertyPath, $path);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setParameter($key, $value)
+ {
+ $this->parameters[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setParameters(array $parameters)
+ {
+ $this->parameters = $parameters;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setTranslationDomain($translationDomain)
+ {
+ $this->translationDomain = $translationDomain;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setInvalidValue($invalidValue)
+ {
+ $this->invalidValue = $invalidValue;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setPlural($number)
+ {
+ $this->plural = $number;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setCode($code)
+ {
+ $this->code = $code;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setCause($cause)
+ {
+ $this->cause = $cause;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addViolation()
+ {
+ if (null === $this->plural) {
+ $translatedMessage = $this->translator->trans(
+ $this->message,
+ $this->parameters,
+ $this->translationDomain
+ );
+ } else {
+ try {
+ $translatedMessage = $this->translator->transChoice(
+ $this->message,
+ $this->plural,
+ $this->parameters,
+ $this->translationDomain#
+ );
+ } catch (\InvalidArgumentException $e) {
+ $translatedMessage = $this->translator->trans(
+ $this->message,
+ $this->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/vendor/symfony/validator/Symfony/Component/Validator/Violation/ConstraintViolationBuilderInterface.php b/vendor/symfony/validator/Symfony/Component/Validator/Violation/ConstraintViolationBuilderInterface.php
new file mode 100644
index 0000000..3dc270a
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Violation/ConstraintViolationBuilderInterface.php
@@ -0,0 +1,115 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+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.
+ *
+ * @since 2.5
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+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 ConstraintViolationBuilderInterface This builder
+ */
+ public function atPath($path);
+
+ /**
+ * 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 ConstraintViolationBuilderInterface This builder
+ */
+ public function setParameter($key, $value);
+
+ /**
+ * 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 ConstraintViolationBuilderInterface This builder
+ */
+ public function setParameters(array $parameters);
+
+ /**
+ * Sets the translation domain which should be used for translating the
+ * violation message.
+ *
+ * @param string $translationDomain The translation domain
+ *
+ * @return ConstraintViolationBuilderInterface This builder
+ *
+ * @see \Symfony\Component\Translation\TranslatorInterface
+ */
+ public function setTranslationDomain($translationDomain);
+
+ /**
+ * Sets the invalid value that caused this violation.
+ *
+ * @param mixed $invalidValue The invalid value
+ *
+ * @return ConstraintViolationBuilderInterface This builder
+ */
+ public function setInvalidValue($invalidValue);
+
+ /**
+ * 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 ConstraintViolationBuilderInterface This builder
+ *
+ * @see \Symfony\Component\Translation\TranslatorInterface::transChoice()
+ */
+ public function setPlural($number);
+
+ /**
+ * Sets the violation code.
+ *
+ * @param int $code The violation code
+ *
+ * @return ConstraintViolationBuilderInterface This builder
+ */
+ public function setCode($code);
+
+ /**
+ * Sets the cause of the violation.
+ *
+ * @param mixed $cause The cause of the violation
+ *
+ * @return ConstraintViolationBuilderInterface This builder
+ */
+ public function setCause($cause);
+
+ /**
+ * Adds the violation to the current execution context.
+ */
+ public function addViolation();
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/Violation/LegacyConstraintViolationBuilder.php b/vendor/symfony/validator/Symfony/Component/Validator/Violation/LegacyConstraintViolationBuilder.php
new file mode 100644
index 0000000..5519f42
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/Violation/LegacyConstraintViolationBuilder.php
@@ -0,0 +1,164 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Violation;
+
+use Symfony\Component\Validator\ExecutionContextInterface;
+
+/**
+ * Backwards-compatible implementation of {@link ConstraintViolationBuilderInterface}.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @internal You should not instantiate or use this class. Code against
+ * {@link ConstraintViolationBuilderInterface} instead.
+ *
+ * @deprecated This class will be removed in Symfony 3.0.
+ */
+class LegacyConstraintViolationBuilder implements ConstraintViolationBuilderInterface
+{
+ /**
+ * @var ExecutionContextInterface
+ */
+ private $context;
+
+ /**
+ * @var string
+ */
+ private $message;
+
+ /**
+ * @var array
+ */
+ private $parameters;
+
+ /**
+ * @var mixed
+ */
+ private $invalidValue;
+
+ /**
+ * @var string
+ */
+ private $propertyPath;
+
+ /**
+ * @var int|null
+ */
+ private $plural;
+
+ /**
+ * @var mixed
+ */
+ private $code;
+
+ public function __construct(ExecutionContextInterface $context, $message, array $parameters)
+ {
+ $this->context = $context;
+ $this->message = $message;
+ $this->parameters = $parameters;
+ $this->invalidValue = $context->getValue();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function atPath($path)
+ {
+ $this->propertyPath = $path;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setParameter($key, $value)
+ {
+ $this->parameters[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setParameters(array $parameters)
+ {
+ $this->parameters = $parameters;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setTranslationDomain($translationDomain)
+ {
+ // can't be set in the old API
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setInvalidValue($invalidValue)
+ {
+ $this->invalidValue = $invalidValue;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setPlural($number)
+ {
+ $this->plural = $number;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setCode($code)
+ {
+ $this->code = $code;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setCause($cause)
+ {
+ // do nothing - we can't save the cause through the old API
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addViolation()
+ {
+ if ($this->propertyPath) {
+ $this->context->addViolationAt($this->propertyPath, $this->message, $this->parameters, $this->invalidValue, $this->plural, $this->code);
+
+ return;
+ }
+
+ $this->context->addViolation($this->message, $this->parameters, $this->invalidValue, $this->plural, $this->code);
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/composer.json b/vendor/symfony/validator/Symfony/Component/Validator/composer.json
new file mode 100644
index 0000000..2d781ea
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/composer.json
@@ -0,0 +1,56 @@
+{
+ "name": "symfony/validator",
+ "type": "library",
+ "description": "Symfony Validator Component",
+ "keywords": [],
+ "homepage": "http://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3",
+ "symfony/translation": "~2.0,>=2.0.5"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7",
+ "doctrine/common": "~2.3",
+ "symfony/http-foundation": "~2.1",
+ "symfony/intl": "~2.3",
+ "symfony/yaml": "~2.0,>=2.0.5",
+ "symfony/config": "~2.2",
+ "symfony/property-access": "~2.3",
+ "symfony/expression-language": "~2.4",
+ "doctrine/annotations": "~1.0",
+ "doctrine/cache": "~1.0",
+ "egulias/email-validator": "~1.2,>=1.2.1"
+ },
+ "suggest": {
+ "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
+ "doctrine/cache": "For using the default cached annotation reader and metadata cache.",
+ "symfony/http-foundation": "",
+ "symfony/intl": "",
+ "symfony/yaml": "",
+ "symfony/config": "",
+ "egulias/email-validator": "Strict (RFC compliant) email validation",
+ "symfony/property-access": "For using the 2.4 Validator API",
+ "symfony/expression-language": "For using the 2.4 Expression validator"
+ },
+ "autoload": {
+ "psr-0": { "Symfony\\Component\\Validator\\": "" }
+ },
+ "target-dir": "Symfony/Component/Validator",
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ }
+}
diff --git a/vendor/symfony/validator/Symfony/Component/Validator/phpunit.xml.dist b/vendor/symfony/validator/Symfony/Component/Validator/phpunit.xml.dist
new file mode 100644
index 0000000..1bf4391
--- /dev/null
+++ b/vendor/symfony/validator/Symfony/Component/Validator/phpunit.xml.dist
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+
+ <testsuites>
+ <testsuite name="Symfony Validator Component Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./vendor</directory>
+ <directory>./Tests</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/.gitignore b/vendor/symfony/yaml/Symfony/Component/Yaml/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/CHANGELOG.md b/vendor/symfony/yaml/Symfony/Component/Yaml/CHANGELOG.md
new file mode 100644
index 0000000..096cf65
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/CHANGELOG.md
@@ -0,0 +1,8 @@
+CHANGELOG
+=========
+
+2.1.0
+-----
+
+ * Yaml::parse() does not evaluate loaded files as PHP files by default
+ anymore (call Yaml::enablePhpParsing() to get back the old behavior)
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Dumper.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Dumper.php
new file mode 100644
index 0000000..39cdcfc
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Dumper.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+/**
+ * Dumper dumps PHP variables to YAML strings.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Dumper
+{
+ /**
+ * The amount of spaces to use for indentation of nested nodes.
+ *
+ * @var int
+ */
+ protected $indentation = 4;
+
+ /**
+ * Sets the indentation.
+ *
+ * @param int $num The amount of spaces to use for indentation of nested nodes.
+ */
+ public function setIndentation($num)
+ {
+ $this->indentation = (int) $num;
+ }
+
+ /**
+ * Dumps a PHP value to YAML.
+ *
+ * @param mixed $input The PHP value
+ * @param int $inline The level where you switch to inline YAML
+ * @param int $indent The level of indentation (used internally)
+ * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
+ * @param bool $objectSupport true if object support is enabled, false otherwise
+ *
+ * @return string The YAML representation of the PHP value
+ */
+ public function dump($input, $inline = 0, $indent = 0, $exceptionOnInvalidType = false, $objectSupport = false)
+ {
+ $output = '';
+ $prefix = $indent ? str_repeat(' ', $indent) : '';
+
+ if ($inline <= 0 || !is_array($input) || empty($input)) {
+ $output .= $prefix.Inline::dump($input, $exceptionOnInvalidType, $objectSupport);
+ } else {
+ $isAHash = array_keys($input) !== range(0, count($input) - 1);
+
+ foreach ($input as $key => $value) {
+ $willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value);
+
+ $output .= sprintf('%s%s%s%s',
+ $prefix,
+ $isAHash ? Inline::dump($key, $exceptionOnInvalidType, $objectSupport).':' : '-',
+ $willBeInlined ? ' ' : "\n",
+ $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $exceptionOnInvalidType, $objectSupport)
+ ).($willBeInlined ? "\n" : '');
+ }
+ }
+
+ return $output;
+ }
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Escaper.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Escaper.php
new file mode 100644
index 0000000..f498765
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Escaper.php
@@ -0,0 +1,97 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+/**
+ * Escaper encapsulates escaping rules for single and double-quoted
+ * YAML strings.
+ *
+ * @author Matthew Lewinski <matthew@lewinski.org>
+ */
+class Escaper
+{
+ // Characters that would cause a dumped string to require double quoting.
+ const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";
+
+ // Mapping arrays for escaping a double quoted string. The backslash is
+ // first to ensure proper escaping because str_replace operates iteratively
+ // on the input arrays. This ordering of the characters avoids the use of strtr,
+ // which performs more slowly.
+ private static $escapees = array('\\', '\\\\', '\\"', '"',
+ "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
+ "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f",
+ "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
+ "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f",
+ "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9",);
+ private static $escaped = array('\\\\', '\\"', '\\\\', '\\"',
+ "\\0", "\\x01", "\\x02", "\\x03", "\\x04", "\\x05", "\\x06", "\\a",
+ "\\b", "\\t", "\\n", "\\v", "\\f", "\\r", "\\x0e", "\\x0f",
+ "\\x10", "\\x11", "\\x12", "\\x13", "\\x14", "\\x15", "\\x16", "\\x17",
+ "\\x18", "\\x19", "\\x1a", "\\e", "\\x1c", "\\x1d", "\\x1e", "\\x1f",
+ "\\N", "\\_", "\\L", "\\P",);
+
+ /**
+ * Determines if a PHP value would require double quoting in YAML.
+ *
+ * @param string $value A PHP value
+ *
+ * @return bool True if the value would require double quotes.
+ */
+ public static function requiresDoubleQuoting($value)
+ {
+ return preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value);
+ }
+
+ /**
+ * Escapes and surrounds a PHP value with double quotes.
+ *
+ * @param string $value A PHP value
+ *
+ * @return string The quoted, escaped string
+ */
+ public static function escapeWithDoubleQuotes($value)
+ {
+ return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value));
+ }
+
+ /**
+ * Determines if a PHP value would require single quoting in YAML.
+ *
+ * @param string $value A PHP value
+ *
+ * @return bool True if the value would require single quotes.
+ */
+ public static function requiresSingleQuoting($value)
+ {
+ // Determines if a PHP value is entirely composed of a value that would
+ // require single quoting in YAML.
+ if (in_array(strtolower($value), array('null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'))) {
+ return true;
+ }
+
+ // Determines if the PHP value contains any single characters that would
+ // cause it to require single quoting in YAML.
+ return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value);
+ }
+
+ /**
+ * Escapes and surrounds a PHP value with single quotes.
+ *
+ * @param string $value A PHP value
+ *
+ * @return string The quoted, escaped string
+ */
+ public static function escapeWithSingleQuotes($value)
+ {
+ return sprintf("'%s'", str_replace('\'', '\'\'', $value));
+ }
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.php
new file mode 100644
index 0000000..9b3e6de
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception class thrown when an error occurs during dumping.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class DumpException extends RuntimeException
+{
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..92e5c2e
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception interface for all exceptions thrown by the component.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface ExceptionInterface
+{
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.php
new file mode 100644
index 0000000..0447dff
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.php
@@ -0,0 +1,148 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception class thrown when an error occurs during parsing.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class ParseException extends RuntimeException
+{
+ private $parsedFile;
+ private $parsedLine;
+ private $snippet;
+ private $rawMessage;
+
+ /**
+ * Constructor.
+ *
+ * @param string $message The error message
+ * @param int $parsedLine The line where the error occurred
+ * @param int $snippet The snippet of code near the problem
+ * @param string $parsedFile The file name where the error occurred
+ * @param \Exception $previous The previous exception
+ */
+ public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, \Exception $previous = null)
+ {
+ $this->parsedFile = $parsedFile;
+ $this->parsedLine = $parsedLine;
+ $this->snippet = $snippet;
+ $this->rawMessage = $message;
+
+ $this->updateRepr();
+
+ parent::__construct($this->message, 0, $previous);
+ }
+
+ /**
+ * Gets the snippet of code near the error.
+ *
+ * @return string The snippet of code
+ */
+ public function getSnippet()
+ {
+ return $this->snippet;
+ }
+
+ /**
+ * Sets the snippet of code near the error.
+ *
+ * @param string $snippet The code snippet
+ */
+ public function setSnippet($snippet)
+ {
+ $this->snippet = $snippet;
+
+ $this->updateRepr();
+ }
+
+ /**
+ * Gets the filename where the error occurred.
+ *
+ * This method returns null if a string is parsed.
+ *
+ * @return string The filename
+ */
+ public function getParsedFile()
+ {
+ return $this->parsedFile;
+ }
+
+ /**
+ * Sets the filename where the error occurred.
+ *
+ * @param string $parsedFile The filename
+ */
+ public function setParsedFile($parsedFile)
+ {
+ $this->parsedFile = $parsedFile;
+
+ $this->updateRepr();
+ }
+
+ /**
+ * Gets the line where the error occurred.
+ *
+ * @return int The file line
+ */
+ public function getParsedLine()
+ {
+ return $this->parsedLine;
+ }
+
+ /**
+ * Sets the line where the error occurred.
+ *
+ * @param int $parsedLine The file line
+ */
+ public function setParsedLine($parsedLine)
+ {
+ $this->parsedLine = $parsedLine;
+
+ $this->updateRepr();
+ }
+
+ private function updateRepr()
+ {
+ $this->message = $this->rawMessage;
+
+ $dot = false;
+ if ('.' === substr($this->message, -1)) {
+ $this->message = substr($this->message, 0, -1);
+ $dot = true;
+ }
+
+ if (null !== $this->parsedFile) {
+ if (PHP_VERSION_ID >= 50400) {
+ $jsonOptions = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
+ } else {
+ $jsonOptions = 0;
+ }
+ $this->message .= sprintf(' in %s', json_encode($this->parsedFile, $jsonOptions));
+ }
+
+ if ($this->parsedLine >= 0) {
+ $this->message .= sprintf(' at line %d', $this->parsedLine);
+ }
+
+ if ($this->snippet) {
+ $this->message .= sprintf(' (near "%s")', $this->snippet);
+ }
+
+ if ($dot) {
+ $this->message .= '.';
+ }
+ }
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.php
new file mode 100644
index 0000000..3573bf1
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception class thrown when an error occurs during parsing.
+ *
+ * @author Romain Neutron <imprec@gmail.com>
+ *
+ * @api
+ */
+class RuntimeException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Inline.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Inline.php
new file mode 100644
index 0000000..52ea724
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Inline.php
@@ -0,0 +1,546 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Exception\DumpException;
+
+/**
+ * Inline implements a YAML parser/dumper for the YAML inline syntax.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Inline
+{
+ const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
+
+ private static $exceptionOnInvalidType = false;
+ private static $objectSupport = false;
+ private static $objectForMap = false;
+
+ /**
+ * Converts a YAML string to a PHP array.
+ *
+ * @param string $value A YAML string
+ * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
+ * @param bool $objectSupport true if object support is enabled, false otherwise
+ * @param bool $objectForMap true if maps should return a stdClass instead of array()
+ * @param array $references Mapping of variable names to values
+ *
+ * @return array A PHP array representing the YAML string
+ *
+ * @throws ParseException
+ */
+ public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false, $references = array())
+ {
+ self::$exceptionOnInvalidType = $exceptionOnInvalidType;
+ self::$objectSupport = $objectSupport;
+ self::$objectForMap = $objectForMap;
+
+ $value = trim($value);
+
+ if (0 == strlen($value)) {
+ return '';
+ }
+
+ if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
+ $mbEncoding = mb_internal_encoding();
+ mb_internal_encoding('ASCII');
+ }
+
+ $i = 0;
+ switch ($value[0]) {
+ case '[':
+ $result = self::parseSequence($value, $i, $references);
+ ++$i;
+ break;
+ case '{':
+ $result = self::parseMapping($value, $i, $references);
+ ++$i;
+ break;
+ default:
+ $result = self::parseScalar($value, null, array('"', "'"), $i, true, $references);
+ }
+
+ // some comments are allowed at the end
+ if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) {
+ throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)));
+ }
+
+ if (isset($mbEncoding)) {
+ mb_internal_encoding($mbEncoding);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Dumps a given PHP variable to a YAML string.
+ *
+ * @param mixed $value The PHP variable to convert
+ * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
+ * @param bool $objectSupport true if object support is enabled, false otherwise
+ *
+ * @return string The YAML string representing the PHP array
+ *
+ * @throws DumpException When trying to dump PHP resource
+ */
+ public static function dump($value, $exceptionOnInvalidType = false, $objectSupport = false)
+ {
+ switch (true) {
+ case is_resource($value):
+ if ($exceptionOnInvalidType) {
+ throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value)));
+ }
+
+ return 'null';
+ case is_object($value):
+ if ($objectSupport) {
+ return '!!php/object:'.serialize($value);
+ }
+
+ if ($exceptionOnInvalidType) {
+ throw new DumpException('Object support when dumping a YAML file has been disabled.');
+ }
+
+ return 'null';
+ case is_array($value):
+ return self::dumpArray($value, $exceptionOnInvalidType, $objectSupport);
+ case null === $value:
+ return 'null';
+ case true === $value:
+ return 'true';
+ case false === $value:
+ return 'false';
+ case ctype_digit($value):
+ return is_string($value) ? "'$value'" : (int) $value;
+ case is_numeric($value):
+ $locale = setlocale(LC_NUMERIC, 0);
+ if (false !== $locale) {
+ setlocale(LC_NUMERIC, 'C');
+ }
+ if (is_float($value)) {
+ $repr = (string) $value;
+ if (is_infinite($value)) {
+ $repr = str_ireplace('INF', '.Inf', $repr);
+ } elseif (floor($value) == $value && $repr == $value) {
+ // Preserve float data type since storing a whole number will result in integer value.
+ $repr = '!!float '.$repr;
+ }
+ } else {
+ $repr = is_string($value) ? "'$value'" : (string) $value;
+ }
+ if (false !== $locale) {
+ setlocale(LC_NUMERIC, $locale);
+ }
+
+ return $repr;
+ case '' == $value:
+ return "''";
+ case Escaper::requiresDoubleQuoting($value):
+ return Escaper::escapeWithDoubleQuotes($value);
+ case Escaper::requiresSingleQuoting($value):
+ case preg_match(self::getHexRegex(), $value):
+ case preg_match(self::getTimestampRegex(), $value):
+ return Escaper::escapeWithSingleQuotes($value);
+ default:
+ return $value;
+ }
+ }
+
+ /**
+ * Dumps a PHP array to a YAML string.
+ *
+ * @param array $value The PHP array to dump
+ * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
+ * @param bool $objectSupport true if object support is enabled, false otherwise
+ *
+ * @return string The YAML string representing the PHP array
+ */
+ private static function dumpArray($value, $exceptionOnInvalidType, $objectSupport)
+ {
+ // array
+ $keys = array_keys($value);
+ $keysCount = count($keys);
+ if ((1 === $keysCount && '0' == $keys[0])
+ || ($keysCount > 1 && array_reduce($keys, function ($v, $w) { return (int) $v + $w; }, 0) === $keysCount * ($keysCount - 1) / 2)
+ ) {
+ $output = array();
+ foreach ($value as $val) {
+ $output[] = self::dump($val, $exceptionOnInvalidType, $objectSupport);
+ }
+
+ return sprintf('[%s]', implode(', ', $output));
+ }
+
+ // mapping
+ $output = array();
+ foreach ($value as $key => $val) {
+ $output[] = sprintf('%s: %s', self::dump($key, $exceptionOnInvalidType, $objectSupport), self::dump($val, $exceptionOnInvalidType, $objectSupport));
+ }
+
+ return sprintf('{ %s }', implode(', ', $output));
+ }
+
+ /**
+ * Parses a scalar to a YAML string.
+ *
+ * @param string $scalar
+ * @param string $delimiters
+ * @param array $stringDelimiters
+ * @param int &$i
+ * @param bool $evaluate
+ * @param array $references
+ *
+ * @return string A YAML string
+ *
+ * @throws ParseException When malformed inline YAML string is parsed
+ */
+ public static function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true, $references = array())
+ {
+ if (in_array($scalar[$i], $stringDelimiters)) {
+ // quoted scalar
+ $output = self::parseQuotedScalar($scalar, $i);
+
+ if (null !== $delimiters) {
+ $tmp = ltrim(substr($scalar, $i), ' ');
+ if (!in_array($tmp[0], $delimiters)) {
+ throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i)));
+ }
+ }
+ } else {
+ // "normal" string
+ if (!$delimiters) {
+ $output = substr($scalar, $i);
+ $i += strlen($output);
+
+ // remove comments
+ if (false !== $strpos = strpos($output, ' #')) {
+ $output = rtrim(substr($output, 0, $strpos));
+ }
+ } elseif (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) {
+ $output = $match[1];
+ $i += strlen($output);
+ } else {
+ throw new ParseException(sprintf('Malformed inline YAML string (%s).', $scalar));
+ }
+
+ if ($evaluate) {
+ $output = self::evaluateScalar($output, $references);
+ }
+ }
+
+ return $output;
+ }
+
+ /**
+ * Parses a quoted scalar to YAML.
+ *
+ * @param string $scalar
+ * @param int &$i
+ *
+ * @return string A YAML string
+ *
+ * @throws ParseException When malformed inline YAML string is parsed
+ */
+ private static function parseQuotedScalar($scalar, &$i)
+ {
+ if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
+ throw new ParseException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i)));
+ }
+
+ $output = substr($match[0], 1, strlen($match[0]) - 2);
+
+ $unescaper = new Unescaper();
+ if ('"' == $scalar[$i]) {
+ $output = $unescaper->unescapeDoubleQuotedString($output);
+ } else {
+ $output = $unescaper->unescapeSingleQuotedString($output);
+ }
+
+ $i += strlen($match[0]);
+
+ return $output;
+ }
+
+ /**
+ * Parses a sequence to a YAML string.
+ *
+ * @param string $sequence
+ * @param int &$i
+ * @param array $references
+ *
+ * @return string A YAML string
+ *
+ * @throws ParseException When malformed inline YAML string is parsed
+ */
+ private static function parseSequence($sequence, &$i = 0, $references = array())
+ {
+ $output = array();
+ $len = strlen($sequence);
+ ++$i;
+
+ // [foo, bar, ...]
+ while ($i < $len) {
+ switch ($sequence[$i]) {
+ case '[':
+ // nested sequence
+ $output[] = self::parseSequence($sequence, $i, $references);
+ break;
+ case '{':
+ // nested mapping
+ $output[] = self::parseMapping($sequence, $i, $references);
+ break;
+ case ']':
+ return $output;
+ case ',':
+ case ' ':
+ break;
+ default:
+ $isQuoted = in_array($sequence[$i], array('"', "'"));
+ $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i, true, $references);
+
+ // the value can be an array if a reference has been resolved to an array var
+ if (!is_array($value) && !$isQuoted && false !== strpos($value, ': ')) {
+ // embedded mapping?
+ try {
+ $pos = 0;
+ $value = self::parseMapping('{'.$value.'}', $pos, $references);
+ } catch (\InvalidArgumentException $e) {
+ // no, it's not
+ }
+ }
+
+ $output[] = $value;
+
+ --$i;
+ }
+
+ ++$i;
+ }
+
+ throw new ParseException(sprintf('Malformed inline YAML string %s', $sequence));
+ }
+
+ /**
+ * Parses a mapping to a YAML string.
+ *
+ * @param string $mapping
+ * @param int &$i
+ * @param array $references
+ *
+ * @return string A YAML string
+ *
+ * @throws ParseException When malformed inline YAML string is parsed
+ */
+ private static function parseMapping($mapping, &$i = 0, $references = array())
+ {
+ $output = array();
+ $len = strlen($mapping);
+ ++$i;
+
+ // {foo: bar, bar:foo, ...}
+ while ($i < $len) {
+ switch ($mapping[$i]) {
+ case ' ':
+ case ',':
+ ++$i;
+ continue 2;
+ case '}':
+ if (self::$objectForMap) {
+ return (object) $output;
+ }
+
+ return $output;
+ }
+
+ // key
+ $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);
+
+ // value
+ $done = false;
+
+ while ($i < $len) {
+ switch ($mapping[$i]) {
+ case '[':
+ // nested sequence
+ $value = self::parseSequence($mapping, $i, $references);
+ // Spec: Keys MUST be unique; first one wins.
+ // Parser cannot abort this mapping earlier, since lines
+ // are processed sequentially.
+ if (!isset($output[$key])) {
+ $output[$key] = $value;
+ }
+ $done = true;
+ break;
+ case '{':
+ // nested mapping
+ $value = self::parseMapping($mapping, $i, $references);
+ // Spec: Keys MUST be unique; first one wins.
+ // Parser cannot abort this mapping earlier, since lines
+ // are processed sequentially.
+ if (!isset($output[$key])) {
+ $output[$key] = $value;
+ }
+ $done = true;
+ break;
+ case ':':
+ case ' ':
+ break;
+ default:
+ $value = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i, true, $references);
+ // Spec: Keys MUST be unique; first one wins.
+ // Parser cannot abort this mapping earlier, since lines
+ // are processed sequentially.
+ if (!isset($output[$key])) {
+ $output[$key] = $value;
+ }
+ $done = true;
+ --$i;
+ }
+
+ ++$i;
+
+ if ($done) {
+ continue 2;
+ }
+ }
+ }
+
+ throw new ParseException(sprintf('Malformed inline YAML string %s', $mapping));
+ }
+
+ /**
+ * Evaluates scalars and replaces magic values.
+ *
+ * @param string $scalar
+ * @param array $references
+ *
+ * @return string A YAML string
+ *
+ * @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved
+ */
+ private static function evaluateScalar($scalar, $references = array())
+ {
+ $scalar = trim($scalar);
+ $scalarLower = strtolower($scalar);
+
+ if (0 === strpos($scalar, '*')) {
+ if (false !== $pos = strpos($scalar, '#')) {
+ $value = substr($scalar, 1, $pos - 2);
+ } else {
+ $value = substr($scalar, 1);
+ }
+
+ // an unquoted *
+ if (false === $value || '' === $value) {
+ throw new ParseException('A reference must contain at least one character.');
+ }
+
+ if (!array_key_exists($value, $references)) {
+ throw new ParseException(sprintf('Reference "%s" does not exist.', $value));
+ }
+
+ return $references[$value];
+ }
+
+ switch (true) {
+ case 'null' === $scalarLower:
+ case '' === $scalar:
+ case '~' === $scalar:
+ return;
+ case 'true' === $scalarLower:
+ return true;
+ case 'false' === $scalarLower:
+ return false;
+ // Optimise for returning strings.
+ case $scalar[0] === '+' || $scalar[0] === '-' || $scalar[0] === '.' || $scalar[0] === '!' || is_numeric($scalar[0]):
+ switch (true) {
+ case 0 === strpos($scalar, '!str'):
+ return (string) substr($scalar, 5);
+ case 0 === strpos($scalar, '! '):
+ return (int) self::parseScalar(substr($scalar, 2));
+ case 0 === strpos($scalar, '!!php/object:'):
+ if (self::$objectSupport) {
+ return unserialize(substr($scalar, 13));
+ }
+
+ if (self::$exceptionOnInvalidType) {
+ throw new ParseException('Object support when parsing a YAML file has been disabled.');
+ }
+
+ return;
+ case 0 === strpos($scalar, '!!float '):
+ return (float) substr($scalar, 8);
+ case ctype_digit($scalar):
+ $raw = $scalar;
+ $cast = (int) $scalar;
+
+ return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
+ case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
+ $raw = $scalar;
+ $cast = (int) $scalar;
+
+ return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw);
+ case is_numeric($scalar):
+ case preg_match(self::getHexRegex(), $scalar):
+ return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar;
+ case '.inf' === $scalarLower:
+ case '.nan' === $scalarLower:
+ return -log(0);
+ case '-.inf' === $scalarLower:
+ return log(0);
+ case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
+ return (float) str_replace(',', '', $scalar);
+ case preg_match(self::getTimestampRegex(), $scalar):
+ return strtotime($scalar);
+ }
+ default:
+ return (string) $scalar;
+ }
+ }
+
+ /**
+ * Gets a regex that matches a YAML date.
+ *
+ * @return string The regular expression
+ *
+ * @see http://www.yaml.org/spec/1.2/spec.html#id2761573
+ */
+ private static function getTimestampRegex()
+ {
+ return <<<EOF
+ ~^
+ (?P<year>[0-9][0-9][0-9][0-9])
+ -(?P<month>[0-9][0-9]?)
+ -(?P<day>[0-9][0-9]?)
+ (?:(?:[Tt]|[ \t]+)
+ (?P<hour>[0-9][0-9]?)
+ :(?P<minute>[0-9][0-9])
+ :(?P<second>[0-9][0-9])
+ (?:\.(?P<fraction>[0-9]*))?
+ (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
+ (?::(?P<tz_minute>[0-9][0-9]))?))?)?
+ $~x
+EOF;
+ }
+
+ /**
+ * Gets a regex that matches a YAML number in hexadecimal notation.
+ *
+ * @return string
+ */
+ private static function getHexRegex()
+ {
+ return '~^0x[0-9a-f]++$~i';
+ }
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/LICENSE b/vendor/symfony/yaml/Symfony/Component/Yaml/LICENSE
new file mode 100644
index 0000000..43028bc
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2015 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/vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php
new file mode 100644
index 0000000..065e650
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php
@@ -0,0 +1,697 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+
+/**
+ * Parser parses YAML strings to convert them to PHP arrays.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Parser
+{
+ const FOLDED_SCALAR_PATTERN = '(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?';
+
+ private $offset = 0;
+ private $lines = array();
+ private $currentLineNb = -1;
+ private $currentLine = '';
+ private $refs = array();
+
+ /**
+ * Constructor.
+ *
+ * @param int $offset The offset of YAML document (used for line numbers in error messages)
+ */
+ public function __construct($offset = 0)
+ {
+ $this->offset = $offset;
+ }
+
+ /**
+ * Parses a YAML string to a PHP value.
+ *
+ * @param string $value A YAML string
+ * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
+ * @param bool $objectSupport true if object support is enabled, false otherwise
+ * @param bool $objectForMap true if maps should return a stdClass instead of array()
+ *
+ * @return mixed A PHP value
+ *
+ * @throws ParseException If the YAML is not valid
+ */
+ public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
+ {
+ if (!preg_match('//u', $value)) {
+ throw new ParseException('The YAML value does not appear to be valid UTF-8.');
+ }
+ $this->currentLineNb = -1;
+ $this->currentLine = '';
+ $value = $this->cleanup($value);
+ $this->lines = explode("\n", $value);
+
+ if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
+ $mbEncoding = mb_internal_encoding();
+ mb_internal_encoding('UTF-8');
+ }
+
+ $data = array();
+ $context = null;
+ $allowOverwrite = false;
+ while ($this->moveToNextLine()) {
+ if ($this->isCurrentLineEmpty()) {
+ continue;
+ }
+
+ // tab?
+ if ("\t" === $this->currentLine[0]) {
+ throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+ }
+
+ $isRef = $mergeNode = false;
+ if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) {
+ if ($context && 'mapping' == $context) {
+ throw new ParseException('You cannot define a sequence item when in a mapping');
+ }
+ $context = 'sequence';
+
+ if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
+ $isRef = $matches['ref'];
+ $values['value'] = $matches['value'];
+ }
+
+ // array
+ if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
+ $c = $this->getRealCurrentLineNb() + 1;
+ $parser = new Parser($c);
+ $parser->refs = &$this->refs;
+ $data[] = $parser->parse($this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport, $objectForMap);
+ } else {
+ if (isset($values['leadspaces'])
+ && preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $values['value'], $matches)
+ ) {
+ // this is a compact notation element, add to next block and parse
+ $c = $this->getRealCurrentLineNb();
+ $parser = new Parser($c);
+ $parser->refs = &$this->refs;
+
+ $block = $values['value'];
+ if ($this->isNextLineIndented()) {
+ $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + strlen($values['leadspaces']) + 1);
+ }
+
+ $data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport, $objectForMap);
+ } else {
+ $data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap);
+ }
+ }
+ } elseif (preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values) && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))) {
+ if ($context && 'sequence' == $context) {
+ throw new ParseException('You cannot define a mapping item when in a sequence');
+ }
+ $context = 'mapping';
+
+ // force correct settings
+ Inline::parse(null, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
+ try {
+ $key = Inline::parseScalar($values['key']);
+ } catch (ParseException $e) {
+ $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+ $e->setSnippet($this->currentLine);
+
+ throw $e;
+ }
+
+ if ('<<' === $key) {
+ $mergeNode = true;
+ $allowOverwrite = true;
+ if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
+ $refName = substr($values['value'], 1);
+ if (!array_key_exists($refName, $this->refs)) {
+ throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine);
+ }
+
+ $refValue = $this->refs[$refName];
+
+ if (!is_array($refValue)) {
+ throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+ }
+
+ foreach ($refValue as $key => $value) {
+ if (!isset($data[$key])) {
+ $data[$key] = $value;
+ }
+ }
+ } else {
+ if (isset($values['value']) && $values['value'] !== '') {
+ $value = $values['value'];
+ } else {
+ $value = $this->getNextEmbedBlock();
+ }
+ $c = $this->getRealCurrentLineNb() + 1;
+ $parser = new Parser($c);
+ $parser->refs = &$this->refs;
+ $parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap);
+
+ if (!is_array($parsed)) {
+ throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+ }
+
+ if (isset($parsed[0])) {
+ // If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes
+ // and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier
+ // in the sequence override keys specified in later mapping nodes.
+ foreach ($parsed as $parsedItem) {
+ if (!is_array($parsedItem)) {
+ throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
+ }
+
+ foreach ($parsedItem as $key => $value) {
+ if (!isset($data[$key])) {
+ $data[$key] = $value;
+ }
+ }
+ }
+ } else {
+ // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the
+ // current mapping, unless the key already exists in it.
+ foreach ($parsed as $key => $value) {
+ if (!isset($data[$key])) {
+ $data[$key] = $value;
+ }
+ }
+ }
+ }
+ } elseif (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
+ $isRef = $matches['ref'];
+ $values['value'] = $matches['value'];
+ }
+
+ if ($mergeNode) {
+ // Merge keys
+ } elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
+ // hash
+ // if next line is less indented or equal, then it means that the current value is null
+ if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
+ // Spec: Keys MUST be unique; first one wins.
+ // But overwriting is allowed when a merge node is used in current block.
+ if ($allowOverwrite || !isset($data[$key])) {
+ $data[$key] = null;
+ }
+ } else {
+ $c = $this->getRealCurrentLineNb() + 1;
+ $parser = new Parser($c);
+ $parser->refs = &$this->refs;
+ $value = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap);
+ // Spec: Keys MUST be unique; first one wins.
+ // But overwriting is allowed when a merge node is used in current block.
+ if ($allowOverwrite || !isset($data[$key])) {
+ $data[$key] = $value;
+ }
+ }
+ } else {
+ $value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap);
+ // Spec: Keys MUST be unique; first one wins.
+ // But overwriting is allowed when a merge node is used in current block.
+ if ($allowOverwrite || !isset($data[$key])) {
+ $data[$key] = $value;
+ }
+ }
+ } else {
+ // multiple documents are not supported
+ if ('---' === $this->currentLine) {
+ throw new ParseException('Multiple documents are not supported.');
+ }
+
+ // 1-liner optionally followed by newline(s)
+ if ($this->lines[0] === trim($value)) {
+ try {
+ $value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
+ } catch (ParseException $e) {
+ $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+ $e->setSnippet($this->currentLine);
+
+ throw $e;
+ }
+
+ if (is_array($value)) {
+ $first = reset($value);
+ if (is_string($first) && 0 === strpos($first, '*')) {
+ $data = array();
+ foreach ($value as $alias) {
+ $data[] = $this->refs[substr($alias, 1)];
+ }
+ $value = $data;
+ }
+ }
+
+ if (isset($mbEncoding)) {
+ mb_internal_encoding($mbEncoding);
+ }
+
+ return $value;
+ }
+
+ switch (preg_last_error()) {
+ case PREG_INTERNAL_ERROR:
+ $error = 'Internal PCRE error.';
+ break;
+ case PREG_BACKTRACK_LIMIT_ERROR:
+ $error = 'pcre.backtrack_limit reached.';
+ break;
+ case PREG_RECURSION_LIMIT_ERROR:
+ $error = 'pcre.recursion_limit reached.';
+ break;
+ case PREG_BAD_UTF8_ERROR:
+ $error = 'Malformed UTF-8 data.';
+ break;
+ case PREG_BAD_UTF8_OFFSET_ERROR:
+ $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.';
+ break;
+ default:
+ $error = 'Unable to parse.';
+ }
+
+ throw new ParseException($error, $this->getRealCurrentLineNb() + 1, $this->currentLine);
+ }
+
+ if ($isRef) {
+ $this->refs[$isRef] = end($data);
+ }
+ }
+
+ if (isset($mbEncoding)) {
+ mb_internal_encoding($mbEncoding);
+ }
+
+ return empty($data) ? null : $data;
+ }
+
+ /**
+ * Returns the current line number (takes the offset into account).
+ *
+ * @return int The current line number
+ */
+ private function getRealCurrentLineNb()
+ {
+ return $this->currentLineNb + $this->offset;
+ }
+
+ /**
+ * Returns the current line indentation.
+ *
+ * @return int The current line indentation
+ */
+ private function getCurrentLineIndentation()
+ {
+ return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' '));
+ }
+
+ /**
+ * Returns the next embed block of YAML.
+ *
+ * @param int $indentation The indent level at which the block is to be read, or null for default
+ * @param bool $inSequence True if the enclosing data structure is a sequence
+ *
+ * @return string A YAML string
+ *
+ * @throws ParseException When indentation problem are detected
+ */
+ private function getNextEmbedBlock($indentation = null, $inSequence = false)
+ {
+ $oldLineIndentation = $this->getCurrentLineIndentation();
+
+ if (!$this->moveToNextLine()) {
+ return;
+ }
+
+ if (null === $indentation) {
+ $newIndent = $this->getCurrentLineIndentation();
+
+ $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem($this->currentLine);
+
+ if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) {
+ throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+ }
+ } else {
+ $newIndent = $indentation;
+ }
+
+ $data = array();
+ if ($this->getCurrentLineIndentation() >= $newIndent) {
+ $data[] = substr($this->currentLine, $newIndent);
+ } else {
+ $this->moveToPreviousLine();
+
+ return;
+ }
+
+ if ($inSequence && $oldLineIndentation === $newIndent && '-' === $data[0][0]) {
+ // the previous line contained a dash but no item content, this line is a sequence item with the same indentation
+ // and therefore no nested list or mapping
+ $this->moveToPreviousLine();
+
+ return;
+ }
+
+ $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem($this->currentLine);
+
+ // Comments must not be removed inside a string block (ie. after a line ending with "|")
+ $removeCommentsPattern = '~'.self::FOLDED_SCALAR_PATTERN.'$~';
+ $removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
+
+ while ($this->moveToNextLine()) {
+ $indent = $this->getCurrentLineIndentation();
+
+ if ($indent === $newIndent) {
+ $removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
+ }
+
+ if ($isItUnindentedCollection && !$this->isStringUnIndentedCollectionItem($this->currentLine) && $newIndent === $indent) {
+ $this->moveToPreviousLine();
+ break;
+ }
+
+ if ($this->isCurrentLineBlank()) {
+ $data[] = substr($this->currentLine, $newIndent);
+ continue;
+ }
+
+ if ($removeComments && $this->isCurrentLineComment()) {
+ continue;
+ }
+
+ if ($indent >= $newIndent) {
+ $data[] = substr($this->currentLine, $newIndent);
+ } elseif (0 == $indent) {
+ $this->moveToPreviousLine();
+
+ break;
+ } else {
+ throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+ }
+ }
+
+ return implode("\n", $data);
+ }
+
+ /**
+ * Moves the parser to the next line.
+ *
+ * @return bool
+ */
+ private function moveToNextLine()
+ {
+ if ($this->currentLineNb >= count($this->lines) - 1) {
+ return false;
+ }
+
+ $this->currentLine = $this->lines[++$this->currentLineNb];
+
+ return true;
+ }
+
+ /**
+ * Moves the parser to the previous line.
+ */
+ private function moveToPreviousLine()
+ {
+ $this->currentLine = $this->lines[--$this->currentLineNb];
+ }
+
+ /**
+ * Parses a YAML value.
+ *
+ * @param string $value A YAML value
+ * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
+ * @param bool $objectSupport True if object support is enabled, false otherwise
+ * @param bool $objectForMap true if maps should return a stdClass instead of array()
+ *
+ * @return mixed A PHP value
+ *
+ * @throws ParseException When reference does not exist
+ */
+ private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $objectForMap)
+ {
+ if (0 === strpos($value, '*')) {
+ if (false !== $pos = strpos($value, '#')) {
+ $value = substr($value, 1, $pos - 2);
+ } else {
+ $value = substr($value, 1);
+ }
+
+ if (!array_key_exists($value, $this->refs)) {
+ throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLine);
+ }
+
+ return $this->refs[$value];
+ }
+
+ if (preg_match('/^'.self::FOLDED_SCALAR_PATTERN.'$/', $value, $matches)) {
+ $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';
+
+ return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers));
+ }
+
+ try {
+ return Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
+ } catch (ParseException $e) {
+ $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+ $e->setSnippet($this->currentLine);
+
+ throw $e;
+ }
+ }
+
+ /**
+ * Parses a folded scalar.
+ *
+ * @param string $separator The separator that was used to begin this folded scalar (| or >)
+ * @param string $indicator The indicator that was used to begin this folded scalar (+ or -)
+ * @param int $indentation The indentation that was used to begin this folded scalar
+ *
+ * @return string The text value
+ */
+ private function parseFoldedScalar($separator, $indicator = '', $indentation = 0)
+ {
+ $notEOF = $this->moveToNextLine();
+ if (!$notEOF) {
+ return '';
+ }
+
+ $isCurrentLineBlank = $this->isCurrentLineBlank();
+ $text = '';
+
+ // leading blank lines are consumed before determining indentation
+ while ($notEOF && $isCurrentLineBlank) {
+ // newline only if not EOF
+ if ($notEOF = $this->moveToNextLine()) {
+ $text .= "\n";
+ $isCurrentLineBlank = $this->isCurrentLineBlank();
+ }
+ }
+
+ // determine indentation if not specified
+ if (0 === $indentation) {
+ if (preg_match('/^ +/', $this->currentLine, $matches)) {
+ $indentation = strlen($matches[0]);
+ }
+ }
+
+ if ($indentation > 0) {
+ $pattern = sprintf('/^ {%d}(.*)$/', $indentation);
+
+ while (
+ $notEOF && (
+ $isCurrentLineBlank ||
+ preg_match($pattern, $this->currentLine, $matches)
+ )
+ ) {
+ if ($isCurrentLineBlank) {
+ $text .= substr($this->currentLine, $indentation);
+ } else {
+ $text .= $matches[1];
+ }
+
+ // newline only if not EOF
+ if ($notEOF = $this->moveToNextLine()) {
+ $text .= "\n";
+ $isCurrentLineBlank = $this->isCurrentLineBlank();
+ }
+ }
+ } elseif ($notEOF) {
+ $text .= "\n";
+ }
+
+ if ($notEOF) {
+ $this->moveToPreviousLine();
+ }
+
+ // replace all non-trailing single newlines with spaces in folded blocks
+ if ('>' === $separator) {
+ preg_match('/(\n*)$/', $text, $matches);
+ $text = preg_replace('/(?<!\n)\n(?!\n)/', ' ', rtrim($text, "\n"));
+ $text .= $matches[1];
+ }
+
+ // deal with trailing newlines as indicated
+ if ('' === $indicator) {
+ $text = preg_replace('/\n+$/s', "\n", $text);
+ } elseif ('-' === $indicator) {
+ $text = preg_replace('/\n+$/s', '', $text);
+ }
+
+ return $text;
+ }
+
+ /**
+ * Returns true if the next line is indented.
+ *
+ * @return bool Returns true if the next line is indented, false otherwise
+ */
+ private function isNextLineIndented()
+ {
+ $currentIndentation = $this->getCurrentLineIndentation();
+ $EOF = !$this->moveToNextLine();
+
+ while (!$EOF && $this->isCurrentLineEmpty()) {
+ $EOF = !$this->moveToNextLine();
+ }
+
+ if ($EOF) {
+ return false;
+ }
+
+ $ret = false;
+ if ($this->getCurrentLineIndentation() > $currentIndentation) {
+ $ret = true;
+ }
+
+ $this->moveToPreviousLine();
+
+ return $ret;
+ }
+
+ /**
+ * Returns true if the current line is blank or if it is a comment line.
+ *
+ * @return bool Returns true if the current line is empty or if it is a comment line, false otherwise
+ */
+ private function isCurrentLineEmpty()
+ {
+ return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
+ }
+
+ /**
+ * Returns true if the current line is blank.
+ *
+ * @return bool Returns true if the current line is blank, false otherwise
+ */
+ private function isCurrentLineBlank()
+ {
+ return '' == trim($this->currentLine, ' ');
+ }
+
+ /**
+ * Returns true if the current line is a comment line.
+ *
+ * @return bool Returns true if the current line is a comment line, false otherwise
+ */
+ private function isCurrentLineComment()
+ {
+ //checking explicitly the first char of the trim is faster than loops or strpos
+ $ltrimmedLine = ltrim($this->currentLine, ' ');
+
+ return $ltrimmedLine[0] === '#';
+ }
+
+ /**
+ * Cleanups a YAML string to be parsed.
+ *
+ * @param string $value The input YAML string
+ *
+ * @return string A cleaned up YAML string
+ */
+ private function cleanup($value)
+ {
+ $value = str_replace(array("\r\n", "\r"), "\n", $value);
+
+ // strip YAML header
+ $count = 0;
+ $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count);
+ $this->offset += $count;
+
+ // remove leading comments
+ $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
+ if ($count == 1) {
+ // items have been removed, update the offset
+ $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
+ $value = $trimmedValue;
+ }
+
+ // remove start of the document marker (---)
+ $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
+ if ($count == 1) {
+ // items have been removed, update the offset
+ $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
+ $value = $trimmedValue;
+
+ // remove end of the document marker (...)
+ $value = preg_replace('#\.\.\.\s*$#s', '', $value);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Returns true if the next line starts unindented collection.
+ *
+ * @return bool Returns true if the next line starts unindented collection, false otherwise
+ */
+ private function isNextLineUnIndentedCollection()
+ {
+ $currentIndentation = $this->getCurrentLineIndentation();
+ $notEOF = $this->moveToNextLine();
+
+ while ($notEOF && $this->isCurrentLineEmpty()) {
+ $notEOF = $this->moveToNextLine();
+ }
+
+ if (false === $notEOF) {
+ return false;
+ }
+
+ $ret = false;
+ if (
+ $this->getCurrentLineIndentation() == $currentIndentation
+ &&
+ $this->isStringUnIndentedCollectionItem($this->currentLine)
+ ) {
+ $ret = true;
+ }
+
+ $this->moveToPreviousLine();
+
+ return $ret;
+ }
+
+ /**
+ * Returns true if the string is un-indented collection item.
+ *
+ * @return bool Returns true if the string is un-indented collection item, false otherwise
+ */
+ private function isStringUnIndentedCollectionItem()
+ {
+ return (0 === strpos($this->currentLine, '- '));
+ }
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/README.md b/vendor/symfony/yaml/Symfony/Component/Yaml/README.md
new file mode 100644
index 0000000..85a9786
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/README.md
@@ -0,0 +1,21 @@
+Yaml Component
+==============
+
+YAML implements most of the YAML 1.2 specification.
+
+```php
+use Symfony\Component\Yaml\Yaml;
+
+$array = Yaml::parse(file_get_contents(filename));
+
+print Yaml::dump($array);
+```
+
+Resources
+---------
+
+You can run the unit tests with the following command:
+
+ $ cd path/to/Symfony/Component/Yaml/
+ $ composer install
+ $ phpunit
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/DumperTest.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/DumperTest.php
new file mode 100644
index 0000000..b103b9a
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/DumperTest.php
@@ -0,0 +1,236 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use Symfony\Component\Yaml\Parser;
+use Symfony\Component\Yaml\Dumper;
+
+class DumperTest extends \PHPUnit_Framework_TestCase
+{
+ protected $parser;
+ protected $dumper;
+ protected $path;
+
+ protected $array = array(
+ '' => 'bar',
+ 'foo' => '#bar',
+ 'foo\'bar' => array(),
+ 'bar' => array(1, 'foo'),
+ 'foobar' => array(
+ 'foo' => 'bar',
+ 'bar' => array(1, 'foo'),
+ 'foobar' => array(
+ 'foo' => 'bar',
+ 'bar' => array(1, 'foo'),
+ ),
+ ),
+ );
+
+ protected function setUp()
+ {
+ $this->parser = new Parser();
+ $this->dumper = new Dumper();
+ $this->path = __DIR__.'/Fixtures';
+ }
+
+ protected function tearDown()
+ {
+ $this->parser = null;
+ $this->dumper = null;
+ $this->path = null;
+ $this->array = null;
+ }
+
+ public function testSetIndentation()
+ {
+ $this->dumper->setIndentation(7);
+
+ $expected = <<<EOF
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar:
+ - 1
+ - foo
+foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+ foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 4, 0));
+ }
+
+ public function testSpecifications()
+ {
+ $files = $this->parser->parse(file_get_contents($this->path.'/index.yml'));
+ foreach ($files as $file) {
+ $yamls = file_get_contents($this->path.'/'.$file.'.yml');
+
+ // split YAMLs documents
+ foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) {
+ if (!$yaml) {
+ continue;
+ }
+
+ $test = $this->parser->parse($yaml);
+ if (isset($test['dump_skip']) && $test['dump_skip']) {
+ continue;
+ } elseif (isset($test['todo']) && $test['todo']) {
+ // TODO
+ } else {
+ eval('$expected = '.trim($test['php']).';');
+ $this->assertSame($expected, $this->parser->parse($this->dumper->dump($expected, 10)), $test['test']);
+ }
+ }
+ }
+ }
+
+ public function testInlineLevel()
+ {
+ $expected = <<<EOF
+{ '': bar, foo: '#bar', 'foo''bar': { }, bar: [1, foo], foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } } }
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, -10), '->dump() takes an inline level argument');
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 0), '->dump() takes an inline level argument');
+
+ $expected = <<<EOF
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar: [1, foo]
+foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } }
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 1), '->dump() takes an inline level argument');
+
+ $expected = <<<EOF
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar:
+ - 1
+ - foo
+foobar:
+ foo: bar
+ bar: [1, foo]
+ foobar: { foo: bar, bar: [1, foo] }
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 2), '->dump() takes an inline level argument');
+
+ $expected = <<<EOF
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar:
+ - 1
+ - foo
+foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+ foobar:
+ foo: bar
+ bar: [1, foo]
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 3), '->dump() takes an inline level argument');
+
+ $expected = <<<EOF
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar:
+ - 1
+ - foo
+foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+ foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 4), '->dump() takes an inline level argument');
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 10), '->dump() takes an inline level argument');
+ }
+
+ public function testObjectSupportEnabled()
+ {
+ $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, false, true);
+
+ $this->assertEquals('{ foo: !!php/object:O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}, bar: 1 }', $dump, '->dump() is able to dump objects');
+ }
+
+ public function testObjectSupportDisabledButNoExceptions()
+ {
+ $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1));
+
+ $this->assertEquals('{ foo: null, bar: 1 }', $dump, '->dump() does not dump objects when disabled');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\DumpException
+ */
+ public function testObjectSupportDisabledWithExceptions()
+ {
+ $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, true, false);
+ }
+
+ /**
+ * @dataProvider getEscapeSequences
+ */
+ public function testEscapedEscapeSequencesInQuotedScalar($input, $expected)
+ {
+ $this->assertEquals($expected, $this->dumper->dump($input));
+ }
+
+ public function getEscapeSequences()
+ {
+ return array(
+ 'null' => array("\t\\0", '"\t\\\\0"'),
+ 'bell' => array("\t\\a", '"\t\\\\a"'),
+ 'backspace' => array("\t\\b", '"\t\\\\b"'),
+ 'horizontal-tab' => array("\t\\t", '"\t\\\\t"'),
+ 'line-feed' => array("\t\\n", '"\t\\\\n"'),
+ 'vertical-tab' => array("\t\\v", '"\t\\\\v"'),
+ 'form-feed' => array("\t\\f", '"\t\\\\f"'),
+ 'carriage-return' => array("\t\\r", '"\t\\\\r"'),
+ 'escape' => array("\t\\e", '"\t\\\\e"'),
+ 'space' => array("\t\\ ", '"\t\\\\ "'),
+ 'double-quote' => array("\t\\\"", '"\t\\\\\\""'),
+ 'slash' => array("\t\\/", '"\t\\\\/"'),
+ 'backslash' => array("\t\\\\", '"\t\\\\\\\\"'),
+ 'next-line' => array("\t\\N", '"\t\\\\N"'),
+ 'non-breaking-space' => array("\t\\�", '"\t\\\\�"'),
+ 'line-separator' => array("\t\\L", '"\t\\\\L"'),
+ 'paragraph-separator' => array("\t\\P", '"\t\\\\P"'),
+ );
+ }
+}
+
+class A
+{
+ public $a = 'foo';
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsAnchorAlias.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsAnchorAlias.yml
new file mode 100644
index 0000000..5f9c942
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsAnchorAlias.yml
@@ -0,0 +1,31 @@
+--- %YAML:1.0
+test: Simple Alias Example
+brief: >
+ If you need to refer to the same item of data twice,
+ you can give that item an alias. The alias is a plain
+ string, starting with an ampersand. The item may then
+ be referred to by the alias throughout your document
+ by using an asterisk before the name of the alias.
+ This is called an anchor.
+yaml: |
+ - &showell Steve
+ - Clark
+ - Brian
+ - Oren
+ - *showell
+php: |
+ array('Steve', 'Clark', 'Brian', 'Oren', 'Steve')
+
+---
+test: Alias of a Mapping
+brief: >
+ An alias can be used on any item of data, including
+ sequences, mappings, and other complex data types.
+yaml: |
+ - &hello
+ Meat: pork
+ Starch: potato
+ - banana
+ - *hello
+php: |
+ array(array('Meat'=>'pork', 'Starch'=>'potato'), 'banana', array('Meat'=>'pork', 'Starch'=>'potato'))
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBasicTests.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBasicTests.yml
new file mode 100644
index 0000000..dfd9302
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBasicTests.yml
@@ -0,0 +1,202 @@
+--- %YAML:1.0
+test: Simple Sequence
+brief: |
+ You can specify a list in YAML by placing each
+ member of the list on a new line with an opening
+ dash. These lists are called sequences.
+yaml: |
+ - apple
+ - banana
+ - carrot
+php: |
+ array('apple', 'banana', 'carrot')
+---
+test: Sequence With Item Being Null In The Middle
+brief: |
+ You can specify a list in YAML by placing each
+ member of the list on a new line with an opening
+ dash. These lists are called sequences.
+yaml: |
+ - apple
+ -
+ - carrot
+php: |
+ array('apple', null, 'carrot')
+---
+test: Sequence With Last Item Being Null
+brief: |
+ You can specify a list in YAML by placing each
+ member of the list on a new line with an opening
+ dash. These lists are called sequences.
+yaml: |
+ - apple
+ - banana
+ -
+php: |
+ array('apple', 'banana', null)
+---
+test: Nested Sequences
+brief: |
+ You can include a sequence within another
+ sequence by giving the sequence an empty
+ dash, followed by an indented list.
+yaml: |
+ -
+ - foo
+ - bar
+ - baz
+php: |
+ array(array('foo', 'bar', 'baz'))
+---
+test: Mixed Sequences
+brief: |
+ Sequences can contain any YAML data,
+ including strings and other sequences.
+yaml: |
+ - apple
+ -
+ - foo
+ - bar
+ - x123
+ - banana
+ - carrot
+php: |
+ array('apple', array('foo', 'bar', 'x123'), 'banana', 'carrot')
+---
+test: Deeply Nested Sequences
+brief: |
+ Sequences can be nested even deeper, with each
+ level of indentation representing a level of
+ depth.
+yaml: |
+ -
+ -
+ - uno
+ - dos
+php: |
+ array(array(array('uno', 'dos')))
+---
+test: Simple Mapping
+brief: |
+ You can add a keyed list (also known as a dictionary or
+ hash) to your document by placing each member of the
+ list on a new line, with a colon separating the key
+ from its value. In YAML, this type of list is called
+ a mapping.
+yaml: |
+ foo: whatever
+ bar: stuff
+php: |
+ array('foo' => 'whatever', 'bar' => 'stuff')
+---
+test: Sequence in a Mapping
+brief: |
+ A value in a mapping can be a sequence.
+yaml: |
+ foo: whatever
+ bar:
+ - uno
+ - dos
+php: |
+ array('foo' => 'whatever', 'bar' => array('uno', 'dos'))
+---
+test: Nested Mappings
+brief: |
+ A value in a mapping can be another mapping.
+yaml: |
+ foo: whatever
+ bar:
+ fruit: apple
+ name: steve
+ sport: baseball
+php: |
+ array(
+ 'foo' => 'whatever',
+ 'bar' => array(
+ 'fruit' => 'apple',
+ 'name' => 'steve',
+ 'sport' => 'baseball'
+ )
+ )
+---
+test: Mixed Mapping
+brief: |
+ A mapping can contain any assortment
+ of mappings and sequences as values.
+yaml: |
+ foo: whatever
+ bar:
+ -
+ fruit: apple
+ name: steve
+ sport: baseball
+ - more
+ -
+ python: rocks
+ perl: papers
+ ruby: scissorses
+php: |
+ array(
+ 'foo' => 'whatever',
+ 'bar' => array(
+ array(
+ 'fruit' => 'apple',
+ 'name' => 'steve',
+ 'sport' => 'baseball'
+ ),
+ 'more',
+ array(
+ 'python' => 'rocks',
+ 'perl' => 'papers',
+ 'ruby' => 'scissorses'
+ )
+ )
+ )
+---
+test: Mapping-in-Sequence Shortcut
+todo: true
+brief: |
+ If you are adding a mapping to a sequence, you
+ can place the mapping on the same line as the
+ dash as a shortcut.
+yaml: |
+ - work on YAML.py:
+ - work on Store
+php: |
+ array(array('work on YAML.py' => array('work on Store')))
+---
+test: Sequence-in-Mapping Shortcut
+todo: true
+brief: |
+ The dash in a sequence counts as indentation, so
+ you can add a sequence inside of a mapping without
+ needing spaces as indentation.
+yaml: |
+ allow:
+ - 'localhost'
+ - '%.sourceforge.net'
+ - '%.freepan.org'
+php: |
+ array('allow' => array('localhost', '%.sourceforge.net', '%.freepan.org'))
+---
+todo: true
+test: Merge key
+brief: |
+ A merge key ('<<') can be used in a mapping to insert other mappings. If
+ the value associated with the merge key is a mapping, each of its key/value
+ pairs is inserted into the current mapping.
+yaml: |
+ mapping:
+ name: Joe
+ job: Accountant
+ <<:
+ age: 38
+php: |
+ array(
+ 'mapping' =>
+ array(
+ 'name' => 'Joe',
+ 'job' => 'Accountant',
+ 'age' => 38
+ )
+ )
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBlockMapping.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBlockMapping.yml
new file mode 100644
index 0000000..f7ca469
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsBlockMapping.yml
@@ -0,0 +1,51 @@
+---
+test: One Element Mapping
+brief: |
+ A mapping with one key/value pair
+yaml: |
+ foo: bar
+php: |
+ array('foo' => 'bar')
+---
+test: Multi Element Mapping
+brief: |
+ More than one key/value pair
+yaml: |
+ red: baron
+ white: walls
+ blue: berries
+php: |
+ array(
+ 'red' => 'baron',
+ 'white' => 'walls',
+ 'blue' => 'berries',
+ )
+---
+test: Values aligned
+brief: |
+ Often times human editors of documents will align the values even
+ though YAML emitters generally don't.
+yaml: |
+ red: baron
+ white: walls
+ blue: berries
+php: |
+ array(
+ 'red' => 'baron',
+ 'white' => 'walls',
+ 'blue' => 'berries',
+ )
+---
+test: Colons aligned
+brief: |
+ Spaces can come before the ': ' key/value separator.
+yaml: |
+ red : baron
+ white : walls
+ blue : berries
+php: |
+ array(
+ 'red' => 'baron',
+ 'white' => 'walls',
+ 'blue' => 'berries',
+ )
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsDocumentSeparator.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsDocumentSeparator.yml
new file mode 100644
index 0000000..f8501dd
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsDocumentSeparator.yml
@@ -0,0 +1,85 @@
+--- %YAML:1.0
+test: Trailing Document Separator
+todo: true
+brief: >
+ You can separate YAML documents
+ with a string of three dashes.
+yaml: |
+ - foo: 1
+ bar: 2
+ ---
+ more: stuff
+python: |
+ [
+ [ { 'foo': 1, 'bar': 2 } ],
+ { 'more': 'stuff' }
+ ]
+ruby: |
+ [ { 'foo' => 1, 'bar' => 2 } ]
+
+---
+test: Leading Document Separator
+todo: true
+brief: >
+ You can explicity give an opening
+ document separator to your YAML stream.
+yaml: |
+ ---
+ - foo: 1
+ bar: 2
+ ---
+ more: stuff
+python: |
+ [
+ [ {'foo': 1, 'bar': 2}],
+ {'more': 'stuff'}
+ ]
+ruby: |
+ [ { 'foo' => 1, 'bar' => 2 } ]
+
+---
+test: YAML Header
+todo: true
+brief: >
+ The opening separator can contain directives
+ to the YAML parser, such as the version
+ number.
+yaml: |
+ --- %YAML:1.0
+ foo: 1
+ bar: 2
+php: |
+ array('foo' => 1, 'bar' => 2)
+documents: 1
+
+---
+test: Red Herring Document Separator
+brief: >
+ Separators included in blocks or strings
+ are treated as blocks or strings, as the
+ document separator should have no indentation
+ preceding it.
+yaml: |
+ foo: |
+ ---
+php: |
+ array('foo' => "---\n")
+
+---
+test: Multiple Document Separators in Block
+brief: >
+ This technique allows you to embed other YAML
+ documents within literal blocks.
+yaml: |
+ foo: |
+ ---
+ foo: bar
+ ---
+ yo: baz
+ bar: |
+ fooness
+php: |
+ array(
+ 'foo' => "---\nfoo: bar\n---\nyo: baz\n",
+ 'bar' => "fooness\n"
+ )
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsErrorTests.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsErrorTests.yml
new file mode 100644
index 0000000..e8506fc
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsErrorTests.yml
@@ -0,0 +1,25 @@
+---
+test: Missing value for hash item
+todo: true
+brief: |
+ Third item in this hash doesn't have a value
+yaml: |
+ okay: value
+ also okay: ~
+ causes error because no value specified
+ last key: value okay here too
+python-error: causes error because no value specified
+
+---
+test: Not indenting enough
+brief: |
+ There was a bug in PyYaml where it was off by one
+ in the indentation check. It was allowing the YAML
+ below.
+# This is actually valid YAML now. Someone should tell showell.
+yaml: |
+ foo:
+ firstline: 1
+ secondline: 2
+php: |
+ array('foo' => null, 'firstline' => 1, 'secondline' => 2)
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsFlowCollections.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsFlowCollections.yml
new file mode 100644
index 0000000..03090e4
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsFlowCollections.yml
@@ -0,0 +1,60 @@
+---
+test: Simple Inline Array
+brief: >
+ Sequences can be contained on a
+ single line, using the inline syntax.
+ Separate each entry with commas and
+ enclose in square brackets.
+yaml: |
+ seq: [ a, b, c ]
+php: |
+ array('seq' => array('a', 'b', 'c'))
+---
+test: Simple Inline Hash
+brief: >
+ Mapping can also be contained on
+ a single line, using the inline
+ syntax. Each key-value pair is
+ separated by a colon, with a comma
+ between each entry in the mapping.
+ Enclose with curly braces.
+yaml: |
+ hash: { name: Steve, foo: bar }
+php: |
+ array('hash' => array('name' => 'Steve', 'foo' => 'bar'))
+---
+test: Multi-line Inline Collections
+todo: true
+brief: >
+ Both inline sequences and inline mappings
+ can span multiple lines, provided that you
+ indent the additional lines.
+yaml: |
+ languages: [ Ruby,
+ Perl,
+ Python ]
+ websites: { YAML: yaml.org,
+ Ruby: ruby-lang.org,
+ Python: python.org,
+ Perl: use.perl.org }
+php: |
+ array(
+ 'languages' => array('Ruby', 'Perl', 'Python'),
+ 'websites' => array(
+ 'YAML' => 'yaml.org',
+ 'Ruby' => 'ruby-lang.org',
+ 'Python' => 'python.org',
+ 'Perl' => 'use.perl.org'
+ )
+ )
+---
+test: Commas in Values (not in the spec!)
+todo: true
+brief: >
+ List items in collections are delimited by commas, but
+ there must be a space after each comma. This allows you
+ to add numbers without quoting.
+yaml: |
+ attendances: [ 45,123, 70,000, 17,222 ]
+php: |
+ array('attendances' => array(45123, 70000, 17222))
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsFoldedScalars.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsFoldedScalars.yml
new file mode 100644
index 0000000..a14735a
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsFoldedScalars.yml
@@ -0,0 +1,176 @@
+--- %YAML:1.0
+test: Single ending newline
+brief: >
+ A pipe character, followed by an indented
+ block of text is treated as a literal
+ block, in which newlines are preserved
+ throughout the block, including the final
+ newline.
+yaml: |
+ ---
+ this: |
+ Foo
+ Bar
+php: |
+ array('this' => "Foo\nBar\n")
+---
+test: The '+' indicator
+brief: >
+ The '+' indicator says to keep newlines at the end of text
+ blocks.
+yaml: |
+ normal: |
+ extra new lines not kept
+
+ preserving: |+
+ extra new lines are kept
+
+
+ dummy: value
+php: |
+ array(
+ 'normal' => "extra new lines not kept\n",
+ 'preserving' => "extra new lines are kept\n\n\n",
+ 'dummy' => 'value'
+ )
+---
+test: Three trailing newlines in literals
+brief: >
+ To give you more control over how space
+ is preserved in text blocks, YAML has
+ the keep '+' and chomp '-' indicators.
+ The keep indicator will preserve all
+ ending newlines, while the chomp indicator
+ will strip all ending newlines.
+yaml: |
+ clipped: |
+ This has one newline.
+
+
+
+ same as "clipped" above: "This has one newline.\n"
+
+ stripped: |-
+ This has no newline.
+
+
+
+ same as "stripped" above: "This has no newline."
+
+ kept: |+
+ This has four newlines.
+
+
+
+ same as "kept" above: "This has four newlines.\n\n\n\n"
+php: |
+ array(
+ 'clipped' => "This has one newline.\n",
+ 'same as "clipped" above' => "This has one newline.\n",
+ 'stripped' => 'This has no newline.',
+ 'same as "stripped" above' => 'This has no newline.',
+ 'kept' => "This has four newlines.\n\n\n\n",
+ 'same as "kept" above' => "This has four newlines.\n\n\n\n"
+ )
+---
+test: Extra trailing newlines with spaces
+todo: true
+brief: >
+ Normally, only a single newline is kept
+ from the end of a literal block, unless the
+ keep '+' character is used in combination
+ with the pipe. The following example
+ will preserve all ending whitespace
+ since the last line of both literal blocks
+ contains spaces which extend past the indentation
+ level.
+yaml: |
+ ---
+ this: |
+ Foo
+
+
+ kept: |+
+ Foo
+
+
+php: |
+ array('this' => "Foo\n\n \n",
+ 'kept' => "Foo\n\n \n" )
+
+---
+test: Folded Block in a Sequence
+brief: >
+ A greater-then character, followed by an indented
+ block of text is treated as a folded block, in
+ which lines of text separated by a single newline
+ are concatenated as a single line.
+yaml: |
+ ---
+ - apple
+ - banana
+ - >
+ can't you see
+ the beauty of yaml?
+ hmm
+ - dog
+php: |
+ array(
+ 'apple',
+ 'banana',
+ "can't you see the beauty of yaml? hmm\n",
+ 'dog'
+ )
+---
+test: Folded Block as a Mapping Value
+brief: >
+ Both literal and folded blocks can be
+ used in collections, as values in a
+ sequence or a mapping.
+yaml: |
+ ---
+ quote: >
+ Mark McGwire's
+ year was crippled
+ by a knee injury.
+ source: espn
+php: |
+ array(
+ 'quote' => "Mark McGwire's year was crippled by a knee injury.\n",
+ 'source' => 'espn'
+ )
+---
+test: Three trailing newlines in folded blocks
+brief: >
+ The keep and chomp indicators can also
+ be applied to folded blocks.
+yaml: |
+ clipped: >
+ This has one newline.
+
+
+
+ same as "clipped" above: "This has one newline.\n"
+
+ stripped: >-
+ This has no newline.
+
+
+
+ same as "stripped" above: "This has no newline."
+
+ kept: >+
+ This has four newlines.
+
+
+
+ same as "kept" above: "This has four newlines.\n\n\n\n"
+php: |
+ array(
+ 'clipped' => "This has one newline.\n",
+ 'same as "clipped" above' => "This has one newline.\n",
+ 'stripped' => 'This has no newline.',
+ 'same as "stripped" above' => 'This has no newline.',
+ 'kept' => "This has four newlines.\n\n\n\n",
+ 'same as "kept" above' => "This has four newlines.\n\n\n\n"
+ )
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsNullsAndEmpties.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsNullsAndEmpties.yml
new file mode 100644
index 0000000..9a5300f
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsNullsAndEmpties.yml
@@ -0,0 +1,45 @@
+--- %YAML:1.0
+test: Empty Sequence
+brief: >
+ You can represent the empty sequence
+ with an empty inline sequence.
+yaml: |
+ empty: []
+php: |
+ array('empty' => array())
+---
+test: Empty Mapping
+brief: >
+ You can represent the empty mapping
+ with an empty inline mapping.
+yaml: |
+ empty: {}
+php: |
+ array('empty' => array())
+---
+test: Empty Sequence as Entire Document
+yaml: |
+ []
+php: |
+ array()
+---
+test: Empty Mapping as Entire Document
+yaml: |
+ {}
+php: |
+ array()
+---
+test: Null as Document
+yaml: |
+ ~
+php: |
+ null
+---
+test: Empty String
+brief: >
+ You can represent an empty string
+ with a pair of quotes.
+yaml: |
+ ''
+php: |
+ ''
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml
new file mode 100644
index 0000000..0a8b5de
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml
@@ -0,0 +1,1697 @@
+--- %YAML:1.0
+test: Sequence of scalars
+spec: 2.1
+yaml: |
+ - Mark McGwire
+ - Sammy Sosa
+ - Ken Griffey
+php: |
+ array('Mark McGwire', 'Sammy Sosa', 'Ken Griffey')
+---
+test: Mapping of scalars to scalars
+spec: 2.2
+yaml: |
+ hr: 65
+ avg: 0.278
+ rbi: 147
+php: |
+ array('hr' => 65, 'avg' => 0.278, 'rbi' => 147)
+---
+test: Mapping of scalars to sequences
+spec: 2.3
+yaml: |
+ american:
+ - Boston Red Sox
+ - Detroit Tigers
+ - New York Yankees
+ national:
+ - New York Mets
+ - Chicago Cubs
+ - Atlanta Braves
+php: |
+ array('american' =>
+ array( 'Boston Red Sox', 'Detroit Tigers',
+ 'New York Yankees' ),
+ 'national' =>
+ array( 'New York Mets', 'Chicago Cubs',
+ 'Atlanta Braves' )
+ )
+---
+test: Sequence of mappings
+spec: 2.4
+yaml: |
+ -
+ name: Mark McGwire
+ hr: 65
+ avg: 0.278
+ -
+ name: Sammy Sosa
+ hr: 63
+ avg: 0.288
+php: |
+ array(
+ array('name' => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278),
+ array('name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288)
+ )
+---
+test: Legacy A5
+todo: true
+spec: legacy_A5
+yaml: |
+ ?
+ - New York Yankees
+ - Atlanta Braves
+ :
+ - 2001-07-02
+ - 2001-08-12
+ - 2001-08-14
+ ?
+ - Detroit Tigers
+ - Chicago Cubs
+ :
+ - 2001-07-23
+perl-busted: >
+ YAML.pm will be able to emulate this behavior soon. In this regard
+ it may be somewhat more correct than Python's native behaviour which
+ can only use tuples as mapping keys. PyYAML will also need to figure
+ out some clever way to roundtrip structured keys.
+python: |
+ [
+ {
+ ('New York Yankees', 'Atlanta Braves'):
+ [yaml.timestamp('2001-07-02'),
+ yaml.timestamp('2001-08-12'),
+ yaml.timestamp('2001-08-14')],
+ ('Detroit Tigers', 'Chicago Cubs'):
+ [yaml.timestamp('2001-07-23')]
+ }
+ ]
+ruby: |
+ {
+ [ 'New York Yankees', 'Atlanta Braves' ] =>
+ [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ],
+ [ 'Detroit Tigers', 'Chicago Cubs' ] =>
+ [ Date.new( 2001, 7, 23 ) ]
+ }
+syck: |
+ struct test_node seq1[] = {
+ { T_STR, 0, "New York Yankees" },
+ { T_STR, 0, "Atlanta Braves" },
+ end_node
+ };
+ struct test_node seq2[] = {
+ { T_STR, 0, "2001-07-02" },
+ { T_STR, 0, "2001-08-12" },
+ { T_STR, 0, "2001-08-14" },
+ end_node
+ };
+ struct test_node seq3[] = {
+ { T_STR, 0, "Detroit Tigers" },
+ { T_STR, 0, "Chicago Cubs" },
+ end_node
+ };
+ struct test_node seq4[] = {
+ { T_STR, 0, "2001-07-23" },
+ end_node
+ };
+ struct test_node map[] = {
+ { T_SEQ, 0, 0, seq1 },
+ { T_SEQ, 0, 0, seq2 },
+ { T_SEQ, 0, 0, seq3 },
+ { T_SEQ, 0, 0, seq4 },
+ end_node
+ };
+ struct test_node stream[] = {
+ { T_MAP, 0, 0, map },
+ end_node
+ };
+
+---
+test: Sequence of sequences
+spec: 2.5
+yaml: |
+ - [ name , hr , avg ]
+ - [ Mark McGwire , 65 , 0.278 ]
+ - [ Sammy Sosa , 63 , 0.288 ]
+php: |
+ array(
+ array( 'name', 'hr', 'avg' ),
+ array( 'Mark McGwire', 65, 0.278 ),
+ array( 'Sammy Sosa', 63, 0.288 )
+ )
+---
+test: Mapping of mappings
+todo: true
+spec: 2.6
+yaml: |
+ Mark McGwire: {hr: 65, avg: 0.278}
+ Sammy Sosa: {
+ hr: 63,
+ avg: 0.288
+ }
+php: |
+ array(
+ 'Mark McGwire' =>
+ array( 'hr' => 65, 'avg' => 0.278 ),
+ 'Sammy Sosa' =>
+ array( 'hr' => 63, 'avg' => 0.288 )
+ )
+---
+test: Two documents in a stream each with a leading comment
+todo: true
+spec: 2.7
+yaml: |
+ # Ranking of 1998 home runs
+ ---
+ - Mark McGwire
+ - Sammy Sosa
+ - Ken Griffey
+
+ # Team ranking
+ ---
+ - Chicago Cubs
+ - St Louis Cardinals
+ruby: |
+ y = YAML::Stream.new
+ y.add( [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] )
+ y.add( [ 'Chicago Cubs', 'St Louis Cardinals' ] )
+documents: 2
+
+---
+test: Play by play feed from a game
+todo: true
+spec: 2.8
+yaml: |
+ ---
+ time: 20:03:20
+ player: Sammy Sosa
+ action: strike (miss)
+ ...
+ ---
+ time: 20:03:47
+ player: Sammy Sosa
+ action: grand slam
+ ...
+perl: |
+ [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ]
+documents: 2
+
+---
+test: Single document with two comments
+spec: 2.9
+yaml: |
+ hr: # 1998 hr ranking
+ - Mark McGwire
+ - Sammy Sosa
+ rbi:
+ # 1998 rbi ranking
+ - Sammy Sosa
+ - Ken Griffey
+php: |
+ array(
+ 'hr' => array( 'Mark McGwire', 'Sammy Sosa' ),
+ 'rbi' => array( 'Sammy Sosa', 'Ken Griffey' )
+ )
+---
+test: Node for Sammy Sosa appears twice in this document
+spec: 2.10
+yaml: |
+ ---
+ hr:
+ - Mark McGwire
+ # Following node labeled SS
+ - &SS Sammy Sosa
+ rbi:
+ - *SS # Subsequent occurrence
+ - Ken Griffey
+php: |
+ array(
+ 'hr' =>
+ array('Mark McGwire', 'Sammy Sosa'),
+ 'rbi' =>
+ array('Sammy Sosa', 'Ken Griffey')
+ )
+---
+test: Mapping between sequences
+todo: true
+spec: 2.11
+yaml: |
+ ? # PLAY SCHEDULE
+ - Detroit Tigers
+ - Chicago Cubs
+ :
+ - 2001-07-23
+
+ ? [ New York Yankees,
+ Atlanta Braves ]
+ : [ 2001-07-02, 2001-08-12,
+ 2001-08-14 ]
+ruby: |
+ {
+ [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ],
+ [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ]
+ }
+syck: |
+ struct test_node seq1[] = {
+ { T_STR, 0, "New York Yankees" },
+ { T_STR, 0, "Atlanta Braves" },
+ end_node
+ };
+ struct test_node seq2[] = {
+ { T_STR, 0, "2001-07-02" },
+ { T_STR, 0, "2001-08-12" },
+ { T_STR, 0, "2001-08-14" },
+ end_node
+ };
+ struct test_node seq3[] = {
+ { T_STR, 0, "Detroit Tigers" },
+ { T_STR, 0, "Chicago Cubs" },
+ end_node
+ };
+ struct test_node seq4[] = {
+ { T_STR, 0, "2001-07-23" },
+ end_node
+ };
+ struct test_node map[] = {
+ { T_SEQ, 0, 0, seq3 },
+ { T_SEQ, 0, 0, seq4 },
+ { T_SEQ, 0, 0, seq1 },
+ { T_SEQ, 0, 0, seq2 },
+ end_node
+ };
+ struct test_node stream[] = {
+ { T_MAP, 0, 0, map },
+ end_node
+ };
+
+---
+test: Sequence key shortcut
+spec: 2.12
+yaml: |
+ ---
+ # products purchased
+ - item : Super Hoop
+ quantity: 1
+ - item : Basketball
+ quantity: 4
+ - item : Big Shoes
+ quantity: 1
+php: |
+ array (
+ array (
+ 'item' => 'Super Hoop',
+ 'quantity' => 1,
+ ),
+ array (
+ 'item' => 'Basketball',
+ 'quantity' => 4,
+ ),
+ array (
+ 'item' => 'Big Shoes',
+ 'quantity' => 1,
+ )
+ )
+perl: |
+ [
+ { item => 'Super Hoop', quantity => 1 },
+ { item => 'Basketball', quantity => 4 },
+ { item => 'Big Shoes', quantity => 1 }
+ ]
+
+ruby: |
+ [
+ { 'item' => 'Super Hoop', 'quantity' => 1 },
+ { 'item' => 'Basketball', 'quantity' => 4 },
+ { 'item' => 'Big Shoes', 'quantity' => 1 }
+ ]
+python: |
+ [
+ { 'item': 'Super Hoop', 'quantity': 1 },
+ { 'item': 'Basketball', 'quantity': 4 },
+ { 'item': 'Big Shoes', 'quantity': 1 }
+ ]
+syck: |
+ struct test_node map1[] = {
+ { T_STR, 0, "item" },
+ { T_STR, 0, "Super Hoop" },
+ { T_STR, 0, "quantity" },
+ { T_STR, 0, "1" },
+ end_node
+ };
+ struct test_node map2[] = {
+ { T_STR, 0, "item" },
+ { T_STR, 0, "Basketball" },
+ { T_STR, 0, "quantity" },
+ { T_STR, 0, "4" },
+ end_node
+ };
+ struct test_node map3[] = {
+ { T_STR, 0, "item" },
+ { T_STR, 0, "Big Shoes" },
+ { T_STR, 0, "quantity" },
+ { T_STR, 0, "1" },
+ end_node
+ };
+ struct test_node seq[] = {
+ { T_MAP, 0, 0, map1 },
+ { T_MAP, 0, 0, map2 },
+ { T_MAP, 0, 0, map3 },
+ end_node
+ };
+ struct test_node stream[] = {
+ { T_SEQ, 0, 0, seq },
+ end_node
+ };
+
+
+---
+test: Literal perserves newlines
+todo: true
+spec: 2.13
+yaml: |
+ # ASCII Art
+ --- |
+ \//||\/||
+ // || ||_
+perl: |
+ "\\//||\\/||\n// || ||_\n"
+ruby: |
+ "\\//||\\/||\n// || ||_\n"
+python: |
+ [
+ flushLeft(
+ """
+ \//||\/||
+ // || ||_
+ """
+ )
+ ]
+syck: |
+ struct test_node stream[] = {
+ { T_STR, 0, "\\//||\\/||\n// || ||_\n" },
+ end_node
+ };
+
+---
+test: Folded treats newlines as a space
+todo: true
+spec: 2.14
+yaml: |
+ ---
+ Mark McGwire's
+ year was crippled
+ by a knee injury.
+perl: |
+ "Mark McGwire's year was crippled by a knee injury."
+ruby: |
+ "Mark McGwire's year was crippled by a knee injury."
+python: |
+ [ "Mark McGwire's year was crippled by a knee injury." ]
+syck: |
+ struct test_node stream[] = {
+ { T_STR, 0, "Mark McGwire's year was crippled by a knee injury." },
+ end_node
+ };
+
+---
+test: Newlines preserved for indented and blank lines
+todo: true
+spec: 2.15
+yaml: |
+ --- >
+ Sammy Sosa completed another
+ fine season with great stats.
+
+ 63 Home Runs
+ 0.288 Batting Average
+
+ What a year!
+perl: |
+ "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n"
+ruby: |
+ "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n"
+python: |
+ [
+ flushLeft(
+ """
+ Sammy Sosa completed another fine season with great stats.
+
+ 63 Home Runs
+ 0.288 Batting Average
+
+ What a year!
+ """
+ )
+ ]
+syck: |
+ struct test_node stream[] = {
+ { T_STR, 0, "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" },
+ end_node
+ };
+
+
+---
+test: Indentation determines scope
+spec: 2.16
+yaml: |
+ name: Mark McGwire
+ accomplishment: >
+ Mark set a major league
+ home run record in 1998.
+ stats: |
+ 65 Home Runs
+ 0.278 Batting Average
+php: |
+ array(
+ 'name' => 'Mark McGwire',
+ 'accomplishment' => "Mark set a major league home run record in 1998.\n",
+ 'stats' => "65 Home Runs\n0.278 Batting Average\n"
+ )
+---
+test: Quoted scalars
+todo: true
+spec: 2.17
+yaml: |
+ unicode: "Sosa did fine.\u263A"
+ control: "\b1998\t1999\t2000\n"
+ hexesc: "\x0D\x0A is \r\n"
+
+ single: '"Howdy!" he cried.'
+ quoted: ' # not a ''comment''.'
+ tie-fighter: '|\-*-/|'
+ruby: |
+ {
+ "tie-fighter" => "|\\-*-/|",
+ "control"=>"\0101998\t1999\t2000\n",
+ "unicode"=>"Sosa did fine." + ["263A".hex ].pack('U*'),
+ "quoted"=>" # not a 'comment'.",
+ "single"=>"\"Howdy!\" he cried.",
+ "hexesc"=>"\r\n is \r\n"
+ }
+---
+test: Multiline flow scalars
+todo: true
+spec: 2.18
+yaml: |
+ plain:
+ This unquoted scalar
+ spans many lines.
+
+ quoted: "So does this
+ quoted scalar.\n"
+ruby: |
+ {
+ 'plain' => 'This unquoted scalar spans many lines.',
+ 'quoted' => "So does this quoted scalar.\n"
+ }
+---
+test: Integers
+spec: 2.19
+yaml: |
+ canonical: 12345
+ decimal: +12,345
+ octal: 014
+ hexadecimal: 0xC
+php: |
+ array(
+ 'canonical' => 12345,
+ 'decimal' => 12345,
+ 'octal' => 014,
+ 'hexadecimal' => 0xC
+ )
+---
+# FIX: spec shows parens around -inf and NaN
+test: Floating point
+spec: 2.20
+yaml: |
+ canonical: 1.23015e+3
+ exponential: 12.3015e+02
+ fixed: 1,230.15
+ negative infinity: -.inf
+ not a number: .NaN
+ float as whole number: !!float 1
+php: |
+ array(
+ 'canonical' => 1230.15,
+ 'exponential' => 1230.15,
+ 'fixed' => 1230.15,
+ 'negative infinity' => log(0),
+ 'not a number' => -log(0),
+ 'float as whole number' => (float) 1
+ )
+---
+test: Miscellaneous
+spec: 2.21
+yaml: |
+ null: ~
+ true: true
+ false: false
+ string: '12345'
+php: |
+ array(
+ '' => null,
+ 1 => true,
+ 0 => false,
+ 'string' => '12345'
+ )
+---
+test: Timestamps
+todo: true
+spec: 2.22
+yaml: |
+ canonical: 2001-12-15T02:59:43.1Z
+ iso8601: 2001-12-14t21:59:43.10-05:00
+ spaced: 2001-12-14 21:59:43.10 -05:00
+ date: 2002-12-14 # Time is noon UTC
+php: |
+ array(
+ 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ),
+ 'iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'date' => Date.new( 2002, 12, 14 )
+ )
+---
+test: legacy Timestamps test
+todo: true
+spec: legacy D4
+yaml: |
+ canonical: 2001-12-15T02:59:43.00Z
+ iso8601: 2001-02-28t21:59:43.00-05:00
+ spaced: 2001-12-14 21:59:43.00 -05:00
+ date: 2002-12-14
+php: |
+ array(
+ 'canonical' => Time::utc( 2001, 12, 15, 2, 59, 43, 0 ),
+ 'iso8601' => YAML::mktime( 2001, 2, 28, 21, 59, 43, 0, "-05:00" ),
+ 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0, "-05:00" ),
+ 'date' => Date.new( 2002, 12, 14 )
+ )
+---
+test: Various explicit families
+todo: true
+spec: 2.23
+yaml: |
+ not-date: !str 2002-04-28
+ picture: !binary |
+ R0lGODlhDAAMAIQAAP//9/X
+ 17unp5WZmZgAAAOfn515eXv
+ Pz7Y6OjuDg4J+fn5OTk6enp
+ 56enmleECcgggoBADs=
+
+ application specific tag: !!something |
+ The semantics of the tag
+ above may be different for
+ different documents.
+
+ruby-setup: |
+ YAML.add_private_type( "something" ) do |type, val|
+ "SOMETHING: #{val}"
+ end
+ruby: |
+ {
+ 'not-date' => '2002-04-28',
+ 'picture' => "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236i^\020' \202\n\001\000;",
+ 'application specific tag' => "SOMETHING: The semantics of the tag\nabove may be different for\ndifferent documents.\n"
+ }
+---
+test: Application specific family
+todo: true
+spec: 2.24
+yaml: |
+ # Establish a tag prefix
+ --- !clarkevans.com,2002/graph/^shape
+ # Use the prefix: shorthand for
+ # !clarkevans.com,2002/graph/circle
+ - !^circle
+ center: &ORIGIN {x: 73, 'y': 129}
+ radius: 7
+ - !^line # !clarkevans.com,2002/graph/line
+ start: *ORIGIN
+ finish: { x: 89, 'y': 102 }
+ - !^label
+ start: *ORIGIN
+ color: 0xFFEEBB
+ value: Pretty vector drawing.
+ruby-setup: |
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/shape' ) { |type, val|
+ if Array === val
+ val << "Shape Container"
+ val
+ else
+ raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect
+ end
+ }
+ one_shape_proc = Proc.new { |type, val|
+ scheme, domain, type = type.split( /:/, 3 )
+ if val.is_a? ::Hash
+ val['TYPE'] = "Shape: #{type}"
+ val
+ else
+ raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect
+ end
+ }
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/circle', &one_shape_proc )
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/line', &one_shape_proc )
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/label', &one_shape_proc )
+ruby: |
+ [
+ {
+ "radius" => 7,
+ "center"=>
+ {
+ "x" => 73,
+ "y" => 129
+ },
+ "TYPE" => "Shape: graph/circle"
+ }, {
+ "finish" =>
+ {
+ "x" => 89,
+ "y" => 102
+ },
+ "TYPE" => "Shape: graph/line",
+ "start" =>
+ {
+ "x" => 73,
+ "y" => 129
+ }
+ }, {
+ "TYPE" => "Shape: graph/label",
+ "value" => "Pretty vector drawing.",
+ "start" =>
+ {
+ "x" => 73,
+ "y" => 129
+ },
+ "color" => 16772795
+ },
+ "Shape Container"
+ ]
+# ---
+# test: Unordered set
+# spec: 2.25
+# yaml: |
+# # sets are represented as a
+# # mapping where each key is
+# # associated with the empty string
+# --- !set
+# ? Mark McGwire
+# ? Sammy Sosa
+# ? Ken Griff
+---
+test: Ordered mappings
+todo: true
+spec: 2.26
+yaml: |
+ # ordered maps are represented as
+ # a sequence of mappings, with
+ # each mapping having one key
+ --- !omap
+ - Mark McGwire: 65
+ - Sammy Sosa: 63
+ - Ken Griffy: 58
+ruby: |
+ YAML::Omap[
+ 'Mark McGwire', 65,
+ 'Sammy Sosa', 63,
+ 'Ken Griffy', 58
+ ]
+---
+test: Invoice
+dump_skip: true
+spec: 2.27
+yaml: |
+ --- !clarkevans.com,2002/^invoice
+ invoice: 34843
+ date : 2001-01-23
+ bill-to: &id001
+ given : Chris
+ family : Dumars
+ address:
+ lines: |
+ 458 Walkman Dr.
+ Suite #292
+ city : Royal Oak
+ state : MI
+ postal : 48046
+ ship-to: *id001
+ product:
+ -
+ sku : BL394D
+ quantity : 4
+ description : Basketball
+ price : 450.00
+ -
+ sku : BL4438H
+ quantity : 1
+ description : Super Hoop
+ price : 2392.00
+ tax : 251.42
+ total: 4443.52
+ comments: >
+ Late afternoon is best.
+ Backup contact is Nancy
+ Billsmer @ 338-4338.
+php: |
+ array(
+ 'invoice' => 34843, 'date' => mktime(0, 0, 0, 1, 23, 2001),
+ 'bill-to' =>
+ array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) )
+ , 'ship-to' =>
+ array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) )
+ , 'product' =>
+ array(
+ array( 'sku' => 'BL394D', 'quantity' => 4, 'description' => 'Basketball', 'price' => 450.00 ),
+ array( 'sku' => 'BL4438H', 'quantity' => 1, 'description' => 'Super Hoop', 'price' => 2392.00 )
+ ),
+ 'tax' => 251.42, 'total' => 4443.52,
+ 'comments' => "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n"
+ )
+---
+test: Log file
+todo: true
+spec: 2.28
+yaml: |
+ ---
+ Time: 2001-11-23 15:01:42 -05:00
+ User: ed
+ Warning: >
+ This is an error message
+ for the log file
+ ---
+ Time: 2001-11-23 15:02:31 -05:00
+ User: ed
+ Warning: >
+ A slightly different error
+ message.
+ ---
+ Date: 2001-11-23 15:03:17 -05:00
+ User: ed
+ Fatal: >
+ Unknown variable "bar"
+ Stack:
+ - file: TopClass.py
+ line: 23
+ code: |
+ x = MoreObject("345\n")
+ - file: MoreClass.py
+ line: 58
+ code: |-
+ foo = bar
+ruby: |
+ y = YAML::Stream.new
+ y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 01, 42, 00, "-05:00" ),
+ 'User' => 'ed', 'Warning' => "This is an error message for the log file\n" } )
+ y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 02, 31, 00, "-05:00" ),
+ 'User' => 'ed', 'Warning' => "A slightly different error message.\n" } )
+ y.add( { 'Date' => YAML::mktime( 2001, 11, 23, 15, 03, 17, 00, "-05:00" ),
+ 'User' => 'ed', 'Fatal' => "Unknown variable \"bar\"\n",
+ 'Stack' => [
+ { 'file' => 'TopClass.py', 'line' => 23, 'code' => "x = MoreObject(\"345\\n\")\n" },
+ { 'file' => 'MoreClass.py', 'line' => 58, 'code' => "foo = bar" } ] } )
+documents: 3
+
+---
+test: Throwaway comments
+yaml: |
+ ### These are four throwaway comment ###
+
+ ### lines (the second line is empty). ###
+ this: | # Comments may trail lines.
+ contains three lines of text.
+ The third one starts with a
+ # character. This isn't a comment.
+
+ # These are three throwaway comment
+ # lines (the first line is empty).
+php: |
+ array(
+ 'this' => "contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n"
+ )
+---
+test: Document with a single value
+todo: true
+yaml: |
+ --- >
+ This YAML stream contains a single text value.
+ The next stream is a log file - a sequence of
+ log entries. Adding an entry to the log is a
+ simple matter of appending it at the end.
+ruby: |
+ "This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\n"
+---
+test: Document stream
+todo: true
+yaml: |
+ ---
+ at: 2001-08-12 09:25:00.00 Z
+ type: GET
+ HTTP: '1.0'
+ url: '/index.html'
+ ---
+ at: 2001-08-12 09:25:10.00 Z
+ type: GET
+ HTTP: '1.0'
+ url: '/toc.html'
+ruby: |
+ y = YAML::Stream.new
+ y.add( {
+ 'at' => Time::utc( 2001, 8, 12, 9, 25, 00 ),
+ 'type' => 'GET',
+ 'HTTP' => '1.0',
+ 'url' => '/index.html'
+ } )
+ y.add( {
+ 'at' => Time::utc( 2001, 8, 12, 9, 25, 10 ),
+ 'type' => 'GET',
+ 'HTTP' => '1.0',
+ 'url' => '/toc.html'
+ } )
+documents: 2
+
+---
+test: Top level mapping
+yaml: |
+ # This stream is an example of a top-level mapping.
+ invoice : 34843
+ date : 2001-01-23
+ total : 4443.52
+php: |
+ array(
+ 'invoice' => 34843,
+ 'date' => mktime(0, 0, 0, 1, 23, 2001),
+ 'total' => 4443.52
+ )
+---
+test: Single-line documents
+todo: true
+yaml: |
+ # The following is a sequence of three documents.
+ # The first contains an empty mapping, the second
+ # an empty sequence, and the last an empty string.
+ --- {}
+ --- [ ]
+ --- ''
+ruby: |
+ y = YAML::Stream.new
+ y.add( {} )
+ y.add( [] )
+ y.add( '' )
+documents: 3
+
+---
+test: Document with pause
+todo: true
+yaml: |
+ # A communication channel based on a YAML stream.
+ ---
+ sent at: 2002-06-06 11:46:25.10 Z
+ payload: Whatever
+ # Receiver can process this as soon as the following is sent:
+ ...
+ # Even if the next message is sent long after:
+ ---
+ sent at: 2002-06-06 12:05:53.47 Z
+ payload: Whatever
+ ...
+ruby: |
+ y = YAML::Stream.new
+ y.add(
+ { 'sent at' => YAML::mktime( 2002, 6, 6, 11, 46, 25, 0.10 ),
+ 'payload' => 'Whatever' }
+ )
+ y.add(
+ { "payload" => "Whatever", "sent at" => YAML::mktime( 2002, 6, 6, 12, 5, 53, 0.47 ) }
+ )
+documents: 2
+
+---
+test: Explicit typing
+yaml: |
+ integer: 12
+ also int: ! "12"
+ string: !str 12
+php: |
+ array( 'integer' => 12, 'also int' => 12, 'string' => '12' )
+---
+test: Private types
+todo: true
+yaml: |
+ # Both examples below make use of the 'x-private:ball'
+ # type family URI, but with different semantics.
+ ---
+ pool: !!ball
+ number: 8
+ color: black
+ ---
+ bearing: !!ball
+ material: steel
+ruby: |
+ y = YAML::Stream.new
+ y.add( { 'pool' =>
+ YAML::PrivateType.new( 'ball',
+ { 'number' => 8, 'color' => 'black' } ) }
+ )
+ y.add( { 'bearing' =>
+ YAML::PrivateType.new( 'ball',
+ { 'material' => 'steel' } ) }
+ )
+documents: 2
+
+---
+test: Type family under yaml.org
+yaml: |
+ # The URI is 'tag:yaml.org,2002:str'
+ - !str a Unicode string
+php: |
+ array( 'a Unicode string' )
+---
+test: Type family under perl.yaml.org
+todo: true
+yaml: |
+ # The URI is 'tag:perl.yaml.org,2002:Text::Tabs'
+ - !perl/Text::Tabs {}
+ruby: |
+ [ YAML::DomainType.new( 'perl.yaml.org,2002', 'Text::Tabs', {} ) ]
+---
+test: Type family under clarkevans.com
+todo: true
+yaml: |
+ # The URI is 'tag:clarkevans.com,2003-02:timesheet'
+ - !clarkevans.com,2003-02/timesheet {}
+ruby: |
+ [ YAML::DomainType.new( 'clarkevans.com,2003-02', 'timesheet', {} ) ]
+---
+test: URI Escaping
+todo: true
+yaml: |
+ same:
+ - !domain.tld,2002/type\x30 value
+ - !domain.tld,2002/type0 value
+ different: # As far as the YAML parser is concerned
+ - !domain.tld,2002/type%30 value
+ - !domain.tld,2002/type0 value
+ruby-setup: |
+ YAML.add_domain_type( "domain.tld,2002", "type0" ) { |type, val|
+ "ONE: #{val}"
+ }
+ YAML.add_domain_type( "domain.tld,2002", "type%30" ) { |type, val|
+ "TWO: #{val}"
+ }
+ruby: |
+ { 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value', 'ONE: value' ] }
+---
+test: URI Prefixing
+todo: true
+yaml: |
+ # 'tag:domain.tld,2002:invoice' is some type family.
+ invoice: !domain.tld,2002/^invoice
+ # 'seq' is shorthand for 'tag:yaml.org,2002:seq'.
+ # This does not effect '^customer' below
+ # because it is does not specify a prefix.
+ customers: !seq
+ # '^customer' is shorthand for the full
+ # notation 'tag:domain.tld,2002:customer'.
+ - !^customer
+ given : Chris
+ family : Dumars
+ruby-setup: |
+ YAML.add_domain_type( "domain.tld,2002", /(invoice|customer)/ ) { |type, val|
+ if val.is_a? ::Hash
+ scheme, domain, type = type.split( /:/, 3 )
+ val['type'] = "domain #{type}"
+ val
+ else
+ raise YAML::Error, "Not a Hash in domain.tld/invoice: " + val.inspect
+ end
+ }
+ruby: |
+ { "invoice"=> { "customers"=> [ { "given"=>"Chris", "type"=>"domain customer", "family"=>"Dumars" } ], "type"=>"domain invoice" } }
+
+---
+test: Overriding anchors
+yaml: |
+ anchor : &A001 This scalar has an anchor.
+ override : &A001 >
+ The alias node below is a
+ repeated use of this value.
+ alias : *A001
+php: |
+ array( 'anchor' => 'This scalar has an anchor.',
+ 'override' => "The alias node below is a repeated use of this value.\n",
+ 'alias' => "The alias node below is a repeated use of this value.\n" )
+---
+test: Flow and block formatting
+todo: true
+yaml: |
+ empty: []
+ flow: [ one, two, three # May span lines,
+ , four, # indentation is
+ five ] # mostly ignored.
+ block:
+ - First item in top sequence
+ -
+ - Subordinate sequence entry
+ - >
+ A folded sequence entry
+ - Sixth item in top sequence
+ruby: |
+ { 'empty' => [], 'flow' => [ 'one', 'two', 'three', 'four', 'five' ],
+ 'block' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ],
+ "A folded sequence entry\n", 'Sixth item in top sequence' ] }
+---
+test: Complete mapping test
+todo: true
+yaml: |
+ empty: {}
+ flow: { one: 1, two: 2 }
+ spanning: { one: 1,
+ two: 2 }
+ block:
+ first : First entry
+ second:
+ key: Subordinate mapping
+ third:
+ - Subordinate sequence
+ - { }
+ - Previous mapping is empty.
+ - A key: value pair in a sequence.
+ A second: key:value pair.
+ - The previous entry is equal to the following one.
+ -
+ A key: value pair in a sequence.
+ A second: key:value pair.
+ !float 12 : This key is a float.
+ ? >
+ ?
+ : This key had to be protected.
+ "\a" : This key had to be escaped.
+ ? >
+ This is a
+ multi-line
+ folded key
+ : Whose value is
+ also multi-line.
+ ? this also works as a key
+ : with a value at the next line.
+ ?
+ - This key
+ - is a sequence
+ :
+ - With a sequence value.
+ ?
+ This: key
+ is a: mapping
+ :
+ with a: mapping value.
+ruby: |
+ { 'empty' => {}, 'flow' => { 'one' => 1, 'two' => 2 },
+ 'spanning' => { 'one' => 1, 'two' => 2 },
+ 'block' => { 'first' => 'First entry', 'second' =>
+ { 'key' => 'Subordinate mapping' }, 'third' =>
+ [ 'Subordinate sequence', {}, 'Previous mapping is empty.',
+ { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' },
+ 'The previous entry is equal to the following one.',
+ { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ],
+ 12.0 => 'This key is a float.', "?\n" => 'This key had to be protected.',
+ "\a" => 'This key had to be escaped.',
+ "This is a multi-line folded key\n" => "Whose value is also multi-line.",
+ 'this also works as a key' => 'with a value at the next line.',
+ [ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } }
+ # Couldn't recreate map exactly, so we'll do a detailed check to be sure it's entact
+ obj_y['block'].keys.each { |k|
+ if Hash === k
+ v = obj_y['block'][k]
+ if k['This'] == 'key' and k['is a'] == 'mapping' and v['with a'] == 'mapping value.'
+ obj_r['block'][k] = v
+ end
+ end
+ }
+---
+test: Literal explicit indentation
+yaml: |
+ # Explicit indentation must
+ # be given in all the three
+ # following cases.
+ leading spaces: |2
+ This value starts with four spaces.
+
+ leading line break: |2
+
+ This value starts with a line break.
+
+ leading comment indicator: |2
+ # first line starts with a
+ # character.
+
+ # Explicit indentation may
+ # also be given when it is
+ # not required.
+ redundant: |2
+ This value is indented 2 spaces.
+php: |
+ array(
+ 'leading spaces' => " This value starts with four spaces.\n",
+ 'leading line break' => "\nThis value starts with a line break.\n",
+ 'leading comment indicator' => "# first line starts with a\n# character.\n",
+ 'redundant' => "This value is indented 2 spaces.\n"
+ )
+---
+test: Chomping and keep modifiers
+yaml: |
+ clipped: |
+ This has one newline.
+
+ same as "clipped" above: "This has one newline.\n"
+
+ stripped: |-
+ This has no newline.
+
+ same as "stripped" above: "This has no newline."
+
+ kept: |+
+ This has two newlines.
+
+ same as "kept" above: "This has two newlines.\n\n"
+php: |
+ array(
+ 'clipped' => "This has one newline.\n",
+ 'same as "clipped" above' => "This has one newline.\n",
+ 'stripped' => 'This has no newline.',
+ 'same as "stripped" above' => 'This has no newline.',
+ 'kept' => "This has two newlines.\n\n",
+ 'same as "kept" above' => "This has two newlines.\n\n"
+ )
+---
+test: Literal combinations
+todo: true
+yaml: |
+ empty: |
+
+ literal: |
+ The \ ' " characters may be
+ freely used. Leading white
+ space is significant.
+
+ Line breaks are significant.
+ Thus this value contains one
+ empty line and ends with a
+ single line break, but does
+ not start with one.
+
+ is equal to: "The \\ ' \" characters may \
+ be\nfreely used. Leading white\n space \
+ is significant.\n\nLine breaks are \
+ significant.\nThus this value contains \
+ one\nempty line and ends with a\nsingle \
+ line break, but does\nnot start with one.\n"
+
+ # Comments may follow a block
+ # scalar value. They must be
+ # less indented.
+
+ # Modifiers may be combined in any order.
+ indented and chomped: |2-
+ This has no newline.
+
+ also written as: |-2
+ This has no newline.
+
+ both are equal to: " This has no newline."
+php: |
+ array(
+ 'empty' => '',
+ 'literal' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " +
+ "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" +
+ "empty line and ends with a\nsingle line break, but does\nnot start with one.\n",
+ 'is equal to' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " +
+ "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" +
+ "empty line and ends with a\nsingle line break, but does\nnot start with one.\n",
+ 'indented and chomped' => ' This has no newline.',
+ 'also written as' => ' This has no newline.',
+ 'both are equal to' => ' This has no newline.'
+ )
+---
+test: Folded combinations
+todo: true
+yaml: |
+ empty: >
+
+ one paragraph: >
+ Line feeds are converted
+ to spaces, so this value
+ contains no line breaks
+ except for the final one.
+
+ multiple paragraphs: >2
+
+ An empty line, either
+ at the start or in
+ the value:
+
+ Is interpreted as a
+ line break. Thus this
+ value contains three
+ line breaks.
+
+ indented text: >
+ This is a folded
+ paragraph followed
+ by a list:
+ * first entry
+ * second entry
+ Followed by another
+ folded paragraph,
+ another list:
+
+ * first entry
+
+ * second entry
+
+ And a final folded
+ paragraph.
+
+ above is equal to: |
+ This is a folded paragraph followed by a list:
+ * first entry
+ * second entry
+ Followed by another folded paragraph, another list:
+
+ * first entry
+
+ * second entry
+
+ And a final folded paragraph.
+
+ # Explicit comments may follow
+ # but must be less indented.
+php: |
+ array(
+ 'empty' => '',
+ 'one paragraph' => 'Line feeds are converted to spaces, so this value'.
+ " contains no line breaks except for the final one.\n",
+ 'multiple paragraphs' => "\nAn empty line, either at the start or in the value:\n".
+ "Is interpreted as a line break. Thus this value contains three line breaks.\n",
+ 'indented text' => "This is a folded paragraph followed by a list:\n".
+ " * first entry\n * second entry\nFollowed by another folded paragraph, ".
+ "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n",
+ 'above is equal to' => "This is a folded paragraph followed by a list:\n".
+ " * first entry\n * second entry\nFollowed by another folded paragraph, ".
+ "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n"
+ )
+---
+test: Single quotes
+todo: true
+yaml: |
+ empty: ''
+ second: '! : \ etc. can be used freely.'
+ third: 'a single quote '' must be escaped.'
+ span: 'this contains
+ six spaces
+
+ and one
+ line break'
+ is same as: "this contains six spaces\nand one line break"
+php: |
+ array(
+ 'empty' => '',
+ 'second' => '! : \\ etc. can be used freely.',
+ 'third' => "a single quote ' must be escaped.",
+ 'span' => "this contains six spaces\nand one line break",
+ 'is same as' => "this contains six spaces\nand one line break"
+ )
+---
+test: Double quotes
+todo: true
+yaml: |
+ empty: ""
+ second: "! : etc. can be used freely."
+ third: "a \" or a \\ must be escaped."
+ fourth: "this value ends with an LF.\n"
+ span: "this contains
+ four \
+ spaces"
+ is equal to: "this contains four spaces"
+php: |
+ array(
+ 'empty' => '',
+ 'second' => '! : etc. can be used freely.',
+ 'third' => 'a " or a \\ must be escaped.',
+ 'fourth' => "this value ends with an LF.\n",
+ 'span' => "this contains four spaces",
+ 'is equal to' => "this contains four spaces"
+ )
+---
+test: Unquoted strings
+todo: true
+yaml: |
+ first: There is no unquoted empty string.
+
+ second: 12 ## This is an integer.
+
+ third: !str 12 ## This is a string.
+
+ span: this contains
+ six spaces
+
+ and one
+ line break
+
+ indicators: this has no comments.
+ #:foo and bar# are
+ both text.
+
+ flow: [ can span
+ lines, # comment
+ like
+ this ]
+
+ note: { one-line keys: but multi-line values }
+
+php: |
+ array(
+ 'first' => 'There is no unquoted empty string.',
+ 'second' => 12,
+ 'third' => '12',
+ 'span' => "this contains six spaces\nand one line break",
+ 'indicators' => "this has no comments. #:foo and bar# are both text.",
+ 'flow' => [ 'can span lines', 'like this' ],
+ 'note' => { 'one-line keys' => 'but multi-line values' }
+ )
+---
+test: Spanning sequences
+todo: true
+yaml: |
+ # The following are equal seqs
+ # with different identities.
+ flow: [ one, two ]
+ spanning: [ one,
+ two ]
+ block:
+ - one
+ - two
+php: |
+ array(
+ 'flow' => [ 'one', 'two' ],
+ 'spanning' => [ 'one', 'two' ],
+ 'block' => [ 'one', 'two' ]
+ )
+---
+test: Flow mappings
+yaml: |
+ # The following are equal maps
+ # with different identities.
+ flow: { one: 1, two: 2 }
+ block:
+ one: 1
+ two: 2
+php: |
+ array(
+ 'flow' => array( 'one' => 1, 'two' => 2 ),
+ 'block' => array( 'one' => 1, 'two' => 2 )
+ )
+---
+test: Representations of 12
+todo: true
+yaml: |
+ - 12 # An integer
+ # The following scalars
+ # are loaded to the
+ # string value '1' '2'.
+ - !str 12
+ - '12'
+ - "12"
+ - "\
+ 1\
+ 2\
+ "
+ # Strings containing paths and regexps can be unquoted:
+ - /foo/bar
+ - d:/foo/bar
+ - foo/bar
+ - /a.*b/
+php: |
+ array( 12, '12', '12', '12', '12', '/foo/bar', 'd:/foo/bar', 'foo/bar', '/a.*b/' )
+---
+test: "Null"
+todo: true
+yaml: |
+ canonical: ~
+
+ english: null
+
+ # This sequence has five
+ # entries, two with values.
+ sparse:
+ - ~
+ - 2nd entry
+ - Null
+ - 4th entry
+ -
+
+ four: This mapping has five keys,
+ only two with values.
+
+php: |
+ array (
+ 'canonical' => null,
+ 'english' => null,
+ 'sparse' => array( null, '2nd entry', null, '4th entry', null ]),
+ 'four' => 'This mapping has five keys, only two with values.'
+ )
+---
+test: Omap
+todo: true
+yaml: |
+ # Explicitly typed dictionary.
+ Bestiary: !omap
+ - aardvark: African pig-like ant eater. Ugly.
+ - anteater: South-American ant eater. Two species.
+ - anaconda: South-American constrictor snake. Scary.
+ # Etc.
+ruby: |
+ {
+ 'Bestiary' => YAML::Omap[
+ 'aardvark', 'African pig-like ant eater. Ugly.',
+ 'anteater', 'South-American ant eater. Two species.',
+ 'anaconda', 'South-American constrictor snake. Scary.'
+ ]
+ }
+
+---
+test: Pairs
+todo: true
+yaml: |
+ # Explicitly typed pairs.
+ tasks: !pairs
+ - meeting: with team.
+ - meeting: with boss.
+ - break: lunch.
+ - meeting: with client.
+ruby: |
+ {
+ 'tasks' => YAML::Pairs[
+ 'meeting', 'with team.',
+ 'meeting', 'with boss.',
+ 'break', 'lunch.',
+ 'meeting', 'with client.'
+ ]
+ }
+
+---
+test: Set
+todo: true
+yaml: |
+ # Explicitly typed set.
+ baseball players: !set
+ Mark McGwire:
+ Sammy Sosa:
+ Ken Griffey:
+ruby: |
+ {
+ 'baseball players' => YAML::Set[
+ 'Mark McGwire', nil,
+ 'Sammy Sosa', nil,
+ 'Ken Griffey', nil
+ ]
+ }
+
+---
+test: Boolean
+yaml: |
+ false: used as key
+ logical: true
+ answer: false
+php: |
+ array(
+ false => 'used as key',
+ 'logical' => true,
+ 'answer' => false
+ )
+---
+test: Integer
+yaml: |
+ canonical: 12345
+ decimal: +12,345
+ octal: 014
+ hexadecimal: 0xC
+php: |
+ array(
+ 'canonical' => 12345,
+ 'decimal' => 12345,
+ 'octal' => 12,
+ 'hexadecimal' => 12
+ )
+---
+test: Float
+yaml: |
+ canonical: 1.23015e+3
+ exponential: 12.3015e+02
+ fixed: 1,230.15
+ negative infinity: -.inf
+ not a number: .NaN
+php: |
+ array(
+ 'canonical' => 1230.15,
+ 'exponential' => 1230.15,
+ 'fixed' => 1230.15,
+ 'negative infinity' => log(0),
+ 'not a number' => -log(0)
+ )
+---
+test: Timestamp
+todo: true
+yaml: |
+ canonical: 2001-12-15T02:59:43.1Z
+ valid iso8601: 2001-12-14t21:59:43.10-05:00
+ space separated: 2001-12-14 21:59:43.10 -05:00
+ date (noon UTC): 2002-12-14
+ruby: |
+ array(
+ 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ),
+ 'valid iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'space separated' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'date (noon UTC)' => Date.new( 2002, 12, 14 )
+ )
+---
+test: Binary
+todo: true
+yaml: |
+ canonical: !binary "\
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs="
+ base64: !binary |
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
+ description: >
+ The binary value above is a tiny arrow
+ encoded as a gif image.
+ruby-setup: |
+ arrow_gif = "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236iiiccc\243\243\243\204\204\204\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371!\376\016Made with GIMP\000,\000\000\000\000\f\000\f\000\000\005, \216\2010\236\343@\024\350i\020\304\321\212\010\034\317\200M$z\357\3770\205p\270\2601f\r\e\316\001\303\001\036\020' \202\n\001\000;"
+ruby: |
+ {
+ 'canonical' => arrow_gif,
+ 'base64' => arrow_gif,
+ 'description' => "The binary value above is a tiny arrow encoded as a gif image.\n"
+ }
+
+---
+test: Merge key
+todo: true
+yaml: |
+ ---
+ - &CENTER { x: 1, y: 2 }
+ - &LEFT { x: 0, y: 2 }
+ - &BIG { r: 10 }
+ - &SMALL { r: 1 }
+
+ # All the following maps are equal:
+
+ - # Explicit keys
+ x: 1
+ y: 2
+ r: 10
+ label: center/big
+
+ - # Merge one map
+ << : *CENTER
+ r: 10
+ label: center/big
+
+ - # Merge multiple maps
+ << : [ *CENTER, *BIG ]
+ label: center/big
+
+ - # Override
+ << : [ *BIG, *LEFT, *SMALL ]
+ x: 1
+ label: center/big
+
+ruby-setup: |
+ center = { 'x' => 1, 'y' => 2 }
+ left = { 'x' => 0, 'y' => 2 }
+ big = { 'r' => 10 }
+ small = { 'r' => 1 }
+ node1 = { 'x' => 1, 'y' => 2, 'r' => 10, 'label' => 'center/big' }
+ node2 = center.dup
+ node2.update( { 'r' => 10, 'label' => 'center/big' } )
+ node3 = big.dup
+ node3.update( center )
+ node3.update( { 'label' => 'center/big' } )
+ node4 = small.dup
+ node4.update( left )
+ node4.update( big )
+ node4.update( { 'x' => 1, 'label' => 'center/big' } )
+
+ruby: |
+ [
+ center, left, big, small, node1, node2, node3, node4
+ ]
+
+---
+test: Default key
+todo: true
+yaml: |
+ --- # Old schema
+ link with:
+ - library1.dll
+ - library2.dll
+ --- # New schema
+ link with:
+ - = : library1.dll
+ version: 1.2
+ - = : library2.dll
+ version: 2.3
+ruby: |
+ y = YAML::Stream.new
+ y.add( { 'link with' => [ 'library1.dll', 'library2.dll' ] } )
+ obj_h = Hash[ 'version' => 1.2 ]
+ obj_h.default = 'library1.dll'
+ obj_h2 = Hash[ 'version' => 2.3 ]
+ obj_h2.default = 'library2.dll'
+ y.add( { 'link with' => [ obj_h, obj_h2 ] } )
+documents: 2
+
+---
+test: Special keys
+todo: true
+yaml: |
+ "!": These three keys
+ "&": had to be quoted
+ "=": and are normal strings.
+ # NOTE: the following node should NOT be serialized this way.
+ encoded node :
+ !special '!' : '!type'
+ !special|canonical '&' : 12
+ = : value
+ # The proper way to serialize the above node is as follows:
+ node : !!type &12 value
+ruby: |
+ { '!' => 'These three keys', '&' => 'had to be quoted',
+ '=' => 'and are normal strings.',
+ 'encoded node' => YAML::PrivateType.new( 'type', 'value' ),
+ 'node' => YAML::PrivateType.new( 'type', 'value' ) }
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsTypeTransfers.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsTypeTransfers.yml
new file mode 100644
index 0000000..aac4e68
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/YtsTypeTransfers.yml
@@ -0,0 +1,244 @@
+--- %YAML:1.0
+test: Strings
+brief: >
+ Any group of characters beginning with an
+ alphabetic or numeric character is a string,
+ unless it belongs to one of the groups below
+ (such as an Integer or Time).
+yaml: |
+ String
+php: |
+ 'String'
+---
+test: String characters
+brief: >
+ A string can contain any alphabetic or
+ numeric character, along with many
+ punctuation characters, including the
+ period, dash, space, quotes, exclamation, and
+ question mark.
+yaml: |
+ - What's Yaml?
+ - It's for writing data structures in plain text.
+ - And?
+ - And what? That's not good enough for you?
+ - No, I mean, "And what about Yaml?"
+ - Oh, oh yeah. Uh.. Yaml for Ruby.
+php: |
+ array(
+ "What's Yaml?",
+ "It's for writing data structures in plain text.",
+ "And?",
+ "And what? That's not good enough for you?",
+ "No, I mean, \"And what about Yaml?\"",
+ "Oh, oh yeah. Uh.. Yaml for Ruby."
+ )
+---
+test: Indicators in Strings
+brief: >
+ Be careful using indicators in strings. In particular,
+ the comma, colon, and pound sign must be used carefully.
+yaml: |
+ the colon followed by space is an indicator: but is a string:right here
+ same for the pound sign: here we have it#in a string
+ the comma can, honestly, be used in most cases: [ but not in, inline collections ]
+php: |
+ array(
+ 'the colon followed by space is an indicator' => 'but is a string:right here',
+ 'same for the pound sign' => 'here we have it#in a string',
+ 'the comma can, honestly, be used in most cases' => array('but not in', 'inline collections')
+ )
+---
+test: Forcing Strings
+brief: >
+ Any YAML type can be forced into a string using the
+ explicit !str method.
+yaml: |
+ date string: !str 2001-08-01
+ number string: !str 192
+php: |
+ array(
+ 'date string' => '2001-08-01',
+ 'number string' => '192'
+ )
+---
+test: Single-quoted Strings
+brief: >
+ You can also enclose your strings within single quotes,
+ which allows use of slashes, colons, and other indicators
+ freely. Inside single quotes, you can represent a single
+ quote in your string by using two single quotes next to
+ each other.
+yaml: |
+ all my favorite symbols: '#:!/%.)'
+ a few i hate: '&(*'
+ why do i hate them?: 'it''s very hard to explain'
+ entities: '&pound; me'
+php: |
+ array(
+ 'all my favorite symbols' => '#:!/%.)',
+ 'a few i hate' => '&(*',
+ 'why do i hate them?' => 'it\'s very hard to explain',
+ 'entities' => '&pound; me'
+ )
+---
+test: Double-quoted Strings
+brief: >
+ Enclosing strings in double quotes allows you
+ to use escapings to represent ASCII and
+ Unicode characters.
+yaml: |
+ i know where i want my line breaks: "one here\nand another here\n"
+php: |
+ array(
+ 'i know where i want my line breaks' => "one here\nand another here\n"
+ )
+---
+test: Multi-line Quoted Strings
+todo: true
+brief: >
+ Both single- and double-quoted strings may be
+ carried on to new lines in your YAML document.
+ They must be indented a step and indentation
+ is interpreted as a single space.
+yaml: |
+ i want a long string: "so i'm going to
+ let it go on and on to other lines
+ until i end it with a quote."
+php: |
+ array('i want a long string' => "so i'm going to ".
+ "let it go on and on to other lines ".
+ "until i end it with a quote."
+ )
+
+---
+test: Plain scalars
+todo: true
+brief: >
+ Unquoted strings may also span multiple lines, if they
+ are free of YAML space indicators and indented.
+yaml: |
+ - My little toe is broken in two places;
+ - I'm crazy to have skied this way;
+ - I'm not the craziest he's seen, since there was always the German guy
+ who skied for 3 hours on a broken shin bone (just below the kneecap);
+ - Nevertheless, second place is respectable, and he doesn't
+ recommend going for the record;
+ - He's going to put my foot in plaster for a month;
+ - This would impair my skiing ability somewhat for the
+ duration, as can be imagined.
+php: |
+ array(
+ "My little toe is broken in two places;",
+ "I'm crazy to have skied this way;",
+ "I'm not the craziest he's seen, since there was always ".
+ "the German guy who skied for 3 hours on a broken shin ".
+ "bone (just below the kneecap);",
+ "Nevertheless, second place is respectable, and he doesn't ".
+ "recommend going for the record;",
+ "He's going to put my foot in plaster for a month;",
+ "This would impair my skiing ability somewhat for the duration, ".
+ "as can be imagined."
+ )
+---
+test: 'Null'
+brief: >
+ You can use the tilde '~' character for a null value.
+yaml: |
+ name: Mr. Show
+ hosted by: Bob and David
+ date of next season: ~
+php: |
+ array(
+ 'name' => 'Mr. Show',
+ 'hosted by' => 'Bob and David',
+ 'date of next season' => null
+ )
+---
+test: Boolean
+brief: >
+ You can use 'true' and 'false' for Boolean values.
+yaml: |
+ Is Gus a Liar?: true
+ Do I rely on Gus for Sustenance?: false
+php: |
+ array(
+ 'Is Gus a Liar?' => true,
+ 'Do I rely on Gus for Sustenance?' => false
+ )
+---
+test: Integers
+dump_skip: true
+brief: >
+ An integer is a series of numbers, optionally
+ starting with a positive or negative sign. Integers
+ may also contain commas for readability.
+yaml: |
+ zero: 0
+ simple: 12
+ one-thousand: 1,000
+ negative one-thousand: -1,000
+php: |
+ array(
+ 'zero' => 0,
+ 'simple' => 12,
+ 'one-thousand' => 1000,
+ 'negative one-thousand' => -1000
+ )
+---
+test: Integers as Map Keys
+brief: >
+ An integer can be used a dictionary key.
+yaml: |
+ 1: one
+ 2: two
+ 3: three
+php: |
+ array(
+ 1 => 'one',
+ 2 => 'two',
+ 3 => 'three'
+ )
+---
+test: Floats
+dump_skip: true
+brief: >
+ Floats are represented by numbers with decimals,
+ allowing for scientific notation, as well as
+ positive and negative infinity and "not a number."
+yaml: |
+ a simple float: 2.00
+ larger float: 1,000.09
+ scientific notation: 1.00009e+3
+php: |
+ array(
+ 'a simple float' => 2.0,
+ 'larger float' => 1000.09,
+ 'scientific notation' => 1000.09
+ )
+---
+test: Time
+todo: true
+brief: >
+ You can represent timestamps by using
+ ISO8601 format, or a variation which
+ allows spaces between the date, time and
+ time zone.
+yaml: |
+ iso8601: 2001-12-14t21:59:43.10-05:00
+ space separated: 2001-12-14 21:59:43.10 -05:00
+php: |
+ array(
+ 'iso8601' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'space separated' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" )
+ )
+---
+test: Date
+todo: true
+brief: >
+ A date can be represented by its year,
+ month and day in ISO8601 order.
+yaml: |
+ 1976-07-31
+php: |
+ date( 1976, 7, 31 )
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/embededPhp.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/embededPhp.yml
new file mode 100644
index 0000000..ec456ed
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/embededPhp.yml
@@ -0,0 +1 @@
+value: <?php echo 1 + 2 + 3 ?>
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/escapedCharacters.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/escapedCharacters.yml
new file mode 100644
index 0000000..09bf86e
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/escapedCharacters.yml
@@ -0,0 +1,147 @@
+test: outside double quotes
+yaml: |
+ \0 \ \a \b \n
+php: |
+ "\\0 \\ \\a \\b \\n"
+---
+test: null
+yaml: |
+ "\0"
+php: |
+ "\x00"
+---
+test: bell
+yaml: |
+ "\a"
+php: |
+ "\x07"
+---
+test: backspace
+yaml: |
+ "\b"
+php: |
+ "\x08"
+---
+test: horizontal tab (1)
+yaml: |
+ "\t"
+php: |
+ "\x09"
+---
+test: horizontal tab (2)
+yaml: |
+ "\ "
+php: |
+ "\x09"
+---
+test: line feed
+yaml: |
+ "\n"
+php: |
+ "\x0a"
+---
+test: vertical tab
+yaml: |
+ "\v"
+php: |
+ "\x0b"
+---
+test: form feed
+yaml: |
+ "\f"
+php: |
+ "\x0c"
+---
+test: carriage return
+yaml: |
+ "\r"
+php: |
+ "\x0d"
+---
+test: escape
+yaml: |
+ "\e"
+php: |
+ "\x1b"
+---
+test: space
+yaml: |
+ "\ "
+php: |
+ "\x20"
+---
+test: slash
+yaml: |
+ "\/"
+php: |
+ "\x2f"
+---
+test: backslash
+yaml: |
+ "\\"
+php: |
+ "\\"
+---
+test: Unicode next line
+yaml: |
+ "\N"
+php: |
+ "\xc2\x85"
+---
+test: Unicode non-breaking space
+yaml: |
+ "\_"
+php: |
+ "\xc2\xa0"
+---
+test: Unicode line separator
+yaml: |
+ "\L"
+php: |
+ "\xe2\x80\xa8"
+---
+test: Unicode paragraph separator
+yaml: |
+ "\P"
+php: |
+ "\xe2\x80\xa9"
+---
+test: Escaped 8-bit Unicode
+yaml: |
+ "\x42"
+php: |
+ "B"
+---
+test: Escaped 16-bit Unicode
+yaml: |
+ "\u20ac"
+php: |
+ "\xe2\x82\xac"
+---
+test: Escaped 32-bit Unicode
+yaml: |
+ "\U00000043"
+php: |
+ "C"
+---
+test: Example 5.13 Escaped Characters
+note: |
+ Currently throws an error parsing first line. Maybe Symfony Yaml doesn't support
+ continuation of string across multiple lines? Keeping test here but disabled.
+todo: true
+yaml: |
+ "Fun with \\
+ \" \a \b \e \f \
+ \n \r \t \v \0 \
+ \ \_ \N \L \P \
+ \x41 \u0041 \U00000041"
+php: |
+ "Fun with \x5C\n\x22 \x07 \x08 \x1B \x0C\n\x0A \x0D \x09 \x0B \x00\n\x20 \xA0 \x85 \xe2\x80\xa8 \xe2\x80\xa9\nA A A"
+---
+test: Double quotes with a line feed
+yaml: |
+ { double: "some value\n \"some quoted string\" and 'some single quotes one'" }
+php: |
+ array(
+ 'double' => "some value\n \"some quoted string\" and 'some single quotes one'"
+ )
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/index.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/index.yml
new file mode 100644
index 0000000..3216a89
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/index.yml
@@ -0,0 +1,18 @@
+- escapedCharacters
+- sfComments
+- sfCompact
+- sfTests
+- sfObjects
+- sfMergeKey
+- sfQuotes
+- YtsAnchorAlias
+- YtsBasicTests
+- YtsBlockMapping
+- YtsDocumentSeparator
+- YtsErrorTests
+- YtsFlowCollections
+- YtsFoldedScalars
+- YtsNullsAndEmpties
+- YtsSpecificationExamples
+- YtsTypeTransfers
+- unindentedCollections
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfComments.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfComments.yml
new file mode 100644
index 0000000..6a7ffec
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfComments.yml
@@ -0,0 +1,73 @@
+--- %YAML:1.0
+test: Comments at the end of a line
+brief: >
+ Comments at the end of a line
+yaml: |
+ ex1: "foo # bar"
+ ex2: "foo # bar" # comment
+ ex3: 'foo # bar' # comment
+ ex4: foo # comment
+php: |
+ array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo')
+---
+test: Comments in the middle
+brief: >
+ Comments in the middle
+yaml: |
+ foo:
+ # some comment
+ # some comment
+ bar: foo
+ # some comment
+ # some comment
+php: |
+ array('foo' => array('bar' => 'foo'))
+---
+test: Comments on a hash line
+brief: >
+ Comments on a hash line
+yaml: |
+ foo: # a comment
+ foo: bar # a comment
+php: |
+ array('foo' => array('foo' => 'bar'))
+---
+test: 'Value starting with a #'
+brief: >
+ 'Value starting with a #'
+yaml: |
+ foo: '#bar'
+php: |
+ array('foo' => '#bar')
+---
+test: Document starting with a comment and a separator
+brief: >
+ Commenting before document start is allowed
+yaml: |
+ # document comment
+ ---
+ foo: bar # a comment
+php: |
+ array('foo' => 'bar')
+---
+test: Comment containing a colon on a hash line
+brief: >
+ Comment containing a colon on a scalar line
+yaml: 'foo # comment: this is also part of the comment'
+php: |
+ 'foo'
+---
+test: 'Hash key containing a #'
+brief: >
+ 'Hash key containing a #'
+yaml: 'foo#bar: baz'
+php: |
+ array('foo#bar' => 'baz')
+---
+test: 'Hash key ending with a space and a #'
+brief: >
+ 'Hash key ending with a space and a #'
+yaml: |
+ 'foo #': baz
+php: |
+ array('foo #' => 'baz')
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfCompact.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfCompact.yml
new file mode 100644
index 0000000..1339d23
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfCompact.yml
@@ -0,0 +1,159 @@
+--- %YAML:1.0
+test: Compact notation
+brief: |
+ Compact notation for sets of mappings with single element
+yaml: |
+ ---
+ # products purchased
+ - item : Super Hoop
+ - item : Basketball
+ quantity: 1
+ - item:
+ name: Big Shoes
+ nick: Biggies
+ quantity: 1
+php: |
+ array (
+ array (
+ 'item' => 'Super Hoop',
+ ),
+ array (
+ 'item' => 'Basketball',
+ 'quantity' => 1,
+ ),
+ array (
+ 'item' => array(
+ 'name' => 'Big Shoes',
+ 'nick' => 'Biggies'
+ ),
+ 'quantity' => 1
+ )
+ )
+---
+test: Compact notation combined with inline notation
+brief: |
+ Combinations of compact and inline notation are allowed
+yaml: |
+ ---
+ items:
+ - { item: Super Hoop, quantity: 1 }
+ - [ Basketball, Big Shoes ]
+php: |
+ array (
+ 'items' => array (
+ array (
+ 'item' => 'Super Hoop',
+ 'quantity' => 1,
+ ),
+ array (
+ 'Basketball',
+ 'Big Shoes'
+ )
+ )
+ )
+--- %YAML:1.0
+test: Compact notation
+brief: |
+ Compact notation for sets of mappings with single element
+yaml: |
+ ---
+ # products purchased
+ - item : Super Hoop
+ - item : Basketball
+ quantity: 1
+ - item:
+ name: Big Shoes
+ nick: Biggies
+ quantity: 1
+php: |
+ array (
+ array (
+ 'item' => 'Super Hoop',
+ ),
+ array (
+ 'item' => 'Basketball',
+ 'quantity' => 1,
+ ),
+ array (
+ 'item' => array(
+ 'name' => 'Big Shoes',
+ 'nick' => 'Biggies'
+ ),
+ 'quantity' => 1
+ )
+ )
+---
+test: Compact notation combined with inline notation
+brief: |
+ Combinations of compact and inline notation are allowed
+yaml: |
+ ---
+ items:
+ - { item: Super Hoop, quantity: 1 }
+ - [ Basketball, Big Shoes ]
+php: |
+ array (
+ 'items' => array (
+ array (
+ 'item' => 'Super Hoop',
+ 'quantity' => 1,
+ ),
+ array (
+ 'Basketball',
+ 'Big Shoes'
+ )
+ )
+ )
+--- %YAML:1.0
+test: Compact notation
+brief: |
+ Compact notation for sets of mappings with single element
+yaml: |
+ ---
+ # products purchased
+ - item : Super Hoop
+ - item : Basketball
+ quantity: 1
+ - item:
+ name: Big Shoes
+ nick: Biggies
+ quantity: 1
+php: |
+ array (
+ array (
+ 'item' => 'Super Hoop',
+ ),
+ array (
+ 'item' => 'Basketball',
+ 'quantity' => 1,
+ ),
+ array (
+ 'item' => array(
+ 'name' => 'Big Shoes',
+ 'nick' => 'Biggies'
+ ),
+ 'quantity' => 1
+ )
+ )
+---
+test: Compact notation combined with inline notation
+brief: |
+ Combinations of compact and inline notation are allowed
+yaml: |
+ ---
+ items:
+ - { item: Super Hoop, quantity: 1 }
+ - [ Basketball, Big Shoes ]
+php: |
+ array (
+ 'items' => array (
+ array (
+ 'item' => 'Super Hoop',
+ 'quantity' => 1,
+ ),
+ array (
+ 'Basketball',
+ 'Big Shoes'
+ )
+ )
+ )
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfMergeKey.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfMergeKey.yml
new file mode 100644
index 0000000..fd99101
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfMergeKey.yml
@@ -0,0 +1,45 @@
+--- %YAML:1.0
+test: Simple In Place Substitution
+brief: >
+ If you want to reuse an entire alias, only overwriting what is different
+ you can use a << in place substitution. This is not part of the official
+ YAML spec, but a widely implemented extension. See the following URL for
+ details: http://yaml.org/type/merge.html
+yaml: |
+ foo: &foo
+ a: Steve
+ b: Clark
+ c: Brian
+ bar:
+ a: before
+ d: other
+ <<: *foo
+ b: new
+ x: Oren
+ c:
+ foo: bar
+ foo: ignore
+ bar: foo
+ duplicate:
+ foo: bar
+ foo: ignore
+ foo2: &foo2
+ a: Ballmer
+ ding: &dong [ fi, fei, fo, fam]
+ check:
+ <<:
+ - *foo
+ - *dong
+ isit: tested
+ head:
+ <<: [ *foo , *dong , *foo2 ]
+php: |
+ array(
+ 'foo' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian'),
+ 'bar' => array('a' => 'before', 'd' => 'other', 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'x' => 'Oren'),
+ 'duplicate' => array('foo' => 'bar'),
+ 'foo2' => array('a' => 'Ballmer'),
+ 'ding' => array('fi', 'fei', 'fo', 'fam'),
+ 'check' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'),
+ 'head' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam')
+ )
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfObjects.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfObjects.yml
new file mode 100644
index 0000000..ee124b2
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfObjects.yml
@@ -0,0 +1,11 @@
+--- %YAML:1.0
+test: Objects
+brief: >
+ Comments at the end of a line
+yaml: |
+ ex1: "foo # bar"
+ ex2: "foo # bar" # comment
+ ex3: 'foo # bar' # comment
+ ex4: foo # comment
+php: |
+ array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo')
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfQuotes.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfQuotes.yml
new file mode 100644
index 0000000..741f1be
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfQuotes.yml
@@ -0,0 +1,33 @@
+--- %YAML:1.0
+test: Some characters at the beginning of a string must be escaped
+brief: >
+ Some characters at the beginning of a string must be escaped
+yaml: |
+ foo: | bar
+php: |
+ array('foo' => '| bar')
+---
+test: A key can be a quoted string
+brief: >
+ A key can be a quoted string
+yaml: |
+ "foo1": bar
+ 'foo2': bar
+ "foo \" bar": bar
+ 'foo '' bar': bar
+ 'foo3: ': bar
+ "foo4: ": bar
+ foo5: { "foo \" bar: ": bar, 'foo '' bar: ': bar }
+php: |
+ array(
+ 'foo1' => 'bar',
+ 'foo2' => 'bar',
+ 'foo " bar' => 'bar',
+ 'foo \' bar' => 'bar',
+ 'foo3: ' => 'bar',
+ 'foo4: ' => 'bar',
+ 'foo5' => array(
+ 'foo " bar: ' => 'bar',
+ 'foo \' bar: ' => 'bar',
+ ),
+ )
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfTests.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfTests.yml
new file mode 100644
index 0000000..7a54f16
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/sfTests.yml
@@ -0,0 +1,135 @@
+--- %YAML:1.0
+test: Multiple quoted string on one line
+brief: >
+ Multiple quoted string on one line
+yaml: |
+ stripped_title: { name: "foo bar", help: "bar foo" }
+php: |
+ array('stripped_title' => array('name' => 'foo bar', 'help' => 'bar foo'))
+---
+test: Empty sequence
+yaml: |
+ foo: [ ]
+php: |
+ array('foo' => array())
+---
+test: Empty value
+yaml: |
+ foo:
+php: |
+ array('foo' => null)
+---
+test: Inline string parsing
+brief: >
+ Inline string parsing
+yaml: |
+ test: ['complex: string', 'another [string]']
+php: |
+ array('test' => array('complex: string', 'another [string]'))
+---
+test: Boolean
+brief: >
+ Boolean
+yaml: |
+ - false
+ - true
+ - null
+ - ~
+ - 'false'
+ - 'true'
+ - 'null'
+ - '~'
+php: |
+ array(
+ false,
+ true,
+ null,
+ null,
+ 'false',
+ 'true',
+ 'null',
+ '~',
+ )
+---
+test: Empty lines in folded blocks
+brief: >
+ Empty lines in folded blocks
+yaml: |
+ foo:
+ bar: |
+ foo
+
+
+
+ bar
+php: |
+ array('foo' => array('bar' => "foo\n\n\n \nbar\n"))
+---
+test: IP addresses
+brief: >
+ IP addresses
+yaml: |
+ foo: 10.0.0.2
+php: |
+ array('foo' => '10.0.0.2')
+---
+test: A sequence with an embedded mapping
+brief: >
+ A sequence with an embedded mapping
+yaml: |
+ - foo
+ - bar: { bar: foo }
+php: |
+ array('foo', array('bar' => array('bar' => 'foo')))
+---
+test: A sequence with an unordered array
+brief: >
+ A sequence with an unordered array
+yaml: |
+ 1: foo
+ 0: bar
+php: |
+ array(1 => 'foo', 0 => 'bar')
+---
+test: Octal
+brief: as in spec example 2.19, octal value is converted
+yaml: |
+ foo: 0123
+php: |
+ array('foo' => 83)
+---
+test: Octal strings
+brief: Octal notation in a string must remain a string
+yaml: |
+ foo: "0123"
+php: |
+ array('foo' => '0123')
+---
+test: Octal strings
+brief: Octal notation in a string must remain a string
+yaml: |
+ foo: '0123'
+php: |
+ array('foo' => '0123')
+---
+test: Octal strings
+brief: Octal notation in a string must remain a string
+yaml: |
+ foo: |
+ 0123
+php: |
+ array('foo' => "0123\n")
+---
+test: Document as a simple hash
+brief: Document as a simple hash
+yaml: |
+ { foo: bar }
+php: |
+ array('foo' => 'bar')
+---
+test: Document as a simple array
+brief: Document as a simple array
+yaml: |
+ [ foo, bar ]
+php: |
+ array('foo', 'bar')
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/unindentedCollections.yml b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/unindentedCollections.yml
new file mode 100644
index 0000000..0c96108
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/Fixtures/unindentedCollections.yml
@@ -0,0 +1,82 @@
+--- %YAML:1.0
+test: Unindented collection
+brief: >
+ Unindented collection
+yaml: |
+ collection:
+ - item1
+ - item2
+ - item3
+php: |
+ array('collection' => array('item1', 'item2', 'item3'))
+---
+test: Nested unindented collection (two levels)
+brief: >
+ Nested unindented collection
+yaml: |
+ collection:
+ key:
+ - a
+ - b
+ - c
+php: |
+ array('collection' => array('key' => array('a', 'b', 'c')))
+---
+test: Nested unindented collection (three levels)
+brief: >
+ Nested unindented collection
+yaml: |
+ collection:
+ key:
+ subkey:
+ - one
+ - two
+ - three
+php: |
+ array('collection' => array('key' => array('subkey' => array('one', 'two', 'three'))))
+---
+test: Key/value after unindented collection (1)
+brief: >
+ Key/value after unindented collection (1)
+yaml: |
+ collection:
+ key:
+ - a
+ - b
+ - c
+ foo: bar
+php: |
+ array('collection' => array('key' => array('a', 'b', 'c')), 'foo' => 'bar')
+---
+test: Key/value after unindented collection (at the same level)
+brief: >
+ Key/value after unindented collection
+yaml: |
+ collection:
+ key:
+ - a
+ - b
+ - c
+ foo: bar
+php: |
+ array('collection' => array('key' => array('a', 'b', 'c'), 'foo' => 'bar'))
+---
+test: Shortcut Key after unindented collection
+brief: >
+ Key/value after unindented collection
+yaml: |
+ collection:
+ - key: foo
+ foo: bar
+php: |
+ array('collection' => array(array('key' => 'foo', 'foo' => 'bar')))
+---
+test: Shortcut Key after unindented collection with custom spaces
+brief: >
+ Key/value after unindented collection
+yaml: |
+ collection:
+ - key: foo
+ foo: bar
+php: |
+ array('collection' => array(array('key' => 'foo', 'foo' => 'bar')))
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/InlineTest.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/InlineTest.php
new file mode 100644
index 0000000..bbff176
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/InlineTest.php
@@ -0,0 +1,380 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use Symfony\Component\Yaml\Inline;
+
+class InlineTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getTestsForParse
+ */
+ public function testParse($yaml, $value)
+ {
+ $this->assertSame($value, Inline::parse($yaml), sprintf('::parse() converts an inline YAML to a PHP structure (%s)', $yaml));
+ }
+
+ /**
+ * @dataProvider getTestsForParseWithMapObjects
+ */
+ public function testParseWithMapObjects($yaml, $value)
+ {
+ $actual = Inline::parse($yaml, false, false, true);
+
+ $this->assertSame(serialize($value), serialize($actual));
+ }
+
+ /**
+ * @dataProvider getTestsForDump
+ */
+ public function testDump($yaml, $value)
+ {
+ $this->assertEquals($yaml, Inline::dump($value), sprintf('::dump() converts a PHP structure to an inline YAML (%s)', $yaml));
+
+ $this->assertSame($value, Inline::parse(Inline::dump($value)), 'check consistency');
+ }
+
+ public function testDumpNumericValueWithLocale()
+ {
+ $locale = setlocale(LC_NUMERIC, 0);
+ if (false === $locale) {
+ $this->markTestSkipped('Your platform does not support locales.');
+ }
+
+ $required_locales = array('fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252');
+ if (false === setlocale(LC_ALL, $required_locales)) {
+ $this->markTestSkipped('Could not set any of required locales: '.implode(', ', $required_locales));
+ }
+
+ $this->assertEquals('1.2', Inline::dump(1.2));
+ $this->assertContains('fr', strtolower(setlocale(LC_NUMERIC, 0)));
+
+ setlocale(LC_ALL, $locale);
+ }
+
+ public function testHashStringsResemblingExponentialNumericsShouldNotBeChangedToINF()
+ {
+ $value = '686e444';
+
+ $this->assertSame($value, Inline::parse(Inline::dump($value)));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseScalarWithIncorrectlyQuotedStringShouldThrowException()
+ {
+ $value = "'don't do somthin' like that'";
+ Inline::parse($value);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseScalarWithIncorrectlyDoubleQuotedStringShouldThrowException()
+ {
+ $value = '"don"t do somthin" like that"';
+ Inline::parse($value);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseInvalidMappingKeyShouldThrowException()
+ {
+ $value = '{ "foo " bar": "bar" }';
+ Inline::parse($value);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseInvalidMappingShouldThrowException()
+ {
+ Inline::parse('[foo] bar');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseInvalidSequenceShouldThrowException()
+ {
+ Inline::parse('{ foo: bar } bar');
+ }
+
+ public function testParseScalarWithCorrectlyQuotedStringShouldReturnString()
+ {
+ $value = "'don''t do somthin'' like that'";
+ $expect = "don't do somthin' like that";
+
+ $this->assertSame($expect, Inline::parseScalar($value));
+ }
+
+ /**
+ * @dataProvider getDataForParseReferences
+ */
+ public function testParseReferences($yaml, $expected)
+ {
+ $this->assertSame($expected, Inline::parse($yaml, false, false, false, array('var' => 'var-value')));
+ }
+
+ public function getDataForParseReferences()
+ {
+ return array(
+ 'scalar' => array('*var', 'var-value'),
+ 'list' => array('[ *var ]', array('var-value')),
+ 'list-in-list' => array('[[ *var ]]', array(array('var-value'))),
+ 'map-in-list' => array('[ { key: *var } ]', array(array('key' => 'var-value'))),
+ 'embedded-mapping-in-list' => array('[ key: *var ]', array(array('key' => 'var-value'))),
+ 'map' => array('{ key: *var }', array('key' => 'var-value')),
+ 'list-in-map' => array('{ key: [*var] }', array('key' => array('var-value'))),
+ 'map-in-map' => array('{ foo: { bar: *var } }', array('foo' => array('bar' => 'var-value'))),
+ );
+ }
+
+ public function testParseMapReferenceInSequence()
+ {
+ $foo = array(
+ 'a' => 'Steve',
+ 'b' => 'Clark',
+ 'c' => 'Brian',
+ );
+ $this->assertSame(array($foo), Inline::parse('[*foo]', false, false, false, array('foo' => $foo)));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage A reference must contain at least one character.
+ */
+ public function testParseUnquotedAsterisk()
+ {
+ Inline::parse('{ foo: * }');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage A reference must contain at least one character.
+ */
+ public function testParseUnquotedAsteriskFollowedByAComment()
+ {
+ Inline::parse('{ foo: * #foo }');
+ }
+
+ public function getTestsForParse()
+ {
+ return array(
+ array('', ''),
+ array('null', null),
+ array('false', false),
+ array('true', true),
+ array('12', 12),
+ array('-12', -12),
+ array('"quoted string"', 'quoted string'),
+ array("'quoted string'", 'quoted string'),
+ array('12.30e+02', 12.30e+02),
+ array('0x4D2', 0x4D2),
+ array('02333', 02333),
+ array('.Inf', -log(0)),
+ array('-.Inf', log(0)),
+ array("'686e444'", '686e444'),
+ array('686e444', 646e444),
+ array('123456789123456789123456789123456789', '123456789123456789123456789123456789'),
+ array('"foo\r\nbar"', "foo\r\nbar"),
+ array("'foo#bar'", 'foo#bar'),
+ array("'foo # bar'", 'foo # bar'),
+ array("'#cfcfcf'", '#cfcfcf'),
+ array('::form_base.html.twig', '::form_base.html.twig'),
+
+ // Pre-YAML-1.2 booleans
+ array("'y'", 'y'),
+ array("'n'", 'n'),
+ array("'yes'", 'yes'),
+ array("'no'", 'no'),
+ array("'on'", 'on'),
+ array("'off'", 'off'),
+
+ array('2007-10-30', mktime(0, 0, 0, 10, 30, 2007)),
+ array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)),
+ array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)),
+ array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)),
+ array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)),
+
+ array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''),
+ array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),
+
+ // sequences
+ // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon
+ array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)),
+ array('[ foo , bar , false , null , 12 ]', array('foo', 'bar', false, null, 12)),
+ array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),
+
+ // mappings
+ array('{foo:bar,bar:foo,false:false,null:null,integer:12}', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
+ array('{ foo : bar, bar : foo, false : false, null : null, integer : 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
+ array('{foo: \'bar\', bar: \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')),
+ array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')),
+ array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', array('foo\'' => 'bar', "bar\"" => 'foo: bar')),
+ array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', array('foo: ' => 'bar', "bar: " => 'foo: bar')),
+
+ // nested sequences and mappings
+ array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),
+ array('[foo, {bar: foo}]', array('foo', array('bar' => 'foo'))),
+ array('{ foo: {bar: foo} }', array('foo' => array('bar' => 'foo'))),
+ array('{ foo: [bar, foo] }', array('foo' => array('bar', 'foo'))),
+
+ array('[ foo, [ bar, foo ] ]', array('foo', array('bar', 'foo'))),
+
+ array('[{ foo: {bar: foo} }]', array(array('foo' => array('bar' => 'foo')))),
+
+ array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),
+
+ array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))),
+
+ array('[foo, bar: { foo: bar }]', array('foo', '1' => array('bar' => array('foo' => 'bar')))),
+ array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),
+ );
+ }
+
+ public function getTestsForParseWithMapObjects()
+ {
+ return array(
+ array('', ''),
+ array('null', null),
+ array('false', false),
+ array('true', true),
+ array('12', 12),
+ array('-12', -12),
+ array('"quoted string"', 'quoted string'),
+ array("'quoted string'", 'quoted string'),
+ array('12.30e+02', 12.30e+02),
+ array('0x4D2', 0x4D2),
+ array('02333', 02333),
+ array('.Inf', -log(0)),
+ array('-.Inf', log(0)),
+ array("'686e444'", '686e444'),
+ array('686e444', 646e444),
+ array('123456789123456789123456789123456789', '123456789123456789123456789123456789'),
+ array('"foo\r\nbar"', "foo\r\nbar"),
+ array("'foo#bar'", 'foo#bar'),
+ array("'foo # bar'", 'foo # bar'),
+ array("'#cfcfcf'", '#cfcfcf'),
+ array('::form_base.html.twig', '::form_base.html.twig'),
+
+ array('2007-10-30', mktime(0, 0, 0, 10, 30, 2007)),
+ array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)),
+ array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)),
+ array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)),
+ array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)),
+
+ array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''),
+ array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),
+
+ // sequences
+ // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon
+ array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)),
+ array('[ foo , bar , false , null , 12 ]', array('foo', 'bar', false, null, 12)),
+ array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),
+
+ // mappings
+ array('{foo:bar,bar:foo,false:false,null:null,integer:12}', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
+ array('{ foo : bar, bar : foo, false : false, null : null, integer : 12 }', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
+ array('{foo: \'bar\', bar: \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')),
+ array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')),
+ array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', (object) array('foo\'' => 'bar', "bar\"" => 'foo: bar')),
+ array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', (object) array('foo: ' => 'bar', "bar: " => 'foo: bar')),
+
+ // nested sequences and mappings
+ array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),
+ array('[foo, {bar: foo}]', array('foo', (object) array('bar' => 'foo'))),
+ array('{ foo: {bar: foo} }', (object) array('foo' => (object) array('bar' => 'foo'))),
+ array('{ foo: [bar, foo] }', (object) array('foo' => array('bar', 'foo'))),
+
+ array('[ foo, [ bar, foo ] ]', array('foo', array('bar', 'foo'))),
+
+ array('[{ foo: {bar: foo} }]', array((object) array('foo' => (object) array('bar' => 'foo')))),
+
+ array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),
+
+ array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', (object) array('bar' => 'foo', 'foo' => array('foo', (object) array('bar' => 'foo'))), array('foo', (object) array('bar' => 'foo')))),
+
+ array('[foo, bar: { foo: bar }]', array('foo', '1' => (object) array('bar' => (object) array('foo' => 'bar')))),
+ array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', (object) array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),
+
+ array('{}', new \stdClass()),
+ array('{ foo : bar, bar : {} }', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
+ array('{ foo : [], bar : {} }', (object) array('foo' => array(), 'bar' => new \stdClass())),
+ array('{foo: \'bar\', bar: {} }', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
+ array('{\'foo\': \'bar\', "bar": {}}', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
+ array('{\'foo\': \'bar\', "bar": \'{}\'}', (object) array('foo' => 'bar', 'bar' => '{}')),
+
+ array('[foo, [{}, {}]]', array('foo', array(new \stdClass(), new \stdClass()))),
+ array('[foo, [[], {}]]', array('foo', array(array(), new \stdClass()))),
+ array('[foo, [[{}, {}], {}]]', array('foo', array(array(new \stdClass(), new \stdClass()), new \stdClass()))),
+ array('[foo, {bar: {}}]', array('foo', '1' => (object) array('bar' => new \stdClass()))),
+ );
+ }
+
+ public function getTestsForDump()
+ {
+ return array(
+ array('null', null),
+ array('false', false),
+ array('true', true),
+ array('12', 12),
+ array("'quoted string'", 'quoted string'),
+ array('!!float 1230', 12.30e+02),
+ array('1234', 0x4D2),
+ array('1243', 02333),
+ array('.Inf', -log(0)),
+ array('-.Inf', log(0)),
+ array("'686e444'", '686e444'),
+ array('"foo\r\nbar"', "foo\r\nbar"),
+ array("'foo#bar'", 'foo#bar'),
+ array("'foo # bar'", 'foo # bar'),
+ array("'#cfcfcf'", '#cfcfcf'),
+
+ array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),
+
+ array("'-dash'", '-dash'),
+ array("'-'", '-'),
+
+ // Pre-YAML-1.2 booleans
+ array("'y'", 'y'),
+ array("'n'", 'n'),
+ array("'yes'", 'yes'),
+ array("'no'", 'no'),
+ array("'on'", 'on'),
+ array("'off'", 'off'),
+
+ // sequences
+ array('[foo, bar, false, null, 12]', array('foo', 'bar', false, null, 12)),
+ array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),
+
+ // mappings
+ array('{ foo: bar, bar: foo, \'false\': false, \'null\': null, integer: 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
+ array('{ foo: bar, bar: \'foo: bar\' }', array('foo' => 'bar', 'bar' => 'foo: bar')),
+
+ // nested sequences and mappings
+ array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),
+
+ array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),
+
+ array('{ foo: { bar: foo } }', array('foo' => array('bar' => 'foo'))),
+
+ array('[foo, { bar: foo }]', array('foo', array('bar' => 'foo'))),
+
+ array('[foo, { bar: foo, foo: [foo, { bar: foo }] }, [foo, { bar: foo }]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))),
+
+ array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),
+ );
+ }
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParseExceptionTest.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParseExceptionTest.php
new file mode 100644
index 0000000..e4eb9c9
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParseExceptionTest.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+
+class ParseExceptionTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetMessage()
+ {
+ $exception = new ParseException('Error message', 42, 'foo: bar', '/var/www/app/config.yml');
+ if (PHP_VERSION_ID >= 50400) {
+ $message = 'Error message in "/var/www/app/config.yml" at line 42 (near "foo: bar")';
+ } else {
+ $message = 'Error message in "\\/var\\/www\\/app\\/config.yml" at line 42 (near "foo: bar")';
+ }
+
+ $this->assertEquals($message, $exception->getMessage());
+ }
+
+ public function testGetMessageWithUnicodeInFilename()
+ {
+ $exception = new ParseException('Error message', 42, 'foo: bar', 'äöü.yml');
+ if (PHP_VERSION_ID >= 50400) {
+ $message = 'Error message in "äöü.yml" at line 42 (near "foo: bar")';
+ } else {
+ $message = 'Error message in "\u00e4\u00f6\u00fc.yml" at line 42 (near "foo: bar")';
+ }
+
+ $this->assertEquals($message, $exception->getMessage());
+ }
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParserTest.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParserTest.php
new file mode 100644
index 0000000..6e39e7d
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParserTest.php
@@ -0,0 +1,740 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use Symfony\Component\Yaml\Yaml;
+use Symfony\Component\Yaml\Parser;
+
+class ParserTest extends \PHPUnit_Framework_TestCase
+{
+ protected $parser;
+
+ protected function setUp()
+ {
+ $this->parser = new Parser();
+ }
+
+ protected function tearDown()
+ {
+ $this->parser = null;
+ }
+
+ /**
+ * @dataProvider getDataFormSpecifications
+ */
+ public function testSpecifications($file, $expected, $yaml, $comment)
+ {
+ $this->assertEquals($expected, var_export($this->parser->parse($yaml), true), $comment);
+ }
+
+ public function getDataFormSpecifications()
+ {
+ $parser = new Parser();
+ $path = __DIR__.'/Fixtures';
+
+ $tests = array();
+ $files = $parser->parse(file_get_contents($path.'/index.yml'));
+ foreach ($files as $file) {
+ $yamls = file_get_contents($path.'/'.$file.'.yml');
+
+ // split YAMLs documents
+ foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) {
+ if (!$yaml) {
+ continue;
+ }
+
+ $test = $parser->parse($yaml);
+ if (isset($test['todo']) && $test['todo']) {
+ // TODO
+ } else {
+ eval('$expected = '.trim($test['php']).';');
+
+ $tests[] = array($file, var_export($expected, true), $test['yaml'], $test['test']);
+ }
+ }
+ }
+
+ return $tests;
+ }
+
+ public function testTabsInYaml()
+ {
+ // test tabs in YAML
+ $yamls = array(
+ "foo:\n bar",
+ "foo:\n bar",
+ "foo:\n bar",
+ "foo:\n bar",
+ );
+
+ foreach ($yamls as $yaml) {
+ try {
+ $content = $this->parser->parse($yaml);
+
+ $this->fail('YAML files must not contain tabs');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\Exception', $e, 'YAML files must not contain tabs');
+ $this->assertEquals('A YAML file cannot contain tabs as indentation at line 2 (near "'.strpbrk($yaml, "\t").'").', $e->getMessage(), 'YAML files must not contain tabs');
+ }
+ }
+ }
+
+ public function testEndOfTheDocumentMarker()
+ {
+ $yaml = <<<EOF
+--- %YAML:1.0
+foo
+...
+EOF;
+
+ $this->assertEquals('foo', $this->parser->parse($yaml));
+ }
+
+ public function getBlockChompingTests()
+ {
+ $tests = array();
+
+ $yaml = <<<'EOF'
+foo: |-
+ one
+ two
+bar: |-
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping strip with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |-
+ one
+ two
+
+bar: |-
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping strip with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+{}
+
+
+EOF;
+ $expected = array();
+ $tests['Literal block chomping strip with multiple trailing newlines after a 1-liner'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |-
+ one
+ two
+bar: |-
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping strip without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |
+ one
+ two
+bar: |
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo\n",
+ );
+ $tests['Literal block chomping clip with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |
+ one
+ two
+
+bar: |
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo\n",
+ );
+ $tests['Literal block chomping clip with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |
+ one
+ two
+bar: |
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping clip without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |+
+ one
+ two
+bar: |+
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo\n",
+ );
+ $tests['Literal block chomping keep with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |+
+ one
+ two
+
+bar: |+
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n\n",
+ 'bar' => "one\ntwo\n\n",
+ );
+ $tests['Literal block chomping keep with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |+
+ one
+ two
+bar: |+
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping keep without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >-
+ one
+ two
+bar: >-
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => 'one two',
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping strip with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >-
+ one
+ two
+
+bar: >-
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => 'one two',
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping strip with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >-
+ one
+ two
+bar: >-
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => 'one two',
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping strip without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >
+ one
+ two
+bar: >
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => "one two\n",
+ );
+ $tests['Folded block chomping clip with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >
+ one
+ two
+
+bar: >
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => "one two\n",
+ );
+ $tests['Folded block chomping clip with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >
+ one
+ two
+bar: >
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping clip without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >+
+ one
+ two
+bar: >+
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => "one two\n",
+ );
+ $tests['Folded block chomping keep with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >+
+ one
+ two
+
+bar: >+
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one two\n\n",
+ 'bar' => "one two\n\n",
+ );
+ $tests['Folded block chomping keep with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >+
+ one
+ two
+bar: >+
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping keep without trailing newline'] = array($expected, $yaml);
+
+ return $tests;
+ }
+
+ /**
+ * @dataProvider getBlockChompingTests
+ */
+ public function testBlockChomping($expected, $yaml)
+ {
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ /**
+ * Regression test for issue #7989.
+ *
+ * @see https://github.com/symfony/symfony/issues/7989
+ */
+ public function testBlockLiteralWithLeadingNewlines()
+ {
+ $yaml = <<<'EOF'
+foo: |-
+
+
+ bar
+
+EOF;
+ $expected = array(
+ 'foo' => "\n\nbar",
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ public function testObjectSupportEnabled()
+ {
+ $input = <<<EOF
+foo: !!php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";}
+bar: 1
+EOF;
+ $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects');
+ }
+
+ public function testObjectSupportDisabledButNoExceptions()
+ {
+ $input = <<<EOF
+foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}
+bar: 1
+EOF;
+
+ $this->assertEquals(array('foo' => null, 'bar' => 1), $this->parser->parse($input), '->parse() does not parse objects');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testObjectsSupportDisabledWithExceptions()
+ {
+ $this->parser->parse('foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}', true, false);
+ }
+
+ public function testNonUtf8Exception()
+ {
+ if (!function_exists('iconv')) {
+ $this->markTestSkipped('Exceptions for non-utf8 charsets require the iconv() function.');
+
+ return;
+ }
+
+ $yamls = array(
+ iconv('UTF-8', 'ISO-8859-1', "foo: 'äöüß'"),
+ iconv('UTF-8', 'ISO-8859-15', "euro: '€'"),
+ iconv('UTF-8', 'CP1252', "cp1252: '©ÉÇáñ'"),
+ );
+
+ foreach ($yamls as $yaml) {
+ try {
+ $this->parser->parse($yaml);
+
+ $this->fail('charsets other than UTF-8 are rejected.');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Yaml\Exception\ParseException', $e, 'charsets other than UTF-8 are rejected.');
+ }
+ }
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testUnindentedCollectionException()
+ {
+ $yaml = <<<EOF
+
+collection:
+-item1
+-item2
+-item3
+
+EOF;
+
+ $this->parser->parse($yaml);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testShortcutKeyUnindentedCollectionException()
+ {
+ $yaml = <<<EOF
+
+collection:
+- key: foo
+ foo: bar
+
+EOF;
+
+ $this->parser->parse($yaml);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Multiple documents are not supported.
+ */
+ public function testMultipleDocumentsNotSupportedException()
+ {
+ Yaml::parse(<<<EOL
+# Ranking of 1998 home runs
+---
+- Mark McGwire
+- Sammy Sosa
+- Ken Griffey
+
+# Team ranking
+---
+- Chicago Cubs
+- St Louis Cardinals
+EOL
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testSequenceInAMapping()
+ {
+ Yaml::parse(<<<EOF
+yaml:
+ hash: me
+ - array stuff
+EOF
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testMappingInASequence()
+ {
+ Yaml::parse(<<<EOF
+yaml:
+ - array stuff
+ hash: me
+EOF
+ );
+ }
+
+ /**
+ * > It is an error for two equal keys to appear in the same mapping node.
+ * > In such a case the YAML processor may continue, ignoring the second
+ * > `key: value` pair and issuing an appropriate warning. This strategy
+ * > preserves a consistent information model for one-pass and random access
+ * > applications.
+ *
+ * @see http://yaml.org/spec/1.2/spec.html#id2759572
+ * @see http://yaml.org/spec/1.1/#id932806
+ *
+ * @covers \Symfony\Component\Yaml\Parser::parse
+ */
+ public function testMappingDuplicateKeyBlock()
+ {
+ $input = <<<EOD
+parent:
+ child: first
+ child: duplicate
+parent:
+ child: duplicate
+ child: duplicate
+EOD;
+ $expected = array(
+ 'parent' => array(
+ 'child' => 'first',
+ ),
+ );
+ $this->assertSame($expected, Yaml::parse($input));
+ }
+
+ /**
+ * @covers \Symfony\Component\Yaml\Inline::parseMapping
+ */
+ public function testMappingDuplicateKeyFlow()
+ {
+ $input = <<<EOD
+parent: { child: first, child: duplicate }
+parent: { child: duplicate, child: duplicate }
+EOD;
+ $expected = array(
+ 'parent' => array(
+ 'child' => 'first',
+ ),
+ );
+ $this->assertSame($expected, Yaml::parse($input));
+ }
+
+ public function testEmptyValue()
+ {
+ $input = <<<EOF
+hash:
+EOF;
+
+ $this->assertEquals(array('hash' => null), Yaml::parse($input));
+ }
+
+ public function testStringBlockWithComments()
+ {
+ $this->assertEquals(array('content' => <<<EOT
+# comment 1
+header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+footer # comment3
+EOT
+ ), Yaml::parse(<<<EOF
+content: |
+ # comment 1
+ header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+ footer # comment3
+EOF
+ ));
+ }
+
+ public function testFoldedStringBlockWithComments()
+ {
+ $this->assertEquals(array(array('content' => <<<EOT
+# comment 1
+header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+footer # comment3
+EOT
+ )), Yaml::parse(<<<EOF
+-
+ content: |
+ # comment 1
+ header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+ footer # comment3
+EOF
+ ));
+ }
+
+ public function testNestedFoldedStringBlockWithComments()
+ {
+ $this->assertEquals(array(array(
+ 'title' => 'some title',
+ 'content' => <<<EOT
+# comment 1
+header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+footer # comment3
+EOT
+ )), Yaml::parse(<<<EOF
+-
+ title: some title
+ content: |
+ # comment 1
+ header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+ footer # comment3
+EOF
+ ));
+ }
+
+ public function testReferenceResolvingInInlineStrings()
+ {
+ $this->assertEquals(array(
+ 'var' => 'var-value',
+ 'scalar' => 'var-value',
+ 'list' => array('var-value'),
+ 'list_in_list' => array(array('var-value')),
+ 'map_in_list' => array(array('key' => 'var-value')),
+ 'embedded_mapping' => array(array('key' => 'var-value')),
+ 'map' => array('key' => 'var-value'),
+ 'list_in_map' => array('key' => array('var-value')),
+ 'map_in_map' => array('foo' => array('bar' => 'var-value')),
+ ), Yaml::parse(<<<EOF
+var: &var var-value
+scalar: *var
+list: [ *var ]
+list_in_list: [[ *var ]]
+map_in_list: [ { key: *var } ]
+embedded_mapping: [ key: *var ]
+map: { key: *var }
+list_in_map: { key: [*var] }
+map_in_map: { foo: { bar: *var } }
+EOF
+ ));
+ }
+
+ public function testYamlDirective()
+ {
+ $yaml = <<<EOF
+%YAML 1.2
+---
+foo: 1
+bar: 2
+EOF;
+ $this->assertEquals(array('foo' => 1, 'bar' => 2), $this->parser->parse($yaml));
+ }
+}
+
+class B
+{
+ public $b = 'foo';
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/YamlTest.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/YamlTest.php
new file mode 100644
index 0000000..633978d
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Tests/YamlTest.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use Symfony\Component\Yaml\Yaml;
+
+class YamlTest extends \PHPUnit_Framework_TestCase
+{
+ public function testParseAndDump()
+ {
+ $data = array('lorem' => 'ipsum', 'dolor' => 'sit');
+ $yml = Yaml::dump($data);
+ $parsed = Yaml::parse($yml);
+ $this->assertEquals($data, $parsed);
+
+ $filename = __DIR__.'/Fixtures/index.yml';
+ $contents = file_get_contents($filename);
+ $parsedByFilename = Yaml::parse($filename);
+ $parsedByContents = Yaml::parse($contents);
+ $this->assertEquals($parsedByFilename, $parsedByContents);
+ }
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Unescaper.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Unescaper.php
new file mode 100644
index 0000000..ffddd95
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Unescaper.php
@@ -0,0 +1,141 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+/**
+ * Unescaper encapsulates unescaping rules for single and double-quoted
+ * YAML strings.
+ *
+ * @author Matthew Lewinski <matthew@lewinski.org>
+ */
+class Unescaper
+{
+ // Parser and Inline assume UTF-8 encoding, so escaped Unicode characters
+ // must be converted to that encoding.
+ // @deprecated since 2.5, to be removed in 3.0
+ const ENCODING = 'UTF-8';
+
+ // Regex fragment that matches an escaped character in a double quoted
+ // string.
+ const REGEX_ESCAPED_CHARACTER = "\\\\([0abt\tnvfre \\\"\\/\\\\N_LP]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})";
+
+ /**
+ * Unescapes a single quoted string.
+ *
+ * @param string $value A single quoted string.
+ *
+ * @return string The unescaped string.
+ */
+ public function unescapeSingleQuotedString($value)
+ {
+ return str_replace('\'\'', '\'', $value);
+ }
+
+ /**
+ * Unescapes a double quoted string.
+ *
+ * @param string $value A double quoted string.
+ *
+ * @return string The unescaped string.
+ */
+ public function unescapeDoubleQuotedString($value)
+ {
+ $self = $this;
+ $callback = function ($match) use ($self) {
+ return $self->unescapeCharacter($match[0]);
+ };
+
+ // evaluate the string
+ return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value);
+ }
+
+ /**
+ * Unescapes a character that was found in a double-quoted string.
+ *
+ * @param string $value An escaped character
+ *
+ * @return string The unescaped character
+ */
+ public function unescapeCharacter($value)
+ {
+ switch ($value{1}) {
+ case '0':
+ return "\x0";
+ case 'a':
+ return "\x7";
+ case 'b':
+ return "\x8";
+ case 't':
+ return "\t";
+ case "\t":
+ return "\t";
+ case 'n':
+ return "\n";
+ case 'v':
+ return "\xB";
+ case 'f':
+ return "\xC";
+ case 'r':
+ return "\r";
+ case 'e':
+ return "\x1B";
+ case ' ':
+ return ' ';
+ case '"':
+ return '"';
+ case '/':
+ return '/';
+ case '\\':
+ return '\\';
+ case 'N':
+ // U+0085 NEXT LINE
+ return "\xC2\x85";
+ case '_':
+ // U+00A0 NO-BREAK SPACE
+ return "\xC2\xA0";
+ case 'L':
+ // U+2028 LINE SEPARATOR
+ return "\xE2\x80\xA8";
+ case 'P':
+ // U+2029 PARAGRAPH SEPARATOR
+ return "\xE2\x80\xA9";
+ case 'x':
+ return self::utf8chr(hexdec(substr($value, 2, 2)));
+ case 'u':
+ return self::utf8chr(hexdec(substr($value, 2, 4)));
+ case 'U':
+ return self::utf8chr(hexdec(substr($value, 2, 8)));
+ }
+ }
+
+ /**
+ * Get the UTF-8 character for the given code point.
+ *
+ * @param int $c The unicode code point
+ *
+ * @return string The corresponding UTF-8 character
+ */
+ private static function utf8chr($c)
+ {
+ if (0x80 > $c %= 0x200000) {
+ return chr($c);
+ }
+ if (0x800 > $c) {
+ return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F);
+ }
+ if (0x10000 > $c) {
+ return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
+ }
+
+ return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
+ }
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/Yaml.php b/vendor/symfony/yaml/Symfony/Component/Yaml/Yaml.php
new file mode 100644
index 0000000..419226a
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/Yaml.php
@@ -0,0 +1,100 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+
+/**
+ * Yaml offers convenience methods to load and dump YAML.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class Yaml
+{
+ /**
+ * Parses YAML into a PHP array.
+ *
+ * The parse method, when supplied with a YAML stream (string or file),
+ * will do its best to convert YAML in a file into a PHP array.
+ *
+ * Usage:
+ * <code>
+ * $array = Yaml::parse('config.yml');
+ * print_r($array);
+ * </code>
+ *
+ * As this method accepts both plain strings and file names as an input,
+ * you must validate the input before calling this method. Passing a file
+ * as an input is a deprecated feature and will be removed in 3.0.
+ *
+ * @param string $input Path to a YAML file or a string containing YAML
+ * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
+ * @param bool $objectSupport True if object support is enabled, false otherwise
+ *
+ * @return array The YAML converted to a PHP array
+ *
+ * @throws ParseException If the YAML is not valid
+ *
+ * @api
+ */
+ public static function parse($input, $exceptionOnInvalidType = false, $objectSupport = false)
+ {
+ // if input is a file, process it
+ $file = '';
+ if (strpos($input, "\n") === false && is_file($input)) {
+ if (false === is_readable($input)) {
+ throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $input));
+ }
+
+ $file = $input;
+ $input = file_get_contents($file);
+ }
+
+ $yaml = new Parser();
+
+ try {
+ return $yaml->parse($input, $exceptionOnInvalidType, $objectSupport);
+ } catch (ParseException $e) {
+ if ($file) {
+ $e->setParsedFile($file);
+ }
+
+ throw $e;
+ }
+ }
+
+ /**
+ * Dumps a PHP array to a YAML string.
+ *
+ * The dump method, when supplied with an array, will do its best
+ * to convert the array into friendly YAML.
+ *
+ * @param array $array PHP array
+ * @param int $inline The level where you switch to inline YAML
+ * @param int $indent The amount of spaces to use for indentation of nested nodes.
+ * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
+ * @param bool $objectSupport true if object support is enabled, false otherwise
+ *
+ * @return string A YAML string representing the original PHP array
+ *
+ * @api
+ */
+ public static function dump($array, $inline = 2, $indent = 4, $exceptionOnInvalidType = false, $objectSupport = false)
+ {
+ $yaml = new Dumper();
+ $yaml->setIndentation($indent);
+
+ return $yaml->dump($array, $inline, 0, $exceptionOnInvalidType, $objectSupport);
+ }
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/composer.json b/vendor/symfony/yaml/Symfony/Component/Yaml/composer.json
new file mode 100644
index 0000000..b38eec2
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/composer.json
@@ -0,0 +1,34 @@
+{
+ "name": "symfony/yaml",
+ "type": "library",
+ "description": "Symfony Yaml Component",
+ "keywords": [],
+ "homepage": "http://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7"
+ },
+ "autoload": {
+ "psr-0": { "Symfony\\Component\\Yaml\\": "" }
+ },
+ "target-dir": "Symfony/Component/Yaml",
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ }
+}
diff --git a/vendor/symfony/yaml/Symfony/Component/Yaml/phpunit.xml.dist b/vendor/symfony/yaml/Symfony/Component/Yaml/phpunit.xml.dist
new file mode 100644
index 0000000..8f7741f
--- /dev/null
+++ b/vendor/symfony/yaml/Symfony/Component/Yaml/phpunit.xml.dist
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+ <testsuites>
+ <testsuite name="Symfony Yaml Component Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./vendor</directory>
+ <directory>./Tests</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>